首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更改窗口的WndProc

更改窗口的WndProc
EN

Stack Overflow用户
提问于 2020-07-28 21:43:36
回答 1查看 520关注 0票数 0

我试图更改standart WndProc函数。我有这样的代码:

代码语言:javascript
复制
HWND btn = CreateWindowEx(WS_EX_TRANSPARENT | WS_EX_CLIENTEDGE, L"BUTTON", L"Window title", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON
    , 50, 50, 50, 50, (HWND)XApplicationMainWindow->window->_wnd, (HMENU)123,
    (HINSTANCE)GetWindowLongPtr(XApplicationMainWindow->window->_wnd, GWLP_HINSTANCE), NULL);

SetWindowLongPtrW(btn, GWLP_WNDPROC, (LONG_PTR)SubclassWindowProc);

我可以使用L"BUTTON"类名,但是当我更改WndProc函数时,我会遇到问题。

在这张图片上,你可以看到空白方块和普通按钮。如果我尝试创建新的WNDCLASS or WNDCLASSEX,我将一无所有.为什么?

如果我使用WndProc类名,如何更改standart L"BUTTON"函数?

这是我的第二个WndProc

代码语言:javascript
复制
LRESULT CALLBACK SubclassWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
    case WM_CREATE:
        break;
    case WM_COMMAND:

        //Event click
        switch (LOWORD(wParam))
        {
        case 123:
            OutputDebugStringA("Subclass click2");
            break;
        default:
            break;
        }

        break;
    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-28 23:55:19

DefWindowProc()SubclassWindowProc()调用的错误窗口过程。

您需要调用要替换的前一个窗口过程--处理按钮所有默认行为的窗口过程(比如绘制按钮,使其看起来像按钮,并响应用户输入,如按钮,等等)。SetWindowLongPtr()向您返回指向该过程的指针,但您目前正在忽略它。

有关更多详细信息,请参见MSDN上的子类控件

试一试:

代码语言:javascript
复制
WNDPROC btnWndProc;

LRESULT CALLBACK SubclassWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
        case WM_COMMAND:
            //Event click
            switch (LOWORD(wParam))
            {
                case 123:
                    OutputDebugStringA("Subclass click2");
                    break;
            }

            break;
    }

    return CallWindowProc(hWnd, btnWndProc, uMsg, wParam, lParam);
}

...

HWND btn = CreateWindowEx(...);

btnWndProc = (WNDPROC) SetWindowLongPtrW(btn, GWLP_WNDPROC, (LONG_PTR)SubclassWindowProc);

或者,使用SetWindowSubclass(),即SetWindowsLongPtr(),例如:

代码语言:javascript
复制
LRESULT CALLBACK SubclassWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
    switch (uMsg) {
        case WM_NCDESTROY:
            RemoveWindowSubclass(hWnd, SubclassWindowProc, uIdSubclass);
            break;

        case WM_COMMAND:
            //Event click
            switch (LOWORD(wParam))
            {
                case 123:
                    OutputDebugStringA("Subclass click2");
                    break;
            }

            break;
    }

    return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}

...

HWND btn = CreateWindowEx(...);

SetWindowSubclass(btn, SubclassWindowProc, 1, 0);

现在,尽管如此,您的子类将永远不会调用OutputDebugStringA(),因为它将永远不会接收您所期望的WM_COMMAND消息。单击按钮时,不会将WM_COMMAND消息发送到按钮本身。该按钮将一个WM_COMMAND消息发布到该按钮的父窗口(在本例中为XApplicationMainWindow->window->_wnd)。因此,您需要在父窗口的窗口过程中处理WM_COMMAND消息,而不是在按钮本身的窗口过程中处理。

否则,如果仍然希望子类按钮本身,则必须处理按钮接收的WM_LBUTTON(DOWN|UP)WM_KEY(DOWN|UP)/WM_CHAR消息,然后将其转换为其父窗口的WM_COMMAND消息。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63143237

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档