【发布时间】:2013-08-01 08:24:23
【问题描述】:
多年来我一直在尝试解决这个问题,但我完全被难住了!我正在尝试对编辑控件进行子类化,以便在按下回车键时进行捕获。
我看过很多其他关于使用 sn-ps 代码进行子类化的帖子,但我似乎无法在我的应用程序中实现它。如果我犯了一个愚蠢的错误,我深表歉意,但我根本无法弄清楚。
我知道这段代码写得不好并且没有错误检查,但我想发布尽可能少的代码来表达问题。
#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;
}
【问题讨论】:
-
editHWND是在哪里创建的?当你的窗口得到WM_CREATE时它真的存在吗? -
就在创建主窗口 hWnd 的位置下方。我想是的。
-
WM_CREATE在对CreateWindowEx的调用返回之前被调用,所以我想你会发现,当你试图对窗口进行子类化时,它实际上还没有被创建. -
您承认您没有进行任何错误检查,但是当您试图找出某些原因无法正常工作时,检查错误通常可以为您提供线索错了。
-
@jamesdlin 好点,我可能应该包括错误检查,但我不希望代码看起来过于复杂或太长。 JonathanPotter 非常感谢你,它现在工作正常,我没有意识到这一点。另一个快速的问题,当按下返回键时,我使用 WM_SETTEXT 清除缓冲区,但是 Windows 仍然处理返回键并且我在机器上收到哔哔声,因为它无法创建新行(如果它设置为 ES_MULTILINE 一个新的行已创建。)如何停止窗口处理返回键,使输入保持空白?谢谢
标签: c++ winapi controls subclassing