我有三个控件位于父窗口的顶部。一个接受用户输入,而另一个显示以前的输入。第三个是将文本从输入编辑控件附加到输出控件的按钮。然而,由于这样做很麻烦,我想为"enter"键添加一个句柄来执行此操作。目前,我已经子类化了输入编辑控件。然而,无论我实现哪种开关语句配置,我都无法从输入控件中解释'WM_KeyDown'消息。但是,如果父控件处于焦点中,则从父控件发送。它不会从编辑控件发送,即使在焦点中也是如此。我已经找到了几个解决办法,但到目前为止都不起作用。
任何帮助都将非常感激!
Win32 c++, Visual Studio 2012
#include <Windows.h>
#include <string.h>
#include <tchar.h>
#include <stdlib.h>
#include <Commctrl.h>
#include "resource.h"
#include "Processing.h"
static TCHAR WinClass[]=_T("SAPA");
static TCHAR WinTitle[]=_T("SAPA");
HWND InText, OutText, Send;
LPWSTR string;
LPTSTR buff = new TCHAR [1024];
LPTSTR Tbuff = new TCHAR [1024];
HINSTANCE hInst;
syscore sysCore;
WNDPROC DefProc;
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
DWORD dwRefData;
UINT uIdSubClass;
int WINAPI WinMain(HINSTANCE hIn, HINSTANCE hpIn, LPSTR CmdLine, int CmdShow)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hIn;
wcex.hIcon = LoadIcon(hIn,MAKEINTRESOURCE(APP_ICO));
wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = L"IDC_WINMENU";
wcex.lpszClassName = WinClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(APP_ICO));
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL,_T("RegClassEx Failure"),_T("ERROR"),NULL);
return 1;
}
hInst=hIn;
HWND hwnd=CreateWindow(WinClass, WinTitle,WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 800,650,NULL,NULL, hIn,NULL);
if (!hwnd)
{
MessageBox(NULL,_T("CreateWindow Failuer"),_T("ERROR"),NULL);
return 1;
}
ShowWindow(hwnd, CmdShow);
UpdateWindow(hwnd);
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK InEditControlProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
// if (LOWORD(wp)==IDM_IN)
switch(msg) {
case WM_COMMAND:
if (LOWORD(wp)==IDM_IN)
if (HIWORD(wp)==WM_KEYDOWN)
if (HIWORD(lp)==VK_LCONTROL)
PostQuitMessage(0);
break;
case WM_KEYDOWN: {
switch (wp) {
case VK_RETURN: {
PostQuitMessage(0);
//simulate a button press, see below
// return 0;//if the procedure responds the action, finish the control procedure
break;
}
break;
}
}
break;
//return CallWindowProc(WndProc,hwnd,msg,wp,lp);//WndProc(hwnd,msg,wp,lp);
default:
return CallWindowProc(WndProc,hwnd,msg,wp,lp);//WndProc(hwnd,msg,wp,lp);
//return WndProc(hwnd,msg,wp,lp);
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
int len=0;
//LPCWSTR buffer=L"";
switch (msg)
{
case WM_CREATE:
OutText=CreateWindow(L"edit", L"",ES_READONLY|ES_MULTILINE|WS_CHILD|WS_VISIBLE|WS_BORDER|ES_AUTOVSCROLL, 0, 0, 800,550,hwnd,(HMENU)IDM_OUT, NULL,NULL);
InText=CreateWindow(L"edit", L"",WS_CHILD|WS_VISIBLE|WS_BORDER, 0, 550, 720,50,hwnd,(HMENU)IDM_IN, NULL,NULL);
Send=CreateWindow(L"button", L"SEND",WS_CHILD|WS_VISIBLE|WS_BORDER, 720, 550, 80,25,hwnd,(HMENU)MSG_SEND, NULL,NULL);
CreateWindow(L"button", L"CLEAR",WS_CHILD|WS_VISIBLE|WS_BORDER, 720, 575, 80,25,hwnd,(HMENU)IDM_CLEAR, NULL,NULL);
//DefProc = (WNDPROC)GetWindowLong(hwnd,GWL_WNDPROC);
//SetWindowLong(hwnd,GWL_WNDPROC,(LONG_PTR)InEditControlProc);
DefProc=(WNDPROC)SetWindowLongPtr(hwnd,GWLP_WNDPROC,(LONG_PTR)InEditControlProc);
//SetWindowSubclass(hwnd,InEditControlProc,uIdSubClass,dwRefData);
ShowWindow(InText,SW_SHOW);
SetFocus(InText);
startup(hwnd,OutText,InText,sysCore);
break;
case WM_DESTROY:
SetWindowLongPtr(hwnd,GWLP_WNDPROC,(LONG_PTR)WndProc);
PostQuitMessage(0);
break;
case WM_COMMAND:
switch (LOWORD(wp))
{
case MSG_SEND:
//TCHAR buff[1024];
buff = new TCHAR [1024];
Tbuff = new TCHAR [1024];
GetWindowText(GetDlgItem(hwnd,IDM_IN),buff,1024);//get text from box, store to buffer
GetWindowText(GetDlgItem(hwnd,IDM_OUT),Tbuff,1024);//retain window text
SetWindowText(GetDlgItem(hwnd,IDM_IN),L"");//clear field
if (buff!=L"")//dont pass if buffer empty
{
AppendText(hwnd,buff);
AppendText(hwnd,L"rn");
}
handleInput(hwnd,buff,sysCore);
//SetWindowText(GetDlgItem(hWnd,OFIELD),buff);//set text
delete buff,Tbuff;
break;
case IDM_CLEAR:
SetWindowText(GetDlgItem(hwnd,IDM_OUT),L"");
break;
case IDM_ABOUT:
MessageBox(hwnd,L"App information",L"About",0);
break;
case IDM_EXIT:
PostQuitMessage(0);
}
default:
return DefWindowProc(hwnd, msg,wp,lp);
break;
}
return 0;
}
好了,经过几天的寻找,我弄明白了,很大程度上是学习使用spy++实用程序。
我发现在子类化之后,添加
行if(msg.message==WM_KEYDOWN)
SendMessage(hwnd,msg.message,msg.wParam,msg.lParam);
在Translate/DispatchMessage之后的消息泵中的允许使用这些自定义信号路由到正确的程序