只接收父消息的子类控件



我有三个控件位于父窗口的顶部。一个接受用户输入,而另一个显示以前的输入。第三个是将文本从输入编辑控件附加到输出控件的按钮。然而,由于这样做很麻烦,我想为"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之后的消息泵中的

允许使用这些自定义信号路由到正确的程序

相关内容

  • 没有找到相关文章

最新更新