自定義訊息獲取訊息(轉)

heying1229發表於2007-07-17
1. 自定義訊息

(1) 手工定義訊息,可以這麼寫 #define WM_MY_MESSAGE(WM_USER+100), MS 推薦的至
少是 WM_USER+100;
(2)寫訊息處理函式,用 WPARAM,LPARAM返回LRESULT.
LRESULT CMainFrame::OnMyMessage(WPARAM wparam,LPARAM lParam)
{
//加入你的處理函式
}
(3) 在類的 AFX_MSG處進行宣告,也就是常說的"宏對映"

//-----------------------------------------------------------------------
2. 獲取有關視窗正在處理的當前訊息的資訊

呼叫CWnd: : GetCurrentMessage 可以獲取一個MSG指標。例如,可以使用ClassWizard
將幾個選單項處理程式對映到一個函式中,然後呼叫GetCurrentMessage 來確定所選中
的選單項。
viod CMainFrame : : OnCommmonMenuHandler ( )
{
//Display selected menu item in debug window .
TRACE ("Menu item %u was selected . " ,
GetCruuentMessage ( ) ―> wParam );
}

//-----------------------------------------------------------------------
3.視窗最大化、最小化及關閉的訊息是什麼

最大化、最小化將傳送WM_SYSCOMMAND訊息。要處理該訊息,可以這麼做:
(1)、在Form的標頭檔案中新增:
void __fastcall RestrictMinimizeMaximize(TMessage &Msg);

BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_SYSCOMMAND, TMessage, RestrictMinimizeMaximize)
END_MESSAGE_MAP(TForm)
(2)、在Form的單元檔案中新增:

void __fastcall TForm1::RestrictMinimizeMaximize(TMessage& Msg)
{
if (Msg.WParam == SC_MINIMIZE)
{
//catches minimize...
}
else if (Msg.WParam == SC_MAXIMIZE)
{
//catches maximize...
}
TForm::Dispatch(&Msg);
// or "else TForm::Dispatch(&Msg)" to trap
}
關閉視窗的訊息為WM_CLOSE,C++Builder提供了OnClose事件

//-----------------------------------------------------------------------
訊息對映的定義和實現
MFC處理的三類訊息
根據處理函式和處理過程的不同, MFC主要處理三類訊息:
Windows 訊息,字首以“WM_”打頭,WM_COMMAND例外。Windows訊息直接送給MFC視窗過程處理,視窗過程呼叫對應的訊息處理函式。一般,由視窗物件來處理這類訊息,也就是說,這類訊息處理函式一般是MFC視窗類的成員函式。
控制通知訊息,是控制子視窗送給父視窗的 WM_COMMAND通知訊息。視窗過程呼叫對應的訊息處理函式。一般,由視窗物件來處理這類訊息,也就是說,這類訊息處理函式一般是MFC視窗類的成員函式。
需要指出的是,Win32使用新的WM_NOFITY來處理複雜的通知訊息。WM_COMMAND型別的通知訊息僅僅能傳遞一個控制視窗控制程式碼(lparam)、控制窗ID和通知程式碼(wparam)。WM_NOTIFY能傳遞任意複雜的資訊。
命令訊息,這是來自選單、工具條按鈕、加速鍵等使用者介面物件的WM_COMMAND通知訊息,屬於應用程式自己定義的訊息。透過訊息對映機制,MFC框架把命令按一定的路徑分發給多種型別的物件(具備訊息處理能力)處理,如文件、視窗、應用程式、文件模板等物件。能處理訊息對映的類必須從CCmdTarget類派生。
在討論了訊息的分類之後,應該是討論各類訊息如何處理的時候了。但是,要知道怎麼處理訊息,首先要知道如何對映訊息。
MFC訊息對映的實現方法
MFC 使用ClassWizard幫助實現訊息對映,它在原始碼中新增一些訊息對映的內容,並宣告和實現訊息處理函式。現在來分析這些被新增的內容。
在類的定義(標頭檔案)裡,它增加了訊息處理函式宣告,並新增一行宣告訊息對映的宏 DECLARE_MESSAGE_MAP。
在類的實現(實現檔案)裡,實現訊息處理函式,並使用 IMPLEMENT_MESSAGE_MAP宏實現訊息對映。一般情況下,這些宣告和實現是由MFC的ClassWizard自動來維護的。看一個例子:
在 AppWizard產生的應用程式類的原始碼中,應用程式類的定義(標頭檔案)包含了類似如下的程式碼:
//{{AFX_MSG(CTttApp)

