子类化后,编辑控件无法获得焦点或设置文本

时间:2015-09-17 04:06:06

标签: c++ winapi subclassing editbox edit-control

我创建了一个编辑框,它工作得很好但是在我为它添加了一个自定义WndProc之后,文本“我的编辑”不可见,并且在单击时不会获得焦点。

HWND handle=CreateWindowExW(0,L"Edit",L"my edit",WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_CENTER | ES_MULTILINE | ES_AUTOVSCROLL,
                         0,0,200,200,window.handle,0,GetModuleHandle(NULL),0);

直到这里工作得很好 设置此窗口过程后,编辑控件不再按预期工作

SetWindowLongPtr(handle,GWLP_WNDPROC,(LRESULT)staticWndProc); 
LRESULT CALLBACK staticWndProc(HWND handle, UINT uMsg, WPARAM wParam, LPARAM lParam){
    switch (uMsg){
        case WM_LBUTTONDOWN:
            std::wcout << handle << L" click\n"; //click event works
            break;
        default:
            return DefWindowProcW(handle,uMsg,wParam,lParam);
    }
    return 0;  
}

我是否必须手动处理某些事件或更改我的构造样式标志?

1 个答案:

答案 0 :(得分:4)

子分类涉及拦截窗口的消息,可能会处理其中一些消息,并将那些您不能处理的消息传递给原始窗口过程

你没有这样做 - 你将所有你无法处理的事情传递给DefWindowProcDefWindowProc没有编辑控件的任何特殊行为(或者实际上对于任何类型的控件)。因此,您已经有效地将编辑控件转换为通用窗口。

这些天不鼓励使用SetWindowLongPtr对窗口进行子类化,但是如果你确实使用了这种方法,那么调用SetWindowLongPtr的返回值会为你提供旧的窗口过程,而你#&# 39;重新打算使用CallWndProc函数代替DefWindowProc来调用它。

然而,现代的窗口子类化方法是使用SetWindowSubclass函数,它处理为您调用原始proc - 您需要做的就是调用DefSubclassProc函数,如下所示:

LRESULT CALLBACK staticWndProc(HWND handle, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR, DWORD_PTR){
    switch (uMsg){
        case WM_LBUTTONDOWN:
            std::wcout << handle << L" click\n"; //click event works
            break;
        case WM_NCDESTROY:
            RemoveWindowSubclass(handle, staticWndProc, 0);
            // fall through
        default:
            return DefSubclassProc(handle,uMsg,wParam,lParam);
    }
    return 0;  
}

SetWindowSubclass(handle, staticWndProc, 0, 0);

请注意,上面显示的子类函数会在收到WM_NCDESTROY时自行删除。