为子Windows指定窗口过程

Vin*_*inz 5 c++ windows winapi wndproc createwindowex

我想知道是否可以为创建的子窗口指定WndProc CreateWindowEx.

我已经创建了一个Window类,主窗口,窗口过程和一个消息循环.该代码有效,我决定将其保留,以便明确我的问题.

到目前为止,这是我的Window Proc:

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        // Creation of the Win32 Window
        case WM_CREATE:
            // Add an Edit Field
            CreateWindowEx(
                WS_EX_CLIENTEDGE,
                "EDIT",
                "",
                WS_CHILD | WS_VISIBLE,
                5, 5, 200, 24,
                hwnd,
                (HMENU)100,
                g_Instance, // Comming from WinMain
                NULL
            );
            return DefWindowProc(hwnd, uMsg, lParam, wParam);
        case WM_KEYDOWN:
            // Track key presses on the edit field
            std::cout << "The key with the code " << wParam << " was pressed." << std::endl;
            return 0;
        case WM_PAINT:
            // Some painting code...
            return DefWindowProc(hwnd, uMsg, lParam, wParam);
        default:
            return DefWindowProc(hwnd, uMsg, lParam, wParam);
    }
}
Run Code Online (Sandbox Code Playgroud)

我期望按下我创建的子Edit字段按下WM_KEYDOWN消息,但他们不要!键只是添加到我的窗口中的编辑字段,但不会导致WM_KEYDOWN消息.

似乎创建的编辑窗口不使用我的WndProc.我怎么能改变呢?

Thr*_*r57 7

WndProc没有得到WM_KEYDOWN消息,因为如果用户在编辑控件内输入,则意味着它具有焦点(而不是你的窗口),因此它们被发送到编辑控制窗口proc,而不是你的.但是,编辑控制窗口proc将向您的WndProc(他的父窗口 proc)发送通知.

因此,如果您只想对用户更改子编辑控件的内容做出反应,则不需要其他窗口过程.您当前WndProcEN_CHANGE通过WM_COMMAND消息接收通知代码.

请参阅https://msdn.microsoft.com/en-us/library/windows/desktop/bb761676(v=vs.85).aspx


如果你真的想要捕获WM_KEYDOWN消息,你需要子类化编辑控件,如下所示:

OldWndProc = (WNDPROC)SetWindowLongPtr (hButton, GWLP_WNDPROC, (LONG_PTR)NewWndProc);
Run Code Online (Sandbox Code Playgroud)

您还需要定义一个新的Windows程序(NewWndProc),它应该处理WM_KEYDOWN消息(以及您要处理的任何其他消息).您还需要按标准OldWndProc调用,除非您想阻止编辑控件执行其正常处理.DefWndProcWndProc

有关子类化的详细信息,请参阅https://msdn.microsoft.com/en-us/library/windows/desktop/bb773183(v=vs.85).aspx

编辑

在这里回应OP评论.

如果您的窗口是一个对话框,则应在以下情况下通知您输入密钥WndProc:

 case WM_COMMAND:

      if(wParam=IDOFDEFBUTTON || IDOK) ...
Run Code Online (Sandbox Code Playgroud)

请参阅https://support2.microsoft.com/Default.aspx?scid=kb;en-us;Q102589

说实话,我从来没有花时间去了解一个对话框,真的是.但是,如果我没记错的话,您可以通过在消息泵中调用IsDialogMessage来获取这些特殊通知:

if(!IsDialogMessage(hWnd,&msg)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
 }
Run Code Online (Sandbox Code Playgroud)

有关的有趣信息IsDialogMessage,请参阅http://blogs.msdn.com/b/oldnewthing/archive/2012/04/16/10293933.aspx

如果这没有给你足够的控制,你可能必须子类化编辑控件.