C++Builder處理Windows訊息(Message)

字號:

前言
    雖然C++Builder為一RAD式的程式發(fā)展工具,程式設(shè)計師在大多數(shù)情況下不需理會Windows訊息的細節(jié),只要將心思放在軟體元件的事件處理函式即可。然而由於Windows作業(yè)系統(tǒng)終究是一個以訊息驅(qū)動的系統(tǒng),因此架構(gòu)其上的的應(yīng)用程式自然無法自外於系統(tǒng)之外,在遭遇到C++Builder沒有
    定義的事件時,Windows訊息處理能力仍然是C++Builder程式人不可或缺的能力。
    不可否認地,C++Builder所提供的事件處理能力已具備了某一程度的完備性,然而我們也必須承認,在C++Buider建構(gòu)的VCL美麗新世界中,仍
    然不免有漏網(wǎng)之魚。例如使用者自定訊息的處理,Winsock訊息的處理及一些Windows訊息如WM_NC**** 系列的訊息都是C++Builder的物件模型所未包
    含的。
    在本文中我將告訴你如何以C++Builder來處理Windows訊息,并透過此一能力,來達成在一般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)中各個物件溝通的方式,舉例來說,當移動滑鼠、按下滑鼠鍵、改變視窗大小時,Windows都會送出訊息以通知程式。當然,為了要辨別事件的內(nèi)容,Windows系統(tǒng)中定義了許多的訊息,如WM_PAINT,WM_CHAR等等。
    當事件發(fā)生時,Windows會判斷該事件必須由那個程式接收,然後將事件以訊息的方式送往程式的視窗中。雖然在Windows系統(tǒng)中包含了數(shù)以百
    計的事件,但是作業(yè)系統(tǒng)并沒有為各個事件設(shè)計不同的訊息結(jié)構(gòu),而是以一個一般性的結(jié)構(gòu)來描述訊息,這個結(jié)構(gòu)在C++Builder就稱是TMessage.
    當然,隨著事件的不同,對於訊息的解釋也有所不同,在C++Builder中也為各種常用的訊息定義了專屬的結(jié)構(gòu),你可以直接使用它們來解釋訊
    息。這些訊息定義在C++Builder目錄下的Includevclmessages.hpp中,你可以決定要自行解釋TMessage參數(shù)或是直接將其轉(zhuǎn)換成專屬的結(jié)構(gòu)。很抽象
    嗎? 我舉個例子吧,以WM_NCHITTEST訊息來說,C++Builder為它定義了TWMNCHitTest的專屬結(jié)構(gòu),所以你可以直接經(jīng)由它來得到XPos、YPos等值。
    或者你也可以直接由TMessage的LParam取得其值,端看你使用的方便。仔細觀察TMessage及TWMNCHitTest兩個結(jié)構(gòu),你會發(fā)現(xiàn)它們是等價的,也就是
    說它們的大小是一致的,因此你可以直接用強制轉(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會將該值傳回給呼叫方。如此就完成了訊息傳遞的程序。