【问题标题】:Switch between edit controls using Tab?使用 Tab 在编辑控件之间切换?
【发布时间】:2013-08-03 18:33:07
【问题描述】:

窗口不是基于对话框的,因此 WS_TABSTOP 不起作用。此外,我不想 Tab 浏览所有控件,我只想 Tab 浏览几个 Edit 控件。

我所做的是超类化编辑控件并处理 WM_KEYDOWN 消息,在编辑控件之间切换,通过在行中获取下一个窗口 ::GetWindow(hwnd,GW_HWNDNEXT);当我到达最后一个时,我想将焦点切换回第一个编辑控件。

当我到达最后一个编辑控件时,代码不起作用,::GetWindow 只是返回行中的下一个窗口(?),这恰好是一个非超类编辑控件。还有更多隐藏的子窗口(SW_HIDE)。

也许我知道如何知道窗口的 HWND 的类名?

注意:纯 Win32 api,c++ oop。

else if (  ( int ) wParam == VK_TAB  )
{
   HWND nextInLine;
   nextInLine = ::GetWindow ( hwnd, GW_HWNDNEXT );
   if ( hwnd == NULL )  nextInLine = ::GetWindow ( hwnd, GW_HWNDPREV );
   ::SendMessage ( nextInLine, EM_SETSEL, ( WPARAM ) 0, ( LPARAM ) -1 );
   ::SetFocus ( nextInLine );
   return 0;
}

【问题讨论】:

标签: c++ oop winapi


【解决方案1】:

您可以使用IsDialogMessage API 调用在任何窗口中免费获得键盘导航。要使用该服务,必须修改窗口消息循环以包含对IsDialogMessage 的调用,并且仅在对话框管理器尚未处理该消息时将其传递给常规消息处理。

MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0)) {
    if (IsDialogMessage(hwnd, &msg)) {
        /* Already handled by dialog manager */
    } else {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

不要忘记在父窗口上设置WS_EX_CONTROLPARENTextended window style,以便对话框管理器递归到子窗口。

【讨论】:

    【解决方案2】:

    只使用calling IsDialogMessage 是可能的,但结果并不是 100% 类似于对话。让一个普通的窗口表现得像一个对话框:

    由于这使您的窗口成为一个对话框,因此您需要在调用GetWindowLongPtrSetWindowLongPtr 时使用DWLP_USER 长窗口而不是GWLP_USERDATA

    (根据记忆,执行上述操作的主要内容是支持WM_NEXTDLGCTL,我发现它可用于支持使用 Enter 键更改焦点,使用我在http://support.microsoft.com/kb/102589 中描述的方法。)

    然后在您的消息泵中,为您的消息泵中的每个类似对话框的窗口调用IsDialogMessage

    最后,在为类似对话框的窗口创建控件时,为要参与分页的每个窗口设置WS_TABSTOP 窗口样式,并在资源编辑器中设置WS_EX_CONTROLPARENT 窗口exstyle(又名Control Parent ) 用于包含对话框控件的子窗口。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-04
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 2011-07-02
      • 1970-01-01
      相关资源
      最近更新 更多