65.9K
CodeProject 正在变化。 阅读更多。
Home

IE 的 2Find 工具栏 - 另一个示例

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.94/5 (60投票s)

2002 年 3 月 13 日

9分钟阅读

viewsIcon

2625292

downloadIcon

10765

类似 Google 的工具栏,支持 XML 文件自定义和 Web 功能更新。

引言

这个工作示例基于Rashid Thadha 的 IE 工具栏示例。我尝试整合了谷歌工具栏中的大部分功能(以及一些新功能)。它现在看起来非常像谷歌工具栏,并且您甚至可以自定义它。

我计划在工具栏的主页上列出支持的错误和功能。希望会有更多的图片、常见问题解答和知识库。

特点

  • 工具栏可以完全通过xml 文件进行自定义。
  • 不需要资源文件。
  • 自动更新工具栏和所有媒体文件。
  • 自动检测更改的文件并从 Web 服务器下载。
  • 在 VC.Net 下编译、链接和运行。
  • 多级菜单
  • TEXT 标签 - 您可以创建带有静态文本的图标!
  • 添加了*许多*组合框
  • PAGE 标签 - 您可以将 HTML 页面插入到工具栏中。
  • .CAB 包。我演示了如何制作安装包。
  • POST 请求
  • 包含额外的 XML.
  • 组合框具有(历史记录和自动完成功能),您可以定义多个不同的 Web 引擎。
  • 按钮、大按钮(带有不同大小的图像)、分隔符、带有图像和项目提示的下拉菜单。
  • 按钮的工具提示。
  • 搜索组合框的拖放
  • 箭头.
  • 选项、关于页面。
  • 在新的/旧的/模态对话框窗口中打开本地/Web URL。
  • 高亮单词并在 HTML 页面中进行增量查找(类似于谷歌工具栏)。
  • 直接从 Web 浏览器卸载工具栏。
  • 选项页面中的运行时隐藏、禁用按钮、更改组合框大小和其他选项(详见选项)。
  • 鼠标进入时更改图像。
  • 在 DLL 注册期间自动打开 IE 并可视化工具栏。
  • 主菜单中按钮的单选/拆分/无类型。
  • 您可以在 Web URL 和帖子数据中使用当前 URL、域、toolbar_id 等。
  • MENU 标签中的 `hot_img` 属性 - 所有图标都可以在鼠标悬停事件上更改。
  • 一些命令被替换为新的SPECIAL命令类型。
  • 组合框包含预定义值。
  • 您可以通过JavaScript设置/获取工具栏的属性,使用 put_NID、put_Pass、get_ver。
  • 卸载会移除所有下载的文件。
  • 添加了xmill 支持以压缩 XML 文件。
  • 在标准工具栏中添加了图标以显示/隐藏您的工具栏。
  • 从工具栏菜单显示/隐藏工具栏。
  • 使用 InternetConnect、HttpOpenRequest 等函数发起 POST 请求。
  • TAB 键可以在组合框之间切换。
  • 禁用组合框中的鼠标滚轮。
  • 热图可以包含在多级菜单中。
  • 从资源加载 XML 和其他图像。
  • 从外部 DLL 文件加载图像。
  • 多种字体选择。
  • 可以通过安装程序“运行”更新。
  • 您可以使用简单的标准菜单(无图像)。
  • 您可以检查用户是否更改了本地文件。
  • 鼠标悬停事件时将文本颜色更改为蓝色。
  • 执行外部程序。
  • TAB 现在可以从标准地址栏跳转到第一个组合框,然后是下一个组合框……再回到地址栏。Shift 键也起作用。
  • 现在您可以插入不仅是组合框,还有编辑控件。(参见 BandEditCtrl.inl 中的第 81 行)。

新功能

  • Script 标签 - 可以执行 Java 脚本!
  • 源代码进行了一些重组(一如既往),我尝试添加了更多注释。
  • 您可以在带有位图(不是图标!)的按钮中添加文本。
  • 在 HTML 页面中添加了示例上下文菜单处理程序 - 选择一些文本并在 HTML 中右键单击鼠标即可调用弹出菜单。
  • 现在您可以在 XML 文件中放入多种字体,我会找到用户计算机上安装的第一个。
  • Ticker 控件,欢迎评论。
  • 修复了许多资源和内存泄漏。
  • 显示/隐藏机制:添加了 `vis_id` 参数 - 现在您可以隐藏每个按钮和每个菜单项!!
  • 修复了 Split 菜单中带有图标的菜单的状态栏提示。
  • 添加了搜索参数的编码。
  • 添加了更新 DLL 的机制。有关详细信息,请参阅 `UPDATE_DLL` 定义。
  • 在选项页面中添加了直接参数以将搜索添加到列表中(`addtoselect` - 设置为“yes”)。
  • 当时是凌晨 1:00,我决定在这个项目中添加一个小的 `TBInfo` 结构。看看它 - 也许您不知道这项技术,您会喜欢的。
  • `wordfindHint` 属性 - 现在您也可以看到为“查找”自动生成的按钮的提示。
  • 添加了新的机制来监控与 WWW 的连接,尚未完成。
  • 从设置中移除了 Scope 属性 - 现在通过 CHECKBOX 实现。

我确定我忘记了实现的一些其他功能 :( 请查看源代码以找到更多... :)

安装

要安装工具栏:运行“regsvr32.exe %path%\2Find.dll”。它将检查同一目录中的 *2find.xml* 和其他一些文件。如果它们不存在,它将尝试从 http://zmike.chat.ru/toolbar 目录下载它们。如果无法完成,它将在 IE 中显示一个“空的”工具栏。在新版本中,您可以在 IE 中打开 *toolbar_sample.html*,安装过程将自动开始。注意:您可以使用 WinZip 从 .cab 文件中提取 .dll 文件。

构建

您必须下载并安装Microsoft Platform SDK(至少 Core SDK)。同时检查您是否安装了 Visual Studio 的 SP5。在 NT4 上,请确保已安装 SP6a。

在 Platform Sdk 的第一个包含目录中添加(例如 VC++ -> Tools -> Options -> Directories -> Include files 中的“E:\Microsoft Platform SDK\Include”)。例如

为了帮助您(如果您不想下载和安装 Platform SDK),我已将 Platform SDK 中必要的压缩包含文件放在此处。使用最新的 WinRar 解压缩它们。

  1. 将 .rar 解压到某个文件夹。
  2. 然后将其添加到 VC 头目录中(列表的顶部)。
  3. 重新构建项目。

不要忘记包含 WTL 库(7.0)。查看 *NamesInc.cpp* 中的一些重要常量。

为了帮助您(如果您不想下载和安装 Platform SDK),我已将 Platform SDK 中压缩的包含文件放在此处。使用最新的 WinRar解压缩它们。

  1. 将 .rar 解压到某个文件夹。
  2. 然后将其添加到 VC 头目录中(列表的顶部)。
  3. 重新构建项目。

不要忘记WTL 库。查看 *NamesInc.cpp* 中的一些重要常量。

示例概述

我将在此仅描述我添加/更改的差异和新功能。有关更多详细信息,请参阅Rashid Thadha 的 IE 工具栏示例。要实现自动检测更改文件并从 Web 服务器下载文件 - 该功能并且防止在客户端更改工具栏(在此示例中禁用)。我使用 `GetCRC` 函数计算每个本地文件的 CRC,将其存储在注册表中,如果文件已更改,则从 Web 服务器下载更新的文件。在此示例中,我禁用了此功能:取消注释 `/*|| oldcrc!=newcrc*/` 字符串以启用它。

您甚至可以在 Web 服务器上创建 .asp 文件,并发送一个 .xml 文件(包含设置)作为其输出。查看这些行:

#ifdef _ECOACH
	if (sstrFile == _bstr_t(L"ecoach.xml"))
		sstrFile = L"ecoach.asp";
#endif

这是打开新 Web 浏览器以显示和启用工具栏的主要代码。

IWebBrowser2 *pIE;
HRESULT hr =  CoCreateInstance(CLSID_InternetExplorer, NULL,
                               CLSCTX_LOCAL_SERVER,
                               IID_IWebBrowser2,(void**)&pIE);
pIE->put_Visible(VARIANT_TRUE);

VARIANT vtBandGUID;
VARIANT vtShow;
VARIANT vtNotUsed;
vtBandGUID.vt = VT_BSTR;
vtBandGUID.bstrVal = SysAllocString( pszBarCLSID );
vtShow.vt = VT_BOOL;
vtShow.boolVal = bShow;
vtNotUsed.vt = VT_INT;
vtNotUsed.intVal = 1;
HRESULT hr = pIE->ShowBrowserBar(&vtBandGUID, &vtShow,
	&vtNotUsed);
SysFreeString(vtBandGUID.bstrVal);

这是如何在一个已打开的页面中注册 `OnChange` 事件处理程序的示例。

