想不想给你的 IE 工具条加一个自定义按钮,就像“网络蚂蚁”“金山词霸”“金山卓越”的那种?听我介绍后,马上就会实现你的愿望。
与大多数软件的高级功能一样,以上软件在 IE
工具条上加入的自定义按钮也是通过操作 Windows 的注册表来实现的。仔细分析安装这些软件后注册表的变化,会发现它们都是在注册表的
HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Extensions
子键下分别以不同的 GUID 进行注册的。GUID 是 Globally Unique Identifier(全球用户标识码)的首字母缩写,代表该软件的唯一标识码,通过特殊方法产生。比如注册表中“词霸”的 GUID 为 {8DE0FCD4-5EB5-11D3-AD25-00002100131B}。
这些 GUID 下基本包含以下信息:
ButtonText
按钮上显示的文本
clsid
IE 工具条的类标识码,为 "{1FBA04EE-3024-11D2-8F1F-0000F87ABD16}"
Default Visible 按钮是否可见,一般为 "Yes"
Exec
按钮执行的目标,为可执行文件或超文本链接等
HotIcon
鼠标移上按钮时显示的图标,取自 EXE 文件或 DLL 文件
Icon
按钮正常显示的图标,取自 EXE 文件或 DLL 文件
MenuText
在 IE 的“工具”菜单中显示的菜单项
MenuStatusBar IE“工具”菜单项的解释,显示在状态条上
明白了以上含义之后,事情就变得简单了。我们完全可以通过手工建立键值的方法来给 IE
工具条上添加一个自定义按钮。假设我们的各参数值如下(可执行文件为 C:\Add2IEToolbar\Add2IEToolbar.exe):
ButtonText = "测试"
clsid = "{1FBA04EE-3024-11D2-8F1F-0000F87ABD16}"
Default Visible = "Yes"
Exec = "C:\Add2IEToolbar\Add2IEToolbar.exe"
HotIcon = "C:\Add2IEToolbar\Add2IEToolbar.exe,101"
Icon = "C:\Add2IEToolbar\Add2IEToolbar.exe,102"
MenuStatusBar = "运行张庆的测试程序"
MenuText = "张庆的测试程序"
GUID 码可以临时取一个,只要位数为 36 位就可以了。而图标显示行的数字“…,101”,“…,102”是指已经编译进 EXE 文件的图标的序号,怎么知道这个序号呢?这和资源文件(*.RES)有关,下面我还要讨论。事实上如果 IE
找不到这个图标资源,它的按钮还是可以显示的,不过呈灰色罢了。经过以上的手工设置,打开 IE,我们已经可以看到工具条最右边有了一个自定义按钮了。
实际上手工操作注册表十分不方便且有一定的危险性。为了达到方便快捷和在我们自己的程序中应用这一技术的目的,我们下面讨论怎么用 VB
程序来实现按钮的添加,这其中还涉及到 GUID 码的产生和资源文件图标资源的应用。
一、产生 GUID 号
我们手工设置按钮时可能随便使用了一个 GUID 号,在自己的机器上也许不会和别的已注册程序的 GUID 号重复。但是对于一个对外发布的成品软件,这个号码就必须用专门的工具产生,以保证其唯一性。好在微软的 Visual Studio6.0 系列软件中的 VC++ 提供了这个工具,它使用了特别的算法以确保其产生的 GUID 号是唯一的。运行 VC++6.0,打开一个工程,按以下操作“Project\Add to Project\Components and Controls\Visual C++ Components\GUID Generator”,按“Insert”按钮,确定,选第 4 项“Registry Format”,再按“Copy”按钮,GUID 生成器就将一个新产生的 GUID 号拷贝到了剪贴板上。我制做示例程序时粘贴回来的 GUID 号为 {3FA4FB86-E43A-11D4-B3DD-00E006E25C0B}。
二、在 EXE 文件中包含 ICO 资源
从 VB6.0 开始,VB 可以编辑自己的资源文件,包含图标、位图、光标、字符串等资源。我们的例子中需要加入图标文件。当然首先要用图形编辑器生成两幅图标文件,最好是同一幅图片的彩色、黑白版本。然后在 VB6.0 中执行菜单项“外接程序\外接程序管理器”,选中“VB 6 资源编辑器”,确定。这时“工具”菜单下应当出现“资源编辑器”菜单项,点击执行,弹出“VB 资源编辑器”窗口,再点击工具条上的“添加图标”按钮,选中我们制做的两幅图标文件,资源编辑器会自动给它们编号,我们就是用这些编号来定位 EXE 文件中的图标资源的。示例中两幅图标的编号分别为 101,102。
三、用 VB 操作 Windows 的注册表
这是我们本例的关键。操作注册表必须调用 Windows 的有关 API 函数,使用时必须先声明再调用。本例用 Windows 提供的原始 API 函数制做了两个存取注册表字符串的函数 SaveString、DeleteValue,分别用来保存、删除字符串型键值。只要你曾经应用过 API 函数,这些也很好理解。
本示例程序的设计界面如(图 1)所示,文本框中显示了它们的控件名称,上面的标签分别标明了它们的内容。最下面“保存”“删除”“退出”三个命令按钮的控件名称分别为 cmdSave、cmdDelete、cmdExit。
(
图一)
程序在 C:\Add2IEToolbar
文件夹下执行,界面如(图 2)所示,执行结果与手工键入相同。可以修改 ButtonText、MenuText、MenuStatusBar 三个文本框的值,其它值取程序默认,按“保存”按钮将结果写入注册表。然后打开 IE
浏览器就会看到工具条上我们的自定义按钮,同时在 IE 的“工具”菜单下会看到“张庆的测试程序”菜单项,点击此菜单项和点击自定义按钮的效果相同。
程序的源代码如下:
Option Explicit
'定义注册表常量
Private Const HKEY_LOCAL_MACHINE = &H80000002
(图二)
Private Const REG_SZ = 1
'声明存取注册表的有关 API 函数
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Private Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey As Long, ByVal lpValueName As String) As Long
Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpData As Any, ByVal cbData As Long) As Long
'定义注册表中的主键、子键、GUID 号
Private Const hKey = HKEY_LOCAL_MACHINE
Private Const GUID = "{3FA4FB86-E43A-11D4-B3DD-00E006E25C0B}" 'GUID 号对不同的程序必须是唯一的!
Private Const subKey = "Software\Microsoft\Internet Explorer\Extensions\" & GUID & "\"
'把字符串值存入注册表
Private Sub SaveString(hKey As Long, strPath As String, strValue As String, strdata As String)
Dim keyhand As Long
Dim r As Long
r = RegCreateKey(hKey, strPath, keyhand)
r = RegSetValueEx(keyhand, strValue, 0, REG_SZ, ByVal strdata, Len(strdata))
r = RegCloseKey(keyhand)
End Sub
'从注册表删除键值
Private Function DeleteValue(ByVal hKey As Long, ByVal strPath As String, ByVal strValue As String)
Dim r, keyhand As Long
r = RegOpenKey(hKey, strPath, keyhand)
r = RegDeleteValue(keyhand, strValue)
r = RegCloseKey(keyhand)
End Function
Private Sub Form_Load()
Dim txt As Control
For Each txt In Me.Controls '清空窗口内所有文本框
If TypeOf txt Is TextBox Then
txt.Text = ""
End If
Next txt
'以下为本程序的测试取值
txtButtonText = "测试"
txtClsid = "{1FBA04EE-3024-11D2-8F1F-0000F87ABD16}" '本值不能修改
txtdefa_visi = "Yes" '一般不修改
txtExec = App.Path & "\Add2IEToolbar.exe"
txtHotIcon = App.Path & "\Add2IEToolbar.exe,101"
txtIcon = App.Path & "\Add2IEToolbar.exe,102"
txtMenuStatusBar = "运行张庆的测试程序"
txtMenuText = "张庆的测试程序"
txtGUID = GUID
txtGUID.Locked = True
txtClsid.Locked = True
End Sub
'将设置存入注册表中(定义按钮):
Private Sub cmdSave_Click()
Call SaveString(hKey, subKey, "ButtonText", txtButtonText)
Call SaveString(hKey, subKey, "clsid", "{1FBA04EE-3024-11D2-8F1F-0000F87ABD16}")
Call SaveString(hKey, subKey, "Default Visible", "Yes")
Call SaveString(hKey, subKey, "Exec", App.Path & "\" & App.EXEName & ".EXE")
Call SaveString(hKey, subKey, "HotIcon", App.Path & "\" & App.EXEName & ".EXE,101")
Call SaveString(hKey, subKey, "Icon", App.Path & "\" & App.EXEName & ".EXE,102")
Call SaveString(hKey, subKey, "MenuStatusBar", txtMenuStatusBar)
Call SaveString(hKey, subKey, "MenuText", txtMenuText)
End Sub
'删除自定义按钮
Private Sub cmdDelete_Click()
Call DeleteValue(hKey, subKey, "ButtonText")
Call DeleteValue(hKey, subKey, "clsid")
Call DeleteValue(hKey, subKey, "Default Visible")
Call DeleteValue(hKey, subKey, "Exec")
Call DeleteValue(hKey, subKey, "HotIcon")
Call DeleteValue(hKey, subKey, "Icon")
Call DeleteValue(hKey, subKey, "MenuStatusBar")
Call DeleteValue(hKey, subKey, "MenuText")
End Sub
'退出程序:
Private Sub cmdExit_Click()
End
End Sub
说明:
1,本程序中自定义按钮的动作指向程序本身,点击按钮会将本程序运行起来;
2、程序运行后锁定了 Clsid 和 GUID 两个文本框,避免了试验时向注册表中写入过多的无用信息;
3、如果把 Default Visible 值设为 No,则按钮不可见,但可以看见“工具”菜单下添加的菜单项;
4、ButtonText
键的取值最好不超过两个汉字长度,否则影响所有按钮的宽度,有碍美观;
5、如果添加 2 个以上按钮,有时后添加的按钮不能在工具条上显示,这时可以在 IE 工具条上按鼠标右键,在弹出的菜单中点击“自定义”,再点击“重置”按钮即可。如果 IE
工具条上的按钮太多,最好选择小图标选项比较美观。工具条上的按钮不宜太多。
张 庆 2001 年 1 月 9 日
|