0

サブクラス化しようとする EDIT コントロールがあり、サブクラス化すると、ウィンドウ全体が空になります。

// Global variables
HINSTANCE hInst;
WNDPROC oldEditWndProc;
INT_PTR CALLBACK EditWndProc(HWND, UINT, WPARAM, LPARAM);

// Messages handler of the parent window
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    HDC hDC;
    HWND myedit;

    switch (message)
    {
    case WM_CREATE:
        // Create the EDIT control
        myedit= CreateWindowEx(
                               WS_EX_CLIENTEDGE|WS_EX_CONTROLPARENT, 
                               L"EDIT", 
                               L"",
                               WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_LEFT, 
                               20, 120, 
                               160, 20, 
                               hWnd, 
                               NULL, 
                               hInst, 
                               NULL
                              );
        oldEditWndProc = (WNDPROC)GetWindowLongPtr (myedit, GWLP_WNDPROC);
        // This is the line where problems begin
        SetWindowLongPtr (myedit, GWLP_WNDPROC, (LONG_PTR)EditWndProc);
        break;
    case WM_PAINT:
        hDC = BeginPaint(hWnd, &ps);
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// EDIT control own handler
INT_PTR CALLBACK EditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
        case WM_GETDLGCODE:
            return DLGC_WANTTAB;
            break;
    }
    return (INT_PTR)FALSE;
}

呼び出し時にウィンドウ全体が空である理由がわかりませんSetWindowLongPtr

4

2 に答える 2

3

「空」とは、画面に表示されていないということですか?

はいの場合、それは、ウィンドウをサブクラス化すると、すべてのメッセージが新しい MessageProc に送信され、defaultProc 関数 (WM_PAINT やボタン クリックなど) で適切に表示するためのすべての機能がないためです。

したがって、次のようなものが必要です。

//store the old window proc somewhere
WNDPROC oldWindowProc = (WNDPROC)SetWindowLong(subWindowHandle, GWL_WNDPROC, long(NewMessageProc));

//and in the message proc
switch(uMsg)
{
    //your "case"s here
    default:
    {
        CallWindowProc(oldWindowProc, windowHandle, uMsg, wParam, lParam);
    }
}

これにより、適切な WM_PAINT およびその他のメッセージが、描画とクリックおよびその他の関数 (サブクラス化されたウィンドウの DefWindowProc()) を担当する messageProc に呼び出されます。

または、サブクラス化されたすべてのウィンドウの NewMessageProc に WM_PAINT を実装することもできますが、それらの DefWindowProc を呼び出すことなく、受け取る可能性のあるすべてのイベント (mousemove、マウス クリック、ボタン クリック、すべて) に対して実行する必要があるため、元のウィンドウを使用します。 DefWindowProc の方が簡単です。

于 2013-03-23T21:05:30.897 に答える
1

編集ウィンドウ プロシージャで、適切なデフォルト メッセージ処理を呼び出す必要があります。

元のウィンドウ プロシージャなど。

コードの抽象化レベルでこれを行う最も簡単な方法は、代わりSetWindowSubclassにサブクラス化を行うために使用することです

于 2013-03-23T21:05:50.050 に答える