SetWindowLongPtr似乎不起作用

时间:2013-01-01 13:05:40

标签: c winapi subclass setwindowlong

我试图将另一个窗口子类化(在另一个进程中),所以我注入了一个调用SetWindowLongPtr的dll,但它失败了,GetLastError返回5.

BOOL APIENTRY DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
{
    switch (dwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            HWND hwnd = GetHwndProc();

            if (!(orgWndProc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)SubclassProc)))
            {
                char buf[40];
                sprintf(buf, "Error code: %d", GetLastError());
                MessageBox(hwnd, buf, "Error", MB_OK);
            }   
            break;
        }
    }
    return TRUE;
}

编辑:它是正确的PID。

编辑2:我收到了错误的HWND ,但现在已修复(编辑了代码) 我不再收到错误5(来自GetLastError)

    HWND GetHwndProc()
{
    HWND hwnd = GetTopWindow(NULL);
    DWORD currentPID = GetCurrentProcessId();
    do
    {
        char title[256];
        if ((GetWindowText(hwnd, title, 256) > 0) && (IsWindowVisible(hwnd)))
        {
            DWORD procId;
            GetWindowThreadProcessId(hwnd, &procId);

            if (procId == currentPID)   
            {
                MessageBox(hwnd, title, "", MB_OK);
                return hwnd;
            }
        }

        hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);
    } while (hwnd);
}

WNDPROC orgWndProc;
LRESULT APIENTRY SubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        case WM_LBUTTONDOWN:
            MessageBox(0, "Subclass", "", 0);
            return TRUE;

        default:
            return CallWindowProc(orgWndProc, hwnd, msg, wParam, lParam);
    }
}

感谢您阅读!

1 个答案:

答案 0 :(得分:1)

您需要从创建窗口的线程中调用SetWindowSubclass,在该线程中运行与之关联的消息队列。来自SetWindowSubclass reference

  

警告您不能使用子类化辅助函数来跨线程子窗口。

必须从创建窗口的进程中调用SetWindowLongPtr。来自SetWindowLongPtr reference

  

Windows XP / 2000 :如果hWnd参数指定的窗口不属于与调用线程相同的进程,则SetWindowLongPtr函数将失败。

还有用户界面权限隔离,它进一步限制了访问。