CB非可視組件的消息處理技巧
一個(gè)非可視的組件必須對(duì)Windows操作系統(tǒng)或用戶定義的消息作出響應(yīng)。然而,由于一個(gè)非可視組件沒(méi)有窗口,因此它也沒(méi)有窗口句柄,自然它也不能接收到消息,為了解決這一問(wèn)題,我們的思路是創(chuàng)建一個(gè)隱藏的窗口,使非可視組件能夠接收到消息。
為了給你的非可視組件創(chuàng)建一個(gè)隱藏的窗口,需要有以下:
1.一個(gè)私有變量型(Private Variable)的HWnd來(lái)取得窗口句柄。
2.一個(gè)用來(lái)捕捉窗口發(fā)送給組件的函數(shù)(a WndProc)。
3.對(duì)AllcolateHwnd的調(diào)用使之創(chuàng)建窗口句柄并設(shè)置WndProc。
為了清楚的解釋上述思路和展示創(chuàng)建過(guò)程,下面我們將以一個(gè)具體的實(shí)例來(lái)說(shuō)明。
首先我們先創(chuàng)建一個(gè)新的組件,在C++Builder中,選擇FILE|NEW...雙擊組件圖標(biāo)顯示一個(gè)新的組件對(duì)話框改變Ancestor Type為T(mén)component和Class name為T(mén)Test并設(shè)置完畢。
然后,切換到新組件的頭文件,在類的私有部分(private section)加入以下聲明:
HWnd FHandle;
voidfastcall WndProc(TMessage& Msg);
第一行聲明了一個(gè)調(diào)用Fhandle的HWnd變量,這個(gè)變量將用于窗口創(chuàng)建后捕獲窗口句柄。第二行聲明了一個(gè)用于接收消息的WndProc函數(shù)。這個(gè)函數(shù)的聲明必須加以標(biāo)識(shí),以便限定它是一個(gè)WndProc,然后在類聲明Public(公有)部分構(gòu)造以下聲明:
Viod DoIt( );
這個(gè)公有函數(shù)將被我們用來(lái)測(cè)試組件,類聲明應(yīng)如下:
class PACKAGE TTest : public
TComponent
{
private:
HWnd FHandle;
voidfastcall WndProc(TMessage& Msg);
protected:
public:
fastcall TTest(TComponent* Owner);
void DoIt( );
published:
};
現(xiàn)在切換到組件的代碼單元,將下面一行加入到單元的頂部(在函數(shù)上也許是不錯(cuò)的地方)
#define MY_Message.WM_USER+1
這一行聲明了一個(gè)在DoIt函數(shù)被調(diào)用時(shí),組件將發(fā)送給它自己的用戶自定義消息。此時(shí)我們必須為組件分配一個(gè)窗口句柄。這個(gè)句柄將提供一個(gè)隱藏的窗口使我們可以捕捉組件中的消息。找到組件構(gòu)造代碼,加入下面代碼:
fastcall Test::Test(TComponent* Owner): TComponent(Owner)
{
FHandle=AllocateHWnd(WndProc);
}
好,重要的一步已完成,AllocateHWnd函數(shù)創(chuàng)建了一個(gè)隱藏窗口并且返回它的句柄,注意這里我們?yōu)榱耸筗indows知道哪里發(fā)來(lái)了消息,傳遞WndProc的地址;
現(xiàn)在我們來(lái)創(chuàng)建WndProc的函數(shù)部分。在源文件中加入:
voidfastcall TTest::WndProc(TMessage& Msg)
{
if (Msg.Msg == MY_MESSAGE)
MessageBox(0, ″Got here!″, ″Message″, 0);
try {
Dispatch(&Msg);
}
catch (...) {
Application-〉HandleException(this);
}
}
無(wú)論何時(shí)Windows發(fā)送消息給組件,Windows都會(huì)調(diào)用這個(gè)函數(shù)。這部分代碼完成了兩件事。首先,它檢查被接收的消息是否是我們用戶自定義的消息。如果是,一個(gè)消息框?qū)⒈伙@示,你可以看到實(shí)際上我們接收到的消息。其次,這段代碼傳送了系統(tǒng)(或VCL)處理過(guò)程中的消息,try/catch塊用來(lái)保證,如果異常出現(xiàn),它將成為缺省風(fēng)格下的句柄。
概括地說(shuō),WndProc函數(shù)在為缺省句柄傳遞所有其他消息,監(jiān)控了所有客戶消息。現(xiàn)在我們創(chuàng)建DoIt函數(shù),完成我們的組件,加入我們創(chuàng)建DoIt函數(shù),完成我們的組件,加入代碼:
void TTest::DoIt()
{
PostMessage(FHandle, MY_MESSAGE, 0, 0);
}
這個(gè)函數(shù)發(fā)送一個(gè)消息組件的窗口句柄(記住,這個(gè)窗口句柄是以前存入到Fhandle數(shù)據(jù)成品中的)。現(xiàn)在我們已經(jīng)完成了創(chuàng)建組件選擇,用SelectFile|ColseAll來(lái)保存我們的工作測(cè)試組件。
下一步將測(cè)試組件。如果你使用BCB3,那么你必須把組件加入到“包”(Packege)中,然后用Componet|install(可以使用DCLSTD35 Packege來(lái)快速測(cè)試)。再選擇你剛存的TestBCB.Cpp,一旦你安裝完成組件后,它將出現(xiàn)在組件板上。雙擊按鈕,為按鈕的OnClick事件創(chuàng)建以下代碼:
Test1-〉 DoIt( );
現(xiàn)在運(yùn)行程序,當(dāng)你點(diǎn)擊按鈕時(shí),將看到一個(gè)消息框顯示“Got here".
ListingA和B包含了頭文件和源代碼以下列出。
總結(jié):一個(gè)
Back
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注