0

別のウィンドウを(別のプロセスで)サブクラス化しようとしたため、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);
    }
}

読んでくれてありがとう!

4

1 に答える 1

2

SetWindowSubclassウィンドウが作成されたスレッドから呼び出す必要があります。このスレッドで、ウィンドウに関連付けられたメッセージキューが実行されます。SetWindowSubclass 参考から:

警告 サブクラス化ヘルパー関数を使用して、スレッド間でウィンドウをサブクラス化することはできません。

次にSetWindowLongPtr、ウィンドウが作成されたプロセスから呼び出す必要があります。SetWindowLongPtr 参考から:

Windows XP / 2000SetWindowLongPtrhWndパラメータで指定されたウィンドウが呼び出し元のスレッドと同じプロセスに属していない場合、関数は失敗します。

アクセスをさらに制限するユーザーインターフェイス特権の分離もあります。

于 2013-01-01T13:08:37.970 に答える