繁体   English   中英

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

[英]Edit control cannot get focus or set text after subclassing

我已经创建了一个编辑框,并且可以正常工作,但是在为其添加了自定义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;  
}

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

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

您没有这样做-您将没有处理的所有内容传递给DefWindowProc DefWindowProc对于编辑控件(或实际上对于任何类型的控件)没有任何专门的行为。 因此,您已经有效地将编辑控件变成了通用窗口。

SetWindowLongPtr ,不鼓励使用SetWindowLongPtr对窗口进行子类化,但是,如果您确实使用该方法,则对SetWindowLongPtr的调用返回值将为您提供旧的窗口过程,并且您打算使用CallWndProc函数而不是DefWindowProc称它为。

但是,现代的子窗口化方法是使用SetWindowSubclass函数,该函数可以为您处理原始DefSubclassProc您需要做的就是调用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时,上面显示的子类函数将自行删除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM