<?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>不敢流泪 &#187; Windows</title>
	<atom:link href="http://www.boluor.com/tag/windows/feed" rel="self" type="application/rss+xml" />
	<link>http://www.boluor.com</link>
	<description></description>
	<lastBuildDate>Fri, 07 Oct 2011 07:28:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>windows下利用CDO发送邮件</title>
		<link>http://www.boluor.com/vbscript-to-send-email-using-cdo-under-windows.html</link>
		<comments>http://www.boluor.com/vbscript-to-send-email-using-cdo-under-windows.html#comments</comments>
		<pubDate>Fri, 14 May 2010 10:02:21 +0000</pubDate>
		<dc:creator>boluor</dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[VBS]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.boluor.com/?p=634</guid>
		<description><![CDATA[<p>前几天同学丢了本子后，毕业论文一个字不剩。要是临到答辩前我也遭遇这么一出可就傻眼了，所以想每天备份下毕业论文。备份的最好的地方就是发到邮箱了，空间大而且方便，不过每次都手动发送邮件是件挺麻烦的事情，搜了下发现用CDO蛮方便的，而且是内建在windows内核中的，不用安装七七八八的组件。</p>
<p>下面的代码实现了一键备份，将当前的系统时间当作Subject的一部分，方便区别。(VBS实现)</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:Courier new,verdana;">NameSpace = <span style="color: #800000;">&#34;http://schemas.microsoft.com/cdo/configuration/&#34;</span>
<span style="color: #000080;">Set</span> Email = CreateObject(<span style="color: #800000;">&#34;CDO.Message&#038;q</span></pre></div></div><p>&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>前几天同学丢了本子后，毕业论文一个字不剩。要是临到答辩前我也遭遇这么一出可就傻眼了，所以想每天备份下毕业论文。备份的最好的地方就是发到邮箱了，空间大而且方便，不过每次都手动发送邮件是件挺麻烦的事情，搜了下发现用CDO蛮方便的，而且是内建在windows内核中的，不用安装七七八八的组件。</p>
<p>下面的代码实现了一键备份，将当前的系统时间当作Subject的一部分，方便区别。(VBS实现)</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:Courier new,verdana;">NameSpace = <span style="color: #800000;">&quot;http://schemas.microsoft.com/cdo/configuration/&quot;</span>
<span style="color: #000080;">Set</span> Email = CreateObject(<span style="color: #800000;">&quot;CDO.Message&quot;</span>)
Email.From = <span style="color: #800000;">&quot;aaa@sina.com&quot;</span>
Email.<span style="color: #000080;">To</span> = <span style="color: #800000;">&quot;bbb@gmail.com&quot;</span>
Email.Subject = <span style="color: #800000;">&quot;毕业论文备份 &quot;</span> + <span style="color: #000080;">cstr</span>(now())
Email.Textbody = <span style="color: #800000;">&quot;OK!&quot;</span>
Email.AddAttachment <span style="color: #800000;">&quot;E:\毕设文档\毕业论文.docx&quot;</span>
<span style="color: #000080;">With</span> Email.Configuration.Fields
.Item(NameSpace&amp;<span style="color: #800000;">&quot;sendusing&quot;</span>) = 2
.Item(NameSpace&amp;<span style="color: #800000;">&quot;smtpserver&quot;</span>) = <span style="color: #800000;">&quot;smtp.sina.com&quot;</span> 
.Item(NameSpace&amp;<span style="color: #800000;">&quot;smtpserverport&quot;</span>) = 25
.Item(NameSpace&amp;<span style="color: #800000;">&quot;smtpauthenticate&quot;</span>) = 1
.Item(NameSpace&amp;<span style="color: #800000;">&quot;sendusername&quot;</span>) = <span style="color: #800000;">&quot;aaa@sina.com&quot;</span>
.Item(NameSpace&amp;<span style="color: #800000;">&quot;sendpassword&quot;</span>) = <span style="color: #800000;">&quot;yourpasswd&quot;</span>
.Update
<span style="color: #000080;">End</span> <span style="color: #000080;">With</span>
Email.Send</pre></div></div>

<p>以上参考：<br />
<a href="http://www.paulsadowski.com/wsh/cdo.htm">VBScript To Send Email Using CDO</a><br />
<a href="http://hi.baidu.com/tbxwz/blog/item/f7daff1637509b57f2de3216.html">一个用Windows脚本发邮件的例子</a><br />
CDO相关参考见：<br />
<a href="http://www.teamits.com/internet/support/nt/cdo.html">CDO (Collaboration Data Objects)</a><br />
MSDN中也有相关的介绍。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.boluor.com/vbscript-to-send-email-using-cdo-under-windows.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>向记事本发送键盘消息</title>
		<link>http://www.boluor.com/send-keyboard-message-to-notepad-in-windows.html</link>
		<comments>http://www.boluor.com/send-keyboard-message-to-notepad-in-windows.html#comments</comments>
		<pubDate>Fri, 10 Jul 2009 16:30:10 +0000</pubDate>
		<dc:creator>boluor</dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[VC]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.boluor.com/?p=185</guid>
		<description><![CDATA[<p>    上午还在实验室的时候，龙哥短信说我们的门锁坏了，开不了，他们出不来，我只好回来。回来后，试了很久，还是打不开，于是一脚踹开了。然后发现门傍貌似裂了，锁的弹簧断了&#8230;打电话找了木工，修了很久终于可以用了，由于时间比较晚，也就没去实验室了。<br />
    打电话让FM帮我带回来本子。突然想起来前天和Sandy的关于魔兽改键工具的讨论，我需要确定war3到底是怎么接受键盘信息的。于是迫不及待地想写个给其他程序发送键盘消息的程序。我选择了记事本做测试。<br />
    思路很简单，FindWindow获得句柄，然后SendMessage或者PostMessage。至于其中遇到的问题，还需要仔细探究消息队列，SendMessa&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>    上午还在实验室的时候，龙哥短信说我们的门锁坏了，开不了，他们出不来，我只好回来。回来后，试了很久，还是打不开，于是一脚踹开了。然后发现门傍貌似裂了，锁的弹簧断了&#8230;打电话找了木工，修了很久终于可以用了，由于时间比较晚，也就没去实验室了。<br />
    打电话让FM帮我带回来本子。突然想起来前天和Sandy的关于魔兽改键工具的讨论，我需要确定war3到底是怎么接受键盘信息的。于是迫不及待地想写个给其他程序发送键盘消息的程序。我选择了记事本做测试。<br />
    思路很简单，FindWindow获得句柄，然后SendMessage或者PostMessage。至于其中遇到的问题，还需要仔细探究消息队列，SendMessage和PostMessage的区别，下次再讨论。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="cpp" style="font-family:Courier new,verdana;"><span style="color: #0000ff;">void</span> CSendMessageTestDlg<span style="color: #008080;">::</span><span style="color: #007788;">OnBnClickedButton1</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #666666;">// TODO: 在此添加控件通知处理程序代码</span>
	HWND hwnd <span style="color: #000080;">=</span> <span style="color: #008080;">::</span><span style="color: #007788;">FindWindow</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">NULL</span>,<span style="color: #FF0000;">&quot;无标题 - 记事本&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
	HWND hedit <span style="color: #000080;">=</span> <span style="color: #008080;">::</span><span style="color: #007788;">GetDlgItem</span><span style="color: #008000;">&#40;</span>hwnd,<span style="color: #208080;">0x0000000F</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><span style="color: #666666;">//编辑框控件ID。用spy++可以看到。</span>
&nbsp;
	<span style="color: #666666;">//HWND hedit = ::FindWindowEx(hwnd,NULL,&quot;edit&quot;,NULL);</span>
	<span style="color: #666666;">//::SendMessage(hedit,WM_KEYDOWN,'1',0);//SendMessage时只有用WM_CHAR才有用。</span>
	<span style="color: #008080;">::</span><span style="color: #007788;">PostMessage</span><span style="color: #008000;">&#40;</span>hedit,WM_CHAR,<span style="color: #FF0000;">'1'</span>,<span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #666666;">//PostMessage用WM_KEYUP,WM_KEYDOWN或者WM_CHAR都可以。</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>    要了解在MFC工程中，用::FindWindow和不使用::的区别。当不使用时，调用的是当前类的成员函数。<br />
    发张用Spy++查看窗口句柄的的截图.Spy++还可以查看进程的消息队列，功能很强大。<br />
<div id="attachment_188" class="wp-caption alignnone" style="width: 310px"><a href="http://www.boluor.com/wp-content/uploads/2009/07/spynotepad.JPG"><img src="http://www.boluor.com/wp-content/uploads/2009/07/spynotepad-300x141.jpg" alt="Spy++查看记事本比编辑控件窗口" title="spy&amp;notepad" width="300" height="141" class="size-medium wp-image-188" /></a><p class="wp-caption-text">Spy++查看记事本比编辑控件窗口</p></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.boluor.com/send-keyboard-message-to-notepad-in-windows.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>VC++创建目录</title>
		<link>http://www.boluor.com/vc-create-directory.html</link>
		<comments>http://www.boluor.com/vc-create-directory.html#comments</comments>
		<pubDate>Wed, 08 Jul 2009 13:53:52 +0000</pubDate>
		<dc:creator>boluor</dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[VC]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.boluor.com/?p=181</guid>
		<description><![CDATA[<p>        这几天暑期集训带队，每天会将各个队的进度报告和自己的带队笔记放到相应的目录下。我习惯每天的记录单独存放，比如今天会创建个名为”090708”的目录，明天会创建一个名为“090709”的。而在这个目录下，会将各队的信息单独存放，就是要创建三个目录：“MFC队”，“ASP队”，“改键工具”。本来想手工一个个建的，后来想不如编程实现。查了些资料，用VC++实现了。<br />
	参照DirectoryInfo类的例子写成的。其实用到的托管到底是怎么回事我现在也没搞清楚。忙完实验室了回头看看吧。<br />
	创建控制台程序，选择空项目。<br />
<span id="more-181"></span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="cpp" style="font-family:Courier new,verdana;"><span style="color: #0000ff;">u</span></pre></td></tr></table></div><p>&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>        这几天暑期集训带队，每天会将各个队的进度报告和自己的带队笔记放到相应的目录下。我习惯每天的记录单独存放，比如今天会创建个名为”090708”的目录，明天会创建一个名为“090709”的。而在这个目录下，会将各队的信息单独存放，就是要创建三个目录：“MFC队”，“ASP队”，“改键工具”。本来想手工一个个建的，后来想不如编程实现。查了些资料，用VC++实现了。<br />
	参照DirectoryInfo类的例子写成的。其实用到的托管到底是怎么回事我现在也没搞清楚。忙完实验室了回头看看吧。<br />
	创建控制台程序，选择空项目。<br />
<span id="more-181"></span></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="cpp" style="font-family:Courier new,verdana;"><span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> System<span style="color: #008080;">;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> System<span style="color: #008080;">::</span><span style="color: #007788;">IO</span><span style="color: #008080;">;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	DirectoryInfo<span style="color: #000040;">^</span> di<span style="color: #008080;">;</span>
	String<span style="color: #000040;">^</span> fatherDir<span style="color: #008080;">;</span>
	String<span style="color: #000040;">^</span> fatherDir_prefix <span style="color: #000080;">=</span> gcnew String <span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;I: 9暑期集训mstc&amp;&amp;cc监督进度 907&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i<span style="color: #000080;">=</span><span style="color: #0000dd;">8</span><span style="color: #008080;">;</span>i<span style="color: #000080;">&lt;=</span><span style="color: #0000dd;">20</span><span style="color: #008080;">;</span>i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
		fatherDir <span style="color: #000080;">=</span> gcnew String <span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>i<span style="color: #000080;">&lt;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
			fatherDir <span style="color: #000080;">=</span> fatherDir_prefix <span style="color: #000040;">+</span> <span style="color: #FF0000;">&quot;0&quot;</span><span style="color: #000040;">+</span> i<span style="color: #008080;">;</span>
		<span style="color: #008000;">&#125;</span><span style="color: #0000ff;">else</span><span style="color: #008000;">&#123;</span>
			fatherDir <span style="color: #000080;">=</span> fatherDir_prefix <span style="color: #000040;">+</span> i<span style="color: #008080;">;</span>
		<span style="color: #008000;">&#125;</span>
&nbsp;
		di<span style="color: #000080;">=</span> gcnew DirectoryInfo<span style="color: #008000;">&#40;</span>fatherDir<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
		<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>di<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>Exists <span style="color: #000080;">==</span> <span style="color: #0000ff;">false</span><span style="color: #008000;">&#41;</span>
			di<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>Create<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
		<span style="color: #666666;">// Create three subdirectory in the directory just created.</span>
		di<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>CreateSubdirectory<span style="color: #008000;">&#40;</span> <span style="color: #FF0000;">&quot;MFC队&quot;</span> <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		di<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>CreateSubdirectory<span style="color: #008000;">&#40;</span> <span style="color: #FF0000;">&quot;ASP队&quot;</span> <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		di<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>CreateSubdirectory<span style="color: #008000;">&#40;</span> <span style="color: #FF0000;">&quot;改键工具&quot;</span> <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>	在编译时，会遇到编译错误。需要设置下：</p>
<p>1.	项目属性—配置属性—常规—字符集，选择多字节字符集。VC2005默认是Unicode。<br />
2.	提示错误error C2871: “System”: 具有该名称的命名空间不存在时，是因为程序是托管代码，在项目中选择公共语言运行库支持/clr就好了。设置路径就在设置字符集的下面一栏。<br />
3.	提示错误error LNK2001: unresolved external symbol _WinMain@16。参照：<a href="http://blog.csai.cn/user1/16781/archives/2006/6412.html ">vc中error LNK2001:unresolved external symbol _WinMain@16的解决方法</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.boluor.com/vc-create-directory.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>键盘钩子函数执行两次解决方法</title>
		<link>http://www.boluor.com/solution-to-the-keyboard-hook-function-is-executed-twice.html</link>
		<comments>http://www.boluor.com/solution-to-the-keyboard-hook-function-is-executed-twice.html#comments</comments>
		<pubDate>Mon, 06 Jul 2009 09:31:03 +0000</pubDate>
		<dc:creator>boluor</dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[hook]]></category>
		<category><![CDATA[VC]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.boluor.com/?p=169</guid>
		<description><![CDATA[<p>考虑下面的键盘钩子函数。(MFC工程)</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="cpp" style="font-family:Courier new,verdana;">LRESULT CALLBACK KeyProc<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> nCode,WPARAM w,LPARAM l<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">'A'</span><span style="color: #000080;">==</span>w<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
		MessageBox<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">NULL</span>,<span style="color: #FF0000;">&#34;yes&#34;</span>,<span style="color: #FF0000;">&#34;test&#34;</span>,MB_OK<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
&#160;
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>    也就是想在按下A的时候，弹出一个对话框。</p>
<p>     然后在一个事件中添加：<br />
     SetWindowsHookEx(WH_KEYBOARD,KeyProc,NULL,GetCurrentThread&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>考虑下面的键盘钩子函数。(MFC工程)</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="cpp" style="font-family:Courier new,verdana;">LRESULT CALLBACK KeyProc<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> nCode,WPARAM w,LPARAM l<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">'A'</span><span style="color: #000080;">==</span>w<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
		MessageBox<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">NULL</span>,<span style="color: #FF0000;">&quot;yes&quot;</span>,<span style="color: #FF0000;">&quot;test&quot;</span>,MB_OK<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
&nbsp;
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>    也就是想在按下A的时候，弹出一个对话框。</p>
<p>     然后在一个事件中添加：<br />
     SetWindowsHookEx(WH_KEYBOARD,KeyProc,NULL,GetCurrentThreadId());<br />
    安装钩子。事件被触发后，就可以调用上面的键盘钩子函数了。</p>
<p>    但是在执行时会发现，当按下A时，提示框弹出了两遍。是什么原因呢？<br />
<span id="more-169"></span><br />
     想到了一个解释，那就是当按键时，按下和弹起分别是一个事件，所以调用了两次钩子函数。那么如何解决呢？看MSDN的帮助时发现，KeyboardProc Function的第三个参数，也就是LPARAM类型的参数，有很多的作用。LAPRAM占4个字节，32位。每一位都是一个特殊的标志。比如说如果Alt键被按下的话，第29位就是1，否则为0。那么键盘按下和弹起是哪个呢？是第30位。这一位标记了上次按键的状态。在消息发送之前，如果按键是按下的，那么值为1，否则为0。(经Sandy提醒,添加下面一句)第31位标记当前按键的状态，取值和第30位的规则相同。我们可以根据这一位来过滤掉按下和弹起中的一个。<br />
     添加一层过滤后，代码如下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="cpp" style="font-family:Courier new,verdana;">LRESULT CALLBACK KeyProc<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> nCode,WPARAM w,LPARAM l<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>l  <span style="color: #000080;">&gt;&gt;</span> <span style="color: #0000dd;">31</span> <span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>	<span style="color: #666666;">//修改前为第30位，应该是第31位，判断当前按键状态。</span>
		<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">'A'</span><span style="color: #000080;">==</span>w<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
			MessageBox<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">NULL</span>,<span style="color: #FF0000;">&quot;yes&quot;</span>,<span style="color: #FF0000;">&quot;test&quot;</span>,MB_OK<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
			<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
		<span style="color: #008000;">&#125;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>	 那么为什么我之前用第30位来判断也是可以的呢? 原因在于，当前按键时，第30位也就是保存了上次按键的状态位必定为弹起状态，那么上面的语句也就可以正常执行。不过，每次判断的都不是当前按键的状态，而是上次的状态。这在其他应用中会造成很难察觉的错误。(谢谢Sandy的提醒，以后多点细心^.^)。</p>
<p>     其实系统提供了一个预定义KF_UP，在winuser.h中，来标记按键是否是弹起状态。不过，使用时需要注意，如果这样判断：<br />
     if ( l &#038; KF_UP){<br />
             //key up<br />
     }<br />
     是不正确的。注意在KF_UP定义的地方有一句：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="cpp" style="font-family:Courier new,verdana;"> <span style="color: #ff0000; font-style: italic;">/*
 * WM_KEYUP/DOWN/CHAR HIWORD(lParam) flags
 */</span>
<span style="color: #339900;">#define KF_UP             0x8000</span></pre></td></tr></table></div>

<p>      这表明，KF_UP是高位标志。使用时需要移位。所以可以这样比较：<br />
      if ( KF_UP &#038; ( l >> 16 ) ){<br />
      }<br />
      或者利用宏HIWORD取得参数l的高16位。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.boluor.com/solution-to-the-keyboard-hook-function-is-executed-twice.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>DLL基础</title>
		<link>http://www.boluor.com/dll-base.html</link>
		<comments>http://www.boluor.com/dll-base.html#comments</comments>
		<pubDate>Mon, 11 May 2009 05:15:00 +0000</pubDate>
		<dc:creator>boluor</dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[DLL]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.boluor.com/blog/?p=60</guid>
		<description><![CDATA[<p>&#160;&#160;&#160;&#160;&#160;&#160; 想写个程序,可以监控某个进程,然后对其进行某些操作…别怀疑我的动机，我是和谐社会的良民<img alt="" src="http://www.zu14.cn/coolemotion/emotions/hi_6.gif" /> </p>
<p>然后第一步开始，DLL到底是什么?听到DLLl这词的次数绝对比我的年龄大（本人年方22，嘿嘿！），不过却从来没去研究过，所以一直觉得DLL很神秘。不过，箭在弦上，不得不去了解了。想找本书看的，结果搜罗了半个小时没发现，烦了，就开始看<a href="http://hi.baidu.com/44997/blog/item/dcf47b59198b2d2a2934f0e1.html">某人的blog</a>，实现了后觉得豁然开朗啊。微软官网的<a href="http://support.microsoft.com/kb/815065/zh-cn">帮助</a>也不错。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; 原文写的很不错。写下我的感受。</p>
<p>【<strong>概念</strong>】</p>
<p>&#160;&#160;&#038;&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>&#160;&#160;&#160;&#160;&#160;&#160; 想写个程序,可以监控某个进程,然后对其进行某些操作…别怀疑我的动机，我是和谐社会的良民<img alt="" src="http://www.zu14.cn/coolemotion/emotions/hi_6.gif" /> </p>
<p>然后第一步开始，DLL到底是什么?听到DLLl这词的次数绝对比我的年龄大（本人年方22，嘿嘿！），不过却从来没去研究过，所以一直觉得DLL很神秘。不过，箭在弦上，不得不去了解了。想找本书看的，结果搜罗了半个小时没发现，烦了，就开始看<a href="http://hi.baidu.com/44997/blog/item/dcf47b59198b2d2a2934f0e1.html">某人的blog</a>，实现了后觉得豁然开朗啊。微软官网的<a href="http://support.microsoft.com/kb/815065/zh-cn">帮助</a>也不错。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; 原文写的很不错。写下我的感受。</p>
<p>【<strong>概念</strong>】</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; DLL是动态链接库的缩写，是一个包含有可使多个程序同时使用的数据和代码。使用促进代码的模块化、代码重用、内存的有效使用和减少所占用的磁盘空间。不过，由于使用DLL的程序需要实时的调用DLL中的数据或者代码，所以DLL必须和软件一起发放。</p>
<p> <span id="more-60"></span>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; DLL是建立在客户/服务器通信的概念上，包含若干函数、类或资源的库文件，函数和数据被存储在一个DLL（服务器）上并由一个或多个客户导出而使用，这些客户可以是应用程序或者是其它的DLL。DLL库不同于静态库，在静态库情况下，函数和数据被编译进一个二进制文件（通常扩展名为*.LIB），Visual C++的编译器在处理程序代码时将从静态库中恢复这些函数和数据并把他们和应用程序中的其他模块组合在一起生成可执行文件。这个过程称为&quot;静态链接&quot;，此时因为应用程序所需的全部内容都是从库中复制了出来，所以静态库本身并不需要与可执行文件一起发行。      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 在动态库的情况下，有两个文件，一个是引入库（.LIB）文件，一个是DLL文件，引入库文件包含被DLL导出的函数的名称和位置，DLL包含实际的函数和数据，应用程序使用LIB文件链接到所需要使用的DLL文件，库中的函数和数据并不复制到可执行文件中，因此在应用程序的可执行文件中，存放的不是被调用的函数代码，而是DLL中所要调用的函数的内存地址，这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来，从而节省了内存资源。</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 微软的Visual C++支持三种DLL，它们分别是Non-MFC Dll（非MFC动态库）、Regular Dll（常规DLL）、Extension Dll（扩展DLL）。Non-MFC DLL指的是不用MFC的类库结构，直接用C语言写的DLL，其导出的函数是标准的C接口，能被非MFC或MFC编写的应用程序所调用。Regular DLL:和下述的Extension Dlls一样，是用MFC类库编写的，它的一个明显的特点是在源文件里有一个继承CWinApp的类（注意：此类DLL虽然从CWinApp派生，但没有消息循环）,被导出的函数是C函数、C++类或者C++成员函数（注意不要把术语C++类与MFC的微软基础C++类相混淆），调用常规DLL的应用程序不必是MFC应用程序，只要是能调用类C函数的应用程序就可以，它们可以是在Visual C++、Dephi、Visual Basic、Borland C等编译环境下利用DLL开发应用程序。</p>
<p>【<strong>编程基础</strong>】(以下多为引用)</p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 由VS6或者VS2005时创建DLL工程只要按照提示一步步就行了。这里都是以VS2005，Non-MFC DLL。</p>
<p><strong>Win32 Dynamic-Link Library方式创建Non-MFC DLL动态链接库：</strong></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 每一个DLL都必须有一个入口函数，默认是DllMain，这跟C里的main函数类似。用这个确省的入口函数就可以对DLL正确的初始化。典型的格式如下：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:Courier new,verdana;">BOOL APIENTRY DllMain<span style="color: #008000;">&#40;</span> HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 <span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">switch</span> <span style="color: #008000;">&#40;</span>ul_reason_for_call<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">case</span> DLL_PROCESS_ATTACH<span style="color: #008080;">:</span>
	<span style="color: #0000ff;">case</span> DLL_THREAD_ATTACH<span style="color: #008080;">:</span>
	<span style="color: #0000ff;">case</span> DLL_THREAD_DETACH<span style="color: #008080;">:</span>
	<span style="color: #0000ff;">case</span> DLL_PROCESS_DETACH<span style="color: #008080;">:</span>
		<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">return</span> TRUE<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 对于进程线程的创建和释放时,需要进行的操作在case时调用就可以了。</p>
<p><strong>导出DLL中的Symbols</strong></p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DLL是包含若干个函数的库文件，应用程序使用DLL中的函数之前，应该先导出这些函数，以便供给应用程序使用。要导出这些函数有两种方法，一是在定义函数时使用导出关键字__declspec(dllexport)，另外一种方法是在创建DLL文件时使用模块定义文件.Def。需要注意的是在使用第一种方法的时候，不能使用DEF文件。例子看附件。</p>
<ol>
<li>&#160;&#160;&#160;&#160;&#160; 使用__declspec(dllexport)来创建mydll.dll。该动态链接库中有两个函数，分别用来实现得到两个数的最大和最小数。在MyDll.h和MyDLL.cpp文件中分别输入如下原代码：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:Courier new,verdana;"><span style="color: #666666;">//MyDll.h</span>
<span style="color: #0000ff;">extern</span> <span style="color: #FF0000;">&quot;C&quot;</span> __declspec<span style="color: #008000;">&#40;</span>dllexport<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">int</span> Max<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> a,<span style="color: #0000ff;">int</span> b<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">extern</span> <span style="color: #FF0000;">&quot;C&quot;</span> __declspec<span style="color: #008000;">&#40;</span>dllexport<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">int</span> Min<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> a,<span style="color: #0000ff;">int</span> b<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #666666;">//MyDll.cpp</span>
<span style="color: #0000ff;">int</span> Max<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> a,<span style="color: #0000ff;">int</span> b<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">return</span> a<span style="color: #000080;">&gt;</span>b<span style="color: #008080;">?</span>a<span style="color: #008080;">:</span>b<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">int</span> Min<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> a,<span style="color: #0000ff;">int</span> b<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">return</span> a<span style="color: #000080;">&gt;</span>b<span style="color: #008080;">?</span>b<span style="color: #008080;">:</span>a<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>  &#160;&#160;&#160;&#160;&#160; 该动态链接库编译成功后，打开MyDll工程中的debug目录，可以看到MyDll.dll、MyDll.lib两个文件。LIB文件中包含DLL文件名和DLL文件中的函数名等，该LIB文件只是对应该DLL文件的&quot;映像文件&quot;，与DLL文件中，LIB文件的长度要小的多，在进行隐式链接DLL时要用到它。读者可能已经注意到在MyDll.h中有关键字&quot;extern C&quot;，它可以使其他编程语言访问你编写的DLL中的函数。 </li>
<li>&#160;&#160;&#160;&#160; 用.def文件来创建DLL。        <br />&#160;&#160; 为了用.def文件创建DLL，请先删除上个例子创建的工程中的MyDll.h文件，保留MyDll.cpp并在该文件头删除#include MyDll.h语句，同时往该工程中加入一个文本文件，命名为MyDll.def，再在该文件中加入如下代码：         <br />LIBRARY MyDll         <br />EXPORTS         <br />Max         <br />Min         <br />其中LIBRARY语句说明该def文件是属于相应DLL的，EXPORTS语句下列出要导出的函数名称。我们可以在.def文件中的导出函数后加 @n，如Max@1，Min@2，表示要导出的函数顺序号，在进行显式连时可以用到它。该DLL编译成功后，打开工程中的Debug目录，同样也会看到 MyDll.dll和MyDll.lib文件。 </li>
</ol>
<p>&#160;</p>
<p><strong>动态链接库DLL的链接 </strong>      <br />&#160;&#160;&#160;&#160;&#160; 应用程序使用DLL可以采用两种方式：一种是隐式链接，另一种是显式链接。在使用DLL之前首先要知道DLL中函数的结构信息。Visual C++安装目录下提供了一个名为Dumpbin.exe的小程序，用它可以查看DLL文件中的函数结构。另外，Windows系统将遵循下面的搜索顺序来定位DLL： 1．包含EXE文件的目录，2．进程的当前工作目录， 3．Windows系统目录， 4．Windows目录，5．列在Path环境变量中的一系列目录。&#160; <br />1．隐式链接       <br />&#160;&#160;&#160;&#160;&#160; 隐式链接就是在程序开始执行时就将DLL文件加载到应用程序当中。实现隐式链接很容易，只要将导入函数关键字 __declspec(dllimport)函数名等写到应用程序相应的头文件中就可以了。下面的例子通过隐式链接调用MyDll.dll库中的Min函数。首先生成一个项目为TestDll，在DllTest.h、DllTest.cpp文件中分别输入如下代码：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:Courier new,verdana;"><span style="color: #666666;">//DllTest.h</span>
<span style="color: #666666;">//dll1.dll生成时用的def文件，不是用头文件生成的。</span>
<span style="color: #339900;">#pragma comment(lib,&quot;dll1.lib&quot;)  </span>
<span style="color: #666666;">//如果生成DLL时使用了头文件，下面的声明和头文件的要相对应。</span>
<span style="color: #666666;">//比如在最前面加 extern &quot;C&quot;</span>
__declspec<span style="color: #008000;">&#40;</span>dllimport<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">int</span> Max<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> a,<span style="color: #0000ff;">int</span> b<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> 
__declspec<span style="color: #008000;">&#40;</span>dllimport<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">int</span> Min<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> a,<span style="color: #0000ff;">int</span> b<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>  
<span style="color: #666666;">//DllTest.cpp</span>
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#include &quot;testdll.h&quot;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
&nbsp;
	<span style="color: #0000ff;">int</span> a,b<span style="color: #008080;">;</span>
	<span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">cin</span><span style="color: #000080;">&gt;&gt;</span>a<span style="color: #000080;">&gt;&gt;</span>b<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
		<span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;</span> <span style="color: #000080;">&lt;</span><span style="color: #FF0000;">&quot;较大数:&quot;</span> <span style="color: #000080;">&lt;&lt;</span> Max<span style="color: #008000;">&#40;</span>a,b<span style="color: #008000;">&#41;</span><span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>    在创建DllTest.exe文件之前，要先将MyDll.dll和MyDll.lib拷贝到当前工程所在的目录下面，也可以拷贝到windows的 System目录下。如果DLL使用的是def文件，要删除TestDll.h文件中关键字extern &quot;C&quot;。TestDll.h文件中的关键字Progam commit是要Visual C+的编译器在link时，链接到MyDll.lib文件，当然，开发人员也可以不使用#pragma comment(lib,”dll1.lib”)语句，而直接在工程的Setting-&gt;Link页的Object/Moduls栏填入 MyDll.lib既可。 </p>
<p>2．显式链接&#160; <br />&#160;&#160;&#160;&#160;&#160; 显式链接是应用程序在执行过程中随时可以加载DLL文件，也可以随时卸载DLL文件，这是隐式链接所无法作到的，所以显式链接具有更好的灵活性，对于解释性语言更为合适。不过实现显式链接要麻烦一些。在应用程序中用LoadLibrary或MFC提供的AfxLoadLibrary显式的将自己所做的动态链接库调进来，动态链接库的文件名即是上述两个函数的参数，此后再用GetProcAddress()获取想要引入的函数。自此，你就可以象使用如同在应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前，应该用FreeLibrary或MFC提供的AfxFreeLibrary释放动态链接库。下面是通过显式链接调用DLL中的Max函数的例子。</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:Courier new,verdana;"><span style="color: #0000ff;">void</span> main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">int</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>pMax<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> a,<span style="color: #0000ff;">int</span> b<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">int</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>pMin<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> a,<span style="color: #0000ff;">int</span> b<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	HINSTANCE hDLL<span style="color: #008080;">;</span>
	PMax Max<span style="color: #008080;">;</span>
	HDLL<span style="color: #000080;">=</span>LoadLibrary<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;MyDll.dll&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><span style="color: #666666;">//加载动态链接库MyDll.dll文件；</span>
	Max<span style="color: #000080;">=</span><span style="color: #008000;">&#40;</span>pMax<span style="color: #008000;">&#41;</span>GetProcAddress<span style="color: #008000;">&#40;</span>hDLL,<span style="color: #FF0000;">&quot;Max&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	A<span style="color: #000080;">=</span>Max<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">5</span>,<span style="color: #0000dd;">8</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	Printf<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;比较的结果为%d&quot;</span>,a<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	FreeLibrary<span style="color: #008000;">&#40;</span>hDLL<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span><span style="color: #666666;">//卸载MyDll.dll文件；</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>&#160;&#160;&#160;&#160;&#160;&#160; 在上例中使用类型定义关键字typedef，定义指向和DLL中相同的函数原型指针，然后通过LoadLibray()将DLL加载到当前的应用程序中并返回当前DLL文件的句柄，然后通过GetProcAddress()函数获取导入到应用程序中的函数指针，函数调用完毕后，使用 FreeLibrary()卸载DLL文件。在编译程序之前，首先要将DLL文件拷贝到工程所在的目录或Windows系统目录下。       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; 使用显式链接应用程序编译时不需要使用相应的Lib文件。另外，使用GetProcAddress()函数时，可以利用 MAKEINTRESOURCE()函数直接使用DLL中函数出现的顺序号，如将GetProcAddress(hDLL,&quot;Min&quot;)改为 GetProcAddress(hDLL, MAKEINTRESOURCE(2))（函数Min()在DLL中的顺序号是2），这样调用DLL中的函数速度很快，但是要记住函数的使用序号，否则会发生错误。</iostream></p>
]]></content:encoded>
			<wfw:commentRss>http://www.boluor.com/dll-base.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

