c++ - 在 C++ WINAPI 中对 EDIT 控件进行子类化时窗口为空

标签 c++ winapi controls edit subclassing

我有一个 EDIT 控件,我尝试对其进行子类化,当我这样做时整个窗口是空的:

// Global variables
HINSTANCE hInst;
WNDPROC oldEditWndProc;
INT_PTR CALLBACK EditWndProc(HWND, UINT, WPARAM, LPARAM);

// Messages handler of the parent window
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    HDC hDC;
    HWND myedit;

    switch (message)
    {
    case WM_CREATE:
        // Create the EDIT control
        myedit= CreateWindowEx(
                               WS_EX_CLIENTEDGE|WS_EX_CONTROLPARENT, 
                               L"EDIT", 
                               L"",
                               WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_LEFT, 
                               20, 120, 
                               160, 20, 
                               hWnd, 
                               NULL, 
                               hInst, 
                               NULL
                              );
        oldEditWndProc = (WNDPROC)GetWindowLongPtr (myedit, GWLP_WNDPROC);
        // This is the line where problems begin
        SetWindowLongPtr (myedit, GWLP_WNDPROC, (LONG_PTR)EditWndProc);
        break;
    case WM_PAINT:
        hDC = BeginPaint(hWnd, &ps);
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// EDIT control own handler
INT_PTR CALLBACK EditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
        case WM_GETDLGCODE:
            return DLGC_WANTTAB;
            break;
    }
    return (INT_PTR)FALSE;
}

我只是想不通为什么在调用 SetWindowLongPtr 时整个窗口都是空的

最佳答案

“空”是指它没有显示在屏幕上吗?

如果是,那是因为当您子类化一个 Window 时,它的所有消息都将被发送到新的 MessageProc,它不具备在 defaultProc 函数中正确显示它的所有函数(例如 WM_PAINT,甚至是按钮点击)。

所以你需要这样的东西:

//store the old window proc somewhere
WNDPROC oldWindowProc = (WNDPROC)SetWindowLong(subWindowHandle, GWL_WNDPROC, long(NewMessageProc));

//and in the message proc
switch(uMsg)
{
    //your "case"s here
    default:
    {
        CallWindowProc(oldWindowProc, windowHandle, uMsg, wParam, lParam);
    }
}

这会将适当的 WM_PAINT 和其他消息调用到负责绘制和单击等功能的 messageProc(子类窗口的 DefWindowProc())。

或者,您也可以在您的所有子类窗口的 NewMessageProc 中实现 WM_PAINT,但无需调用它们的 DefWindowProc,您需要为它们可能接收到的每个事件(mousemove、鼠标点击、按钮点击,一切),所以使用他们原来的 DefWindowProc 更容易。

关于c++ - 在 C++ WINAPI 中对 EDIT 控件进行子类化时窗口为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15591916/

相关文章:

c++ - 麦片序列化错误

c++ - 在 VS 中编译程序,无需任何外部运行时 dll

c++ - std::vector 混合数据类型

c++ - 为什么这个 C++ 代码可以编译?它有什么作用?

objective-c - 如何确定哪个 UIControlEvents 类型导致了 UIEvent?

c++ - 使用 system() 启动另一个可执行文件时程序停止

.net - .Net 中的异步文件 IO

c - 相对于父窗口放置窗口

delphi - 自定义 TControl 在剪切和粘贴之前不会在设计时绘制

c++ - WinAPI C++ - 子类控件是否仍向其父级发送通知?