6

によって作成された子ウィンドウに WndProc を指定できるかどうかを知りたいですCreateWindowEx

ウィンドウ クラス、メイン ウィンドウ、ウィンドウ プロシージャ、およびメッセージ ループを既に作成しています。コードは機能するので、質問を明確にするためにそれを除外することにしました。

これまでのところ、これは私の Window Proc です。

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        // Creation of the Win32 Window
        case WM_CREATE:
            // Add an Edit Field
            CreateWindowEx(
                WS_EX_CLIENTEDGE,
                "EDIT",
                "",
                WS_CHILD | WS_VISIBLE,
                5, 5, 200, 24,
                hwnd,
                (HMENU)100,
                g_Instance, // Comming from WinMain
                NULL
            );
            return DefWindowProc(hwnd, uMsg, lParam, wParam);
        case WM_KEYDOWN:
            // Track key presses on the edit field
            std::cout << "The key with the code " << wParam << " was pressed." << std::endl;
            return 0;
        case WM_PAINT:
            // Some painting code...
            return DefWindowProc(hwnd, uMsg, lParam, wParam);
        default:
            return DefWindowProc(hwnd, uMsg, lParam, wParam);
    }
}

作成した子編集フィールドでキーを押すと WM_KEYDOWN メッセージがスローされると思っていましたが、そうではありません。キーはウィンドウの編集フィールドに追加されるだけですが、WM_KEYDOWN メッセージは発生しません。

作成された編集ウィンドウは私の WndProc を使用していないようです。どうすればそれを変更できますか?

4

2 に答える 2

7

ユーザーがエディットコントロール内で入力している場合、(ウィンドウではなく) フォーカスがあることを意味するため、メッセージは表示されWndProcないため、メッセージはエディット コントロールウィンドウ proc に送信されます。ただし、編集コントロール ウィンドウ プロシージャは、 (彼の親ウィンドウプロシージャ)に通知を送信します。WM_KEYDOWNWndProc

したがって、子エディット コントロールの内容を変更するユーザーにのみ対応する場合は、別のウィンドウ プロシージャは必要ありません。あなたの現在は、メッセージを介して通知コードをWndProc受け取ります。EN_CHANGEWM_COMMAND

https://msdn.microsoft.com/en-us/library/windows/desktop/bb761676(v=vs.85).aspxを参照してください。


本当にメッセージをキャッチしたい場合はWM_KEYDOWN、次のようにエディット コントロールをサブクラス化する必要があります。

OldWndProc = (WNDPROC)SetWindowLongPtr (hButton, GWLP_WNDPROC, (LONG_PTR)NewWndProc);

また、メッセージ (および処理したいその他のメッセージ) を処理する新しい Windows プロシージャ ( NewWndProc)を定義する必要があります。また、エディット コントロールが通常の処理を実行するのを防ぎたい場合を除き、標準ので呼び出すのと同じようWM_KEYDOWNに呼び出す必要があります。OldWndProcDefWndProcWndProc

サブクラス化の詳細については、https://msdn.microsoft.com/en-us/library/windows/desktop/bb773183 (v=vs.85).aspx を参照してください。

編集

ここでOPコメントに応答します。

ウィンドウがダイアログ ボックスの場合、次のように入力キーが通知されるはずですWndProc

 case WM_COMMAND:

      if(wParam=IDOFDEFBUTTON || IDOK) ...

https://support2.microsoft.com/Default.aspx?scid=kb;en-us;Q102589を参照してください。

正直なところ、ダイアログ ボックスが実際に何であるかを理解するのに時間をかけたことはありません。しかし、私の記憶が正しければ、メッセージ ポンプで IsDialogMessage を呼び出すことで、これらの特別な通知をウィンドウに表示させることができます。

if(!IsDialogMessage(hWnd,&msg)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
 }

に関する興味深い情報については、 http://blogs.msdn.com/b/oldnewthing/archive/2012/04/16/10293933.aspxIsDialogMessageを参照してください。

これで十分な制御ができない場合は、編集コントロールをサブクラス化する必要があります。

于 2015-06-05T13:58:20.120 に答える
2

CreateWindowsEx を呼び出すと、独自の Window プロシージャを持つ "EDIT" wnd クラスで新しいウィンドウが作成されます。新しい WndProc が必要で、それを SetClassLong 関数を介して新しく作成されたウィンドウ (CreateWindowEx によってハンドルが返される) に設定します。

于 2015-06-05T13:52:07.580 に答える