C++在运行时更改HWND窗口过程

Pro*_*oid 5 c++ winapi runtime hwnd wndproc

我正在一个IDE中创建一个hwnd及其各自的IDE WndProc LRESULT CALLBACK.我需要将其更改WndProc为自定义的.

我已经读过SetWindowLong会做的工作,但我找不到任何有效的例子.例如:

HWND hwnd; //My window

SetWindowLong(hwnd, GWL_WNDPROC, myNewWndProc);

第三个参数SetWindowLong是a Long作为函数名称的名称.如何从我的WndProc函数中引用Long

我的WndProc:

LRESULT CALLBACK WndProcedure(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){

msg_dev(toString(uMsg));

switch(uMsg){

    case WM_MOUSEMOVE:
        SetCursor(LoadCursor(NULL, IDC_HAND));
        break;

    case WM_LBUTTONDOWN:
        msg_dev("Button down!");
        break;

    default:
        DefWindowProc(hwnd, uMsg, wParam, lParam);
}

return 0;
};
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 10

你需要使用这样的东西:

WNDPROC prevWndProc;
...
prevWndProc = (WNDPROC) SetWindowLongPtr(hwnd, GWL_WNDPROC, (LONG_PTR)&myNewWndProc);
...    
LRESULT CALLBACK myNewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    msg_dev(toString(uMsg));

    switch(uMsg)
    {
        case WM_MOUSEMOVE:
            SetCursor(LoadCursor(NULL, IDC_HAND));
            break;

        case WM_LBUTTONDOWN:
            msg_dev("Button down!");
            break;
    }

    return CallWindowProc(prevWndProc, hwnd, uMsg, wParam, lParam);
}
Run Code Online (Sandbox Code Playgroud)

看到这篇文章:

子类化窗口时,它是您要调用原始窗口过程时必须调用的子类窗口的原始窗口过程

话虽如此,你应该使用SetWindowSubclass()而不是SetWindowLongPtr().看到这篇文章:

更安全的子类化

例如:

SetWindowSubclass(hwnd, &mySubClassProc, 1, 0);
...    
LRESULT CALLBACK mySubClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
    msg_dev(toString(uMsg));

    switch(uMsg)
    {
        case WM_MOUSEMOVE:
            SetCursor(LoadCursor(NULL, IDC_HAND));
            break;

        case WM_LBUTTONDOWN:
            msg_dev("Button down!");
            break;

        case WM_NCDESTROY:
            RemoveWindowSubclass(hWnd, &mySubClassProc, 1);
            break;
    }

    return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
Run Code Online (Sandbox Code Playgroud)


use*_*392 0

MSDN 文档SetWindowLong()指出GWL_WNDPROC

为窗口过程设置一个新地址。

这意味着您的第三个参数应该是指向函数的指针。因此,您的SetWindowLong()调用应如下所示:

SetWindowLong(hwnd, GWL_WNDPROC, (LONG_PTR)&myNewWndProc);
Run Code Online (Sandbox Code Playgroud)

另请注意备注部分指出:

应用程序必须通过调用 CallWindowProc 将新窗口过程未处理的任何消息传递给前一个窗口过程。