Subclassed Control仅接收父消息

时间:2014-06-14 07:28:42

标签: c++ event-handling message subclass subclassing

我有三个控件位于父窗口的顶部。 一个接受用户输入,另一个显示先前的输入。第三个是将输入编辑控件中的文本附加到输出控件的按钮。但是,由于这样做很麻烦,我想为“输入”添加一个句柄。键执行此操作。目前,我已经将输入编辑控件子类化了。但是,无论我实现哪种switch语句配置,我都无法获得' WM_KeyDown'要从Input控件解释的消息。但是,如果父控件处于焦点,则从父控件发送。即使在对焦时,它也不会从编辑控件发送。我已经找到了几种解决方案,但到目前为止它们都没有。

非常感谢任何帮助!

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"\r\n");
            }
            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;
}

1 个答案:

答案 0 :(得分:0)

好的,经过几天的环顾四周,我发现了很多,部分原因是学习使用spy ++实用程序。

我在子类化后发现添加了行

if(msg.message==WM_KEYDOWN)
     SendMessage(hwnd,msg.message,msg.wParam,msg.lParam);
Translate / DispatchMessage允许这些自定义信号后,在消息泵中的

路由到正确的程序。