• <label id="pxtpz"><meter id="pxtpz"></meter></label>
      1. <span id="pxtpz"><optgroup id="pxtpz"></optgroup></span>

        當(dāng)前位置:雨林木風(fēng)下載站 > 技術(shù)開發(fā)教程 > 詳細(xì)頁面

        C++ BUILDER 消息處理的深入探索

        C++ BUILDER 消息處理的深入探索

        更新時間:2022-05-02 文章作者:未知 信息來源:網(wǎng)絡(luò) 閱讀次數(shù):

        在本文中我將告訴你如何以C++Builder來處理Windows訊息,並透過此一能力,來達(dá)成在一般VCL元件所無法做到的功能。


        何謂Window訊息(Message)


        大家都知道 Windows是一套以訊息驅(qū)動(Message Driven)的作業(yè)系統(tǒng)。然而對於訊息本身卻諱莫如深,只知其然而不知其所以然,雖然C++Builder將某些Windows訊息封裝於事件(Event)系統(tǒng)中,但身為一個Windows程式設(shè)計師,實有必要瞭解Windows的訊息系統(tǒng)。


        所謂訊息是由Windows作業(yè)系統(tǒng)送往程式的事件。它是系統(tǒng)中各個物件溝通的方式,舉例來說,當(dāng)移動滑鼠、按下滑鼠鍵、改變視窗大小時,Windows都會送出訊息以通知程式。當(dāng)然,為了要辨別事件的內(nèi)容,Windows系統(tǒng)中定義了許多的訊息,如WM_PAINT,WM_CHAR等等。


        當(dāng)事件發(fā)生時,Windows會判斷該事件必須由那個程式接收,然後將事件以訊息的方式送往程式的視窗中。雖然在Windows系統(tǒng)中包含了數(shù)以百計的事件,但是作業(yè)系統(tǒng)並沒有為各個事件設(shè)計不同的訊息結(jié)構(gòu),而是以一個一般性的結(jié)構(gòu)來描述訊息,這個結(jié)構(gòu)在C++Builder就稱是TMessage。


        當(dāng)然,隨著事件的不同,對於訊息的解釋也有所不同,在C++Builder中也為各種常用的訊息定義了專屬的結(jié)構(gòu),你可以直接使用它們來解釋訊息。這些訊息定義在C++Builder目錄下的Include\vcl\messages.hpp中,你可以決定要自行解釋TMessage參數(shù)或是直接將其轉(zhuǎn)換成專屬的結(jié)構(gòu)。很抽象嗎?我舉個例子吧,以WM_NCHITTEST訊息來說,C++Builder為它定義了TWMNCHitTest的專屬結(jié)構(gòu),所以你可以直接經(jīng)由它來得到XPos、YPos等值。或者你也可以直接由TMessage的LParam取得其值,端看你使用的方便。仔細(xì)觀察TMessage及TWMNCHitTest兩個結(jié)構(gòu),你會發(fā)現(xiàn)它們是等價的,也就是說它們的大小是一致的,因此你可以直接用強(qiáng)制轉(zhuǎn)型互相轉(zhuǎn)換(這有點類似union的方法)。


        struct TMessage

        {

        Cardinal Msg;

        union

        {

        struct

        {

        Word WParamLo;

        Word WParamHi;

        Word LParamLo;

        Word LParamHi;

        Word ResultLo;

        Word ResultHi;

        };

        struct

        {

        long WParam;

        long LParam;

        long Result;

        };

        };

        };

        struct TWMNCHitTest

        {

        Cardinal Msg;

        long Unused;

        union

        {

        struct

        {

        Windows::TSmallPoint Pos;

        long Result;

        };

        struct

        {

        short XPos;

        short YPos;

        };

        };

        } ;


        在收到訊息後,程式必須處理該訊息,若是不處理,則可直接將它交給Windows的內(nèi)定處理程序來處理之,若是程式需要傳回值,也可以在此時傳回,Windows會將該值傳回給呼叫方。如此就完成了訊息傳遞的程序。

        WM_NCHITTEST訊息的奧秘


        WM_NCHITTEST訊息是一個很特殊的訊息。它是用來決定目前滑鼠所在位置屬性的訊息,因此我們可以利用此特性,當(dāng)滑鼠移至指定的位置時,傳回 HTCAPTION,使得系統(tǒng)以為滑鼠目前位於標(biāo)題棒,如此你就可以移動視窗了。如何?是不是很神奇呢?


        由上可知,只要我們適時地攔截WM_NCHITTEST訊息,然後傳回HTCAPTION,就可以順利地欺騙系統(tǒng),達(dá)成在任何位置模擬出標(biāo)題棒的效果。


        C++ Builder的處理訊息的巨集


        在C++Builder為了處理訊息的方便,因此定義了三個處理訊息的巨集(Macro)。


        BEGIN_MESSAGE_MAP

        MESSAGE_HANDLER(WM_NCHITTEST,TMessage,OnNcHitTest)

        END_MESSAGE_MAP(TForm)


        以上的三個巨集BEGIN_MESSAGE_MAP、MESSAGE_HANDLER及END_MESSAGE就是C++ Builder定義的巨集,其中比較重要的是MESSAGE_HANDLER;它共需要三個參數(shù),第一個參數(shù)代表訊息的ID,第二個代表參數(shù)型態(tài),最後一個則是訊息事件處理函數(shù)。


        乍看之下,這個巨集似乎和MFC及OWL所使用的巨集有幾分神似,沒錯,不過其機(jī)制卻更為簡單及簡潔,我們可以看看C++Builder對於這三個巨集的原始定義:


        #define BEGIN_MESSAGE_MAP virtual void __fastcall Dispatch(void *Message) \

        { \

        switch (((PMessage)Message)->Msg) \

        {

        #define MESSAGE_HANDLER(msg,type,meth) \

        case msg: \

        meth(*((type *)Message)); \

        break;

        #define END_MESSAGE_MAP(base) default: \

        base::Dispatch(Message); \

        break; \

        } \

        }


        相較於MFC或 OWL的可怕巨集,它實在是簡單多了,這是因為C++Builder已替你完成了大部份的工作。其實若我們把以上的巨集展開後,可以得到以下的結(jié)果:


        virtual void __fastcall Dispatch(void *Message)

        {

        switch (((PMessage)Message)->Msg)

        {

        case WM_NCHITTEST:

        OnNcHitTest(*((TMessage *)Message));

        break;

        default:

        TForm::Dispatch(Message);

        break;

        }

        }


        怎麼樣?展開之後是不是有恍然大悟的感覺,要弄清楚這個巨集在賣啥膏藥是很容易的,如果你玩過MFC的訊息處理機(jī)制,再看到以上的巨集,相較之下,實在是小兒科,不過也就因其簡單,所以C++Builder的優(yōu)勢益加彰顯。


        我簡單地說明以上的程式:在每個TForm中都定義一個名為Dispatch的虛擬函式,它就是用來處理Windows的訊息的,在大部份情況下,訊息都是呼叫C++Builder所提供的處理函式,因此你不需要修改它。


        換句話說,我們只要改寫Dispatch函式,就可以藉以處理指定的訊息了。前面提到的三個巨集只是將這個程序簡化而已,沒什麼大不了。

        溫馨提示:喜歡本站的話,請收藏一下本站!

        本類教程下載

        系統(tǒng)下載排行

        主站蜘蛛池模板: 一级毛片免费播放男男| 亚洲色欲色欲www| 精品人妻系列无码人妻免费视频| 日韩免费视频网站| 狠狠综合亚洲综合亚洲色| 永久中文字幕免费视频网站| 亚洲人成图片网站| 国产精品色午夜视频免费看| 国产精品亚洲一区二区三区| 免费a级毛片视频| 九一在线完整视频免费观看 | 国产精品久久久久久久久免费| 青青草原精品国产亚洲av| 2019中文字幕在线电影免费| 亚洲人成777在线播放| 免费看少妇作爱视频| 羞羞漫画小舞被黄漫免费| 国产日产亚洲系列最新| 国产精品白浆在线观看免费| 亚洲videos| 亚洲Av无码乱码在线观看性色| 国产中文字幕在线免费观看| 亚洲国产成人久久综合一| 黄色片在线免费观看| 日韩成人精品日本亚洲| 久久精品国产69国产精品亚洲| 18禁男女爽爽爽午夜网站免费| 亚洲色偷偷偷综合网| 亚洲精品无码日韩国产不卡?V| 人人玩人人添人人澡免费| 亚洲一级黄色大片| 九月婷婷亚洲综合在线 | 四虎永久在线观看免费网站网址 | 亚洲嫩草影院在线观看| 国产美女无遮挡免费网站| a视频免费在线观看| 亚洲成aⅴ人在线观看| 免费一级毛片不卡在线播放 | 大地资源二在线观看免费高清| 看免费毛片天天看| 亚洲毛片在线观看|