﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-FireBird</title><link>http://www.cppblog.com/firebird/</link><description /><language>zh-cn</language><lastBuildDate>Mon, 13 Apr 2026 10:47:56 GMT</lastBuildDate><pubDate>Mon, 13 Apr 2026 10:47:56 GMT</pubDate><ttl>60</ttl><item><title>子类化</title><link>http://www.cppblog.com/firebird/archive/2011/11/20/160572.html</link><dc:creator>firebird</dc:creator><author>firebird</author><pubDate>Sun, 20 Nov 2011 09:52:00 GMT</pubDate><guid>http://www.cppblog.com/firebird/archive/2011/11/20/160572.html</guid><wfw:comment>http://www.cppblog.com/firebird/comments/160572.html</wfw:comment><comments>http://www.cppblog.com/firebird/archive/2011/11/20/160572.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/firebird/comments/commentRss/160572.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/firebird/services/trackbacks/160572.html</trackback:ping><description><![CDATA[<div>为了知道什么时候一个消息被发送到应用程序，必须用自己的窗口过程代替 Application的窗口过程。当在自己的窗口过程中对消息处理完后，要把消息再传递给原窗口过程。这样的过程就叫做子类化窗口。</div>
<div>可以传递一个常量GWL _ WNDPROC给Win32 API函数SetWindowLong( )来指定一个新的窗口过程。窗口过程可以是以下两种格式:一是利用API定义;二是利用Delphi使窗口方法作为窗口过程。注意 当子类化一个VCL窗口的窗口过程时，可能由于窗口的句柄被重复创建而导致应用程序失败。使用子类化技术一定要小心。一种更为安全的使用方法是使用 Application.HookMainWindow()。我们将在后面讨论它。</div>
<div><br />
</div>
<div>1. 一个Win32 API的窗口过程</div>
<div>一个API的窗口过程必须像这样声明：</div>
<div>
<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">1</span>&nbsp;<span style="color: #000000; ">function&nbsp;AWndProc&nbsp;(Handle:hWnd;&nbsp;Msg,&nbsp;wParam,&nbsp;lParam:Longint):Longint;stdcall;</span></div>
</div>
<div><br />
</div>
<div>声明中，Handle参数用于标识目标窗口；Msg是一个消息；wParam、lpParam参数含有消息的附加信息。函数的返回值要依靠收到的消息确定。需要特别注意，此函数必须用 stdcall作为调用约定。</div>
<div>可以这样使用SetWindowLong( )函数给应用程序的窗口指定窗口过程：</div>
<div>
<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000; ">var<br />
&nbsp;&nbsp;&nbsp;WProc:&nbsp;Pointer;<br />
begin<br />
&nbsp;&nbsp;&nbsp;WProc:</span><span style="color: #000000; ">=</span><span style="color: #000000; ">Pointer(SetWindowLong(Application.Handle,&nbsp;GWL_WINDPROC,&nbsp;Integer(@NewWndProc)));<br />
</span></div>
</div>
<div><br />
</div>
<div>在此调用后，返回一个指针类型的WProc指向旧的窗口过程。对这个值的保留是很必要的，因为</div>
<div>有些消息可能需要传递给旧的窗口过程。下面是一个窗口过程的实现示例：</div>
<div>
<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">1</span>&nbsp;<span style="color: #000000; ">function&nbsp;AWndProc&nbsp;(Handle:hWnd;&nbsp;Msg,&nbsp;wParam,&nbsp;lParam:Longint):Longint;stdcall;<br />
</span><span style="color: #008080; ">2</span>&nbsp;<span style="color: #000000; ">begin<br />
</span><span style="color: #008080; ">3</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;Result:</span><span style="color: #000000; ">=</span><span style="color: #000000; ">CallWindowProc(WProc,&nbsp;Application.Handle,&nbsp;Msg,&nbsp;wParam,&nbsp;lParam);<br />
</span><span style="color: #008080; ">4</span>&nbsp;<span style="color: #000000; ">end;<br />
</span><span style="color: #008080; ">5</span>&nbsp;<span style="color: #000000; "></span></div>
</div>
<div><br />
</div>
<div>ScWndPrc. pas单元的代码，程序中利用自己的窗口过程代替了 Application对象的窗口过程来处理自定义的消息DDG MFOOMSG。</div>
<div>unit ScWndPro;</div>
<div><br />
</div>
<div>
<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">interface</span><span style="color: #000000; "><br />
</span><span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #000000; ">uses&nbsp;Forms,&nbsp;Messages;<br />
</span><span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">&nbsp;4</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;DDGM_FOOMSG&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;WM_USER;<br />
</span><span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">&nbsp;6</span>&nbsp;<span style="color: #000000; ">var<br />
</span><span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;WProc:&nbsp;Pointer;<br />
</span><span style="color: #008080; ">&nbsp;8</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">&nbsp;9</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;function&nbsp;NewWndProc(Handle:hWnd;&nbsp;Msg,&nbsp;wParam,&nbsp;lParam:Longint):Logint;stdcall;<br />
</span><span style="color: #008080; ">10</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;begin<br />
</span><span style="color: #008080; ">11</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;Msg&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;DDGM_FOOMSG&nbsp;then<br />
</span><span style="color: #008080; ">12</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;showmessage(</span><span style="color: #000000; ">'</span><span style="color: #000000; ">DDGM_FOOMSG&nbsp;new</span><span style="color: #000000; ">'</span><span style="color: #000000; ">);<br />
</span><span style="color: #008080; ">13</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">14</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Result:</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;CallWindowProc(WProc,&nbsp;Handle,&nbsp;Msg,&nbsp;wParam,&nbsp;lParam);<br />
</span><span style="color: #008080; ">15</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;end;<br />
</span><span style="color: #008080; ">16</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">17</span>&nbsp;<span style="color: #000000; ">initialization<br />
</span><span style="color: #008080; ">18</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;WProc&nbsp;:</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;Pointer(SetWindowLong(Application.Handle,&nbsp;gwl_WndProc,&nbsp;Integer(@NewWndProc)));<br />
</span><span style="color: #008080; ">19</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">20</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;end.</span></div>
</div>
<div><br />
</div>
<div><br />
</div>
<div>警告 一定要把SetWindowLong( )函数值保存起来。如果你在自定义的窗口过程中不把该值返还给旧窗口过程，有可能导致应用程序甚至操作系统的崩溃。</div>
<div><br />
</div>
<div><br />
</div>
<div>2. Delphi的窗口方法</div>
<div>利用Delphi提供的函数MakeObjectInstance()可以把一个API窗口过程与一个Delphi方法关联。</div>
<div>MakeObjectInstance()能够创建一个TWndMethod类型的方法，该方法可以当作窗口过程使用。</div>
<div>MakeObjectInstance()在Forms单元中声明如下：</div>
<div>function MakeObjectInstance(Method: TWndMethod): Pointer;</div>
<div><br />
</div>
<div>TWndMethod在Forms单元中定义如下：</div>
<div>
<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000; ">type<br />
&nbsp;&nbsp;&nbsp;TWndMethod&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;procedure&nbsp;(var&nbsp;Message:&nbsp;TMessage)&nbsp;of&nbsp;</span><span style="color: #0000FF; ">object</span><span style="color: #000000; ">;</span></div>
</div>
<div><br />
</div>
<div>MakeObjectInstance()的返回值为一个指针即Pointer,它指向新创建的窗口过程。这是SetWindowLong()需要的最后一个参数的值。最后，你要利用FreeObjectInstance()函数释放用MakeObjectInstance()创建的窗口方法。</div>
<div>作为一个示范程序，WinProc.dpr演示了子类化应用程序的窗口过程和如何利用Application.OnMessage的方法。</div>
<div>
<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #000000; ">unit&nbsp;Unit1;<br />
</span><span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">interface</span><span style="color: #000000; "><br />
</span><span style="color: #008080; ">&nbsp;4</span>&nbsp;<span style="color: #000000; ">uses<br />
</span><span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;Windows,&nbsp;Messages,&nbsp;SysUtils,&nbsp;Variants,&nbsp;Classes,&nbsp;Graphics,&nbsp;Controls,&nbsp;Forms,<br />
</span><span style="color: #008080; ">&nbsp;6</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;Dialogs,&nbsp;StdCtrls;<br />
</span><span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">&nbsp;8</span>&nbsp;<span style="color: #000000; ">type<br />
</span><span style="color: #008080; ">&nbsp;9</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;TForm1&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">(TForm)<br />
</span><span style="color: #008080; ">10</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;btnSend:&nbsp;TButton;<br />
</span><span style="color: #008080; ">11</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;btnPost:&nbsp;TButton;<br />
</span><span style="color: #008080; ">12</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;FormCreate(Sender:&nbsp;TObject);<br />
</span><span style="color: #008080; ">13</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;FormDestroy(Sender:&nbsp;TObject);<br />
</span><span style="color: #008080; ">14</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;btnSendClick(Sender:&nbsp;TObject);<br />
</span><span style="color: #008080; ">15</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;btnPostClick(Sender:&nbsp;TObject);<br />
</span><span style="color: #008080; ">16</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">private</span><span style="color: #000000; "><br />
</span><span style="color: #008080; ">17</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;OldWndProc:&nbsp;Pointer;<br />
</span><span style="color: #008080; ">18</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;WndProcPtr:&nbsp;Pointer;<br />
</span><span style="color: #008080; ">19</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;WndMethod(var&nbsp;Msg:TMessage);<br />
</span><span style="color: #008080; ">20</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;procedure&nbsp;HandleAppMessage(var&nbsp;Msg:TMsg;&nbsp;var&nbsp;Handle:&nbsp;Boolean);<br />
</span><span style="color: #008080; ">21</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; "><br />
</span><span style="color: #008080; ">22</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;Public&nbsp;declarations&nbsp;}<br />
</span><span style="color: #008080; ">23</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;end;<br />
</span><span style="color: #008080; ">24</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">25</span>&nbsp;<span style="color: #000000; ">var<br />
</span><span style="color: #008080; ">26</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;Form1:&nbsp;TForm1;<br />
</span><span style="color: #008080; ">27</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">28</span>&nbsp;<span style="color: #000000; ">implementation<br />
</span><span style="color: #008080; ">29</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">30</span>&nbsp;<span style="color: #000000; ">{$R&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">.dfm}<br />
</span><span style="color: #008080; ">31</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">32</span>&nbsp;<span style="color: #000000; ">procedure&nbsp;TForm1.btnPostClick(Sender:&nbsp;TObject);<br />
</span><span style="color: #008080; ">33</span>&nbsp;<span style="color: #000000; ">begin<br />
</span><span style="color: #008080; ">34</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;PostMessage(Application.Handle,&nbsp;DDGM_FOOMSG,&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);<br />
</span><span style="color: #008080; ">35</span>&nbsp;<span style="color: #000000; ">end;<br />
</span><span style="color: #008080; ">36</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">37</span>&nbsp;<span style="color: #000000; ">procedure&nbsp;TForm1.btnSendClick(Sender:&nbsp;TObject);<br />
</span><span style="color: #008080; ">38</span>&nbsp;<span style="color: #000000; ">begin<br />
</span><span style="color: #008080; ">39</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;SendMessage(Application.Handle,&nbsp;DDGM_FOOMSG,&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">);<br />
</span><span style="color: #008080; ">40</span>&nbsp;<span style="color: #000000; ">end;<br />
</span><span style="color: #008080; ">41</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">42</span>&nbsp;<span style="color: #000000; ">procedure&nbsp;TForm1.FormCreate(Sender:&nbsp;TObject);<br />
</span><span style="color: #008080; ">43</span>&nbsp;<span style="color: #000000; ">begin<br />
</span><span style="color: #008080; ">44</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;Application.OnMessage&nbsp;:</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;HandleAppMessage;<br />
</span><span style="color: #008080; ">45</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;WndProcPtr&nbsp;:</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;MakeObjectInstance(WndMethod);<br />
</span><span style="color: #008080; ">46</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;OldWndProc&nbsp;:</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;Pointer(SetWindowLong(Application.Handle,&nbsp;GWL_WNDPROC,&nbsp;integer(WndProcPtr)));<br />
</span><span style="color: #008080; ">47</span>&nbsp;<span style="color: #000000; ">end;<br />
</span><span style="color: #008080; ">48</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">49</span>&nbsp;<span style="color: #000000; ">procedure&nbsp;TForm1.FormDestroy(Sender:&nbsp;TObject);<br />
</span><span style="color: #008080; ">50</span>&nbsp;<span style="color: #000000; ">begin<br />
</span><span style="color: #008080; ">51</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;SetWindowLong(Application.Handle,GWL_WNDPROC,&nbsp;Longint(OldWndProc));<br />
</span><span style="color: #008080; ">52</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;FreeObjectInstance(WndProcPtr);<br />
</span><span style="color: #008080; ">53</span>&nbsp;<span style="color: #000000; ">end;<br />
</span><span style="color: #008080; ">54</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">55</span>&nbsp;<span style="color: #000000; ">procedure&nbsp;TForm1.HandleAppMessage(var&nbsp;Msg:&nbsp;TMsg;&nbsp;var&nbsp;Handle:&nbsp;Boolean);<br />
</span><span style="color: #008080; ">56</span>&nbsp;<span style="color: #000000; ">begin<br />
</span><span style="color: #008080; ">57</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;Msg.message&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;DDGM_FOOMSG&nbsp;then<br />
</span><span style="color: #008080; ">58</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Showmessage(</span><span style="color: #000000; ">'</span><span style="color: #000000; ">DDGM_FOOMSG</span><span style="color: #000000; ">'</span><span style="color: #000000; ">);<br />
</span><span style="color: #008080; ">59</span>&nbsp;<span style="color: #000000; ">end;<br />
</span><span style="color: #008080; ">60</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">61</span>&nbsp;<span style="color: #000000; ">procedure&nbsp;TForm1.WndMethod(var&nbsp;Msg:&nbsp;TMessage);<br />
</span><span style="color: #008080; ">62</span>&nbsp;<span style="color: #000000; ">begin<br />
</span><span style="color: #008080; ">63</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;Msg.Msg&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;DDGM_FOOMSG&nbsp;then<br />
</span><span style="color: #008080; ">64</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;showmessage(</span><span style="color: #000000; ">'</span><span style="color: #000000; ">New&nbsp;DDGM_FOOMSG</span><span style="color: #000000; ">'</span><span style="color: #000000; ">);<br />
</span><span style="color: #008080; ">65</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;with&nbsp;Msg&nbsp;</span><span style="color: #0000FF; ">do</span><span style="color: #000000; "><br />
</span><span style="color: #008080; ">66</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;result:</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;CallWindowProc(OldWndProc,&nbsp;Application.Handle,&nbsp;Msg,&nbsp;wParam,&nbsp;lParam);<br />
</span><span style="color: #008080; ">67</span>&nbsp;<span style="color: #000000; ">end;<br />
</span><span style="color: #008080; ">68</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">69</span>&nbsp;<span style="color: #000000; ">end.</span></div>
</div>
<div><br />
</div>
<div><br />
</div>
<div>SendBtn按钮被按下时，API函数SendMessage()发送一个消息DDGM_FOOMSG给Application的窗</div>
<div>口句柄。当PostBtn按钮被按下时，同样的消息被PostMessage()API函数发送给Application。</div>
<div><br />
</div>
<div>HandleAppMessage()被指定来处理Application.OnMessage事件。HandleAppMessage()只是简单地</div>
<div>使用ShowMessage()显示一个消息框。OnMessage在主窗体的OnCreate事件处理过程中被指定。</div>
<div>注意在主窗体的OnDestroy事件处理过程中，要首先恢复应用程序原有的窗口过程，然后再通过调</div>
<div>用FreeObjectInstance()来释放由MakeProcInstance()创建的窗口过程。请注意，一定要先恢复再释放。</div>
<div>否则，会导致应用程序或操作系统被破坏。</div>
<div>可以看出，ScWndPrc单元被Main.pas引用。这意味着应用程序窗口被两次子类化一次是由</div>
<div>ScWndPrc单元使用API技术实现；另一次是在Main单元中使用窗口方法技术实现。注意：一定要牢记</div>
<div>在自定义的窗口过程和窗口方法中必须要用CallWindowProc()把消息传递给原窗口过程。</div>
<div>当运行此程序时，会看到无论哪一个按钮被按下，都有一个消息框被窗口过程或窗口方法引发。</div>
<div>但是，Application.OnMessage事件只能看到由PostMessage()函数发来的消息。</div>
<div>
<div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--></div>
</div><img src ="http://www.cppblog.com/firebird/aggbug/160572.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/firebird/" target="_blank">firebird</a> 2011-11-20 17:52 <a href="http://www.cppblog.com/firebird/archive/2011/11/20/160572.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>开博</title><link>http://www.cppblog.com/firebird/archive/2011/11/20/160570.html</link><dc:creator>firebird</dc:creator><author>firebird</author><pubDate>Sun, 20 Nov 2011 09:28:00 GMT</pubDate><guid>http://www.cppblog.com/firebird/archive/2011/11/20/160570.html</guid><wfw:comment>http://www.cppblog.com/firebird/comments/160570.html</wfw:comment><comments>http://www.cppblog.com/firebird/archive/2011/11/20/160570.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/firebird/comments/commentRss/160570.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/firebird/services/trackbacks/160570.html</trackback:ping><description><![CDATA[     今天是2011年11月20日，决定开博，目的仅仅是督促自己，在人生的路上，越战越勇.....
<img src ="http://www.cppblog.com/firebird/aggbug/160570.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/firebird/" target="_blank">firebird</a> 2011-11-20 17:28 <a href="http://www.cppblog.com/firebird/archive/2011/11/20/160570.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>