<?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>Google Stop Blog - Make a change &#187; C++</title>
	<atom:link href="http://googlestop.com/blog/category/programming-language/cpp/feed/" rel="self" type="application/rss+xml" />
	<link>http://googlestop.com/blog</link>
	<description>Just another weblog of Charry</description>
	<lastBuildDate>Sat, 07 Jan 2012 09:51:13 +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>为什么不用SEH</title>
		<link>http://googlestop.com/blog/2007/07/%e4%b8%ba%e4%bb%80%e4%b9%88%e4%b8%8d%e7%94%a8seh/</link>
		<comments>http://googlestop.com/blog/2007/07/%e4%b8%ba%e4%bb%80%e4%b9%88%e4%b8%8d%e7%94%a8seh/#comments</comments>
		<pubDate>Tue, 17 Jul 2007 01:55:35 +0000</pubDate>
		<dc:creator>Charry</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[VC]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://googlestop.com/blog/2007/07/16/%e4%b8%ba%e4%bb%80%e4%b9%88%e4%b8%8d%e7%94%a8seh/</guid>
		<description><![CDATA[前些时候，在论坛上看到一个朋友说SEH怎么怎么不好，一定不要用它。其实存在即合理。就像GOTO，不能因为它破坏了程序的流程，就不用它，适当的使用，还是可以事半功倍的。 大家知道SEH是Windows操作系统提供的一种异常处理机制，它和C++无关。在Compiler编译的时候，就把这个机制加入了我们的程序中。在VC下可以用__try, __finally, __except, __leave等关键字来标识。由于SEH可以捕获硬件异常(Hardware Exception)和软件异常(Software Exception)，它比C++的异常机制能捕获更多的异常，所以有朋友不喜欢这点，认为它掩盖了错误。其实这种说法是也是合情合理的，毕竟掩盖错误不是最好的解决方案，找出问题的所在才是我们应该做的。可是在现实中，我们不可能找到所有的bug，或者由于时间的关系，来不及修补这个bug，不如先用SEH挡一挡，何尝不可。 就像我之前的一个项目，程序在一个地方偶尔会Crash掉，而且这个地方如果不能正常执行丝毫不影响整个程序的运作，不会对用户造成损失，在找出问题真正的原因之前，我们完全可以用SEH捕获异常。  下面的例子也是一个SEH优势的体现 BOOL SafeDiv(INT32 dividend, INT32 divisor, INT32 *pResult) {     __try     {         *pResult = dividend / divisor;     }     __except(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO ?              EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)     {         return FALSE;     }     return TRUE; } SafeDiv用来做除法操作，它的返回值指出函数是否执行成功。pResult指向最终的结果，如果不用SEH，这类Hardware Exception会导致程序Crash，这里引入了SEH，我们在发现有除零错误的时候，让函数返回FALSE，调用处通过检查函数的返回值就可以判断除法运算是否成功，没必要就因为一个除零错误导致程序Crash掉。 由于SEH是Windows操作系统特有的机制，所以它不适合用在那些跨平台的代码，这种情况不用也罢，既然SEH是一个Windows的一个很好的异常处理机制，我们虽不能滥用它，适当的、合理的使用还是值得推荐的。 P.S. For details [...]]]></description>
			<content:encoded><![CDATA[<p>前些时候，在论坛上看到一个朋友说SEH怎么怎么不好，一定不要用它。其实存在即合理。就像GOTO，不能因为它破坏了程序的流程，就不用它，适当的使用，还是可以事半功倍的。</p>
<p>大家知道SEH是Windows操作系统提供的一种异常处理机制，它和C++无关。在Compiler编译的时候，就把这个机制加入了我们的程序中。在VC下可以用__try, __finally, __except, __leave等关键字来标识。由于SEH可以捕获硬件异常(Hardware Exception)和软件异常(Software Exception)，它比C++的异常机制能捕获更多的异常，所以有朋友不喜欢这点，认为它掩盖了错误。其实这种说法是也是合情合理的，毕竟掩盖错误不是最好的解决方案，找出问题的所在才是我们应该做的。可是在现实中，我们不可能找到所有的bug，或者由于时间的关系，来不及修补这个bug，不如先用SEH挡一挡，何尝不可。</p>
<p>就像我之前的一个项目，程序在一个地方偶尔会Crash掉，而且这个地方如果不能正常执行丝毫不影响整个程序的运作，不会对用户造成损失，在找出问题真正的原因之前，我们完全可以用SEH捕获异常。</p>
<p> 下面的例子也是一个SEH优势的体现</p>
<p>BOOL SafeDiv(INT32 dividend, INT32 divisor, INT32 *pResult)<br />
{<br />
    __try<br />
    {<br />
        *pResult = dividend / divisor;<br />
    }<br />
    __except(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO ?<br />
             EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)<br />
    {<br />
        return FALSE;<br />
    }<br />
    return TRUE;<br />
}</p>
<p>SafeDiv用来做除法操作，它的返回值指出函数是否执行成功。pResult指向最终的结果，如果不用SEH，这类Hardware Exception会导致程序Crash，这里引入了SEH，我们在发现有除零错误的时候，让函数返回FALSE，调用处通过检查函数的返回值就可以判断除法运算是否成功，没必要就因为一个除零错误导致程序Crash掉。</p>
<p>由于SEH是Windows操作系统特有的机制，所以它不适合用在那些跨平台的代码，这种情况不用也罢，既然SEH是一个Windows的一个很好的异常处理机制，我们虽不能滥用它，适当的、合理的使用还是值得推荐的。</p>
<p>P.S.<br />
For details about SEH, check this: <a href="http://www.google.com/search?hl=en&amp;q=Programming+Applications+for+Microsoft+Windows">http://www.google.com/search?hl=en&amp;q=Programming+Applications+for+Microsoft+Windows</a></p>
]]></content:encoded>
			<wfw:commentRss>http://googlestop.com/blog/2007/07/%e4%b8%ba%e4%bb%80%e4%b9%88%e4%b8%8d%e7%94%a8seh/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>API Hook的问题，卡住了:(</title>
		<link>http://googlestop.com/blog/2007/07/api-hook%e7%9a%84%e9%97%ae%e9%a2%98%ef%bc%8c%e5%8d%a1%e4%bd%8f%e4%ba%86/</link>
		<comments>http://googlestop.com/blog/2007/07/api-hook%e7%9a%84%e9%97%ae%e9%a2%98%ef%bc%8c%e5%8d%a1%e4%bd%8f%e4%ba%86/#comments</comments>
		<pubDate>Fri, 06 Jul 2007 16:25:14 +0000</pubDate>
		<dc:creator>Charry</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Windows Programming]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Network Programming]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://googlestop.com/blog/2007/07/06/api-hook%e7%9a%84%e9%97%ae%e9%a2%98%ef%bc%8c%e5%8d%a1%e4%bd%8f%e4%ba%86/</guid>
		<description><![CDATA[这两天研究如何在我自己的进程中，获取IE或者FireFox中的网页内容，也就是监视用户上网信息。需要通过API Hook的方式拦截IE(拦截FireFox也是一个道理)用的API。  刚开始的思路是，我想Hook MSHTML.dll 中的API，用Depends看了一下，发现只有寥寥几个导出函数，诸如ShowHTMLDialog(), 这些都不能获取网页内容。那么再换个DLL呢，于是Depends一下，ShDocVw.dll，导出函数倒是不少，大部分名字都是N/A，只有几个如OpenURL(), AddUrlToFavorites()，对我也没什么用。 上面的方法不行，我只能再向底层靠了，准备Hook Ws2_32.dll，Depends这个DLL，你可以看到，N多导出函数，让人赏心悦目，其中recv就是我要Hook的API，写了一个Demo程序，然后打开IE，运行这个Demo，发现毫无反应，我开始怀疑是我的API Hook的方式不对，后来我用同样的方法，发现可以拦截住user32.dll的MessageBoxA，百思不得其解。Google一下，发现有人和我遇到类似的问题： Hook MSN Messenger之socket通訊的鳥事 于是这次我挂到wsock32.dll，果然，这次有反应了。总算前进了一小步，离我要获得网页内容还有很多距离呢，我的recv函数中也就是my_recv内容如下： int PASCAL FAR my_recv (SOCKET s, char FAR * buf, int len, int flags) {         OutputDebugString(_T(&#8220;In my_recv&#8221;));           OutputDebugString(buf);         SaveLog(buf, len);         int nReturn = 0;         myJmp.SetHookOff();         nReturn = recv(s, buf, len, flags);         myJmp.SetHookOn();         [...]]]></description>
			<content:encoded><![CDATA[<p>这两天研究如何在我自己的进程中，获取IE或者FireFox中的网页内容，也就是监视用户上网信息。需要通过API Hook的方式拦截IE(拦截FireFox也是一个道理)用的API。</p>
<p> 刚开始的思路是，我想Hook MSHTML.dll 中的API，用Depends看了一下，发现只有寥寥几个导出函数，诸如ShowHTMLDialog(), 这些都不能获取网页内容。那么再换个DLL呢，于是Depends一下，ShDocVw.dll，导出函数倒是不少，大部分名字都是N/A，只有几个如OpenURL(), AddUrlToFavorites()，对我也没什么用。</p>
<p>上面的方法不行，我只能再向底层靠了，准备Hook Ws2_32.dll，Depends这个DLL，你可以看到，N多导出函数，让人赏心悦目，其中recv就是我要Hook的API，写了一个Demo程序，然后打开IE，运行这个Demo，发现毫无反应，我开始怀疑是我的API Hook的方式不对，后来我用同样的方法，发现可以拦截住user32.dll的MessageBoxA，百思不得其解。Google一下，发现有人和我遇到类似的问题：</p>
<p><strong><a href="http://www.javaworld.com.tw/roller/page/qing?entry=2007_3_26_hook_msn_messenger%E4%B9%8Bsocket%E9%80%9A%E8%A8%8A%E7%9A%84%E9%B3%A5%E4%BA%8B" target="_blank">Hook MSN Messenger之socket通訊的鳥事</a></strong></p>
<p>于是这次我挂到wsock32.dll，果然，这次有反应了。总算前进了一小步，离我要获得网页内容还有很多距离呢，我的recv函数中也就是my_recv内容如下：</p>
<p>int PASCAL FAR my_recv (SOCKET s, char FAR * buf, int len, int flags)<br />
{<br />
        OutputDebugString(_T(&#8220;In my_recv&#8221;));<br />
 <br />
        OutputDebugString(buf);</p>
<p>        SaveLog(buf, len);</p>
<p>        int nReturn = 0;<br />
        myJmp.SetHookOff();<br />
        nReturn = recv(s, buf, len, flags);<br />
        myJmp.SetHookOn();</p>
<p>        return (nReturn);<br />
}</p>
<p>打印出buf的内容，用DebugView可以看到，很多都是乱码。不知道别人都怎么分析recv到的数据流的，怎么才能从中获取文本内容。接下来，保存也是一个问题，SaveLog的第二个参数是buf的长度，我觉得应该填recv的返回值，它是实际返回的数据的长度。但是把SaveLog放到recv后面，就不能保存到文件中，放到前面就可以，没办法，这里我只能用len。</p>
<p>打开文件如下图：</p>
<p><a title="2007-07-07_00-14-02.jpg" rel="lightbox" href="http://googlestop.com/blog/wp-content/uploads/2007/07/2007-07-07_00-14-021.jpg"><img src="http://googlestop.com/blog/wp-content/uploads/2007/07/2007-07-07_00-14-021-150x150.jpg" alt="2007-07-07_00-14-02.jpg" /></a></p>
<p>最后还有个问题是：卸载这个钩子的时候，偶尔会让IE崩溃。下面是我的一个demo，有兴趣的可以帮忙调试看看上面的若干个问题该怎么解决。写的仓促，代码很乱，我也没去测试Release是否有问题，暂且这么着吧。</p>
<p><a href="http://googlestop.com/download/APIHookTest.zip">Downlaod Demo</a></p>
]]></content:encoded>
			<wfw:commentRss>http://googlestop.com/blog/2007/07/api-hook%e7%9a%84%e9%97%ae%e9%a2%98%ef%bc%8c%e5%8d%a1%e4%bd%8f%e4%ba%86/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A New Release of Yet Another Browser</title>
		<link>http://googlestop.com/blog/2007/06/a-new-release-of-yet-another-browser/</link>
		<comments>http://googlestop.com/blog/2007/06/a-new-release-of-yet-another-browser/#comments</comments>
		<pubDate>Fri, 29 Jun 2007 03:17:39 +0000</pubDate>
		<dc:creator>Charry</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[My Application]]></category>

		<guid isPermaLink="false">http://googlestop.com/blog/2007/06/28/a-new-release-of-yet-another-browser/</guid>
		<description><![CDATA[I&#8217;ve changed my plan, Yet Another Browser(YAB for short) still looks like its sibling, if a brower has a MS-Word-like look-and-feel, is it weird? So far, I think YAB will be helpful for some guys. If you&#8217;re addicted to online photo communities, like Flickr, it can help you download photos when you go surfing, you don&#8217;t need to save the photos manually. Just one [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve changed my plan, Yet Another Browser(YAB for short) still looks like its sibling, if a brower has a MS-Word-like look-and-feel, is it weird? So far, I think YAB will be helpful for some guys. If you&#8217;re addicted to online photo communities, like <a href="http://www.flickr.com" target="_blank">Flickr</a>, it can help you download photos when you go surfing, you don&#8217;t need to save the photos manually. Just one click, all photos are flying to your disk on autopilot.</p>
<p>Features:</p>
<ol>
<li>You can tune up the opacity of main window</li>
<li>Multi-tab support</li>
<li>Right-click Close-Button to click all tabs, Left-Click just close one.</li>
<li>Your can rename the title of YAB, it will show what you want on task bar.</li>
<li>You can set the length of tab&#8217;s title.</li>
<li>Keep a list of websites you recently closed, you can easily undo it.</li>
<li>Just one-click to download all images in current tab</li>
<li>You can change the default direcotry where images will be saved.</li>
</ol>
<p>Todo:</p>
<ol>
<li>Boss key</li>
<li><span style="font-size: x-small;">Regular-Expressions for downloading images</span></li>
<li>Password Protection</li>
<li>Favorites</li>
<li>Clear hisotry</li>
<li>Clear dropdown list</li>
<li>Self-update</li>
<li>i18n</li>
<li>Auto-downloading images when you go surfing, even you don&#8217;t need one-click.</li>
<li>You can replace the icon of YAB with another one.</li>
</ol>
<p>Homepage for YAB: <a href="http://charry.org/m/myapps/YetAnotherBrowser">http://charry.org/m/myapps/YetAnotherBrowser</a> <br />
Stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://googlestop.com/blog/2007/06/a-new-release-of-yet-another-browser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TabIndex != TabPages.IndexOf</title>
		<link>http://googlestop.com/blog/2007/06/tabindex-tabpagesindexof/</link>
		<comments>http://googlestop.com/blog/2007/06/tabindex-tabpagesindexof/#comments</comments>
		<pubDate>Mon, 25 Jun 2007 11:17:39 +0000</pubDate>
		<dc:creator>Charry</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://googlestop.com/blog/2007/06/25/tabindex-tabpagesindexof/</guid>
		<description><![CDATA[TabControl的有个属性叫TabIndex，每个从Control派生来的控件都有这个属性，这个Tab是Tab键的顺序（MSDN说：A control with a lower tab index receives focus before a control with a higher index.） 我正好需要获取TabControl中某个Tab Page的Index。这些Tab Page保存在TabControl的TabPages中，它是一个集合，实现了IList接口，其中有个方法就是IndexOf (Determines the index of a specific item in the IList.)。 鬼使神差的，我把TabIndex属性当成了Tab Page在TabPages中的Index了，花费了N久时间，才发现问题所在。Tab Index和IndexOf，TabPages，这几个词放在一起，一不小心就会搞错，错误总在不经意间。]]></description>
			<content:encoded><![CDATA[<p>TabControl的有个属性叫TabIndex，每个从Control派生来的控件都有这个属性，这个<strong>Tab</strong>是Tab键的顺序（MSDN说：A control with a lower tab index receives focus before a control with a higher index.）</p>
<p>我正好需要获取TabControl中某个Tab Page的Index。这些Tab Page保存在TabControl的TabPages中，它是一个集合，实现了IList接口，其中有个方法就是IndexOf (Determines the index of a specific item in the <strong>IList</strong>.)。</p>
<p>鬼使神差的，我把TabIndex属性当成了Tab Page在TabPages中的Index了，花费了N久时间，才发现问题所在。Tab Index和IndexOf，TabPages，这几个词放在一起，一不小心就会搞错，错误总在不经意间。</p>
]]></content:encoded>
			<wfw:commentRss>http://googlestop.com/blog/2007/06/tabindex-tabpagesindexof/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Yet Another Browser</title>
		<link>http://googlestop.com/blog/2007/06/yet-another-browser/</link>
		<comments>http://googlestop.com/blog/2007/06/yet-another-browser/#comments</comments>
		<pubDate>Thu, 14 Jun 2007 07:39:40 +0000</pubDate>
		<dc:creator>Charry</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[My Application]]></category>

		<guid isPermaLink="false">http://googlestop.com/blog/2007/06/14/yet-another-browser/</guid>
		<description><![CDATA[If you&#8217;re a office worker, are you afraid of being busted by your boss when surfing? I make this semi-browser from scratch, it resembles a regular Microsoft Office Suit Application,  I&#8217;ll add the following features to the browser, e.g.: Transparent window One-click to hide Download all images to your disk &#8230; I created it with [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re a office worker, are you afraid of being busted by your boss when surfing? I make this semi-browser from scratch, it resembles a regular Microsoft Office Suit Application,  I&#8217;ll add the following features to the browser, e.g.:</p>
<ol>
<li>Transparent window</li>
<li>One-click to hide</li>
<li>Download all images to your disk</li>
<li>&#8230;</li>
</ol>
<p>I created it with C#,  it&#8217;s easy to create your own browser with its powerful components, everyone can make it if he wishes.</p>
<p><a href="http://www.googlestop.com/download/YetAnotherBrowser.exe">Download it!</a> (Make sure you have the .NET Framework 2.0 installed on your computer)</p>
]]></content:encoded>
			<wfw:commentRss>http://googlestop.com/blog/2007/06/yet-another-browser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A parser for Netscape Bookmark File Format</title>
		<link>http://googlestop.com/blog/2007/06/a-parser-for-netscape-bookmark-file-format/</link>
		<comments>http://googlestop.com/blog/2007/06/a-parser-for-netscape-bookmark-file-format/#comments</comments>
		<pubDate>Fri, 08 Jun 2007 07:54:55 +0000</pubDate>
		<dc:creator>Charry</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[My Application]]></category>

		<guid isPermaLink="false">http://googlestop.com/blog/2007/06/08/a-parser-for-netscape-bookmark-file-format/</guid>
		<description><![CDATA[There&#8217;re many kinds of bookmark formats for browsers, Netscapte Bookmark File Format is a popular one. it has a long story, the HTML-like bookmark is not easy to parse, XML is the best alternative, if I&#8217;ve got choice. but the well-known browser FireFox still use this format. In order to parse it, you have to do it using [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;re many kinds of bookmark formats for browsers, <a href="http://msdn2.microsoft.com/En-US/library/aa753582.aspx" title="Netscape Bookmark File Format">Netscapte Bookmark File Format</a> is a popular one. it has a long story, the HTML-like bookmark is not easy to parse, XML is the best alternative, if I&#8217;ve got choice. but the well-known browser <a href="http://www.firefox.com">FireFox</a> still use this format. In order to parse it, you have to do it using the basic string operation, like &#8216;find&#8217;, &#8216;substring&#8217;, etc. I wrote a small app for parsing bookmarks.html which is located in &#8220;&#8230;\Application Data\Mozilla\Firefox&#8221;, the project was built with VS2005(UNICODE version). Follow <a href="http://www.googlestop.com/download/BookmarkTree.zip">this link </a>to download the project files.</p>
<p>I&#8217;v got a question: How to sort IE&#8217;s favorites, IE saves its favorites in a directory, but the order is saved in Windows Registry([HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MenuOrder\Favorites]). The binary data is saved as private data format, AFAIK there is no articles about this format on MSDN. I saw some articles illustrating how to &#8216;GUESS&#8217; the real meaning of it. but guessing is not the perfect solution, if you know about this, please tell me <img src='http://googlestop.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://googlestop.com/blog/2007/06/a-parser-for-netscape-bookmark-file-format/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>建立自己的消息循环(续)</title>
		<link>http://googlestop.com/blog/2007/05/%e5%bb%ba%e7%ab%8b%e8%87%aa%e5%b7%b1%e7%9a%84%e6%b6%88%e6%81%af%e5%be%aa%e7%8e%af%e7%bb%ad/</link>
		<comments>http://googlestop.com/blog/2007/05/%e5%bb%ba%e7%ab%8b%e8%87%aa%e5%b7%b1%e7%9a%84%e6%b6%88%e6%81%af%e5%be%aa%e7%8e%af%e7%bb%ad/#comments</comments>
		<pubDate>Tue, 22 May 2007 13:21:55 +0000</pubDate>
		<dc:creator>Charry</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Design Pattern]]></category>

		<guid isPermaLink="false">http://googlestop.com/blog/2007/05/22/%e5%bb%ba%e7%ab%8b%e8%87%aa%e5%b7%b1%e7%9a%84%e6%b6%88%e6%81%af%e5%be%aa%e7%8e%af%e7%bb%ad/</guid>
		<description><![CDATA[前面的帖子《建立自己的消息循环》中提到使用从CCmdTarget派生的类作为消息传递的载体，但这种方法不能传递多余的参数(也许可以，但我不知道怎么搞:)。为了使这个机制支持大多数的消息，我把前面的例子改动了一下，把那些用于消息处理的类，改为从CWnd派生，然后再Create这些窗口。这样这些类其实就是个标准的窗口了，只是我没有把它们显示出来。 本例和前面的例子，主要用在那些多使用消息机制的Project中，其实也可以不必这么做，完全可以直接去调用类的方法。但是如果消息机制比较适合，此方法不失为一种选择。 点击这里下载Demo]]></description>
			<content:encoded><![CDATA[<p>前面的帖子《<a href="http://googlestop.com/blog/2007/05/18/%e5%bb%ba%e7%ab%8b%e8%87%aa%e5%b7%b1%e7%9a%84%e6%b6%88%e6%81%af%e5%be%aa%e7%8e%af/">建立自己的消息循环</a>》中提到使用从CCmdTarget派生的类作为消息传递的载体，但这种方法不能传递多余的参数(也许可以，但我不知道怎么搞:)。为了使这个机制支持大多数的消息，我把前面的例子改动了一下，把那些用于消息处理的类，改为从CWnd派生，然后再Create这些窗口。这样这些类其实就是个标准的窗口了，只是我没有把它们显示出来。</p>
<p>本例和前面的例子，主要用在那些多使用消息机制的Project中，其实也可以不必这么做，完全可以直接去调用类的方法。但是如果消息机制比较适合，此方法不失为一种选择。</p>
<p>点击<a href="http://www.googlestop.com/download/MsgDemo.zip">这里</a>下载Demo</p>
]]></content:encoded>
			<wfw:commentRss>http://googlestop.com/blog/2007/05/%e5%bb%ba%e7%ab%8b%e8%87%aa%e5%b7%b1%e7%9a%84%e6%b6%88%e6%81%af%e5%be%aa%e7%8e%af%e7%bb%ad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>建立自己的消息循环</title>
		<link>http://googlestop.com/blog/2007/05/%e5%bb%ba%e7%ab%8b%e8%87%aa%e5%b7%b1%e7%9a%84%e6%b6%88%e6%81%af%e5%be%aa%e7%8e%af/</link>
		<comments>http://googlestop.com/blog/2007/05/%e5%bb%ba%e7%ab%8b%e8%87%aa%e5%b7%b1%e7%9a%84%e6%b6%88%e6%81%af%e5%be%aa%e7%8e%af/#comments</comments>
		<pubDate>Fri, 18 May 2007 14:48:50 +0000</pubDate>
		<dc:creator>Charry</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Design Pattern]]></category>

		<guid isPermaLink="false">http://googlestop.com/blog/2007/05/18/%e5%bb%ba%e7%ab%8b%e8%87%aa%e5%b7%b1%e7%9a%84%e6%b6%88%e6%81%af%e5%be%aa%e7%8e%af/</guid>
		<description><![CDATA[在MFC程序中使用消息机制的时候，常常会在程序即将完成的时候发现，在某个窗口中加入了太多的消息处理宏，并且这些消息的Handler和UI界面的方法混合在一起，待到项目规模大的时候，会导致后续的维护越来越困难。我们希望将UI的动作和业务处理的动作隔离开，互不影响，我们可以模仿MFC的消息流转机制，就本文来说，是Command的流转(Command Routing)，大家知道，所有的从CCmdTarget派生的类都可以支持消息处理，比如CDocument, CView, CDocTemplate等。Framework在内部使用了Chain of Responsiblity。消息会在一个链条上找到自己的执行的地方，我们可以把不同的业务逻辑分割为各个不同的环，我们可以在修改一个环的情况下，而不去影响其他的环。附件中的例子只是简单的发送一个WM_COMMAND消息，消息的ID，表示了不同的动作。此方法适合发送消息时候，参数很少或者不用参数的情况。  示例代码的简单说明： 业务处理类需要从CCmdTarget派生 在每个业务处理类里面加入适当的消息映射(注意更新MyCommand.h中的消息的宏) 在CCmdManager类的BuildCmdTarget()中加入类的初始化 在主窗口的OnCmdMsg中调用 CCmdManager的CallOnCmdMsg方法 P.S. 这里写的只是MFC消息机制最粗糙的改造，由于时间的关系，这里不做过多的介绍 示例代码，点击这里下载]]></description>
			<content:encoded><![CDATA[<p>在MFC程序中使用消息机制的时候，常常会在程序即将完成的时候发现，在某个窗口中加入了太多的消息处理宏，并且这些消息的Handler和UI界面的方法混合在一起，待到项目规模大的时候，会导致后续的维护越来越困难。我们希望将UI的动作和业务处理的动作隔离开，互不影响，我们可以模仿MFC的消息流转机制，就本文来说，是Command的流转(Command Routing)，大家知道，所有的从CCmdTarget派生的类都可以支持消息处理，比如CDocument, CView, CDocTemplate等。Framework在内部使用了Chain of Responsiblity。消息会在一个链条上找到自己的执行的地方，我们可以把不同的业务逻辑分割为各个不同的环，我们可以在修改一个环的情况下，而不去影响其他的环。附件中的例子只是简单的发送一个WM_COMMAND消息，消息的ID，表示了不同的动作。此方法适合发送消息时候，参数很少或者不用参数的情况。</p>
<p> 示例代码的简单说明：</p>
<ol>
<li>业务处理类需要从CCmdTarget派生</li>
<li>在每个业务处理类里面加入适当的消息映射(注意更新MyCommand.h中的消息的宏)</li>
<li>在CCmdManager类的BuildCmdTarget()中加入类的初始化</li>
<li>在主窗口的OnCmdMsg中调用 CCmdManager的CallOnCmdMsg方法</li>
</ol>
<p>P.S.<br />
这里写的只是MFC消息机制最粗糙的改造，由于时间的关系，这里不做过多的介绍</p>
<p>示例代码，点击<a href="http://www.googlestop.com/download/CommandTest.zip">这里</a>下载</p>
]]></content:encoded>
			<wfw:commentRss>http://googlestop.com/blog/2007/05/%e5%bb%ba%e7%ab%8b%e8%87%aa%e5%b7%b1%e7%9a%84%e6%b6%88%e6%81%af%e5%be%aa%e7%8e%af/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Add crash report to your application</title>
		<link>http://googlestop.com/blog/2007/05/add-crash-report-to-your-application/</link>
		<comments>http://googlestop.com/blog/2007/05/add-crash-report-to-your-application/#comments</comments>
		<pubDate>Wed, 16 May 2007 13:19:04 +0000</pubDate>
		<dc:creator>Charry</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://googlestop.com/blog/2007/05/16/add-crash-report-to-your-application/</guid>
		<description><![CDATA[By Charry  编写‘零缺陷’的软件是人们追求的目标，然而要做到真正的‘零缺陷’是不太可能的任务，即使的最简单的程序，我们也不敢保证它是一个理想的&#8217;bug-free&#8217;的产品。bug会贯穿一个产品的每个阶段。在开发阶段我们可以debug我们的代码，但到了后期，当我们把程序release给用户时，如果程序发生的问题，比如Crash，我们应该收集程序Crash的原因，以帮助我们修补程序的bug，现今有很多软件都提供了&#8221;Crash Report&#8221;的功能，最常见的就是MS的一些产品，在程序崩溃的时候，会出现一个对话框，提示我们程序崩溃了，是否愿意将崩溃时候的一些信息发给MS，以供开发人员调试之用。 且不说用户反馈的信息是否对我们有用，但说崩溃后提示：“程序崩溃，请blah, blah, blah”这样的字样，从某种意义上说就是在增强用户体验，因为比起程序咣当一声倒地身亡，这样起码给用户一个暗示：问题是有解决的途径的。 CodeProject上有篇文章详细的介绍了Crash Report，http://www.codeproject.com/debug/XCrashReportPt1.asp 。不过文章中介绍的内容是针对VC6的，对于VS2005还是有些问题的。我总结了一下，如何给VS2005的工程加入Crash Reprot的支持（如果是VC6的工程，请直接参考上面的链接）。 首先，去http://www.codeproject.com/debug/XCrashReportPt4.asp 下载DEMO程序，我们需要其中的XCrashReport，将它编译后，会生成XCrashReport.EXE。然后将 ExceptionAttacher.cpp ExceptionHandler.cpp - 需要去除它的预编译头文件开关 ExceptionHandler.h GetWinVer.cpp GetWinVer.h MiniVersion.cpp MiniVersion.h CrashFileNames.h 这个几个文件加入到工程中。注意，直接加入工程中并不能编译通过，作者在他的文章中提到了：“The Unicode implementation is not complete or tested.”，好在修改上面的错误也很简单，这里就不赘述了。然后将工程切换到release模式并打开工程的属性。先找到&#8221;C/C++-&#62;General&#8221;，把&#8221;Debug Information Format&#8221;设置为&#8221;Program Database(/Zi)&#8221;；然后找到&#8221;Linker-&#62;Debugging&#8221;，把&#8221;Generate Debug Info&#8221;设置为&#8221;Yes(/DEBUG)&#8221;；最后，找到&#8221;Linker-&#62;Command Line&#8221;，增加一个选项&#8221;/OPT:REF&#8221;。(好像VS2005缺省就是这样的设置) 保存好后，就可以编译您的工程了，把XCrashReport.exe 和你的EXE程序放到一起，这样在程序崩溃的时候，就会自动生成Crash Report。对于VC6编译出来的EXE程序，我们可以按照作者文章中介绍的那样，直接用VC IDE找到引发Crash的代码行，可是在VS2005下，我尝试了N次，始终不行。为了定位出错的代码行，我们还需要再下载一个工具，就是WinDbg。这是MS开发的一个非常有用的DEBUG工具，安装完毕后，将XCrashReport.EXE生成的&#8221;CRASH.DMP&#8221;的拖到WinDbg中，然后选择&#8221;File-&#62;Source File Path&#8221;设置工程源码的目录，选择&#8221;File-&#62;Symbol File Path&#8221;指向最后一次编译生成的pdb文件所在的目录，接下来在&#8221;View&#8221;菜单中打开&#8221;Call Stack&#8221;窗口，最后在&#8221;Command&#8221;窗口中输入：.ecxr 并回车，WinDbg就会显示Call Stack和引发Crash的代码。 最后补充一点，XCrashReport需要dbghelp.dll，Windows自带的dbghelp.dll可能无法正常使用，最好将原作者的DEMO中的dbghelp.dll一并copy了。还有填写接受report的email的时候，不要简单的写一个email，那样outlook不能正常的发送，得在email前面加上SMTP，例如：SMTP:test@hotmail.com 。 提醒一下：一定要把VC/VS2005生成的pdb文件备份好，以及和这个pdb文件对应的代码，如果代码改变了，WinDbg就不能跳到正确的代码行。 完!]]></description>
			<content:encoded><![CDATA[<p>By Charry </p>
<p>编写‘零缺陷’的软件是人们追求的目标，然而要做到真正的‘零缺陷’是不太可能的任务，即使的最简单的程序，我们也不敢保证它是一个理想的&#8217;bug-free&#8217;的产品。bug会贯穿一个产品的每个阶段。在开发阶段我们可以debug我们的代码，但到了后期，当我们把程序release给用户时，如果程序发生的问题，比如Crash，我们应该收集程序Crash的原因，以帮助我们修补程序的bug，现今有很多软件都提供了&#8221;Crash Report&#8221;的功能，最常见的就是MS的一些产品，在程序崩溃的时候，会出现一个对话框，提示我们程序崩溃了，是否愿意将崩溃时候的一些信息发给MS，以供开发人员调试之用。</p>
<p>且不说用户反馈的信息是否对我们有用，但说崩溃后提示：“程序崩溃，请blah, blah, blah”这样的字样，从某种意义上说就是在增强用户体验，因为比起程序咣当一声倒地身亡，这样起码给用户一个暗示：问题是有解决的途径的。</p>
<p>CodeProject上有篇文章详细的介绍了Crash Report，<a href="http://www.codeproject.com/debug/XCrashReportPt1.asp">http://www.codeproject.com/debug/XCrashReportPt1.asp</a> 。不过文章中介绍的内容是针对VC6的，对于VS2005还是有些问题的。我总结了一下，如何给VS2005的工程加入Crash Reprot的支持（如果是VC6的工程，请直接参考上面的链接）。</p>
<p>首先，去<a href="http://www.codeproject.com/debug/XCrashReportPt4.asp">http://www.codeproject.com/debug/XCrashReportPt4.asp</a> 下载DEMO程序，我们需要其中的XCrashReport，将它编译后，会生成XCrashReport.EXE。然后将</p>
<blockquote><p>ExceptionAttacher.cpp<br />
ExceptionHandler.cpp - 需要去除它的预编译头文件开关<br />
ExceptionHandler.h<br />
GetWinVer.cpp<br />
GetWinVer.h<br />
MiniVersion.cpp<br />
MiniVersion.h<br />
CrashFileNames.h</p></blockquote>
<blockquote></blockquote>
<p>这个几个文件加入到工程中。注意，直接加入工程中并不能编译通过，作者在他的文章中提到了：“The Unicode implementation is not complete or tested.”，好在修改上面的错误也很简单，这里就不赘述了。然后将工程切换到release模式并打开工程的属性。先找到&#8221;C/C++-&gt;General&#8221;，把&#8221;Debug Information Format&#8221;设置为&#8221;Program Database(/Zi)&#8221;；然后找到&#8221;Linker-&gt;Debugging&#8221;，把&#8221;Generate Debug Info&#8221;设置为&#8221;Yes(/DEBUG)&#8221;；最后，找到&#8221;Linker-&gt;Command Line&#8221;，增加一个选项&#8221;/OPT:REF&#8221;。(好像VS2005缺省就是这样的设置)</p>
<p>保存好后，就可以编译您的工程了，把XCrashReport.exe 和你的EXE程序放到一起，这样在程序崩溃的时候，就会自动生成Crash Report。对于VC6编译出来的EXE程序，我们可以按照作者文章中介绍的那样，直接用VC IDE找到引发Crash的代码行，可是在VS2005下，我尝试了N次，始终不行。为了定位出错的代码行，我们还需要再下载一个工具，就是WinDbg。这是MS开发的一个非常有用的DEBUG工具，安装完毕后，将XCrashReport.EXE生成的&#8221;CRASH.DMP&#8221;的拖到WinDbg中，然后选择&#8221;File-&gt;Source File Path&#8221;设置工程源码的目录，选择&#8221;File-&gt;Symbol File Path&#8221;指向最后一次编译生成的pdb文件所在的目录，接下来在&#8221;View&#8221;菜单中打开&#8221;Call Stack&#8221;窗口，最后在&#8221;Command&#8221;窗口中输入：.ecxr 并回车，WinDbg就会显示Call Stack和引发Crash的代码。</p>
<p>最后补充一点，XCrashReport需要dbghelp.dll，Windows自带的dbghelp.dll可能无法正常使用，最好将原作者的DEMO中的dbghelp.dll一并copy了。还有填写接受report的email的时候，不要简单的写一个email，那样outlook不能正常的发送，得在email前面加上SMTP，例如：SMTP:test@hotmail.com 。</p>
<p>提醒一下：一定要把VC/VS2005生成的pdb文件备份好，以及和这个pdb文件对应的代码，如果代码改变了，WinDbg就不能跳到正确的代码行。</p>
<p>完!</p>
]]></content:encoded>
			<wfw:commentRss>http://googlestop.com/blog/2007/05/add-crash-report-to-your-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A class for simulating MSN Messenger popup window</title>
		<link>http://googlestop.com/blog/2007/05/a-class-for-simulating-msn-messenger-popup/</link>
		<comments>http://googlestop.com/blog/2007/05/a-class-for-simulating-msn-messenger-popup/#comments</comments>
		<pubDate>Fri, 04 May 2007 16:53:31 +0000</pubDate>
		<dc:creator>Charry</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[My Application]]></category>

		<guid isPermaLink="false">http://googlestop.com/blog/2007/05/04/a-class-for-simulating-msn-messenger-popup/</guid>
		<description><![CDATA[This is a dialog-based class derived from CDialog, it shows or hides a dialog in an animated way, just like MSN Messenger does. it&#8217;s still a draft, I&#8217;ll add more features and refactor it later on. Usage: Add &#8220;AnimateDlg.h&#8221; and &#8220;AnimateDlg.cpp&#8221; in your project. Add a CDialog-based class in your program. Replace all &#8216;CDialog&#8217; with [...]]]></description>
			<content:encoded><![CDATA[<p>This is a dialog-based class derived from CDialog, it shows or hides a dialog in an animated way, just like MSN Messenger does. it&#8217;s still a draft, I&#8217;ll add more features and refactor it later on.</p>
<p><strong>Usage</strong>:</p>
<ol>
<li>Add &#8220;AnimateDlg.h&#8221; and &#8220;AnimateDlg.cpp&#8221; in your project.</li>
<li>Add a CDialog-based class in your program.</li>
<li>Replace all &#8216;CDialog&#8217; with &#8216;CAnimateDlg&#8217; in header file and implementation file.</li>
</ol>
<p><strong>Known Bugs</strong>:</p>
<p>This verstion of CAnimateDlg only works properly when Windows task bar is on the bottom of screen. it&#8217;ll be fixed in a future version.</p>
<p>To be continued&#8230;</p>
<p><a href="http://www.googlestop.com/download/AnimateDlgDemo.zip">Download project</a></p>
]]></content:encoded>
			<wfw:commentRss>http://googlestop.com/blog/2007/05/a-class-for-simulating-msn-messenger-popup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

