📄 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 + -