我一直在努力解决这个问题很长时间,我绝对难过!我正在尝试子类化编辑控件,以便在按下回车键时捕获。
我已经看到很多关于使用代码片段进行子类化的其他帖子来添加它,但我似乎无法将其实现到我的应用程序中。如果我犯了一个愚蠢的错误,我道歉,但我根本无法解决这个问题。
我知道这段代码编写得很糟糕且没有错误检查,但我希望发布尽可能少的代码来传达问题。
#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 :(得分: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;
}