程序员人生 网站导航

[ATL/WTL]_[初级]_[Win32窗口自定义消息处理过程]

栏目:php教程时间:2016-07-20 08:16:24

场景

  1. 有时候我们需要单独对某个窗口消息进行拦截,比如CEdit响应回车, 这时候候就需要拦截窗口处理进程了. 固然MFC的界面可以重载:
BOOL CXXXDlg::PreTranslateMessage(MSG* pMsg){

但是WTL的CEdit其实不支持这类方式,WTL如果想在 PreTranslateMessage 里拦截消息,必须继承 CMessageFilter 后还要把这个控件注册到消息循环里才行,也就是必须写子类 或从父窗口拦截这个CEdit的消息.

CMessageLoop* pLoop = _Module.GetMessageLoop(); ATLASSERT(pLoop != NULL); pLoop->AddMessageFilter(this);

方案

  1. 通过使用 SetWindowLong来改变窗口处理进程来处理相干的消息,其他消息使用原进程继续处理.
static WNDPROC OldWndProc = NULL; static UiPreviewListDialog* gDialog = NULL; static LRESULT CALLBACK NewEditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) // 该对话框新的窗口回调函数,过滤WM_KEYDOWN消息。 { switch(message) { case WM_GETDLGCODE: { return (DLGC_WANTALLKEYS | CallWindowProc(OldWndProc, hWnd, message, wParam, lParam)); // 注意这里,否则没有办法捕获Tab/方向键 } case WM_KEYDOWN: { if(wParam == VK_RETURN) { std::cout << "Enter: " << std::endl; BOOL handle; gDialog->OnSearch(message,wParam,hWnd,handle); } } break; default: break; } return CallWindowProc(OldWndProc, hWnd, message, wParam, lParam); } gDialog = this; OldWndProc = (WNDPROC)edit_.SetWindowLong(GWL_WNDPROC, (LONG)NewEditProc);

参考:
CEdit中对回车键的响应
SetWindowLong function
CallWindowProc

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