使我的win32应用程序中的TAB键正常工作

6

我希望我的应用程序能够使用Tab键,这样当我按下Tab键时,它将从一个编辑框转换到另一个,以下是编辑框的代码:

    case WM_CREATE:

    TextBox = CreateWindow("EDIT",
                            "",
                            WS_BORDER|WS_CHILD|WS_VISIBLE|WS_EX_LAYERED|WS_TABSTOP|WS_GROUP,
                            60,50,200,20,
                            hwnd,NULL,NULL,NULL);
    DataBox = CreateWindow("EDIT",
                            "",
                            WS_BORDER|WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_GROUP,
                            60,72,200,20,
                            hwnd,NULL,NULL,NULL);
    MotivBox = CreateWindow("EDIT",
                            "",
                            WS_BORDER|WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_GROUP,
                            60,92,200,20,
                            hwnd,NULL,NULL,NULL);
    PretBox = CreateWindow("EDIT",
                            "",
                            WS_BORDER|WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_GROUP,
                            60,112,200,20,
                            hwnd,NULL,NULL,NULL);

1
什么问题? - Jérôme Teisseire
在Windows和其他GUI中,使用TAB键移动到下一个控件是标准行为。那么你到底有什么问题? - Devolus
嗯,当我按下TAB键时,什么都不发生,它不会从一个编辑框切换到另一个。 - cUser26
如果有帮助的话,我可以发布整个代码。 - cUser26
你为什么将 WS_EX_LAYERED 包含在窗口样式中? - Jonathan Potter
错误地,本来是想对一个静态文本进行操作的。 - cUser26
3个回答

11

修复方法很简单。考虑到您处理的是 WM_CREATE 消息而不是 WM_INITDIALOG 消息,似乎可以安全地假设您正在向“标准”窗口添加控件而不是“对话框”。

有了这个想法,我预计您在 winmain 中有类似以下的代码:

/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
    /* Translate virtual-key messages into character messages */
    TranslateMessage(&messages);
    /* Send message to WindowProcedure */
    DispatchMessage(&messages);
}

然而,IsDialogMessage 的文档说明如下:

"虽然 IsDialogMessage 函数旨在用于非模态对话框,但您可以将其用于包含控件的任何窗口,使得该窗口能够提供与对话框中使用的相同的键盘选择功能。 当 IsDialogMessage 处理一条消息时,它会检查键盘消息并将其转换为相应对话框的选择命令。例如,按下 TAB 键会选中下一个控件或组合控件,按下向下箭头键会选中组中的下一个控件。

由于 IsDialogMessage 函数执行所有必要的消息转换和分发,因此由 IsDialogMessage 处理的消息不得传递给 TranslateMessage 或 DispatchMessage 函数。"

因此,你可以将你的消息泵修改为以下形式:

/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
    /* Translate virtual-key messages into character messages */
    if (IsDialogMessage(hwnd, &messages) == 0)
    {
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }
}

如果这有助于你找出为什么不起作用,我可以添加 main.cpp 文件,因为我在这方面毫无进展。 - cUser26
不客气。在这种情况下,我建议您提供一个SSCCE - 短自包含可编译(正确)示例(http://www.sscce.org/)。这样,我们就能指出您所犯的错误,而不是只是猜测。在一个工作项目中,删除对`IsDialogMessage`的调用会破坏TAB键的功能,因此还必须有其他问题。 :) 编辑:刚看到您关于main.cpp的建议 - 听起来我们同时想到了同样的想法! - enhzflep
解决了!谢谢,我之前为了让 TAB 键起作用而添加了一些额外的代码,但我忘记删除了,现在 TAB 键运行得很好。 - cUser26
太好了!不用谢。很高兴听到您已经解决了这个问题。 - enhzflep

2
据我记得,你只应在第一个窗口上使用WS_GROUP。所有后续的子窗口都将添加到此组中。创建新组时,需要在正在创建的第一个窗口上再次使用WS_GROUP。因此,请保留TextBox上的WS_GROUP并从其他窗口中删除它。
您可以在MSDN中了解此信息。
您还应在消息循环中使用IsDialogMessage。您可以在此处查看示例。

请看我的回答,附加了一条评论。 - Devolus
是的,我认为IsDialogMessage是解决这个问题的关键。 - enhzflep
示例链接是这里所有答案中最好的! - Brian Knoblauch

0

我曾经遇到过类似的问题,后来发现在TranslateMessage和DispatchMessage之前添加IsDialogMessage语句(如所接受的答案中所示)可以解决我的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接