C++ 如何杀死“焦点”;编辑";管制「;输入“;按键

C++ 如何杀死“焦点”;编辑";管制「;输入“;按键,c++,c,winapi,C++,C,Winapi,我在main函数中创建了一个主窗口。在WM_CREATE消息的主窗口程序中,我使用系统“edit”窗口类创建了一个编辑控件,作为父窗口的子窗口。我希望焦点转移到主窗口时,进入编辑控制键按下。因为我使用了system类,所以我无法访问它的过程。 我在VisualStudio10中使用了C++ 因为我不熟悉win32应用程序,所以无论代码有多长,我都需要一个简单的解决方案。如果您的窗口只有一个可聚焦控件(例如编辑控件),那么该控件将始终具有焦点。不能有没有聚焦控件的窗口,并且父窗口本身不可聚焦(即不

我在main函数中创建了一个主窗口。在WM_CREATE消息的主窗口程序中,我使用系统“edit”窗口类创建了一个编辑控件,作为父窗口的子窗口。我希望焦点转移到主窗口时,进入编辑控制键按下。因为我使用了system类,所以我无法访问它的过程。 我在VisualStudio10中使用了C++
因为我不熟悉win32应用程序,所以无论代码有多长,我都需要一个简单的解决方案。如果您的窗口只有一个可聚焦控件(例如编辑控件),那么该控件将始终具有焦点。不能有没有聚焦控件的窗口,并且父窗口本身不可聚焦(即不能有焦点)

因此,如果您还没有一个可聚焦控件,您首先需要向窗口添加另一个可聚焦控件(我无法从问题中判断)。例如,您可以添加“确定”或“取消”按钮。这样,无论何时取消编辑控件的焦点,按钮都可以接收焦点

然后,您需要对编辑控件进行子类化,以便处理其按键事件(例如
WM\u KEYDOWN
WM\u keydup
)。要对单个窗口进行子类化,请调用函数并传递窗口句柄以及
GWLP\u WNDPROC
标志和指向自定义窗口过程的指针。这有效地将该类控件的默认窗口过程替换为自定义窗口过程。例如:

// Stores the old original window procedure for the edit control.
WNDPROC wpOldEditProc;

// The new custom window procedure for the edit control.
LRESULT CALLBACK CustomEditProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        case WM_KEYDOWN:
        {
            if (wParam == VK_RETURN)
            {
                // The user pressed Enter, so set the focus to the other control
                // on the window (where 'hwndOther' is a handle to that window).
                SetFocus(hwndOther);

                // Indicate that we processed the message.
                return 0;
            }
        }
    }

    // Pass the messages we don't process here on to the
    // original window procedure for default handling.
    CallWindowProc(wpOldEditProc, hWnd, msg, wParam, lParam);
}
有关子类化windows的进一步阅读请参阅。这里的示例代码(以及web上的许多其他地方)假设您正在对对话框窗口中的编辑控件进行子类化。由于对话框是自动处理大量键盘处理的特殊类型的父窗口,因此您需要采取额外的步骤来克服对话框完成的默认处理。如果您使用的是使用
CreateWindowEx
创建的常规窗口,则不需要这样做

如果您希望多个编辑控件在响应某些按键时都以相同的方式运行,那么注册自定义窗口子类将更简洁、更好。尽管上面的代码只子类化了一个编辑控件对象,但这种方法将创建一种新类型的自定义编辑控件类。您可以创建任意数量的这种新型编辑控件的实例,它们的行为方式都相同


但我不会在这里讨论如何做到这一点。如果您感兴趣,并且您的特定用例使它变得更复杂。为了改变焦点,控件必须知道它应该将焦点设置到哪个其他控件。这很难在全球范围内处理。建议使用对话框窗口作为父窗口。它管理Z顺序并自动为您设置焦点。

我真的不记得是否有更好的方法,但子类化控件非常常见。一些关于子类化的帮助在线上有大量的示例,
SetWindowSubclass
可以让您的生活更轻松。嗯,“无论代码有多长,都是一个简单的解决方案”。这难道不是一个矛盾吗?长代码往往并不简单。:-“简单代码”意味着不使用高级功能等。非常感谢您的帮助,每当用户使用SetFocus(hparent,…)在父窗口中单击时,我已经设法杀死focus但我想在enter键按下时完成。我想知道我们是否可以从编辑控件发送到父窗口的消息中找出答案,而不使用子类。@工程师否。您需要子类才能获取消息。编辑控件不会将有关enter键按下的消息转发到其父窗口。其他控件可能会这样做,但不是编辑控件。它们的设计目的是将Enter键作为新行(在多行编辑控件中)进行解释,或者忽略它们。
// ----- Add to the parent window's WM_CREATE: -----

// Create the edit control
HWND hwndEdit = CreateWindowEx(...);

// Subclass it.
wpOldEditProc = (WNDPROC)SetWindowLongPtr(hwndEdit,
                                          GWLP_WNDPROC,
                                          (LONG_PTR)CustomEditProc);

// Show it.
ShowWindow(hwndEdit, SW_SHOW);

// ... your other code (e.g. creating and showing the other control)
// ----- Add to the parent window's WM_DESTROY: -----

// Unsubclass the edit control.
SetWindowLongPtr(hwndEdit, GWLP_WNDPROC, (LONG_PTR)wpOldEditProc);

// ... your other code (e.g. calling PostQuitMessage(...) to close your app)