Подклассификация элемента управления редактирования (в полном окне, НЕ диалог)

Я пытался понять это целую вечность, и я абсолютно в замешательстве! Я пытаюсь создать подкласс для элемента управления редактирования, чтобы я мог захватить при нажатии клавиши ввода.

Я видел много других постов о подклассах с фрагментами кода, которые можно добавить, чтобы сделать это, но я не могу реализовать это в своем приложении. Я прошу прощения, если я совершаю глупую ошибку, но я просто не могу понять это.

Я знаю, что этот код плохо написан и не имеет проверки ошибок, но я хотел опубликовать как можно меньше кода, чтобы сообщить о проблеме.

#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;
}

0

Решение

MsgProc() процедура окна для окна «Мое окно». Когда вы обрабатываете WM_CREATE сообщение, вы обрабатываете создание этого окна, до второго CreateWindow() был вызван для создания окна редактирования.

Хуже того, даже если вы правильно создали подкласс окна редактирования, вы удаляете подкласс сразу после его установки. Так 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;
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]