類内聲明,類外定義宏,綁定消息處理函數
派生自CCmdTarget
類内聲明宏:DECLARE_MESSAGE_MAP()
類外添加實作宏:
BEGIN_MESSAGE_MAP(類名,父類名)
END_MESSAGE_MAP()
//資料結構
struct AFX_MSGMAP_ENTRY
{
UINT nMessage; // 消息ID
UINT nCode; // 通知碼
UINT nID; // 控件ID或消息
UINT nLastID; // 最後控制ID
UINT nSig; // 消息處理函數類型
AFX_PMSG pfn; // 消息處理函數
};
//宏定義的靜态變量
struct AFX_MSGMAP
const AFX_MSGMAP* pBaseMap;//父類靜态變量位址
const AFX_MSGMAP_ENTRY* lpEntries;//本類靜态數組位址
調用過程:
Afx_WndProc()
CWnd* pWnd=CWnd::FromHandlePermanent(hWnd);
AfxCallWndProc(pWnd)
pWnd->WindowProc(...)//this指針為pFrame
OnWndMsg(...)
AFX_MSGMAP*pMessageMap=GetMessageMap()
//調用宏綁定的重寫的消息處理
}
windows标準消息示例:
class CMyFrameWnd:public CFrameWnd
DECLARE_MESSAGE_MAP()
public:
LRESULT OnCreate(WPARAM wparam,LPARAM lparam);
BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd)
ON_MESSAGE(WM_CREATE,OnCreate)
LRESULT CMyFrameWnd::OnCreate(WPARAM wparam,LPARAM lparam)
AfxMessageBox("OnCreate");
return 0;
(具體消息函數要查MSDN):
#include "stdafx.h"
afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct);
LRESULT OnPaint(WPARAM wparam,LPARAM lparam);
ON_WM_CREATE()
ON_MESSAGE(WM_PAINT,OnPaint)
int CMyFrameWnd::OnCreate( LPCREATESTRUCT lpCreateStruct)
AfxMessageBox("afx_msg:OnCreate");
return CFrameWnd::OnCreate(lpCreateStruct);
LRESULT CMyFrameWnd::OnPaint(WPARAM wparam,LPARAM lparam)
PAINTSTRUCT ps={0};
HDC hdc=::BeginPaint(this->m_hWnd,&ps);
::TextOut(hdc,100,100,"hello",5);
::EndPaint(this->m_hWnd,&ps);
class CMyWinApp:public CWinApp
virtual BOOL InitInstance();
CMyWinApp theApp;
BOOL CMyWinApp::InitInstance()
CMyFrameWnd *pFrame=new CMyFrameWnd;
pFrame->Create(NULL,"MFCmsg");
m_pMainWnd=pFrame;
pFrame->ShowWindow(SW_SHOW);
pFrame->UpdateWindow();
return TRUE;
day80 am over!
自定義消息
#define WM_MYMSG WM_USER+100
//類内聲明
afx_msg LRESULT OnMyMsg(WPARAM wparam, LPARAM lparam);
//類外實作
LRESULT CMyFrameWnd::OnMyMsg(WPARAM wparam, LPARAM lparam)
CString s;
s.Format("%d,%d",wparam,lparam);
AfxMessageBox(s);
//消息映射
ON_MESSAGE(WM_MYMSG,OnMyMsg)
//點選時發消息觸發
void CMyFrameWnd::OnLButtonUp( UINT flags, CPoint point)
TCHAR s[20]={0};
sprintf(s,"point %d,%d",point.x,point.y);
::PostMessage(m_hWnd,WM_MYMSG,1,2);
指令消息映射示例:
//建立按鈕
::CreateWindowEx(0,"BUTTON","Test1",
WS_CHILD|WS_VISIBLE,100,100,100,40,
m_hWnd,(HMENU)1001,AfxGetInstanceHandle(),NULL);
//映射
ON_COMMAND(1001,OnTest1)
//ON_COMMAND_RANGE(1002,1003,OnTest);//多個控件使用一個處理函數
afx_msg void OnTest1();
//afx_msg void OnTest( UINT nID );//多控件處理函數原型
void CMyFrameWnd::OnTest1()
AfxMessageBox("OnTest1");
通知消息:
ON_通知碼(如:ON_EN_CHANGE、ON_BN_CLICKED)
//建立控件
::CreateWindowEx(0,"EDIT","edit1",
WS_CHILD|WS_VISIBLE|WS_BORDER,200,100,100,40,
m_hWnd,(HMENU)1004,AfxGetInstanceHandle(),NULL);
ON_EN_CHANGE(1004,OnEnChange);
afx_msg void OnEnChange();
void CMyFrameWnd::OnEnChange()
AfxMessageBox("OnEnChange");
CMenu類封裝了對菜單操作的各種函數,還封裝了m_hMenu 菜單句柄
1.插入菜單資源,并建立幾項,把.res和resource.h檔案插入到工程,在.cpp中包含resource.h
2.加載菜單
方式1,建立時傳入,其他值預設值:
pFrame->Create(NULL,"MFCmenu",WS_OVERLAPPEDWINDOW,CFrameWnd::rectDefault,NULL,MAKEINTRESOURCE(IDR_MENU1));
方式2,在WM_CREATE中挂載菜單:
CMenu menu;
menu.LoadMenu(IDR_MENU1);
SetMenu(&menu);
//消息
ON_WM_INITMENUPOPUP() //将要顯示菜單時的消息
//消息原型
afx_msg void OnInitMenuPopup(CMenu* menu,UINT flag,BOOL IsWindowMenu);
void CMyFrameWnd::OnInitMenuPopup(CMenu* menu,UINT flag,BOOL IsWindowMenu)
//::CheckMenuItem(menu->m_hMenu,IDM_new,MF_BYCOMMAND|MF_CHECKED);//win32
menu->CheckMenuItem(IDM_new,MF_BYCOMMAND|MF_CHECKED);//mfc
//菜單項目點選事件綁定
ON_COMMAND(IDM_new,OnNew)
//函數原型和實作
afx_msg void OnNew();
void CMyFrameWnd::OnNew()
AfxMessageBox("OnNew");
day80 pm over!
WM_COMMAND消息處理順序:CView>CFrameWnd>CWinApp
3、顯示菜單:右鍵菜單
ON_WM_CONTEXTMENU()
afx_msg void OnContextMenu( CWnd* pwin, CPoint point);
void CMyFrameWnd::OnContextMenu( CWnd* pwin, CPoint point )
CMenu * menufile=menu.GetSubMenu(0);//擷取彈出菜單部分
//::TrackPopupMenu(menufile->m_hMenu,TPM_LEFTALIGN,point.x,point.y,NULL,m_hWnd,NULL);//顯示菜單
menufile->TrackPopupMenu(TPM_LEFTALIGN,point.x,point.y,pwin,NULL);
綜合示例,插入菜單資源,包含resource.h頭檔案: