0

私は何年もの間これを理解しようとしてきましたが、完全に困惑しています! Enterキーが押されたときにキャプチャできるように、編集コントロールをサブクラス化しようとしています。

それを行うために追加するコードのスニペットを使用したサブクラス化に関する他の多くの投稿を見てきましたが、それをアプリケーションに実装できないようです。愚かな間違いを犯していたら申し訳ありませんが、これを理解することはできません。

このコードの書き方が悪く、エラー チェックが行われていないことは承知していますが、問題を伝えるためにできるだけ少ないコードを投稿したかったのです。

#include <Windows.h>
#include <wchar.h>

HWND editHWND;
WNDPROC wpOrigEditProc;

LRESULT APIENTRY EditSubclassProc(HWND hwnd,UINT uMsg,WPARAM wParam, LPARAM lParam)
{
    if (uMsg == WM_CHAR)
    {
        //do my stuff
    }
    return CallWindowProc(wpOrigEditProc, hwnd, uMsg, wParam, lParam);
}


LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
    case WM_CREATE:

        wpOrigEditProc = (WNDPROC) SetWindowLong(editHWND,GWL_WNDPROC, (LONG) EditSubclassProc);
        SetWindowLong(editHWND, GWL_WNDPROC,(LONG) wpOrigEditProc);
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        return 0;
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}

int WINAPI wWinMain( HINSTANCE hInst,HINSTANCE,LPWSTR,INT )
{
    WNDCLASSEX wc = { sizeof( WNDCLASSEX ),CS_CLASSDC,MsgProc,0,0,
                      GetModuleHandle( NULL ),NULL,NULL,NULL,NULL,
                      L"My Window",NULL };
    RegisterClassEx( &wc );

    HWND hWnd = CreateWindowW( L"My Window",L"test application",
                              WS_OVERLAPPEDWINDOW,100,100,800,600,
                              NULL,NULL,wc.hInstance,NULL );

    editHWND = CreateWindow( L"edit",L"hi there",WS_VISIBLE | WS_CHILD | WS_BORDER,100,100,300,50,hWnd,(HMENU)17,0,0);

    ShowWindow( hWnd,SW_SHOWDEFAULT );

    MSG msg;
    ZeroMemory( &msg,sizeof( msg ) );
    while( msg.message != WM_QUIT )
    {
        if( PeekMessage( &msg,NULL,0,0,PM_REMOVE ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
    }

    UnregisterClass( L"My Window",wc.hInstance );
    return 0;
}
4

1 に答える 1

0

MsgProc()「マイウィンドウ」ウィンドウのウィンドウプロシージャです。WM_CREATEメッセージを処理しているときはCreateWindow()、編集ウィンドウを作成するために 2 番目のウィンドウが呼び出される前に、そのウィンドウの作成を処理しています。

さらに悪いことに、編集ウィンドウを正しくサブクラス化していたとしても、サブクラスを設定した直後にサブクラスを削除しています。したがってEditSubClassProc()、とにかく呼び出される変更はありません。

エディット ウィンドウの作成時にカスタム ウィンドウ プロシージャを定義していないため、メッセージを使用してエディット ウィンドウをサブクラス化することはできませんWM_CREATE(メッセージ フックを使用しない限り、この状況ではやり過ぎです)。SetWindowLong()が終了した後に呼び出すだけCreateWindow()です。

これを試して:

#include <Windows.h>
#include <wchar.h>

HWND editHWND = NULL;
WNDPROC wpOrigEditProc = NULL;

LRESULT APIENTRY EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg == WM_CHAR)
    {
        //do my stuff
    }
    return CallWindowProc(wpOrigEditProc, hwnd, uMsg, wParam, lParam);
}

LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
    case WM_CLOSE:
        DestroyWindow(hWnd);
        return 0;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        return 0;
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}

int WINAPI wWinMain( HINSTANCE hInst,HINSTANCE,LPWSTR,INT )
{
    WNDCLASSEX wc = { sizeof( WNDCLASSEX ),CS_CLASSDC,MsgProc,0,0,
                      GetModuleHandle( NULL ),NULL,NULL,NULL,NULL,
                      TEXT("My Window"),NULL };
    RegisterClassEx( &wc );

    HWND hWnd = CreateWindowW( TEXT("My Window"),TEXT("test application"),
                              WS_OVERLAPPEDWINDOW,100,100,800,600,
                              NULL,NULL,wc.hInstance,NULL );

    editHWND = CreateWindow( TEXT("edit"),TEXT("hi there"),WS_VISIBLE | WS_CHILD | WS_BORDER,100,100,300,50,hWnd,(HMENU)17,0,0);

    wpOrigEditProc = (WNDPROC) SetWindowLongPtr(editHWND, GWL_WNDPROC, (LONG_PTR) EditSubclassProc);

    ShowWindow( hWnd, SW_SHOWDEFAULT );

    MSG msg;
    while ( GetMessage( &msg,NULL,0,0 ) > 0 )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }

    UnregisterClass( TEXT("My Window"),wc.hInstance );
    return 0;
}

そうは言っても、ウィンドウをサブクラス化する別の方法は、SetWindowSubclass()代わりに使用することです。

#include <Windows.h>
#include <wchar.h>

HWND editHWND = NULL;

LRESULT CALLBACK EditSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
    if (uMsg == WM_CHAR)
    {
        //do my stuff
    }

    return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}

LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
    case WM_CLOSE:
        DestroyWindow(hWnd);
        return 0;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        return 0;
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}

int WINAPI wWinMain( HINSTANCE hInst,HINSTANCE,LPWSTR,INT )
{
    WNDCLASSEX wc = { sizeof( WNDCLASSEX ),CS_CLASSDC,MsgProc,0,0,
                      GetModuleHandle( NULL ),NULL,NULL,NULL,NULL,
                      TEXT("My Window"),NULL };
    RegisterClassEx( &wc );

    HWND hWnd = CreateWindowW( TEXT("My Window"),TEXT("test application"),
                              WS_OVERLAPPEDWINDOW,100,100,800,600,
                              NULL,NULL,wc.hInstance,NULL );

    editHWND = CreateWindow( TEXT("edit"),TEXT("hi there"),WS_VISIBLE | WS_CHILD | WS_BORDER,100,100,300,50,hWnd,(HMENU)17,0,0);

    SetWindowSubclass(editWND, EditSubclassProc, 0, 0);

    ShowWindow( hWnd, SW_SHOWDEFAULT );

    MSG msg;
    while ( GetMessage( &msg,NULL,0,0 ) > 0 )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }

    UnregisterClass( TEXT("My Window"),wc.hInstance );
    return 0;
}
于 2013-08-01T18:32:49.637 に答える