天天看點

C++MFC程式設計筆記day02 MFC消息映射機制、菜單資源使用機制3:MFC消息映射機制:MFC菜單(CMenu)

類内聲明,類外定義宏,綁定消息處理函數

派生自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頭檔案: