<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Free2000fly&#039;s Official Blog &#187; Internet Explorer Programming</title>
	<atom:link href="http://blog.tinybrowser.net/archives/category/internet-explorer-programming/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.tinybrowser.net</link>
	<description>Free2000fly 个人博客</description>
	<lastBuildDate>Fri, 06 Jan 2012 21:12:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>IE 工具栏插件例子</title>
		<link>http://blog.tinybrowser.net/archives/341</link>
		<comments>http://blog.tinybrowser.net/archives/341#comments</comments>
		<pubDate>Thu, 14 Jan 2010 13:59:27 +0000</pubDate>
		<dc:creator>free2000fly</dc:creator>
				<category><![CDATA[Internet Explorer Programming]]></category>

		<guid isPermaLink="false">http://blog.tinybrowser.net/?p=341</guid>
		<description><![CDATA[原始链接在 codeproject 修正了在 IE7 及更高版本下崩溃的问题. 下载地址 微软的文章 微软提供的例子 Creating Custom Explorer Bars, Tool Bands, and Desk Bands 源码(很清晰) ATL 实现定制的 IE 浏览器栏, 工具栏和桌面工具栏 源码 用 VC6 实现 IE 工具栏 源码 Internet Explorer 编程简述 (9) 在自己的浏览器中嵌入 Google 工具条]]></description>
		<wfw:commentRss>http://blog.tinybrowser.net/archives/341/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>老文章 &#8212; TWebBrowser编程简述</title>
		<link>http://blog.tinybrowser.net/archives/178</link>
		<comments>http://blog.tinybrowser.net/archives/178#comments</comments>
		<pubDate>Tue, 05 Jan 2010 07:28:24 +0000</pubDate>
		<dc:creator>free2000fly</dc:creator>
				<category><![CDATA[Internet Explorer Programming]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[TWebBrowser]]></category>
		<category><![CDATA[WebBrowser]]></category>

		<guid isPermaLink="false">http://tinybrowser.net/blog/?p=178</guid>
		<description><![CDATA[转贴, 原帖在此: http://blog.csdn.net/cathyeagle/archive/2004/09/03/93984.aspx 引　言 　　这篇文章最先发表于2000年07月25日，最后一次修改是在2001年02月07日。这里再次贴出的目的，一是作为前一阶段的完结，所以文章中的错误都不作修改；二是希望作为一个新的起点。我准备整理一下至今所积累的浏览器编程的知识，比较完整地写出来，与网友共勉。 TWebBrowser编程简述 摘要：Delphi 3开始有了TWebBrowser构件，不过那时是以ActiveX控件的形式出现的，而且需要自己引入，在其后的4.0和5.0中，它就在封装好shdocvw.dll之后作为Internet构件组之一出现在构件面板上了。常常听到有人骂Delphi的帮助做得极差，这次的TWebBrowser又是Microsoft的东东，自然不会好到哪里去，虽说MSDN上什么都有，可是内容太过庞杂，如果没有入口点更是件烦人的事，查找起来给人的感觉大概可以用一句话来形容：非常复杂、复杂非常。 　　这里有平时我自己用TWebBrowser做程序的一些心得和上网收集到的部分例子和资料，整理了一下，希望能给有兴趣用TWebBrowser编程的朋友带来些帮助。 １、初始化和终止化（Initialization &#038; Finalization） 　　大家在执行TWebBrowser的某个方法以进行期望的操作，如ExecWB等的时候可能都碰到过“试图激活未注册的丢失目标”或“OLE对象未注册”等错误，或者并没有出错但是得不到希望的结果，比如不能将选中的网页内容复制到剪贴板等。以前用它编程的时候，我发现ExecWB有时侯起作用但有时侯又不行，在Delphi生成的缺省工程主窗口上加入TWebBrowser，运行时并不会出现“OLE对象未注册”的错误。同样是一个偶然的机会，我才知道OLE对象需要初始化和终止化（懂得的东东实在太少了）。 　　我用我的前一篇文章《Delphi程序窗口动画&#038;正常排列平铺的解决》所说的方法编程，运行时出了上面所说的错误，我便猜想应该有OleInitialize之类的语句，于是，找到并加上了下面几句话，终于搞定！究其原因，我想大概是由于TWebBrowser是一个嵌入的OLE对象而不算是用Delphi编写的VCL吧。 　　这几句话放在主窗口所有语句之后，“end.”之前。 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; ２、EmptyParam 　　在Delphi 5中TWebBrowser的Navigate方法被多次重载： 　　而在实际应用中，使用后几种方法调用时，由于我们很少用到后面几个参数，但函数声明又要求是变量参数，一般的做法如下： 　　需要定义变量t（还有很多地方要用到它），很麻烦。其实我们可以用EmptyParam来代替（EmptyParam是一个公用的Variant空变量，不要对它赋值），只需一句话就可以了： 　　虽然长一点，但比每次都定义变量方便得多。当然，也可以使用第一种方式。 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; ３、命令操作 　　常用的命令操作用ExecWB方法即可完成，ExecWB同样多次被重载： 　　打开：　弹出“打开Internet地址”对话框，CommandID为OLECMDID_OPEN（若浏览器版本为IE5.0， 　　　　　　则此命令不可用）。 　　另存为：调用“另存为”对话框。 　　打印、打印预览和页面设置：　调用“打印”、“打印预览”和“页面设置”对话框（IE5.5及以上版本才支持打 　　　　　　　　　　　　　　　　印预览，故实现应该检查此命令是否可用）。 　　剪切、复制、粘贴、全选：　功能无须多说，需要注意的是：剪切和粘贴不仅对编辑框文字，而且对网页上的非编辑框文字同样有效，用得好的话，也许可以做出功能特殊的东东。获得其命令使能状态和执行命令的方法有两种（以复制为例，剪切、粘贴和全选分别将各自的关键字替换即可，分别为CUT,PASTE和SELECTALL）： 　　　A、用TWebBrowser的QueryStatusWB方法。 　　　B、用IHTMLDocument2的QueryCommandEnabled方法。 　　查找：　参考第九条“查找”功能。 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; ４、字体大小 　　类似“字体”菜单上的从“最大”到“最小”五项（对应整数0～4，Largest等假设为五个菜单项的名字，Tag 属性分别设为0～4）。 　　　A、读取当前页面字体大小。 　　　B、设置页面字体大小。 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; ５、添加到收藏夹和整理收藏夹 　　用上面的通过ISHellUIHelper接口来打开“添加到收藏夹”对话框的方法比较简单，但是有个缺陷，就是打开的窗口不是模式窗口，而是独立于应用程序的。可以想象，如果使用与OrganizeFavorite过程同样的方法来打开对话框，由于可以指定父窗口的句柄，自然可以实现模式窗口（效果与在资源管理器和IE中打开“添加到收藏夹”对话框相同）。问题显然是这样的，上面两个过程的作者当时只知道shdocvw.dll中DoOrganizeFavDlg的原型而不知道DoAddToFavDlg的原型，所以只好用ISHellUIHelper接口来实现（或许是他不够严谨，认为是否是模式窗口无所谓？）。 　　下面的过程就告诉你DoAddToFavDlg的函数原型。需要注意的是，这样打开的对话框并不执行“添加到收藏夹”的操作，它只是告诉应用程序用户是否选择了“确定”，同时在DoAddToFavDlg的第二个参数中返回用户希望放置Internet快捷方式的路径，建立.Url文件的工作由应用程序自己来完成。 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; ６、使WebBrowser获得焦点 　　TWebBrowser非常特殊，它从TWinControl继承来的SetFocus方法并不能使得它所包含的文档获得焦点，从而不能立即使用Internet Explorer本身具有得快捷键，解决方法如下：]]></description>
		<wfw:commentRss>http://blog.tinybrowser.net/archives/178/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MFC 程序员的 WTL 教程 ( 6 ) — 宿纳 ActiveX 控件</title>
		<link>http://blog.tinybrowser.net/archives/94</link>
		<comments>http://blog.tinybrowser.net/archives/94#comments</comments>
		<pubDate>Mon, 04 Jan 2010 10:01:55 +0000</pubDate>
		<dc:creator>free2000fly</dc:creator>
				<category><![CDATA[Internet Explorer Programming]]></category>
		<category><![CDATA[MFC 程序员的 WTL 教程]]></category>
		<category><![CDATA[WTL]]></category>
		<category><![CDATA[ActiveX]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[Internet Explorer]]></category>

		<guid isPermaLink="false">http://tinybrowser.net/blog/?p=94</guid>
		<description><![CDATA[链接：上一部分；下一部分 第六部分 &#8211; 宿纳 ActiveX 控件 下载示例工程 &#8211; 63.2 KB 内容 简介 以 AppWizard 开始 创建工程 生成的代码 使用资源编辑器添加控件 用于宿纳控件的 ATL 类 CAxDialogImpl AtlAxWin 和 CAxWindow 调用控件的方法 接收控件激发的事件 在 VC 6 里添加处理器 在 VC 7 里添加处理器 事件的知会 VC 6 里的知会 VC 7 里的知会 示例工程概述 运行时创建 ActiveX 控件 键盘处理 下一步 修订历史 简介 在这第六部分里，我将介绍 ATL 对在对话框中宿纳（hosting）ActiveX 控件的支持。由于 ActiveX [...]]]></description>
		<wfw:commentRss>http://blog.tinybrowser.net/archives/94/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Internet Explorer 编程简述（十三）调用IE隐藏的命令（续）</title>
		<link>http://blog.tinybrowser.net/archives/70</link>
		<comments>http://blog.tinybrowser.net/archives/70#comments</comments>
		<pubDate>Tue, 29 Dec 2009 17:58:57 +0000</pubDate>
		<dc:creator>free2000fly</dc:creator>
				<category><![CDATA[Internet Explorer Programming]]></category>
		<category><![CDATA[CGID_ShellDocView]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[WebBrowser]]></category>

		<guid isPermaLink="false">http://tinybrowser.net/blog/?p=70</guid>
		<description><![CDATA[关键字：CGID_ShellDocView 1、概述 在本系列五《调用IE隐藏的命令》中我们曾经从MSDN的一篇文章给出的ShowContextMenu范例入手，深入shdoclc.dll找到了藏于其中的浏览器上下文菜单资源，并以SendMessage发送WM_COMMAND消息到”Internet Explorer_Server”窗口以及其父窗口”Shell DocObject View”的方法完美实现了对“添加到收藏夹”对话框，“导入/导出向导”对话框等的调用，《自定义浏览器上下文菜单》和《完美的“编码”菜单》也运用了同样的技术。 这次，我们还是从 ShowContextMenu 范例入手，再次挖掘 IE 隐藏的命令——CGID_ShellDocView 的命令。 2、原理 《完美的“编码”菜单》一文所用的技术，其关键在于从浏览器的文档接口查询得到 IOleCommandTarget, 进而调用 CGID_ShellDocView 命令组的命令 CmdID_GetMimeSubMenu(27) 实现将 IE 内置的编码菜单“拿来”使用。好了，既然 CGID_ShellDocView 是一个 Command Group，那么CmdID_GetMimeSubMenu 当然不会是惟一的一个，那为什么不尝试一下将其它可用的命令找出来呢。 3、找命令 先为我们的任务定一个目标：找到那些传入简单Variant参数就能得到可观察的效果或输出参数的命令ID。像CmdID_GetMimeSubMenu(27)这类输出参数需要转换为一个HMENU才有意义的命令，如果没有MSDN的文档，我们只怕打破脑袋也想不出其中的含义，所以这类命令不在目标范围之内。 下面的函数简单地实现了对CGID_ShellDocView命令组命令的调用。 4、命令列表 总算功夫没有完全白费，经过多轮测试（费时费力不一定讨好的工作）之后找到了如下命令: 4.1 编码菜单和文字大小菜单 想不到吧，传入命令ID = 1，编码菜单居然弹出来了！但有些问题，由于vtIn.vt = VT_EMPTY，所以菜单弹出点在屏幕左上角(0, 0)，不过我们倒发挥发挥“猜”的功夫，怎么传入一个POINT呢？先试试把一个POINT的指针强制转换一下传进去，不行；再试试Win32程序设计的风格，两个坐标一个放高位，一个放低位拼成一个长整数，再以VT_I4传入，这次成功了。所以我们写出下面的函数： nCmdID当然就是上面两个值，分别表示显示编码菜单和文字大小菜单。 这样一来，菜单的Enable/Disable状态不需要我们来维护，命令也不需要我们来转发，系列七《完美的“编码”菜单》这篇文章也许可以删掉了，因为文中的代码可以简化为下面的样子，更改文字大小也只需要一行代码就能实现。 4.2 Location URL 调用这个命令获得的返回参数是 BSTR 类型，其值是网页的 Location URL 4.3 文档当前的代码页codepage 调用这个命令可以得到当前网页的编码类型，比如936（简体中文），1200（Unicode）等。 4.4 证书对话框 [...]]]></description>
		<wfw:commentRss>http://blog.tinybrowser.net/archives/70/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Internet Explorer 编程简述（十二）正确地设置和转移焦点</title>
		<link>http://blog.tinybrowser.net/archives/69</link>
		<comments>http://blog.tinybrowser.net/archives/69#comments</comments>
		<pubDate>Tue, 29 Dec 2009 17:57:35 +0000</pubDate>
		<dc:creator>free2000fly</dc:creator>
				<category><![CDATA[Internet Explorer Programming]]></category>
		<category><![CDATA[Accelerator]]></category>
		<category><![CDATA[Focus]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[IHTMLDocument4]]></category>
		<category><![CDATA[IHTMLWindow2]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[OLEIVERB_UIACTIVATE]]></category>
		<category><![CDATA[WebBrowser]]></category>
		<category><![CDATA[加速键]]></category>
		<category><![CDATA[焦点]]></category>

		<guid isPermaLink="false">http://tinybrowser.net/blog/?p=69</guid>
		<description><![CDATA[关键字：焦点，Focus，加速键，Accelerator，OLEIVERB_UIACTIVATE，IHTMLWindow2，IHTMLDocument4 1、概述 对于99%有UI的Windows应用程序来说，键盘操作都是不可或缺而又容易被人们遗忘的一环。如果对Windows组件作一次逐个的测试，我们会发现Microsoft提供的任何一个Windows组件都通过键盘实现完全的控制（“计算器”比较特殊，它是一个按钮很多且每个按钮都不能获得焦点的程序，但在帮助文档中我们仍然可以找到为每个按钮设置的快捷键），这对于一个专业的Windows应用程序或软件来说非常重要。换句话说，就算没有鼠标用户也不应该束手无策，用户应该可以通过键盘操作完成其希望的功能。焦点的转移无疑是键盘操作的一个重要方面，在浏览器编程中尤其如此。 2、焦点的基本概念 一般说来，在Windows中用户通过键盘转移焦点（Focus）有两个方法：第一，对于输入框附近有标签提示的情况，按住Alt+某个预设的字母（Accelerator，加速键）将焦点快速转移到输入框。如下图所示，按下“Alt+D”，焦点应转移到地址输入框；按下“Alt+G”，焦点应转移到搜索框（本文对此不做讨论）。第二，按住Tab键，焦点转移到由应用程序控制的下一个可获得焦点的窗口；按下Shift+Tab，焦点转移到上一个可获得焦点的窗口。如下图所示，如果地址输入框是当前获得焦点的窗口，则按下Tab时，焦点应转移到搜索框，再按下Shift+Tab，焦点应回到地址输入框。 焦点的设置和转移对于用户体验（Experience）来说是细微体贴而又重要的设计，但不幸的是不少Windows应用程序都或多或少犯了一些错误： 完全没有加速键。 这在国产信息系统中尤为常见。设计较差的信息系统常常会出现一个窗口拥有数十个输入框的情况，如果为每个编辑框都提供一个加速键的话，问题就出来了。字母键只有26个，就算把数字键也用上，也难免不能满足要求，所以很多信息系统干脆就不要加速键。 摆设用的加速键。 一些应用软件甚至不懂得加速键的意义，只知道依样画葫地在输入框的旁边用标签说明加速键，但仅此而已，用户根本无法通过Alt+加速键转移焦点到输入框。 错误地（或不能）转移焦点 对于基于对话框的应用程序来说，常犯的错误是用户按下Tab键时，焦点出乎用户意料地在输入框之间乱窜。而在上图这样的例子中，常犯的错误则是不能通过Tab转移焦点，或者按Tab能转移焦点但按Shift+Tab不能朝反方向转移焦点。 对嵌入的ActiveX控件缺乏处理 对于嵌入的ActiveX控件，尤其是WebBrowser控件来说，焦点的处理就更为麻烦了（这本是基于WebBrowser的浏览器编程的难题之一）。常见的浏览器要么不处理常规窗口与WebBrowser控件之间的焦点传递（Maxthon、Gosurf只支持在输入框之间传递焦点）；要么处理不完整，焦点一旦从某个输入框转移到WebBrowser控件就再也回不来（如GreenBrowser）；更有的根本就不处理任何焦点的传递（如世界之窗浏览器）。 按照本系列文章的惯例，本文讨论的目的将是提供一个完整（未必完美）的解决方案——：一，焦点在嵌入ReBar的各个输入框之间传递；二，焦点在普通Windows窗口（输入框）与WebBrowser控件之间传递。 3、设定目标 下图说明了我们希望实现的正常的焦点转移行为： 从工具条上的任何一个输入框出发，按Tab将焦点转移到下一个输入框，按Shift+Tab将焦点转移到上一个输入框 如果焦点所在输入框是工具条上的最后一个输入框，按Tab将焦点转移到WebBrowser控件当前的活动Html Element（上一次获得焦点的Element） 如果焦点所在输入框是工具条上的第一个输入框，按Shift+Tab将焦点转移到WebBrowser控件当前活动Html Element 对于上面两种情况，若WebBrowser控件没有当前活动的可获得焦点Html Element，则焦点应从输入框转移到WebBrowser控件的第一个或最后一个可获得焦点的Html Element 如果焦点当前位于WebBrowser控件中，按Tab将焦点转移到下一个Html Element，按Shift+Tab将焦点转移到上一个Html Element 如果焦点当前位于WebBrowser控件中，且当前的活动Html Element是最后一个可获得焦点的Html Element，按Tab将焦点转移到工具条的第一个输入框 如果焦点当前位于WebBrowser控件中，且当前的活动Html Element是第一个可获得焦点的Html Element，按Shif+Tab将焦点转移到工具条的最后输入框 以下图为例，“Google大全”为WebBrowser当前获得焦点的Html Element，举例如下： 例1：假设当前焦点位于地址输入框，按下Tab键不松开，焦点转移的顺序应是：“地址栏”，“搜索栏”，“Google大全”……“将Google设为首页”，“地址栏”，“搜索栏”，“个性化主页”，“搜索记录”…… 例2：假设当前焦点位于地址输入框，且WebBrowser控件没有活动的获得焦点的Html Element，按下Tab键不松开，焦点转移的顺序应是：“地址栏”，“搜索栏”，“个性化主页”，“搜索记录”……“将Google设为首页”，“地址栏”，…… 例3：假设当前焦点位于“搜索记录”，按下Shift+Tab键不松开，焦点转移的顺序应是：“搜索记录”，“个性化主页”，“搜索栏”，“地址栏”，“将Google设为首页”……“搜索记录”…… 4、工具条输入框之间的焦点转移 为实现统一的处理，我们从CDialogBar派生一个CDialogBarEx类，由该类处理Tab/Shift Tab按键，而输入框（如EditBox，ComboBox等）则放在CDialogBarEx的派生类（如CUrlAddressBar、CSearchBar等）中，这样输入框就可以专注于其它的功能。示例代码如下： 5、焦点从WebBrowser转移到工具条输入框 处理浏览器的按键也曾是嵌入WebBrowser控件的编程难题之一，Delphi对WebBrowser的封装对按键的支持就存在很大问题。在《Programming Internet Explorer》中曾提到的方法是处理MainFrame的PreTranslateMessage，并在其中从WebBrowser的Document查询得到IOleInPlaceActiveObject接口，将按键交给IOleInPlaceActiveObject的TranslateAccelerator成员区处理。查询MSDN我们可以知道，IOleInPlaceActiveObject::TranslateAccelerator被调用时，MSHTML引擎会调用IDocHostUIHandler接口的TranslateAccelerator方法，从而给开发人员一个接口来处理按键。所以对于实现了IDocHostUIHandler接口的应用程序来说，按键处理就非常简单了。 6、使WebBrowser获得焦点 使浏览器获得焦点也颇为讲究。我的一篇老文章《TWebBrowser编程简述中》写到有好几种方法可以使WebBrowser获得焦点：IOleObject::DoVerb(OLEIVERB_UIACTIVATE&#8230;)、IHTMLWindow2::focus()、IHTMLDocument4::focus()。而实际上这几种方法是有区别的（内部实现我们并不清楚，也不关心）。 IOleObject::DoVerb能够将焦点设置到WebBrowser上一次失去焦点时获得焦点的Html Element上。缺点在于如果WebBrowser上次失去焦点时没有任何Html Element获得焦点，则DoVerb并不能保证焦点会转移到WebBrowser中。 IHTMLWindow2::focus不管三七二十一，将焦点转移到WebBrowser的开头Html Element。这显然不是我们想要的。 测试的结果，IHTMLDocument4::focus似乎能够满足要求：能够记住WebBrowser上次失去焦点时获得焦点的Html [...]]]></description>
		<wfw:commentRss>http://blog.tinybrowser.net/archives/69/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Internet Explorer 编程简述（十一）实现完美的Inplace Drag &amp; Drop——“超级拖放”</title>
		<link>http://blog.tinybrowser.net/archives/68</link>
		<comments>http://blog.tinybrowser.net/archives/68#comments</comments>
		<pubDate>Tue, 29 Dec 2009 17:56:55 +0000</pubDate>
		<dc:creator>free2000fly</dc:creator>
				<category><![CDATA[Internet Explorer Programming]]></category>
		<category><![CDATA[GetDropTarget]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[IHTMLDataTransfer]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[ondragover]]></category>
		<category><![CDATA[WebBrowser]]></category>
		<category><![CDATA[超级拖放]]></category>

		<guid isPermaLink="false">http://tinybrowser.net/blog/?p=68</guid>
		<description><![CDATA[关键字：超级拖放，GetDropTarget，ondragover，IHTMLDataTransfer 1、概述 许多多窗口浏览器都提供了一种被称为“超级拖放”（或“超级拖拽”、“随心拖放”等等，不一而足）的功能。作为对IE拖拽行为对扩展，“超级拖放”实现了一些非常实用的功能： 拖放网页链接：通常是在新窗口中打开 拖放选中的文字：保存文字、作为关键字通过搜索引擎搜索网络、作为Url打开等 拖放图片：通常是保存图片到指定文件夹 当然，还有很关键的一点：拖动对象时鼠标指针反馈不同的拖拽效果 在《Internet Explorer 编程简述（十）响应来自HTML Element的事件通知——几个好用的类》中曾提到，尽管许多浏览器都提供了超级拖放的功能，但与 IE 的缺省实现相比，除了具备鼠标指针拖拽效果外，还没有哪个浏览器的实现能够实现： 文字在页面内与输入框之间的交互拖放（这一点最为重要） 来自外部的文字与网页输入框之间的交互拖放 拖拽时滚动页面（这一点是被忽略了） 本文的目的，一是介绍实现超级拖放的两种方法，二是说明如何实现“完美”的拖放——即扩展IE拖拽行为的同时，保留IE默认的拖拽行为。三是给出一个最为直接和简洁的实现，至于拖放不同的对象以实现不同的功能，不在本文讨论的范围，略去。 2、标准的实现方法 标准方法即通过 IDocHostUIHandler 的 GetDropTarget 成员函数来实现，在 MSDN 这样说到： IDocHostUIHandler::GetDropTarget Method——Called by MSHTML when it is used as a drop target. This method enables the host to supply an alternative IDropTarget interface. 即在适当的时候, MSHTML 引擎会调用 IDocHostUIHandler 的 GetDropTarget 方法，为应用程序提供一个机会来替换 [...]]]></description>
		<wfw:commentRss>http://blog.tinybrowser.net/archives/68/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Internet Explorer 编程简述（十）响应来自HTML Element的事件通知——几个好用的类</title>
		<link>http://blog.tinybrowser.net/archives/67</link>
		<comments>http://blog.tinybrowser.net/archives/67#comments</comments>
		<pubDate>Tue, 29 Dec 2009 17:56:02 +0000</pubDate>
		<dc:creator>free2000fly</dc:creator>
				<category><![CDATA[Internet Explorer Programming]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTML Element]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Sink]]></category>
		<category><![CDATA[WebBrowser]]></category>

		<guid isPermaLink="false">http://tinybrowser.net/blog/?p=67</guid>
		<description><![CDATA[关键字：HTML Element, Sink 1、概述 实现了对 Webbrowser 的 resuing 之后我们便会发现有时候我们还需要处理浏览器中的元素（HTML Element）。这种处理包括主动和被动两个方面，像《FAQ：如何访问WebBrowser的滚动条》、《FAQ：操纵下拉列表》、《FAQ：两种方法访问多层嵌套的frame》等文章所演示的就是主动的处理。通常我们从 Webbrowser 获得一个 Web 文档接口（IHTMLDocumentx），从它出发便可访问到浏览器所包含的一切 HTML 元素。而被动的处理则是在 COM 技术中称为 Sink 的技术，我更喜欢的说法是事件通知。当文档的下载进度发生变化时，我们可以获得 ProgressChange 通知，当 Webbrowser 下载完 HTML 文档时，我们可以获得 DocumentComplete 的通知，而当链接被点击，或图片被拖动时，我们如何获得通知呢？本文希望能够给出部分的答案。 2. HtmlObj Template 如何 Sink 一个 HTML Element 并不是本文的重点，其理论我不是太了解，也懒得去搞透彻，所以使用现成的库来实现。CodeProject 上的一篇文章《CHtmlObj Template》给出的一个模板类 CHtmlObj 就非常好用。下面的例子是针对 Html Anchor Element 的一个实例化。 当我们得到某个链接的 HTML 接口指针，便可调用 CHtmlAnchorElement 继承自 CHtmlObj 的 SetSite(IUnknown *pUnkSite) 成员函数传入该接口指针。在 [...]]]></description>
		<wfw:commentRss>http://blog.tinybrowser.net/archives/67/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Internet Explorer 编程简述（九）在自己的浏览器中嵌入Google工具条</title>
		<link>http://blog.tinybrowser.net/archives/60</link>
		<comments>http://blog.tinybrowser.net/archives/60#comments</comments>
		<pubDate>Tue, 29 Dec 2009 17:04:36 +0000</pubDate>
		<dc:creator>free2000fly</dc:creator>
				<category><![CDATA[Internet Explorer Programming]]></category>
		<category><![CDATA[Explorer Bars]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Toolbar]]></category>
		<category><![CDATA[IDeskBand]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[IObjectWithSite]]></category>
		<category><![CDATA[ToolBands]]></category>
		<category><![CDATA[Toolbar]]></category>
		<category><![CDATA[WebBrowser]]></category>

		<guid isPermaLink="false">http://tinybrowser.net/blog/?p=60</guid>
		<description><![CDATA[关键字：Google Toolbar, Explorer Bars, ToolBands, IObjectWithSite, IDeskBand 1、概述 　　Internet Explorer强大而方便的可编程能力和可扩展能力为其抢占浏览器市场可谓是立下了汗马功劳。可编程主要体现两方面： 实现浏览功能的部分被包装成一个控件——WebBrowser Control，开发人员可以在自己的应用程序中嵌入它从而使程序具有访问Internet上网页的能力，同时WebBrowser Control也能够被灵活地自定义以满足不同的需要。 可对Microsoft Internet Explorer应用程序本身嵌入的浏览器控件编程，一般通过BHO（Browser Helper Object）来实现。 　　可扩展能力则体现在几个方面： 嵌入式面板型扩展，包括Explorer Bars（如收藏夹、搜索、历史等嵌入IE主窗口的大型面板）, Tool Bands（如Google Toolbar、MSN Toolbar等嵌入IE的工具条）, 和Desk Bands（如快速启动这类嵌入任务栏的面板，实际上是Explorer外壳的扩展）。这几种面板的编写方法相差无几，不同之处主要在于向系统注册方式的不同。 是参数型扩展，包括为浏览器增加上下文菜单项（调用脚本）、为浏览器主菜单增加菜单项、为浏览器“标准按钮”工具条添加按钮等。 其他扩展，如文件下载的扩展（Custom Download Manager）、地址栏扩展（搜索扩展）等。 　　随着IE的发展，各种类型的扩展遍地开花，其中最为引人注目的，当属地址栏扩展和工具条扩展（几乎成了兵家必争之地）。本文讨论的主题，正是工具条的扩展。 2、问题的提出 　　两个原因促成了 Google Toolbar 的流行，一是广告窗口的泛滥、二是Google Search。Google“简单”（实则一点都不简单，没有搜索引擎的强力支持，Toolbar 的用途就大受限制）地抓住了这两点，迅速占领了市场。 　　插件的一大好处在于可以不修改主程序，只需换一个样子差不多但功能更强的东西就可以使得整个应用程序功能增强，所以IE不升级大家也觉得Google Toobar越来越好用。于是利用WebBroser Control编写浏览器的开发人员就想，如果能像IE一样支持上述这些扩展，不就能把Google Toolbar拿过来用了吗？其他的事交给Google去做就行了。这就是我们要讨论的问题，“如何在自己的浏览器中嵌入Google Toolbar”。 3、分析 　　微软并未在MSDN中说明如何将Google Toolbar这类IE的工具条插件嵌入自己的应用程序，但其基于COM的设计方法实际上给予了我们这个能力（创建嵌入式的工具条的方法并不是本文的重点，此处略去，有兴趣的朋友可以参考MSDN）。我们知道，除了IUnknown接口外，Bands和Bars（以下简称Band对象）还需要实现三个接口：IObjectWithSite，IPersistStream和IDeskBand。当用户选择工具条或面板时，其容器（如IE的外壳框架）就会调用Band对象的IObjectWithSite::SetSite方法（该方法仅需要一个IUnknown类型的指针），将自己实现的IUnknown指针传递给Band对象。这就是整个插件开始真正激活的入口，也是我们的着手点。 　　MSDN中说到，一般来说，Band对象对于SetSite方法的实现需要完成以下几件事： 如果当前Band对象持有另外的Site指针，则首先释放该指针。 如果容器向SetSite方法传入的是一个空指针，则表示要删除该Band对象，此时SetSite返回S_OK即可。 如果容器传入的不是空指针，则需要设置新的Site： 对此IUnknown指针所指的新Site调用QueryInterface查询得到其IOleWindow接口。 调用得到的IOleWindow接口的GetWindow方法获取父窗口的句柄（此窗口即是Band对象的栖身之处）并保存下来。如果以后不会再用到IOleWindow接口的话就对其调用Release。 现在可以创建Band对象的窗口了，当然，要以第2步得到的窗口为父窗口来创建，并且该窗口目前只能以不可见状态存在。 如果Band对象实现了IInputObject接口，即需要接收键盘输入，则还需要向容器传来的Site查询（QueryInterface）IInputObjectSite接口，此接口指针也需要保存下来。 [...]]]></description>
		<wfw:commentRss>http://blog.tinybrowser.net/archives/60/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Internet Explorer 编程简述（八）实现浏览历史菜单</title>
		<link>http://blog.tinybrowser.net/archives/57</link>
		<comments>http://blog.tinybrowser.net/archives/57#comments</comments>
		<pubDate>Tue, 29 Dec 2009 15:26:00 +0000</pubDate>
		<dc:creator>free2000fly</dc:creator>
				<category><![CDATA[Internet Explorer Programming]]></category>
		<category><![CDATA[IEnumTravelLogEntry]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[ITravelLogEntry]]></category>
		<category><![CDATA[ITravelLogStg]]></category>
		<category><![CDATA[WebBrowser]]></category>

		<guid isPermaLink="false">http://tinybrowser.net/blog/?p=57</guid>
		<description><![CDATA[关键字：ITravelLogStg, IEnumTravelLogEntry, ITravelLogEntry 1、概述 Internet Explorer的浏览历史菜单在4.0版本开始出现，但直到5.5之前，微软都未公布用于访问浏览历史的COM接口，如今已是IE6.0大行其道的年代，用于访问浏览历史的接口也早已公布多时，本文的目的则是试图抛砖引玉，简单介绍用于访问浏览历史的Travel Log接口，并用一个小小的类CIETravelLog来实现对Travel Log的封装。 2、IOmHistory接口 在早些时候的MSDN中，我们能够查阅到关于浏览历史的接口仅有IOmHistory，而该接口实际上对应的是浏览器中可以通过脚本访问的“history”对象。对于“history”对象，MSDN中是这样说的： For security reasons, the history object does not expose the actual URLs in the browser history. It does allow navigation through the browser history by exposing the back, forward, and go methods. A particular document in the browser history can be identified as an index [...]]]></description>
		<wfw:commentRss>http://blog.tinybrowser.net/archives/57/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Internet Explorer 编程简述（七）完美的“编码”菜单</title>
		<link>http://blog.tinybrowser.net/archives/55</link>
		<comments>http://blog.tinybrowser.net/archives/55#comments</comments>
		<pubDate>Tue, 29 Dec 2009 15:11:10 +0000</pubDate>
		<dc:creator>free2000fly</dc:creator>
				<category><![CDATA[Internet Explorer Programming]]></category>
		<category><![CDATA[Encoding Menu]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[SHDVID_GETMIMECSETMENU]]></category>
		<category><![CDATA[WebBrowser]]></category>
		<category><![CDATA[编码菜单]]></category>

		<guid isPermaLink="false">http://tinybrowser.net/blog/?p=55</guid>
		<description><![CDATA[关键字：编码菜单, Encoding Menu, SHDVID_GETMIMECSETMENU 1、概述 Internet Explorer有实在太多没有公布的东西。上一篇文章《Internet Explorer 编程简述（六）自定义浏览器上下文菜单》提到的获取“编码”菜单的方法就是利用了浏览器的上层窗口“Shell DocObject View”的未公布的命令ID。本文将要介绍的是如何用这个ID把“编码”菜单放到我们自己的菜单中来（如工具条上的“编码”按钮的下拉菜单）。 2、原理 上面指向IOleCommandTarget接口的智能指针spCT是从IDocHostUIHandler::ShowContextMenu的参数pcmdTarget得到的，它其实也可以从HTML文档接口得到，这就是实现的关键。 3、实现 下面的代码演示了如何将“编码”菜单放置到我们自己的编码菜单上去。 这样一来，原本只在浏览器上下文菜单中出现的“编码”菜单就出现在了我们自己的工具条按钮下拉菜单上，无需更多的处理，菜单状态的改变，编码的设置等，一切都教给浏览器自己去完成了。 参考资料： 《Internet Explorer 编程简述（六）自定义浏览器上下文菜单》]]></description>
		<wfw:commentRss>http://blog.tinybrowser.net/archives/55/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

