暨南区庆彬:
请先看看附件中的两幅图片,注意红框框住的地方。1.jpg 是OutLook中的部分界面,2.jpg 是win98中的资源管理器中的部分界面,在VB、VC中,都提供了一个叫listview的控件,它的样式跟2.jpg一样,点击时只有红框框住的地方有兰色条,同一行的其它部分却没有,而点击这部分时却不能选定这一行。但在1.jpg中,却能实现上面所说的缺少的功能:即单击一行中的任何部分,都能选定一行,且能整行加兰色底。请问在VB和VC中怎样才能实现这种功能呢?
李海:对于大多数用户来说,Outlook的整行选中更舒服一些。Outlook实际上利用了ListView的一个未公开的设置。只要你的Comctl32.dll的版本高于3.71,就可以使用这一技巧。下面我们以VB为例说明:
首先,在窗体中加入如下声明
Private Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
Const LVS_EX_FULLROWSELECT = &H20
Const LVM_FIRST = &H1000
Const LVM_GETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + &H37
Const LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + &H36
在窗体上加上一个ListView和一个按钮,并输入如下代码:
Private Sub Command1_Click()
Dim lStyle As Long
lStyle = SendMessage(ListView1.hwnd, _
LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0)
lStyle = lStyle Or LVS_EX_FULLROWSELECT
Call SendMessage(ListView1.hwnd, _
LVM_SETEXTENDEDLISTVIEWSTYLE, 0, ByVal lStyle)
End Sub
Private Sub Form_Load()
'Add two Column Headers to the ListView control
Set clmAdd = ListView1.ColumnHeaders.Add(Text:="Name")
Set clmAdd = ListView1.ColumnHeaders.Add(Text:="Date")
'Set the view property of the Listview control to Report view
ListView1.View = lvwReport
'Add data to the ListView control
Set itmAdd = ListView1.ListItems.Add(Text:="Joe")
itmAdd.SubItems(1) = "05/07/97"
Set itmAdd = ListView1.ListItems.Add(Text:="Sally")
itmAdd.SubItems(1) = "04/08/97"
Set itmAdd = ListView1.ListItems.Add(Text:="Bill")
itmAdd.SubItems(1) = "05/29/97"
Set itmAdd = ListView1.ListItems.Add(Text:="Fred")
itmAdd.SubItems(1) = "05/17/97"
Set itmAdd = ListView1.ListItems.Add(Text:="Anne")
itmAdd.SubItems(1) = "04/01/97"
End Sub
只要你按下按钮,你就会发现你的ListView也可以象Outlook一样工作了。
回到开始(1)我使用EXCEL 97中的VBA编制了大量的代码,可是近来我发现VBA的速度慢的几乎无法忍受,于是我打算使用VB 5.0编译这些代码,使之成为EXE文件,可是我该如何将这些EXE文件集成到EXCEL 97的界面中呢?
(2) 我在使用VBA时发现“控件工具箱”中的控件太少,连DriveListBox、DirListBox、FileListBox这样的控件都没有,使用“附加控件”也没有找到这些控件,应怎样添加这些控件?
李海:(1)比较好的办法是编写Automation服务器或者编写ActiveX控件。我们将在下一个问题的回答中介绍如何编写ActiveX控件,先来说说如何编写Automation服务器。
首先启动VB 5.0,在New Project窗口中选择ActiveX DLL或ActiveX EXE(前者速度更快些)。这时你的工程文件中将包括一个Class1,你可以在属性窗口中将它的名字改为MyClass。在Project菜单下选择Project1 Properties修改工程的名字为MyComponent。在MyClass中插入以下代码:
Option Explicit
Public Function SquareIt(lngNumber As Long)
SquareIt = lngNumber ^ 2
End Function
你可以利用类似的步骤插入其它函数。调试时,你可以在集成环境中运行程序,在Excel中调用这个Automation服务器。调试结束后,编译成DLL或EXE就可以了。
下面再来谈谈如何在Excel中调用Automation服务器。首先启动Excel 97,然后打开Visual Basic编辑器,选择“工具|引用”菜单,在其中选择MyComponent。然后你可以在一个过程、函数或事件中加入以下代码:
'建立对象
Dim obj As MyComponent.MyClass
Dim lngArgument As Long
Dim lngResult As Long
'建立对象实例
Set obj = New MyClass
lngArgument = 2
'调用SquareIt方法
lngResult = obj.SquareIt(lngArgument)
MsgBox "The Square of " & lngArgument & _
" is " & lngResult
'结束
(2)你所说的几个控件都是VB的内置控件,它们不是ActiveX控件,所以你不能在“附加控件”找到。既然你对VB 5.0很熟悉,完全可以利用VB 5.0编写ActiveX控件,然后在VBA中加以调用。
首先启动VB 5.0,在New Project窗口中选择ActiveX Control。这时你的工程文件中将包括一个UserControl1。在Project菜单下选择Project1 Properties修改工程的名字为MyFileControl。然后在UserContronl1上放置一个标准的VB的FileListBox,然后选择Add-ins菜单中的ActiveX Control Interface Wizard。如果你的Add-ins菜单中没有这项,你需要在Add-ins菜单的Add-ins Manager中加上这项。这个Wizard是用来向你控件中加入属性、方法和事件的。在第一步你要决定加入哪些属性、方法和事件,你可以在左边的列表框中选择所有标准的属性、方法和事件,加入到右边列表框中。一些FileListBox的核心属性、事件,象Path、PathChange、Pattern当然不能缺少。第二步,你可以加入自己的属性,如果没什么属性可以加的,就跳过这一步。第三步是建立你的控件的属性和File1之间的关联(下图),这一步你只要将File1的属性、事件与你的控件的相同名字的属性、事件关联起来就行了。然后,一直继续下去直至结束。最后,在UserControl_Resize事件中加入如下代码。
Private Sub UserControl_Resize()
File1.Width = UserControl.Width
File1.Height = UserControl.Height
File1.Move 0, 0
End Sub
至此,一个FileListBox控件就制作好了,编译生成.ocx文件。在使用VBA时在“控件工具箱”中加入MyFileControl控件,你就可以使用自己的文件框了。类似的,你还可以处理VB的其它控件。
图 建立用户控件同File控件属性和事件的对应关系
回到开始dunlop
如何防止同一个VFP程序被重复运行多次?
李海:你可以使用Windows API函数FindWindow来做。FindWindow函数需要两个参数,一个是要寻找的窗口的标题,一个是窗口的类。如果找到符合条件的窗口,该函数返回窗口句柄,如果没找到,返回0。在下面的程序中,我们假定你的软件的标题为My Application。
SET LIBRARY TO SYS(2004)+"foxtools.fll" ADDITIVE
GetWind = RegFn("FindWindow", "CC", "I")
* 将getwind的第一个参数设为0。
wclass=0
winname="My Application"
apphand=CallFn(GetWind,wclass ,winname)
*如果找到窗口,停止运行
IF apphand<>0
WAIT WINDOW ;
"你不能运行'My Application'两次!"
QUIT
ENDIF
MODIFY WINDOW screen TITLE "My Application"
WAIT WINDOW ;
"第一个'My Application'已经运行了。"
刘顺
在VB中如何直接对内存口地址进行数据读写?(我需要与电脑内的一块通讯卡进行数据交换,其地址为300H,301H。)
李海:这是我最经常被问到的三个问题之一(另两个是VB是否是面向对象的语言和如何打印DBGrid)。VB不象Quick Basic那样,它没有提供Inp、Out这样的语句来直接操作I/O口。在去年的两期(98年2期和98年4期)中,我介绍了如何使用C语言编写一个DLL,然后在VB中进行调用。不过很多VB的用户不熟悉C语言,在编译DLL上遇到了一些麻烦。你可以从我的网站下载编译好的VBIO.DLL。在这个软件中包括有VB的程序示例,你可以参考。
回到开始Keen Wang
我的Java VM出问题了:IE4不能正常显示含有Java插件的网页,要么是一块灰色,要么只显示一个图标,即使重新安装也不能解决。我怀疑这跟注册表有关,是这样吗?请问如何解决?
李海:你的问题可能是由于注册表问题,也可能不是。你可以按下面的步骤来检查。
http://www.microsoft.com/ie/most/howto/java.htm
http://www.microsoft.com/ie/ie40/features/ie-java.htm
如果你能够访问这两个站点,则说明你的IE没什么问题。下面我们假定你的IE不能访问所有Java站点。
此外,如果你重新安装IE4,应该先完全卸载,然后再安装。
回到开始
如果您有任何建议,请给我发电子邮件:
。
版权所有 李海,热情软件屋 1997-2006