1

要件は、自分の情報を別のアプリケーションのウィンドウの横に描画することです。Z オーダーなどを処理するには、WH_GETMESSAGE をフックして WM_PAINT を描画するのが良さそうです。

ただし、一部の WM_PAINT は関心のあるウィンドウ領域を対象としていますが、他の WM_PAINT はコンテキスト メニューやボタンなど、まったく異なるものを対象としています。

例 メモ帳は、メモ帳画面に「Hello」と書き込むオーバーレイでフックされます。これはうまくいきます。ただし、メモ帳を右クリックすると、コンテキスト メニューに Hello が表示されます。基本的にコンテキスト メニューは破棄されます。

コンテキスト メニューである WM_PAINT を特定するエレガントな方法はありますか?

LRESULT CALLBACK overlayHook(int code, WPARAM wParam, LPARAM lParam) {
    //Try and be the LAST responder to WM_PAINT messages;
    LRESULT retCode = CallNextHookEx(hhk, code, wParam, lParam);

    //Per GetMsgProc documentation, don't do anything fancy
    if(code < 0) {
        return retCode;
    }

    //Assumes that target application only draws when WM_PAINT message is
    //removed from input queue.
    if(wParam == PM_NOREMOVE) {
        return retCode;
    }

    MSG* message = (MSG*)lParam;
    if(message->message != WM_PAINT) {
        //Ignore everything that isn't a paint request
        return retCode;
    }

    PAINTSTRUCT psPaint;    
    BeginPaint(message->hwnd, &psPaint);
    HDC hdc = psPaint.hdc;
    RECT r = psPaint.rcPaint;           
    TextOut(hdc, 10, 10, "Hello", 4);
    EndPaint(message->hwnd, &psPaint);
    return retCode;
}

描画更新領域をテストするだけでは十分ではありません。なぜなら、コンテキスト メニューはどこにでもあり、関心のある領域を含んでいる可能性があるからです。

4

1 に答える 1

0

これを行うエレガントな方法はわかりませんが、GetWindowLong() を使用してウィンドウのスタイルを取得するか、GetClassName() を使用してそのクラス名を取得し、それらの値に基づいてフィルタリングを決定することができます。

于 2009-06-03T20:28:40.800 に答える