?? chap41.htm
字號:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
<title>訊息使用范例一 使用者自定標題棒的實作</title>
<link rel="stylesheet" href="../../../include/style.css">
</head>
<body>
<font SIZE="2">
<p><small><a href="../../../index.htm">首頁</a> >> <a href="../../program.htm">程序設計</a>
>> <a href="../cbuilder.htm">C++ Builder</a> >> </small>訊息使用范例一
使用者自定標題棒的實作<br>
</p>
<p align="left"><!--webbot bot="ImageMap" rectangle=" (40,1) (71, 23) chap42.htm" rectangle=" (4,1) (36, 23) chap04.htm" src="../ch1/NextBack.gif" width="72" height="24" alt="NextBack.gif (743字節)" border="0" startspan --><MAP NAME="FrontPageMap"><AREA SHAPE="RECT" COORDS="40, 1, 71, 23" HREF="chap42.htm"><AREA SHAPE="RECT" COORDS="4, 1, 36, 23" HREF="chap04.htm"></MAP><a href="../../../_vti_bin/shtml.exe/program/C++/ch4/chap41.htm/map"><img ismap usemap="#FrontPageMap" border="0" height="24" alt="NextBack.gif (743字節)" src="../ch1/NextBack.gif" width="72"></a><!--webbot bot="ImageMap" endspan i-checksum="23219" --></p>
</font>
<p><font SIZE="2" color="#FF0000">訊息使用范例一 使用者自定標題棒的實作</font></p>
<p><font SIZE="2">一般Windows程式的標題棒位於視窗的上方,我們可以利用該標題棒來移動視窗。以下我將為你示范如何利用C++Builder實作出置於視窗左方的標題棒。如圖一:
</font></p>
<p><font SIZE="2"><br>
</font><img SRC="IMG00001.GIF" WIDTH="336" HEIGHT="174"><font SIZE="2">圖一
標題棒在左方的視窗。</font></p>
<p><font SIZE="2"><br>
如上圖,你可以很清楚地看到,這個視窗和其他的視窗有很大的不同;它的標題棒位於左方,而且其顏色為綠色,同時其文字的走向為由下而上的90度字形,而其功能則和一般的標題棒相同,你可以將滑鼠移至該處,然後移動該視窗。到底這是如何達成的呢?
</font></p>
<p><font color="#FF0000" SIZE="2">WM_NCHITTEST訊息的奧秘</font></p>
<p><font SIZE="2">WM_NCHITTEST訊息是一個很特殊的訊息。它是用來決定目前滑鼠所在位置屬性的訊息,因此我們可以利用此特性,當滑鼠移至指定的位置時,傳回
HTCAPTION,使得系統以為滑鼠目前位於標題棒,如此你就可以移動視窗了。如何?是不是很神奇呢?
</font></p>
<p><font SIZE="2">由上可知,只要我們適時地攔截WM_NCHITTEST訊息,然後傳回HTCAPTION,就可以順利地欺騙系統,達成在任何位置模擬出標題棒的效果。
</font></p>
<p><font SIZE="2" color="#FF0000">C++ Builder的處理訊息的聚集</font></p>
<p><font SIZE="2">在C++Builder為了處理訊息的方便,因此定義了叁個處理訊息的巨集(Macro)。
</font></p>
<p><font SIZE="2">BEGIN_MESSAGE_MAP</font> </p>
<p><font SIZE="2">MESSAGE_HANDLER(WM_NCHITTEST,TMessage,OnNcHitTest)</font> </p>
<p><font SIZE="2">END_MESSAGE_MAP(TForm)</font></p>
<p><font SIZE="2">以上的叁個巨集BEGIN_MESSAGE_MAP、MESSAGE_HANDLER及END_MESSAGE就是C++
Builder定義的巨集,其中比較重要的是MESSAGE_HANDLER;它共需要叁個參數,第一個參數代表訊息的ID,第二個代表參數型態,最後一個則是訊息事件處理函數。
</font></p>
<p><font SIZE="2">乍看之下,這個巨集似乎和MFC及OWL所使用的巨集有幾分神似,沒錯,不過其機制卻更為簡單及簡潔,我們可以看看C++Builder對於這叁個巨集的原始定義:
</font></p>
<p><font SIZE="2">#define BEGIN_MESSAGE_MAP virtual void __fastcall Dispatch(void
*Message); </font></p>
<p><font SIZE="2">{ </font></p>
<p><font SIZE="2"> switch (((PMessage)Message)->Msg)</font></p>
<p><font SIZE="2"> {</font> </p>
<p><font SIZE="2"> #define
MESSAGE_HANDLER(msg,type,meth);</font></p>
<p><font SIZE="2"> case msg: </font></p>
<p><font SIZE="2">
meth(*((type
*)Message)); </font></p>
<p><font SIZE="2">
break;</font> </p>
<p><font SIZE="2">
#define
END_MESSAGE_MAP(base) default:</font></p>
<p><font SIZE="2">
base::Dispatch(Message);
</font></p>
<p><font SIZE="2">
break; </font></p>
<p><font SIZE="2"> }</font> </p>
<p><font SIZE="2">}</font></p>
<p><font SIZE="2">相較於MFC或 OWL的可怕巨集,它實在是簡單多了,這是因為C++Builder已替你完成了大部份的工作。其實若我們把以上的巨集展開後,可以得到以下的結果:
</font></p>
<p><font SIZE="2">virtual void __fastcall Dispatch(void *Message)</font> </p>
<p><font SIZE="2">{</font> </p>
<p><font SIZE="2"> switch (((PMessage)Message)->Msg)</font> </p>
<p><font SIZE="2"> {</font> </p>
<p><font SIZE="2"> case WM_NCHITTEST:</font> </p>
<p><font SIZE="2">
OnNcHitTest(*((TMessage
*)Message));</font> </p>
<p><font SIZE="2">
break;</font> </p>
<p><font SIZE="2"> default:</font> </p>
<p><font SIZE="2">
TForm::Dispatch(Message);</font>
</p>
<p><font SIZE="2">
break;</font> </p>
<p><font SIZE="2"> }</font> </p>
<p><font SIZE="2">}</font></p>
<p><font SIZE="2">怎麼樣?展開之後是不是有恍然大悟的感覺,要弄清楚這個巨集在賣啥膏藥是很容易的,如果你玩過MFC的訊息處理機制,再看到以上的巨集,相較之下,實在是小兒科,不過也就因其簡單,所以C++Builder的優勢益加彰顯。
</font></p>
<p><font SIZE="2">我簡單地說明以上的程式:在每個TForm中都定義一個名為Dispatch的虛擬函式,它就是用來處理Windows的訊息的,在大部份情況下,訊息都是呼叫C++Builder所提供的處理函式,因此你不需要修改它。
</font></p>
<p><font SIZE="2">換句話說,我們只要改寫Dispatch函式,就可以藉以處理指定的訊息了。前面提到的叁個巨集只是將這個程序簡化而已,沒什麼大不了。</font></p>
<font SIZE="2">
<p align="right"><!--webbot bot="ImageMap" rectangle=" (40,1) (71, 23) chap42.htm" rectangle=" (4,1) (36, 23) chap04.htm" src="../ch1/NextBack.gif" width="72" height="24" alt="NextBack.gif (743字節)" border="0" startspan --><MAP NAME="FrontPageMap1"><AREA SHAPE="RECT" COORDS="40, 1, 71, 23" HREF="chap42.htm"><AREA SHAPE="RECT" COORDS="4, 1, 36, 23" HREF="chap04.htm"></MAP><a href="../../../_vti_bin/shtml.exe/program/C++/ch4/chap41.htm/map1"><img ismap usemap="#FrontPageMap1" border="0" height="24" alt="NextBack.gif (743字節)" src="../ch1/NextBack.gif" width="72"></a><!--webbot bot="ImageMap" endspan i-checksum="41384" --></p>
</font>
<p><font SIZE="2"><small><a href="../../../index.htm">首頁</a> >> <a href="../../program.htm">程序設計</a>
>> <a href="../cbuilder.htm">C++ Builder</a> >> </small>訊息使用范例一
使用者自定標題棒的實作<br>
</font></p>
</body>
</html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -