關於捕獲VCL沒有處理的Windows訊息 (轉)
對於C++ Builder的員來說,VCL以其靈活、高效的特點令人喜愛。因為VCL是在 的基礎上進行了封裝,同時捨棄了一些不常用的功能,所以,VCL在功能上是Windows API 的子集。VCL提供了對大多數Windows訊息的處理機制,但是對於沒有處理的Windows訊息呢,在需要是如何捕獲呢?C++ Builder採用了訊息對映標機制,透過訊息對映表將特定的Windows訊息於程式碼中的聯絡起來,當視窗捕獲到訊息時就會這個函式。
C++ Builder訊息對映表定義形式如下:
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(
END_MESSAGE_MAP(ClassName)
其中:
BEGIN_MESSAGE_MAP:訊息對映定義起始語句
MESSAGE_HANDLER:訊息處理定義
END_MESSAGE_MAP:訊息對映定義結束語句
ClassName:是要接受訊息的類名
message:是要截獲的Windows訊息
message handler:訊息處理函式名稱
message structure:是用於傳遞給VCL訊息的結構名稱,此結構裡包含有處理訊息時所需的全部引數,不同的訊息所對應的訊息結構是不同的。
由於每一個VCL(無論是窗體還是按鈕)都可以獨立的接收Windows訊息,並且進行獨立的響應,所以一定要注意訊息定一種的ClassName引數。
現在舉例說明訊息定義、傳遞的應用。現在一個窗體FormMain,和2個TperformanceGraph控制元件(不能響應滑鼠事件),現在我要對2個TperformanceGraph控制元件定義滑鼠單擊事件,對FormMain也重定義滑鼠單擊事件,過程如下(假定工程為Message.bpr,程式檔案為main.cpp、main.h):
如下:
//----main.h--------------------------------------------------------------
#ifndef mainH
#define mainH
//----------------------------------------------------------
#include
#include
#include
#include
#include "PERFGRAP.h"
//-----------------------------------------------------------
class TFormMain : public TForm
{
__published: // -managed Components
//----2個標準TperformanceGraph控制元件
TPerformanceGraph *PerformanceGraph1;
TPerformanceGraph *PerformanceGraph2;
TEdit *Edit2;
TEdit *Edit1;
void __fastcall FormCreate(T *Sender);
private: // User declarations
//----自定義的訊息處理函式,其中MESSAGE可以不寫
MESSAGE void __fastcall LButtonDown(TMessage &message);
//----定義的函式(處理訊息,具體使用見.cpp檔案)
void __fastcall MyWndProc1(TMessage &message);
void __fastcall MyWndProc2(TMessage &message);
//----函式指標,用來儲存2個TperformanceGraph控制元件的訊息處理函式的指標
TWndMethod OldWndProc1 , OldWndProc2;
public: // User declarations
__fastcall TFormMain(TComponent* Owner);
//----窗體的訊息定義
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_LBUTTONDOWN , TMessage , LButtonDown)
END_MESSAGE_MAP(TForm)
};
//---------------------------------------------------------------------------
extern PACKAGE TFormMain *FormMain;
//---------------------------------------------------------------------------
#endif
//----main.cpp------------------------------------------------------------
#include
#pragma hdrstop
#include "main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "PERFGRAP"
#pragma re "*.dfm"
TFormMain *FormMain;
//---------------------------------------------------------------------------
__fastcall TFormMain::TFormMain(TComponent* Owner)
: TForm(Owner)
{}
//---------------------------------------------------------------------------
void __fastcall TFormMain::LButtonDown(TMessage &message)
{
//----如果滑鼠在窗體內(控制元件外)被單擊,則此事件被啟用
if(GetAsyncKeyState(VK_LBUTTON) < 0)
{
Application->MessageBoxA("FoGet Messsge" , "Message" , MB_OK);
//----向Edit2傳送滑鼠訊息,則Edit2將產生單擊獲得焦點的現象
SendMessage(FormMain->Edit2->Handle ,
message.Msg ,
message.WParam ,
message.LParam);
}
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::FormCreate(TObject *Sender)
{
//----替換2個TperformanceGraph控制元件的訊息處理函式控制程式碼
OldWndProc1 = PerformanceGraph1->WindowProc;
OldWndProc2 = PerformanceGraph2->WindowProc;
PerformanceGraph1->WindowProc = MyWndProc1;
PerformanceGraph2->WindowProc = MyWndProc2;
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::MyWndProc1(TMessage &message)
{
if (message.Msg == WM_LBUTTONDOWN)
//----如果訊息是“滑鼠單擊訊息”,則顯示資訊
ShowMessage("PerformanceGraph1 Get Message ");
else
//----如果訊息是其他訊息,則交給控制元件原來的處理
OldWndProc1(message);
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::MyWndProc2(TMessage &message)
{
if (message.Msg == WM_LBUTTONDOWN)
ShowMessage("PerformanceGraph 2 get Message");
else
OldWndProc2(message);
}
如果在TFormMain::FormCreate()函式中加入以下兩句語句:
OldWndProc3 = FormMain->WindowProc;
FormMain->WindowProc = MyWndProc3;
再新增函式:
void __fastcall TFormMain::MyWndProc3(TMessage &message)
{
if (message.Msg == WM_LBUTTONDOWN)
//----如果訊息是“滑鼠單擊訊息”,則顯示資訊
ShowMessage(“FormMain Get the Message ");
else
//----如果訊息是其他訊息,則交給控制元件原來的處理
OldWndProc1(message);
}
則把FormMain的滑鼠訊息響應函式進行了改裝,此時窗體就會截獲滑鼠訊息,而2個TperformanceGraph控制元件將不會得到訊息。這是因為窗體將先於控制元件得到訊息。
從上面的例子可以看出:
1、 窗體將先於控制元件得到訊息;
2、 對於響應某一訊息的控制元件,可以用SendMessage想起傳送訊息;
3、 對於不響應某一訊息的控制元件,可以用過載其WindowProc屬性獲得你想要的效果。
實際上,掌握了利用Windows的訊息傳遞機制才是掌握C++ Builder的第二階段,任重而道遠。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-990910/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- VCL中訊息處理初探 (轉)
- 截獲與管理Windows的訊息 (轉)Windows
- 深入VCL 理解BCB的訊息機制 (一) (轉)
- 異常的捕獲及處理
- C#的訊息處理方法 (轉)C#
- java中如何捕獲鍵盤訊息Java
- 集計時對於溢位的捕獲和處理
- Windows應用程式的訊息處理機制Windows
- 關於SQLServer2005的學習筆記——異常捕獲及處理SQLServer筆記
- 處理鍵盤輸入訊息(轉)
- 利用Delphi訊息處理建立類似Windows開始選單 (轉)Windows
- C++ BUILDER 訊息處理的深入探索 (轉)C++UI
- 關於 JavaScript 錯誤捕獲JavaScript
- 自定義訊息獲取訊息(轉)
- 三、訊息的可靠處理
- KafkaConsumer對於事務訊息的處理Kafka
- php ActiveMQ的傳送訊息,與處理訊息PHPMQ
- IOS 訊息推送處理iOS
- 關於面試“有戲”和“沒戲”的訊號面試
- 關於 appium 獲取不到 toast 訊息的討論APPAST
- MFC動態建立控制元件的訊息處理 (轉)控制元件
- 異常處理機制(二)之異常處理與捕獲
- WINDOWS訊息說明 (轉)Windows
- 關於js事件冒泡和事件捕獲JS事件
- MPLS RSVP訊息處理——VecloudCloud
- Storm保證訊息處理ORM
- 靈活定義和處理SOAP頭訊息 (轉)
- 有沒有處理貨幣的類庫?
- Java培訓簡述如何處理沒有被捕獲的異常Java
- 文字處理的有關
- 在Python中捕獲finally語句中異常訊息Python
- 關於NSNotificationCenter訊息通訊用法
- 關於RocketMQ的順序訊息MQ
- windows10怎麼關閉通知欄訊息|windows10通知欄訊息關閉的方法Windows
- .net core 訊息流處理流程
- sql server 15404無法獲取有關 Windows NT 組/使用者 處理SQLServerWindows
- 關於鑑權流程的捕獲和冒泡子流程
- Go 語言的錯誤訊息處理Go