场景
- 有时候我们需要单独对某个窗口消息进行拦截,比如CEdit响应回车, 这时候就需要拦截窗口处理过程了. 当然MFC的界面可以重载:
BOOL CXXXDlg::PreTranslateMessage(MSG* pMsg){
但是WTL的CEdit并不支持这种方式,WTL如果想在 PreTranslateMessage 里拦截消息,必须继承 CMessageFilter 后还要把这个控件注册到消息循环里才行,也就是必须写子类 或者从父窗口拦截这个CEdit的消息.
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->AddMessageFilter(this);
方案
- 通过使用 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);
参考:
时间: 2024-12-29 07:28:24