IHTMLElementPtr e3 = NULL;
pHtmlDoc3->getElementById(_bstr_t(m_id.c_str()),&e3);
if (e3)
{
  IHTMLDocument2Ptr pHtmlDoc2 = pHtmlDoc3;

  IHTMLSelectElement *e = NULL;
  HRESULT  hr= e3->QueryInterface( __uuidof( IHTMLSelectElement ),
                                  (void**)&e);
  e3->Release();
  if (e)
  {
   LPDISPATCH dispFO
          = CHtmlEventObject<CBANDTOOLBARCTRL>::CreateHandler(ctrl,
                                CBandToolBarCtrl::OnSelChange, 1);

   VARIANT vIn;
   V_VT(&vIn) = VT_DISPATCH;
   V_DISPATCH(&vIn) = dispFO;
   hr = e->put_onchange( vIn );
  }
 }

这是处理程序的原型。

void OnSelChange( DISPID id, VARIANT* pVarResult );

我使用这些函数来检测是否有任何文档(例如选项页面)已加载。

BEGIN_SINK_MAP(CPugiObj)
  SINK_ENTRY_EX(0, DIID_DWebBrowserEvents2, DISPID_ONQUIT, OnQuit)
  SINK_ENTRY_EX(0, DIID_DWebBrowserEvents2, DISPID_DOWNLOADCOMPLETE,
                OnDownloadComplete)
END_SINK_MAP()

我们还可以修改已加载的页面和/或添加新元素。

IHTMLElementPtr element;
hr = pHtmlDoc2->createElement(_bstr_t(L"OPTION"),&element);
IHTMLOptionElementPtroption = element;
option->put_text(_bstr_t(ctrl->m_toolbar->
                          m_toolbarItems[b]->m_caption.c_str()));
hr = e->add(element,_variant_t(long(-1)));

或者更改旧的。

IHTMLInputElement *i = NULL;
HRESULT  hr = el->QueryInterface( __uuidof( IHTMLInputElement),
                                  (void**)&i );
if (i)
{
   i->put_checked(VARIANT_TRUE);i->Release();
}

我使用此代码从磁盘加载位图。

 CImageList list;
 list.CreateFromImage((wchar_t*)filebmp,bSize.cy,0,
                      CLR_DEFAULT,IMAGE_BITMAP,
                      LR_CREATEDIBSECTION|LR_LOADFROMFILE);

此代码从资源加载。

CImageList ilCool;
ilCool.CreateFromImage(IDB_TOPICONS,16,0, CLR_DEFAULT,IMAGE_BITMAP,
	LR_CREATEDIBSECTION);
m_wndToolBar.SetImageList(ilCool);

此代码从另一个 .dll 文件加载。

    h_image = LoadLibrary(filebmp.c_str());
    EnumResourceNames(h_image,RT_BITMAP,EnumResNameProc,0);
    CImageList list;
    list.Create (bSize.cx,bSize.cy,ILC_COLORDDB|ILC_MASK,0,1);
    list.Add(LoadImage(s),clr_format);

这是附加的属主绘制菜单。

handle.AppendMenu(MF_OWNERDRAW,WM_MENU_USER + MAX_MENU_SIZE*id +j,
                  LPCTSTR(pMI));

我添加了这个处理程序来处理默认函数,您可以在 Platform SDK 中找到它们。

MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem)
MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem)

预期的多级菜单!
查看“菜单”按钮中的 `

` 标签和 `virtual void appendMenu(CMenuHandle handle,...)` 函数。

CAB 包

我演示了如何制作安装包。使用 CabArc.Exe、makecert.exe、exptext.exe、signcode.exe。有关详细信息,请参阅 *toolbar_sample.bat* 和 *toolbar_sample.html*。

POST 请求

查看 `WEBJUMP` atg 中 post 属性以及最有趣的 `getPostData` 函数,该函数使用 `byteSafeVector` 类。

包含额外的 XML。

使用 `INCLUDEXML` 标签。

(<INCLUDEXML>toolbar_sample_ex.xml</INCLUDEXML>)
在 XML 文件中

主菜单中按钮的单选/拆分/无类型。

`Menu` 标签的 `type` 属性,有关详细信息,请参阅 .XML

您可以在 Web URL 和帖子数据中使用当前 URL、域、toolbar_id 等。
`%url` - 当前 URL
`%d` - 域
`%nid` - 工具栏 ID
还有一些其他的 - 有关详细信息,请参阅源代码。

一些命令被替换为新的 `SPECIAL` 命令类型。命令类型:ClearHistory、Search、Uninstall、Update、Switch to、Make Default Toolbar、Hide toolbar 等,有关详细信息,请参阅 Special 类和 `SPECIAL` 标签。

您可以通过 JavaScript 设置/获取工具栏的属性,使用 put_NID、put_Pass、get_ver。
有关详细信息,请参阅 *toolbar_sample.html*。

卸载会移除所有下载的文件。

我将它们存储在 HKEY_CURRENT_USER\Software\toolbar_sample\toolbar_sample\Historyfiles 中。
并在 Windows 重启时删除 .dll。我在 RunOnce 注册表项中写入了一个值。

添加了 xmill 支持以压缩 XML 文件。

我没有在此示例中添加源代码,但您可以轻松插入它。请参阅 *XmlParserImpl.cpp* 中的 `_XmlParserImpl::parse`

在标准工具栏中添加了图标以显示/隐藏您的工具栏。

  CRegKey keyAppID;
  keyAppID.Create(HKEY_LOCAL_MACHINE,
  	_T("SOFTWARE\\Microsoft\\Internet Explorer\\Extensions
\\{C6A4CB5E-ACE2-4256-8864-059BDA996CE7}"));
  _bstr_t ico = getprogpath() + "favicon.ico";
  keyAppID.SetValue("Praize", "ButtonText");
  keyAppID.SetValue("{E0DD6CAB-2D10-11D2-8F1A-0000F87ABD16}", "CLSID");
  keyAppID.SetValue("yes", "Default Visible");
  keyAppID.SetValue(ico, "HotIcon");
  keyAppID.SetValue(ico, "Icon");
  keyAppID.SetValue("Praize", "MenuStatusBar");
  keyAppID.SetValue("&Praize", "MenuText");
  keyAppID.SetValue(bandUUID, "BandCLSID");

PAGE 标签 - 您可以将 HTML 页面插入到工具栏中。

查看...

class CPage :
       public IDispEventImpl<1, CPage, &DIID_DWebBrowserEvents2, 
                            &LIBID_SHDocVw, 1, 0>,
       public CWindowImpl<CPage,CAxWindow>

...有关详细信息 - 它很简短。

多级菜单中的热图。

我对 CCommandBarCtrlImpl::DrawItem3D 函数进行了一些修改。

从资源加载 XML 和图像。

查找 `USE_RESOURCE_FILES` 定义。

从外部 DLL 文件加载图像。

查找 `EnumResourceNames(h_image,RT_BITMAP,EnumResNameProc,0);` 并查看详细信息。

多种字体。

您可以在 XML 中添加多个 `` 标签。

还有

  • 更新可以从安装程序“运行”。查找 `UPDATE_DLL_FROM_EXE` 获取详细信息。
  • 您可以使用简单的标准菜单(无图像)。查找 `_USE_SIMPLE_MENU` 获取详细信息。
  • 您可以检查用户是否更改了本地文件。查找源代码中的 `_DONT_CHECK_VERSION_FILE`。
  • 在鼠标悬停事件时将文本变成蓝色:有关详细信息,请参阅 `CBandToolBarReflectorCtrl::OnItemPrePaint`。
  • 执行外部程序。执行外部应用程序,例如
<SHELLEXECUTE name="Send mail"
	command="mailto:mtscf@microsoft.com?subject=Feedback&body=
The%20InetSDK%20Site%20Is%20Superlative"
	not_found="Can't send email"/>

所有其他功能和实现均参考 MSDN 和 codeproject 网站!

自动完成和工具提示。

箭头

搜索组合框中的拖放。

鼠标进入时更改图像,所有按钮都使用图像。

XML架构

您可以在此处查看 XML 源代码。

我正在使用我自己的XML 解析器助手来处理它。

选项

请注意,选项页面中没有任何脚本。我使用事件来设置/获取设置。您可以在此处查看 HTML 文本。

Adrian Bickle 协助我编辑了这篇文章。我计划添加更多关于实现的细节。但请告诉我您对哪些内容更感兴趣。

Victor Chiel 制作了一个很好的 Bug、修复、请求、安装问题索引

我计划在工具栏的主页上支持 Bug 列表和功能列表。
希望会有更多的图片、常见问题解答和知识库。
所以,您随时欢迎。

感谢您的关注。

历史

  • v1.0.0 (2002 年 3 月 13 日) 初始发布
  • v1.0.4 (2002 年 3 月 22 日) 修复了在 Win98 上注册的问题。修复了一些在离线模式下与 IE 相关的问题。
  • v1.0.5 (2002 年 11 月 22 日) 添加/删除了许多功能/Bug。最重要的是:VC.Net 支持,多级菜单。
  • v1.1.0 (2003 年 2 月 1 日) 添加/删除了许多 Bug。
  • v1.2.0 (2003 年 5 月 29 日) Ticker 控件、Script 命令、上下文处理程序、一些其他外观上的更改。


© . All rights reserved.