MFC消息映射与命令传递
MFC消息映射与命令传递
MFC消息映射与命令传递
张杰
2011-09-17
声明
本文由张杰原创,参考了侯俊杰先生的《深入浅出MFC》,源码摘自Microsoft Visual Studio 9.0\VC。
个人能力有限,文章必定存在很多错误。我的邮箱是:chinajiezhang@gmail.comchinajiezhang@163.com欢迎您来邮件斧正。当然您也可以加我 msn:chinazhangjie@hotmail.com交流。
本文可供传播、交流、学习使用,但请不要用于商业用途。转载请标明此声明,谢谢您的合作。
DECLARE_MESSAGE_MAP宏
在MFC 几乎每个头文件下(类的最后一行声明),都会有这么几行代码:
// 生成的消息映射函数
protected:
DECLARE_MESSAGE_MAP()
我们看一看DECLARE_MESSAGE_MAP到底为何物,查看DECLARE_MESSAGE_MAP源码(c:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\include\afxwin.h):
#defineDECLARE_MESSAGE_MAP() \
protected: \
staticconstAFX_MSGMAP* PASCAL GetThisMessageMap(); \
virtualconstAFX_MSGMAP* GetMessageMap()const; \
我们看到了一个陌生的类型AFX_MSGMAP,查看其定义:
structAFX_MSGMAP
{
constAFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
constAFX_MSGMAP_ENTRY* lpEntries;
};
这个结构体第一个成员是一个函数指针,第二个成员类型为AFX_MSGMAP_ENTRY* ,查看AFX_MSGMAP_ENTRY定义:
structAFX_MSGMAP_ENTRY
{
UINT nMessage;// windows message
UINT nCode;// control code or WM_NOTIFY code
UINT nID;// control ID (or 0 for windows messages)
UINT nLastID;// used for entries specifying a range of control id's
UINT_PTR nSig;// signature type (action) or pointer to message #
AFX_PMSG pfn;// routine to call (or special value)
};
AFX_MSGMAP_ENTRY 定义一些消息的相关信息,AFX_PSG定义为:
typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void);
是一个函数指针。是不是将每个消息与其处理方法绑定起来呢?真有可能。
BEGIN_MESSAGE_MAP/ON.../END_MESSAGEBOX 宏
在MFC几乎每个(类定义的)源文件下都会出现下面几行代码(或者类似):
BEGIN_MESSAGE_MAP(CXXX, C***)
ON_……
END_MESSAGE_MAP()
我们继续一探究竟,查看这几个宏的源码:
#defineBEGIN_MESSAGE_MAP(theClass, baseClass) \
PTM_WARNING_DISABLE \
constAFX_MSGMAP* theClass::GetMessageMap()const\
{returnGetThisMessageMap(); } \
constAFX_MSGMAP* PASCAL theClass::GetThisMessageMap() \
{ \
typedeftheClass ThisClass; \
typedefbaseClass TheBaseClass; \
staticconstAFX_MSGMAP_ENTRY _messageEntries[] = \
{
#defineEND_MESSAGE_MAP()\
{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \
}; \
staticconstAFX_MSGMAP messageMap = \
{ &TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; \
return&messageMap; \
} \
PTM_WARNING_RESTORE
关于ON_...类型的宏就多了,下面我摘了(C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\include\afxmsg_.h)下面一些我们很熟悉的代码:
#defineON_COMMAND(id, memberFxn)\
{ WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSigCmd_v, \
static_cast<AFX_PMSG> (memberFxn) },
// ON_COMMAND(id, OnBar) is the same as
// ON_CONTROL(0, id, OnBar) or ON_BN_CLICKED(0, id, OnBar)
#defineON_NOTIFY(wNotifyCode, id, memberFxn)\
{ WM_NOTIFY, (WORD)(int)wNotifyCode, (WORD)id, (WORD)id, AfxSigNotify_v, \
(AFX_PMSG) \
(static_cast<void(AFX_MSG_CALL CCmdTarget::*)(NMHDR*, LRESULT*) > \
(memberFxn)) },
// for general controls
#defineON_CONTROL(wNotifyCode, id, memberFxn) \
{ WM_COMMAND, (WORD)wNotifyCode, (WORD)id, (WORD)id, AfxSigCmd_v, \
(static_cast< AFX_PMSG > (memberFxn)) },
#defineON_WM_DESTROY()\
{ WM_DESTROY, 0, 0, 0, AfxSig_vv, \
(AFX_PMSG)(AFX_PMSGW) \
(static_cast<void(AFX_MSG_CALL CWnd::*)(void) > ( &ThisClass :: OnDestroy)) },
#defineON_WM_SIZE() \
{ WM_SIZE, 0, 0, 0, AfxSig_vwii, \
(AFX_PMSG)(AFX_PMSGW) \
(static_cast<void(AFX_MSG_CALL CWnd::*)(UINT,int,int) > ( &ThisClass :: OnSize)) },
又加了一些宏,一步一步的看吧,PTM_WARNING_DISABLE与PTM_WARNING_RESTORE:
#definePTM_WARNING_DISABLE \
__pragma(warning( push )) \
__pragma(warning( disable : 4867 ))
#definePTM_WARNING_RESTORE \
__pragma(warning( pop ))
是处理警告的,貌似和我们的话题不符,就先不看了。
查看AfxSig_end定义:
enumAfxSig
{
AfxSig_end = 0,// [marks end of message map]
AfxSig_b_D_v, // BOOL (CDC*)
AfxSig_b_b_v, // BOOL (BOOL)
AfxSig_b_u_v, // BOOL (UINT)
AfxSig_b_h_v, // BOOL (HANDLE)
AfxSig_b_W_uu, // BOOL (CWnd*, UINT, UINT)
AfxSig_b_W_COPYDATASTRUCT, // BOOL (CWnd*, COPYDATASTRUCT*)
AfxSig_b_v_HELPINFO, // BOOL (LPHELPINFO);
AfxSig_CTLCOLOR, // HBRUSH (CDC*, CWnd*, UINT)
AfxSig_CTLCOLOR_REFLECT, // HBRUSH (CDC*, UINT)
AfxSig_i_u_W_u, // int (UINT, CWnd*, UINT) // ?TOITEM
AfxSig_i_uu_v, // int (UINT, UINT)
AfxSig_i_W_uu, // int (CWnd*, UINT, UINT)
AfxSig_i_v_s, // int (LPTSTR)
AfxSig_l_w_l, // LRESULT (WPARAM, LPARAM)
AfxSig_l_uu_M, // LRESULT (UINT, UINT, CMenu*)
AfxSig_v_b_h, // void (BOOL, HANDLE)
AfxSig_v_h_v, // void (HANDLE)
AfxSig_v_h_h, // void (HANDLE, HANDLE)
AfxSig_v_v_v, // void ()
AfxSig_v_u_v, // void (UINT)
AfxSig_v_u_u, // void (UINT, UINT)
AfxSig_v_uu_v, // void (UINT, UINT)
AfxSig_v_v_ii, // void (int, int)
AfxSig_v_u_uu, // void (UINT, UINT, UINT)
AfxSig_v_u_ii, // void (UINT, int, int)
AfxSig_v_u_W, // void (UINT, CWnd*)
AfxSig_i_u_v, // int (UINT)
AfxSig_u_u_v, // UINT (UINT)
AfxSig_b_v_v, // BOOL ()
AfxSig_v_w_l, // void (WPARAM, LPARAM)
AfxSig_MDIACTIVATE, // void (BOOL, CWnd*, CWnd*)
AfxSig_v_D_v, // void (CDC*)
AfxSig_v_M_v, // void (CMenu*)
AfxSig_v_M_ub, // void (CMenu*, UINT, BOOL)
AfxSig_v_W_v, // void (CWnd*)
AfxSig_v_v_W, // void (CWnd*)
AfxSig_v_W_uu, // void (CWnd*, UINT, UINT)
AfxSig_v_W_p, // void (CWnd*, CPoint)
AfxSig_v_W_h, // void (CWnd*, HANDLE)
AfxSig_C_v_v, // HCURSOR ()
AfxSig_ACTIVATE, // void (UINT, CWnd*, BOOL)
AfxSig_SCROLL, // void (UINT, UINT, CWnd*)
AfxSig_SCROLL_REFLECT, // void (UINT, UINT)
AfxSig_v_v_s, // void (LPTSTR)
AfxSig_v_u_cs, // void (UINT, LPCTSTR)
AfxSig_OWNERDRAW, // void (int, LPTSTR) force return TRUE
AfxSig_i_i_s, // int (int, LPTSTR)
AfxSig_u_v_p, // UINT (CPoint)
AfxSig_u_v_v, // UINT ()
AfxSig_v_b_NCCALCSIZEPARAMS, // void (BOOL, NCCALCSIZE_PARAMS*)
AfxSig_v_v_WINDOWPOS, // void (WINDOWPOS*)
AfxSig_v_uu_M, // void (UINT, UINT, HMENU)
AfxSig_v_u_p, // void (UINT, CPoint)
AfxSig_SIZING, // void (UINT, LPRECT)
AfxSig_MOUSEWHEEL, // BOOL (UINT, short, CPoint)
AfxSig_MOUSEHWHEEL, // void (UINT, short, CPoint)
AfxSigCmd_v, // void ()
AfxSigCmd_b, // BOOL ()
AfxSigCmd_RANGE, // void (UINT)
AfxSigCmd_EX, // BOOL (UINT)
AfxSigNotify_v, // void (NMHDR*, LRESULT*)
AfxSigNotify_b, // BOOL (NMHDR*, LRESULT*)
AfxSigNotify_RANGE, // void (UINT, NMHDR*, LRESULT*)
AfxSigNotify_EX, // BOOL (UINT, NMHDR*, LRESULT*)
AfxSigCmdUI, // void (CCmdUI*)
AfxSigCmdUI_RANGE, // void (CCmdUI*, UINT)
AfxSigCmd_v_pv, // void (void*)
AfxSigCmd_b_pv, // BOOL (void*)
AfxSig_l, // LRESULT ()
AfxSig_l_p, // LRESULT (CPOINT)
AfxSig_u_W_u, // UINT (CWnd*, UINT)
AfxSig_v_u_M, // void (UINT, CMenu* )
AfxSig_u_u_M, // UINT (UINT, CMenu* )
AfxSig_u_v_MENUGETOBJECTINFO, // UINT (MENUGETOBJECTINFO*)
AfxSig_v_M_u, // void (CMenu*, UINT)
AfxSig_v_u_LPMDINEXTMENU, // void (UINT, LPMDINEXTMENU)
AfxSig_APPCOMMAND, // void (CWnd*, UINT, UINT, UINT)
AfxSig_RAWINPUT, // void (UINT, HRAWINPUT)
AfxSig_u_u_u, // UINT (UINT, UINT)
AfxSig_MOUSE_XBUTTON, // void (UINT, UINT, CPoint)
AfxSig_MOUSE_NCXBUTTON, // void (short, UINT, CPoint)
AfxSig_INPUTLANGCHANGE, // void (BYTE, UINT)
AfxSig_v_u_hkl, // void (UINT, HKL)
AfxSig_INPUTDEVICECHANGE, // void (unsigned short)
// Old
AfxSig_bD = AfxSig_b_D_v,// BOOL (CDC*)
AfxSig_bb = AfxSig_b_b_v,// BOOL (BOOL)
AfxSig_bWww = AfxSig_b_W_uu,// BOOL (CWnd*, UINT, UINT)
AfxSig_hDWw = AfxSig_CTLCOLOR,// HBRUSH (CDC*, CWnd*, UINT)
AfxSig_hDw = AfxSig_CTLCOLOR_REFLECT,// HBRUSH (CDC*, UINT)
AfxSig_iwWw = AfxSig_i_u_W_u,// int (UINT, CWnd*, UINT)
AfxSig_iww = AfxSig_i_uu_v,// int (UINT, UINT)
AfxSig_iWww = AfxSig_i_W_uu,// int (CWnd*, UINT, UINT)
AfxSig_is = AfxSig_i_v_s,// int (LPTSTR)
AfxSig_lwl = AfxSig_l_w_l,// LRESULT (WPARAM, LPARAM)
AfxSig_lwwM = AfxSig_l_uu_M,// LRESULT (UINT, UINT, CMenu*)
AfxSig_vv = AfxSig_v_v_v,// void (void)
AfxSig_vw = AfxSig_v_u_v,// void (UINT)
AfxSig_vww = AfxSig_v_u_u,// void (UINT, UINT)
AfxSig_vww2 = AfxSig_v_uu_v,// void (UINT, UINT) // both come from wParam
AfxSig_vvii = AfxSig_v_v_ii,// void (int, int) // wParam is ignored
AfxSig_vwww = AfxSig_v_u_uu,// void (UINT, UINT, UINT)
AfxSig_vwii = AfxSig_v_u_ii,// void (UINT, int, int)
AfxSig_vwl = AfxSig_v_w_l,// void (UINT, LPARAM)
AfxSig_vbWW = AfxSig_MDIACTIVATE,// void (BOOL, CWnd*, CWnd*)
AfxSig_vD = AfxSig_v_D_v,// void (CDC*)
AfxSig_vM = AfxSig_v_M_v,// void (CMenu*)
AfxSig_vMwb = AfxSig_v_M_ub,// void (CMenu*, UINT, BOOL)
AfxSig_vW = AfxSig_v_W_v,// void (CWnd*)
AfxSig_vWww = AfxSig_v_W_uu,// void (CWnd*, UINT, UINT)
AfxSig_vWp = AfxSig_v_W_p,// void (CWnd*, CPoint)
AfxSig_vWh = AfxSig_v_W_h,// void (CWnd*, HANDLE)
AfxSig_vwW = AfxSig_v_u_W,// void (UINT, CWnd*)
AfxSig_vwWb = AfxSig_ACTIVATE,// void (UINT, CWnd*, BOOL)
AfxSig_vwwW = AfxSig_SCROLL,// void (UINT, UINT, CWnd*)
AfxSig_vwwx = AfxSig_SCROLL_REFLECT,// void (UINT, UINT)
AfxSig_vs = AfxSig_v_v_s,// void (LPTSTR)
AfxSig_vOWNER = AfxSig_OWNERDRAW,// void (int, LPTSTR), force return TRUE
AfxSig_iis = AfxSig_i_i_s,// int (int, LPTSTR)
AfxSig_wp = AfxSig_u_v_p,// UINT (CPoint)
AfxSig_wv = AfxSig_u_v_v,// UINT (void)
AfxSig_vPOS = AfxSig_v_v_WINDOWPOS,// void (WINDOWPOS*)
AfxSig_vCALC = AfxSig_v_b_NCCALCSIZEPARAMS,// void (BOOL, NCCALCSIZE_PARAMS*)
AfxSig_vNMHDRpl = AfxSigNotify_v,// void (NMHDR*, LRESULT*)
AfxSig_bNMHDRpl = AfxSigNotify_b,// BOOL (NMHDR*, LRESULT*)
AfxSig_vwNMHDRpl = AfxSigNotify_RANGE,// void (UINT, NMHDR*, LRESULT*)
AfxSig_bwNMHDRpl = AfxSigNotify_EX,// BOOL (UINT, NMHDR*, LRESULT*)
AfxSig_bHELPINFO = AfxSig_b_v_HELPINFO,// BOOL (HELPINFO*)
AfxSig_vwSIZING = AfxSig_SIZING,// void (UINT, LPRECT) -- return TRUE
// signatures specific to CCmdTarget
AfxSig_cmdui = AfxSigCmdUI,// void (CCmdUI*)
AfxSig_cmduiw = AfxSigCmdUI_RANGE,// void (CCmdUI*, UINT)
AfxSig_vpv = AfxSigCmd_v_pv,// void (void*)
AfxSig_bpv = AfxSigCmd_b_pv,// BOOL (void*)
// Other aliases (based on implementation)
AfxSig_vwwh = AfxSig_v_uu_M,// void (UINT, UINT, HMENU)
AfxSig_vwp = AfxSig_v_u_p,// void (UINT, CPoint)
AfxSig_bw = AfxSig_b_u_v,// BOOL (UINT)
AfxSig_bh = AfxSig_b_h_v,// BOOL (HANDLE)
AfxSig_iw = AfxSig_i_u_v,// int (UINT)
AfxSig_ww = AfxSig_u_u_v,// UINT (UINT)
AfxSig_bv = AfxSig_b_v_v,// BOOL (void)
AfxSig_hv = AfxSig_C_v_v,// HANDLE (void)
AfxSig_vb = AfxSig_vw,// void (BOOL)
AfxSig_vbh = AfxSig_v_b_h,// void (BOOL, HANDLE)
AfxSig_vbw = AfxSig_vww,// void (BOOL, UINT)
AfxSig_vhh = AfxSig_v_h_h,// void (HANDLE, HANDLE)
AfxSig_vh = AfxSig_v_h_v,// void (HANDLE)
AfxSig_viSS = AfxSig_vwl,// void (int, STYLESTRUCT*)
AfxSig_bwl = AfxSig_lwl,
AfxSig_vwMOVING = AfxSig_vwSIZING,// void (UINT, LPRECT) -- return TRUE
AfxSig_vW2 = AfxSig_v_v_W,// void (CWnd*) (CWnd* comes from lParam)
AfxSig_bWCDS = AfxSig_b_W_COPYDATASTRUCT,// BOOL (CWnd*, COPYDATASTRUCT*)
AfxSig_bwsp = AfxSig_MOUSEWHEEL,// BOOL (UINT, short, CPoint)
AfxSig_vws = AfxSig_v_u_cs,
};
AfxSig的含义暂时不讲,稍后再说。
把几个宏分散开来,没有整体效果。还是举个例子吧:
DECLARE_MESSAGE_MAP()
EGIN_MESSAGE_MAP(CFirstMFCDemoApp, CWinApp)
ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen)
END_MESSAGE_MAP()
展开以后为:
protected:
staticconstAFX_MSGMAP* PASCAL GetThisMessageMap();
virtualconstAFX_MSGMAP* GetMessageMap()const;
constAFX_MSGMAP* CFirstMFCDemoApp::GetMessageMap()const
{
returnGetThisMessageMap();
}
constAFX_MSGMAP* PASCAL
CFirstMFCDemoApp::GetThisMessageMap()
{
typedefCFirstMFCDemoApp ThisClass;
typedefCWinApp TheBaseClass;
staticconstAFX_MSGMAP_ENTRY _messageEntries[] =
{
{
WM_COMMAND, CN_COMMAND, (WORD)ID_FILE_NEW,
(WORD)ID_FILE_NEW, AfxSigCmd_v,
static_cast<AFX_PMSG> (&CWinApp::OnFileNew)
},
{
WM_COMMAND, CN_COMMAND, (WORD)ID_FILE_OPEN,
(WORD)ID_FILE_OPEN, AfxSigCmd_v,
static_cast<AFX_PMSG> (&CWinApp::OnFileOpen)
},
{
0, 0, 0, 0,
AfxSig_end, (AFX_PMSG)0
}
};
staticconstAFX_MSGMAP messageMap =
{ &TheBaseClass::GetThisMessageMap,
&_messageEntries[0] };
return&messageMap;
}
仔细看上述代码,会发现这和RTTI一样,还是一个链表。将子类的消息映射表和父类的消息映射表联系起来。
下图为 MFC消息映射表:
消息泵的开始
这里用到 window高级编程中的hook技术,而我对hook技术很不了解,所以无法讲述(与其讲错,不如不讲)。想了解更多,自己查资料去吧,O(∩_∩)O~。
消息传递方式
(1)直线上溯(一般 windows消息)
CWnd::WindowProc 调用OnWndMsg用来分辨并处理消息;如果是命令消息,交给OnCommand处理,如果是通知消息(Notification),交给OnNotify处理。而一般的Windows消息,就直接在消息映射表中上溯,寻找其归宿(消息处理程序)。
下图是WM_PAINT消息发生于View时,消息传递路径:
(2)拐弯上溯(WM_COMMAND命令消息)
如果消息是 WM_COMMAND ,CWnd::OnWndMsg另辟蹊径,交流OnCommand来处理。这并不一定是CWnd::OnCommand,得视this指针指向哪一种对象而定。在MFC之中,以下类都改写了OnCommand函数;
Class CWnd : public CCmdTarget
Class CFrameWnd : public CFrameWnd
Class CMDIFrameWnd : public CWnd
Class CSplitterWnd : public CWnd
Class CPropertySheet : public CWnd
Class COlePropertyPage : public CDialog
下图示出了 FrameWnd窗口收到命令消息后的四个尝试路径:
消息映射和命令传递,大体上应该有了一个了解。一些细节如“AfxSig_XX的奥秘”以及具体到程序的代码,这是一个极其复杂的过程,需要深厚的Windows编程功底。而我觉得作为MFC普通用户而言,了解到这里就已经够了。
![](/assets/blank.gif)
» 下一篇:MFC RTTI 探究
公告
本博客所有内容均为博主原创(如有参考,在文章中有标示),转载请标明文章链接,谢谢您的合作。联系我:
这是我在博客园的一个马甲,文章版本不会更新,如果您对我的文章感兴趣的话,请关注我的独立博客。
主页:http://www.perfect-is-shit.com/
园龄:4年5个月
粉丝:172
关注:16
随笔分类(64)
- C/C++ Language(14)
- Data structure and Algorithm(18)
- emacs(1)
- Game Programming(7)
- Linux Programing(3)
- Others(3)
- Windows Programing(14)
- 翻译(2)
- 思绪飘零(2)
随笔档案(63)
- 2012年8月 (3)
- 2012年7月 (5)
- 2011年11月 (4)
- 2011年10月 (3)
- 2011年9月 (10)
- 2011年8月 (1)
- 2011年7月 (2)
- 2011年6月 (3)
- 2011年5月 (1)
- 2011年1月 (3)
- 2010年12月 (3)
- 2010年11月 (6)
- 2010年10月 (8)
- 2010年9月 (2)
- 2010年8月 (9)
最新评论
- 1. Re:深度探索C语言函数可变长参数
- 楼主这句话有问题哦--无论32位还是64位机器,sizeof(int)永远代表机器的位数,明白了吧!^_^。
- 2. Re:贪心算法
- 单源最短路径,不是单源最大路径
- 3. Re:贪心算法
- 给楼主赞一个
- 4. Re:ubuntu下 GCC编译程序出现 undefined reference to `std::ios_base::Init::Init()&#39;问题
- “也就是说如果想要使用g++编译程序的话,那么链接时需要添加“-Istdc++”。这句话中的g++应该是gcc吧?
- 5. Re:动态规划
- 实例3代码在序列元素全负时存在bug
MFC消息映射与命令传递相关推荐
- MFC六大核心机制之五、六:消息映射和命令传递
作为C++程序员,我们总是希望自己程序的所有代码都是自己写出来的,如果使用了其他的一些库,也总是千方百计想弄清楚其中的类和函数的原理,否则就会感觉不踏实.所以,我们对于在进行MFC视窗程序设计时经常要 ...
- MFC消息映射与消息传递内幕
MFC消息映射与消息传递内幕 Windows操作系统是以消息为基础,事件驱动的.作为程序员了解操作系统的消息传递机制是非常必要的.Microsoft的MFC有它自己的一套支持Windows操作系统消息 ...
- 【MFC系列-第9天】MFC消息映射机制的原理
关注公号[逆向通信猿]更精彩!!! 第9天 MFC消息映射机制的原理 9.1 对话框常用的回调函数 a)窗口创建时的消息和虚函数包括:WM_CREATE,WM_INITDIALOG,和PreSubcl ...
- 用MFC消息映射机制自定义消息
Windows系统中的程序大部分都是通过消息和事件驱动的.在windows下的应用程序主要工作是进行消息的循环处理,通过循环等待消息的到来和事件的发生,然后对不同的消息和事件运行相关的代码,完成相应的 ...
- VC++/MFC消息映射机制(1):MFC消息映射原理
VC++/MFC消息映射机制(1):模仿MFC的消息映射原理 本文为原创文章,转载请注明出处,或注明转载自"黄邦勇帅(原名:黄勇) <C++语法详解>网盘地址:https://p ...
- 【转】MFC消息映射详解(整理转载)
消息:主要指由用户操作而向应用程序发出的信息,也包括操作系统内部产生的消息.例如,单击鼠标左按钮,windows将产WM_LBUTTONDOWN消息,而释放鼠标左按钮将产生WM_LBUTTONUP消息 ...
- 转MFC消息映射梳理
http://blog.csdn.net/phunxm/article/details/5640766 一.CWnd消息处理 一切从窗口(HWND)的创建说起,在MFC中,CWnd::CreateEx ...
- 【MFC】MFC消息映射(二)
00. 目录 文章目录 00. 目录 01. 概述 02. 消息映射宏 2.1 BEGIN_MESSAGE_MAP 2.2 DECLARE_MESSAGE_MAP 2.3 END_MESSAGE_MA ...
- MFc消息映射机制理解
何谓消息.消息处理函数.消息映射? 消息简单的说就是指通过输入设备向程序发出指令要执行某个操作.具体的某个操作是你的一系列代码.称为消息处理函数.在SDK中消息其实非常容易理解,当窗口建立后便会有一个 ...
最新文章
- python输入输出流详解_输入输出流的概念
- centos7安装mysql缺失依赖_CentOS7安装mysql5.7不成功,解决依赖包之后还是无法安装成功...
- vs与qt版本对应关系
- 工业用微型计算机(15)-指令系统(10)
- ASP.NET的错误处理机制之一(概念)
- JAVA面向对象OOP、类、属性、方法、样例代码
- mediacodec surfaceview解码失败
- Linu下建立svn版本库
- 月球探测器中的计算机技术,月球探测器自主视觉导航技术的研究
- 深度学习算法原理——神经网络的基本原理
- cruzer php sandisk 闪迪u盘量产工具_SanDisk Cruzer Micro(闪迪U盘量产助手)V1.1 最新版
- Win10 远程桌面登陆闪退问题处理
- oracle 同义词循环连,Oracle出现ORA-01775: 同义词的循环链问题
- android进入recovery模式,Android关机重启至recovery安卓进入Recovery模式模式
- 测试每秒点击速度的软件,测试点击速度
- R语言Error in model.frame.default(formula = y ~ ., data = exam.data, drop.unused.levels = TRUE) :
- Latex 大括号错位显示
- 小精灵家庭理财 v3.01 是什么
- 多台网络分析仪自动化测试软件NSAT-1000
- dnn解读_论文学习+解读1--受优化算法启发的DNN网络设计
热门文章
- 在c#后台设置LinkButton控件的属性
- SpringBoot(四) Web开发(2)Restful风格的CRUD操作
- 【畅购商城】校验用户名、手机号以及前置技术Redis和阿里大鱼短信验证码
- 网络初识 - JavaEE初级 - 细节狂魔
- ROS察微【51】:如何将里程计和 IMU 与 robots_localization 融合
- 网口转串口线(console线)制作
- 保持数字小键盘一直开着的方法
- php pop3 gmail,Gmail pop3 smtp 设置
- 华为OD机试 - 射击比赛(JavaScript) | 机试题+算法思路+考点+代码解析 【2023】
- USB状态错误及其原因(错误码)
【推荐】50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
融云,免费为你的App加入IM功能——让你的App“聊”起来!!
· 携程回应退票扣费80%:购买套餐须遵循规则
· LG众高管涉嫌损坏三星产品案正式被检察院起诉
· 李开复离开的17个月 创新工场错过了什么?
· 百度战略投资医护网 探索医疗O2O新模式
· 神秘黑客组织从百家银行盗窃3亿美元
» 更多新闻...
· Web API设计方法论
· Bitmap的秘密
· 我该如何向非技术人解释SQL注入?
· 使用2-3法则设计分布式数据访问层
» 更多知识库文章...