真爱无限的知识驿站

学习积累技术经验,提升自身能力

C++MFC编程笔记day02 MFC消息映射机制、菜单资源使用

机制3:MFC消息映射机制:

类内声明,类外定义宏,绑定消息处理函数

派生自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)

END_MESSAGE_MAP()

LRESULT CMyFrameWnd::OnCreate(WPARAM wparam,LPARAM lparam)

{

AfxMessageBox("OnCreate");

return 0;

}

(具体消息函数要查MSDN):

#include "stdafx.h"

class CMyFrameWnd:public CFrameWnd

{

DECLARE_MESSAGE_MAP()

public:

afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct);

LRESULT OnPaint(WPARAM wparam,LPARAM lparam);

};

BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd)

ON_WM_CREATE()

ON_MESSAGE(WM_PAINT,OnPaint)

END_MESSAGE_MAP()

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);

return 0;

}

class CMyWinApp:public CWinApp

{

public:

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);

return 0;

}

//消息映射

BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd)

ON_MESSAGE(WM_MYMSG,OnMyMsg)

END_MESSAGE_MAP()

//点击时发消息触发

void CMyFrameWnd::OnLButtonUp( UINT flags, CPoint point)

{

TCHAR s[20]={0};

sprintf(s,"point %d,%d",point.x,point.y);

AfxMessageBox(s);

::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);

//映射

BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd)

ON_COMMAND(1001,OnTest1)

//ON_COMMAND_RANGE(1002,1003,OnTest);//多个控件使用一个处理函数

END_MESSAGE_MAP()

//类内声明

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");

}


MFC菜单(CMenu)

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中挂载菜单:

class CMyFrameWnd:public CFrameWnd

{

DECLARE_MESSAGE_MAP()

public:

afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct);

};

BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd)

ON_WM_CREATE()

END_MESSAGE_MAP()

int CMyFrameWnd::OnCreate( LPCREATESTRUCT lpCreateStruct)

{

CMenu menu;

menu.LoadMenu(IDR_MENU1);

SetMenu(&menu);

return CFrameWnd::OnCreate(lpCreateStruct);

}



//消息

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 menu;

menu.LoadMenu(IDR_MENU1);

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头文件:

// MFCmenu.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
class CMyFrameWnd:public CFrameWnd
{
DECLARE_MESSAGE_MAP()
public:
afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct);
afx_msg void OnNew();
afx_msg void OnInitMenuPopup(CMenu* menu,UINT flag,BOOL IsWindowMenu);
afx_msg void OnContextMenu( CWnd* pwin, CPoint point );
};
BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd)
ON_WM_CREATE()
//ON_COMMAND(IDM_new,OnNew)
ON_WM_CONTEXTMENU()
ON_WM_INITMENUPOPUP()
END_MESSAGE_MAP()
void CMyFrameWnd::OnContextMenu( CWnd* pwin, CPoint point )
{
CMenu menu;
menu.LoadMenu(IDR_MENU1);
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);
}
void CMyFrameWnd::OnInitMenuPopup(CMenu* menu,UINT flag,BOOL IsWindowMenu)
{
//::CheckMenuItem(menu->m_hMenu,IDM_new,MF_BYCOMMAND|MF_CHECKED);//win32 API函数
menu->CheckMenuItem(IDM_new,MF_BYCOMMAND|MF_CHECKED);//mfc函数
}
void CMyFrameWnd::OnNew()
{
AfxMessageBox("CMyFrameWnd::OnNew");
}
int CMyFrameWnd::OnCreate( LPCREATESTRUCT lpCreateStruct)
{
CMenu menu;
menu.LoadMenu(IDR_MENU1);
this->SetMenu(&menu);
return CFrameWnd::OnCreate(lpCreateStruct);
}
class CMyWinApp:public CWinApp
{
DECLARE_MESSAGE_MAP()
public:
virtual BOOL InitInstance();
afx_msg void OnNew();
};
BEGIN_MESSAGE_MAP(CMyWinApp,CWinApp)
ON_COMMAND(IDM_new,OnNew)
END_MESSAGE_MAP()
void CMyWinApp::OnNew()
{
AfxMessageBox("CMyWinApp::OnNew");
}
CMyWinApp theApp;
BOOL CMyWinApp::InitInstance()
{
CMyFrameWnd *pFrame=new CMyFrameWnd;
pFrame->Create(NULL,"MFCmenu"/*,WS_OVERLAPPEDWINDOW,CFrameWnd::rectDefault,
NULL,MAKEINTRESOURCE(IDR_MENU1)*/);
m_pMainWnd=pFrame;
pFrame->ShowWindow(SW_SHOW);
pFrame->UpdateWindow();
return TRUE;
}


发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

Powered By Z-BlogPHP 1.7.3

Copyright 2024-2027 pukuimin Rights Reserved.
粤ICP备17100155号