<?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; 添加到收藏夹</title>
	<atom:link href="http://blog.tinybrowser.net/archives/tag/%e6%b7%bb%e5%8a%a0%e5%88%b0%e6%94%b6%e8%97%8f%e5%a4%b9/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>Internet Explorer 编程简述（四）“添加到收藏夹”对话框</title>
		<link>http://blog.tinybrowser.net/archives/39</link>
		<comments>http://blog.tinybrowser.net/archives/39#comments</comments>
		<pubDate>Tue, 29 Dec 2009 14:10:56 +0000</pubDate>
		<dc:creator>free2000fly</dc:creator>
				<category><![CDATA[Internet Explorer Programming]]></category>
		<category><![CDATA[DoAddToFavDlg]]></category>
		<category><![CDATA[DoOrganizeFavDlg]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[IShellUIHelper]]></category>
		<category><![CDATA[WebBrowser]]></category>
		<category><![CDATA[模态窗口]]></category>
		<category><![CDATA[添加到收藏夹]]></category>

		<guid isPermaLink="false">http://tinybrowser.net/blog/?p=39</guid>
		<description><![CDATA[关键字：“添加到收藏夹”对话框， 模态窗口，IShellUIHelper，DoAddToFavDlg， DoOrganizeFavDlg 1、概述 调用“添加到收藏夹”对话框（如下）与调用“整理收藏夹”对话框有不同之处，前者所做的工作比后者要来得复杂。将链接添加到收藏夹除了将链接保存之外，还可能会有脱机访问的设置，从IE 4.0到IE 5.0，处理的方式也发生了一些变化。 2、IShellUIHelper接口 微软专门提供了一个接口 IShellUIHelper 来实现对 Windows Shell API 一些功能的访问，将链接添加到收藏夹也是其中之一，就是下面的 AddFavorite 函数。 实例代码如下： 我们注意到这里的“AddFavorite”函数并没有像“DoOrganizeFavDlg”那样需要一个父窗口句柄。这也导致与在IE中打开不同，通过IShellUIHelper接口显示出来的“添加到收藏夹”对话框是“非模态”的，有一个独立于我们应用程序的任务栏按钮，这使我们的浏览器显得非常不专业（我是个追求完美的人，这也是我的浏览器迟迟不能发布的原因之一）。 于是我们很自然地想到“shdocvw.dll”中除了“DoOrganizeFavDlg”外，应该还有一个类似的函数，可以传入一个父窗口句柄用以显示模态窗口，也许就像这样： 事实上，这样的函数确实存在于“shdocvw.dll”中，那就是“DoAddToFavDlg”。 3、DoAddToFavDlg函数 “DoAddToFavDlg”函数也是“shdocvw.dll”暴露出来的函数之一，其原型如下： 第一个参数正是我们想要的父窗口句柄，第二和第四个参数分别是初始目录（一般来说就是收藏夹目录）和要添加的链接的名字（比如网页的Title），第三和第五个参数分别是第二和第四两个缓冲区的长度，而最后一个参数则是指向与第二个参数目录相关的item identifier list的指针(PIDL)。但最奇怪的是这里并没有像“AddFavorite”函数一样的链接URL，那链接是怎样添加的呢？答案是“手动创建”。 第二个参数在函数调用返回后会包含用户在“添加到收藏夹”对话框中选择或创建的完整链接路径名（如“X:\XXX\mylink.url”），我们就根据这个路径和网页的URL来创建链接，代码如下（为简化，此处省去检查”shdocvw.dll”是否已在内存中的代码，参见《Internet Explorer 编程简述（三）“整理收藏夹”对话框》）： 实现CreateInternetShortcut函数创建Internet快捷方式，可以用读写INI文件的方法，但更好的则是利用IUniformResourceLocator接口。 好，上面的方法虽然麻烦一点，但总算解决了“模态窗口”的问题，使得我们的程序不至于让用户鄙视。但是问题又来了，我们发现“允许脱机使用”是Disabled的，那“自定义”也就无从谈起了，尽管90%的人都没有使用过IE提供的脱机浏览。 难道我们的希望要破灭吗？我们一方面想像调用“AddFavorite”函数一样的不必手动创建链接，一方面又要模态显示窗口，就像IE那样，还能自定义脱机浏览。 4、脚本方式 许多网页上都会有一个按钮或链接“添加本页到收藏夹”，实际上通过下面的脚本显示模态的“添加到收藏夹”对话框将网页加入到收藏夹。 这里的external对象是WebBrowser内置的COM自动化对象，以实现对文档对象模型（DOM）的扩展（我们也可以通过IDocHostUIHandler实现自己的扩展）.查阅MSDN可以得知external对象的的方法与IShellUIHelper接口提供的方法是一样的。我们有理由相信，IShellUIHelper提供了对WebBrowser内置的external对象的访问，如果在适当的地方创建IShellUIHelper接口的实例，也许调用“AddFavorite”函数显示出来的就是模态对话框了。问题是我们还没有找到这样的地方。 从上面的脚本，我们很自然地又想到另一个方法。如果能够让网页来执行上面的脚本，岂不是问题就解决了？说做就做，如下： 先从CHtmlView获得文档的父窗口window对象的指针，再调用其方法execScript来执行脚本（事实上可以执行任意的脚本）。试验发现，这个方法非常有效，不仅窗口是模态的，而且不需要手动创建链接，更重要的是“允许脱机使用”和“自定义”按钮也可以用了。 5、问题仍旧没有解决 执行脚本的方式看起来有效，可一旦我们的程序实现了IDocHostUIHandler接口对WebBrowser进行高级控制，就会发现一旦执行的脚本包含有对“external”对象的调用，就会出现“缺少对象”的脚本错误。原因是当MSHTML解析引擎（并非WebBrowser）检查到宿主实现了IDocHostUIHandler接口，就会调用其GetExternal方法以获得一个用以扩展DOM的自动化接口的引用。 但有时候我们并没有想要扩展DOM，同时我们还希望WebBrowser使用它自己的DOM扩展。糟糕的是GetExternal方法的文档中说这种情况下必须把ppDispatch设置为NULL，换句话说，WebBrowser连它内置的external对象也不用了，那我们的window.external.AddFavorite就变得无处为家了。 我曾多方尝试将WebBrowser内置的external对象找出来，虽然都没有成功，但是解决问题的方法却被我找到了。 6、完美的方案 WebBrowser内置的external对象我们虽然找不到，但它肯定存在，我们只要想办法让WebBrowser自己完成对其调用即可。实现非常简单，找到WebBrowser中包含的“Internet Explorer_Server”窗口的句柄，发一个消息就完成了。下面的代码中假设m_hWndIE就是“Internet Explorer_Server”窗口的句柄。 试一试成果，是不是和在Internet Explorer中选择“添加到收藏夹”的效果一模一样。 至于为什么这样做，后续文章再说。 参考资料： MSDN: Adding Internet Explorer Favorites to [...]]]></description>
		<wfw:commentRss>http://blog.tinybrowser.net/archives/39/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Internet Explorer 编程简述（三）“整理收藏夹”对话框</title>
		<link>http://blog.tinybrowser.net/archives/33</link>
		<comments>http://blog.tinybrowser.net/archives/33#comments</comments>
		<pubDate>Tue, 29 Dec 2009 13:57:07 +0000</pubDate>
		<dc:creator>free2000fly</dc:creator>
				<category><![CDATA[Internet Explorer Programming]]></category>
		<category><![CDATA[DoAddToFavDlg]]></category>
		<category><![CDATA[DoOrganizeFavDlg]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[WebBrowser]]></category>
		<category><![CDATA[整理收藏夹]]></category>
		<category><![CDATA[添加到收藏夹]]></category>

		<guid isPermaLink="false">http://tinybrowser.net/blog/?p=33</guid>
		<description><![CDATA[关于Internet Explorer的收藏夹，比较常见的两个问题就是调用“整理收藏夹”对话框和“添加到收藏夹”对话框。调用的方法有多种，但其中还是有些值得讨论的地方。 关键字：添加到收藏夹，整理收藏夹，DoAddToFavDlg， DoOrganizeFavDlg 1、整理收藏夹 调用“整理收藏夹”对话框（如下），基本上来说都用的是同一个方法，即调用“shdocvw.dll”中的“DoOrganizeFavDlg”函数，把父窗口句柄和收藏夹路径作为参数传入即可。 2、代码 代码实例如下所示，值得注意的是对“shdocvw.dll”的处理，为避免重复调用，应该先检查其是否已经在内存中。 3、讨论 实际上，从“DoOrganizeFavDlg” 函数的原型声明我们可以看到，由于需要一个路径，所以“整理收藏夹”对话框其实不仅可以用来整理收藏夹，还可以整理磁盘上的目录。而且所谓的整理也不过是提供了一个对话框使用户用起来比较方便而已，和直接在资源管理器中整理没有实质性的差别。因此调用“整理收藏夹”对话框的方法从IE4.0开始就没有变过，除了对话框的布局有所改变。 IE 4.0的“整理收藏夹”对话框 IE 4.0的“整理收藏夹”对话框（原先的设计） “添加到收藏夹”就不同了，“DoAddToFavDlg”函数不再像“DoOrganizeFavDlg”函数一样对所有IE的版本都适用。 参考资料： MSDN: Adding Internet Explorer Favorites to Your Application]]></description>
		<wfw:commentRss>http://blog.tinybrowser.net/archives/33/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