afx_msg void OnAppAbout();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()
應用程式類的實現檔案中包含了類似如下的程式碼:
BEGIN_MESSAGE_MAP(CTApp, CWinApp)
//{{AFX_MSG_MAP(CTttApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
標頭檔案裡是訊息對映和訊息處理函式的宣告,實現檔案裡是訊息對映的實現和訊息處理函式的現。它表示讓應用程式物件處理命令訊息 ID_APP_ABOUT,訊息處理函式是OnAppAbout。
為什麼這樣做之後就完成了一個訊息對映?這些宣告和實現到底作了些什麼呢?接著,將討論這些問題。
在宣告與實現的內部
DECLARE_MESSAGE_MAP宏:
首先,看DECLARE_MESSAGE_MAP宏的內容:

#ifdef _AFXDLL

#define DECLARE_MESSAGE_MAP()

private:

static const AFX_MSGMAP_ENTRY _messageEntries[];

protected:

static AFX_DATA const AFX_MSGMAP messageMap;

static const AFX_MSGMAP* PASCAL _GetBaseMessageMap();

virtual const AFX_MSGMAP* GetMessageMap() const;


#else

#define DECLARE_MESSAGE_MAP()

private:

static const AFX_MSGMAP_ENTRY _messageEntries[];

protected:

static AFX_DATA const AFX_MSGMAP messageMap;

virtual const AFX_MSGMAP* GetMessageMap() const;


#endif

DECLARE_MESSAGE_MAP 定義了兩個版本,分別用於靜態或者動態連結到MFC DLL的情形。



BEGIN_MESSAE_MAP宏

然後,看BEGIN_MESSAE_MAP宏的內容:

#ifdef _AFXDLL

#define BEGIN_MESSAGE_MAP(theClass, baseClass)

const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap()

{ return &baseClass::messageMap; }

const AFX_MSGMAP* theClass::GetMessageMap() const

{ return &theClass::messageMap; }

AFX_DATADEF const AFX_MSGMAP theClass::messageMap =

{ &theClass::_GetBaseMessageMap, &theClass::_messageEntries[0] };

const AFX_MSGMAP_ENTRY theClass::_messageEntries[] =

{


#else

#define BEGIN_MESSAGE_MAP(theClass, baseClass)

const AFX_MSGMAP* theClass::GetMessageMap() const

{ return &theClass::messageMap; }

AFX_DATADEF const AFX_MSGMAP theClass::messageMap =

{ &baseClass::messageMap, &theClass::_messageEntries[0] };

const AFX_MSGMAP_ENTRY theClass::_messageEntries[] =

{


#endif


#define END_MESSAGE_MAP()

{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }

};

對應地, BEGIN_MESSAGE_MAP定義了兩個版本,分別用於靜態或者動態連結到MFC DLL的情形。END_MESSAGE_MAP相對簡單,就只有一種定義。



ON_COMMAND宏

最後,看ON_COMMAND宏的內容:

#define ON_COMMAND(id, memberFxn)

{

WM_COMMAND,

CN_COMMAND,

(WORD)id,

(WORD)id,

AfxSig_vv,

(AFX_PMSG)memberFxn

};

訊息對映宣告的解釋
在清楚了有關宏的定義之後,現在來分析它們的作用和功能。
訊息對映宣告的實質是給所在類新增幾個靜態成員變數和靜態或虛擬函式,當然它們是與訊息對映相關的變數和函式。[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10172717/viewspace-926894/,如需轉載,請註明出處,否則將追究法律責任。

相關文章