一個非可視的組件必須對Windows操作系統或用戶定義的消息作出響應然而由於一個非可視組件沒有窗口因此它也沒有窗口句柄自然它也不能接收到消息為了解決這一問題我們的思路是創建一個隱藏的窗口使非可視組件能夠接收到消息為了給你的非可視組件創建一個隱藏的窗口需要有以下 .一個私有變量型(Private Variable)的HWnd來取得窗口句柄 .一個用來捕捉窗口發送給組件的函數(a WndProc) .對AllcolateHwnd的調用使之創建窗口句柄並設置WndProc為了清楚的解釋上述思路和展示創建過程下面我們將以一個具體的實例來說明
首先我們先創建一個新的組件在C++Builder中選擇FILE|NEW…雙擊組件圖標顯示一個新的組件對話框改變Ancestor Type為Tcomponent和Class name為Ttest並設置完畢
然後切換到新組件的頭文件在類的私有部分(private section)加入以下聲明 HWnd Fhandle;
void—fastcall WndProc(Tmessage& Msg); 第一行聲明了一個調用Fhandle的HWnd變量這個變量將用於窗口創建後捕獲窗口句柄第二行聲明了一個用於接收消息的WndProc函數這個函數的聲明必須加以標識以便限定它是一個WndProc然後在類聲明Public(公有)部分構造以下聲明 Viod DoIt( )這個公有函數將被我們用來測試組件類聲明應如下
class PACKAGE Ttest : public Tcomponent{private: HWnd Fhandle;
void—fastcall WndProc(Tmessage& Msg); protected: public: —fastcall Ttest(Tcomponent* Owner); void DoIt( );
—published: }; 現在切換到組件的代碼單元將下面一行加入到單元的頂部(在函數上也許是不錯的地方) #define MY—MessageWM_USER+ 這一行聲明了一個在DoIt函數被調用時組件將發送給它自己的用戶自定義消息此時我們必須為組件分配一個窗口句柄這個句柄將提供一個隱藏的窗口使我們可以捕捉組件中的消息找到組件構造代碼加入下面代碼: —fastcall Test::Test(Tcomponent* Owner): Tcomponent(Owner)
{
Fhandle=AllocateHWnd(WndProc);
} 好重要的一步已完成AllocateHWnd函數創建了一個隱藏窗口並且返回它的句柄注意這裡我們為了使Windows知道哪裡發來了消息傳遞WndProc的地址 現在我們來創建WndProc的函數部分在源文件中加入:
void—fastcall Ttest::WndProc(Tmessage& Msg)
{
if (MsgMsg == MY_MESSAGE)
MessageBox( ″Got here!″ ″Message″ );
try {
Dispatch(&Msg);
}
catch (…) { Application-〉HandleException(this); } } 無論何時Windows發送消息給組件Windows都會調用這個函數這部分代碼完成了兩件事首先它檢查被接收的消息是否是我們用戶自定義的消息如果是一個消息框將被顯示你可以看到實際上我們接收到的消息其次這段代碼傳送了系統(或VCL)處理過程中的消息try/catch塊用來保證如果異常出現它將成為缺省風格下的句柄概括地說WndProc函數在為缺省句柄傳遞所有其他消息監控了所有客戶消息現在我們創建DoIt函數完成我們的組件加入我們創建DoIt函數完成我們的組件加入代碼 void Ttest::DoIt() { PostMessage(Fhandle MY—MESSAGE ); } 這個函數發送一個消息組件的窗口句柄(記住這個窗口句柄是以前存入到Fhandle數據成品中的)現在我們已經完成了創建組件選擇用 SelectFile|ColseAll來保存我們的工作測試組件下一步將測試組件如果你使用BCB那麼你必須把組件加入到包(Packege)中然後用Componet|install(可以使用 DCLSTD Packege來快速測試)再選擇你剛存的TestBCBCpp一旦你安裝完成組件後它將出現在組件板上雙擊按鈕為按鈕的OnClick事件創建以下代碼 Test-〉 DoIt( ); 現在運行程序當你點擊按鈕時將看到一個消息框顯示Got here ListingA和B包含了頭文件和源代碼以下列出總結一個可以響應Windows消息的非可視組件有許多用途最顯而易見的就是用來封裝某些方面的WindowsAPI例如TAPI和 WinSock發送消息給事件的指定用戶如果你寫的組件封裝了一個這樣的API你將需要捕捉Windows發送的消息而在你的組件中加入隱藏窗口將很好的幫你做到這一點 以上程序在C++ BUILDER 中調試通過
From:http://tw.wingwit.com/Article/program/net/201311/13433.html