如何在“Enter”键上按下“编辑”控件的焦点

我在main函数中创建了一个主窗口。 在WM_CREATE消息的主窗口的过程中,我创建了一个编辑控件,它使用系统“编辑”窗口类作为父窗口的子窗口。 我希望在编辑控件中按下回车键时将焦点转移到主窗口。 由于我使用了系统类,因此无法访问其程序。 我在Visual Studio 10中使用C ++因为我是win32应用程序的新手我想要一个简单的解决方案,无论代码有多长

如果您的窗口只有一个可聚焦控件(例如编辑控件),那么该控件将始终具有焦点。 您不能拥有没有聚焦控件的窗口,并且父窗口本身不可聚焦(即无法聚焦)。

所以你首先需要在你的窗口添加另一个可聚焦控件,如果你还没有(我无法从问题中得知)。 例如,您可以添加“确定”或“取消”按钮。 这样,每当您对编辑控件失去焦点时,按钮都可以获得焦点。

然后,您将需要子类化编辑控件,以便您可以处理其按键事件(例如WM_KEYDOWNWM_KEYUP )。 要子类化单个窗口,请调用SetWindowLongPtr函数并将窗口句柄与GWLP_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); } 
 // ----- 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 (eg 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 (eg calling PostQuitMessage(...) to close your app) 

关于子类化窗口的进一步阅读在MSDN上 。 那里的示例代码(以及Web上的许多其他位置)假定您在对话框窗口中inheritance了编辑控件。 由于对话框是特殊类型的父窗口,可以自动处理大量键盘处理,因此您需要采取额外步骤来克服对话框执行的默认处理。 如果您使用的是使用CreateWindowEx创建的常规窗口,则不需要。

如果你想要多个编辑控件,它们在响应某些键按下时的行为方式都相同,那么注册自定义窗口子类会更清晰,更好。 虽然上面的代码只包含一个编辑控件对象,但这种方法会创建一种新类型的自定义编辑控件类。 您可以根据需要创建这种新类型的编辑控件的实例,并且它们的行为方式都相同。

但我不会在这里讨论如何做到这一点。 如果您感兴趣, 可以在线查找代码 ,并且您的特定用例会使其更复杂一些。 为了改变焦点,控件必须知道应该将焦点设置到哪个其他控件。 这在全球很难处理。 使用对话窗口作为父对象可能是可取的。 它管理Z顺序并自动为您设置焦点。