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

Posted infoworld

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ATL/WTL]_[初级]_[Win32窗口自定义消息处理过程]相关的知识,希望对你有一定的参考价值。

场景

  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

以上是关于[ATL/WTL]_[初级]_[Win32窗口自定义消息处理过程]的主要内容,如果未能解决你的问题,请参考以下文章

[ATL/WTL]_[初级]_[解决自定义按钮禁用时没有绘制自定义样式-显示黑色矩形框的问题]

[ATL/WTL]_[初级]_[解决自定义按钮禁用时没有绘制自定义样式-显示黑色矩形框的问题]

[ATL/WTL]_[初级]_[解决自定义按钮禁用时没有绘制自定义样式-显示黑色矩形框的问题]

[ATL/WTL]_[0基础]_[CBitmap复制图片-截取图片-平铺图片]

[ATL/WTL]_[中级]_[保存CBitmap到文件-保存屏幕内容到文件]

[WTL/ATL]_[初级]_[如何设置CEdit的文本框背景色和文字颜色]