Win32 GUI:用于编辑控件的选项卡序列

时间:2010-02-09 22:41:45

标签: user-interface winapi

我有一个窗口,里面有10个子编辑控件。我想通过按Tab键从一个编辑控件移动到另一个编辑控件 - 我该怎么做?

我的意思是,即使我能找出是否按下了tab键,我如何找到要关注的下一个编辑控件?我希望自己不必跟踪编辑控件,因为我已将它们添加到父窗口中。

PS:“下一步”是指我创建编辑控件的顺序......

编辑:我使用普通的C在Win32上。

编辑2:示例



#include 

#define NAME "test"

LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    HWND edit1, edit2;
    switch (msg)
    {
        case WM_CREATE:
            edit1 = CreateWindow("edit", "", WS_CHILD|WS_VISIBLE, 0, 0, 200, 50, hWnd, NULL, NULL, NULL);
            edit2 = CreateWindow("edit", "", WS_CHILD|WS_VISIBLE, 250, 0, 200, 50, hWnd, NULL, NULL, NULL);
            return 0;

        case WM_CLOSE:
            DestroyWindow(hWnd);
            return 0;

        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASS wc;
    wc.style = 0;
    wc.lpfnWndProc = WinProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    wc.lpszMenuName = NAME;
    wc.lpszClassName = NAME;
    RegisterClass(&wc);

    HWND win;
    win = CreateWindow(NAME, "test", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, NULL, NULL, hInstance, NULL);

    ShowWindow(win, nCmdShow);
    UpdateWindow(win);

    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;

}

2 个答案:

答案 0 :(得分:3)

对话管理器为你做了很多这样的事情,所以如果你没有充分的理由创建自己的窗口类,你可以考虑改为创建一个对话框。

如果你仍然想要自己动手,你必须拦截 WM_CHAR 并寻找 VK_TAB VK_SHIFT | VK_TAB 即可。对话管理器使用称为“z-order”的东西作为Tab键顺序(http://msdn.microsoft.com/en-us/library/ms632599%28VS.85%29.aspx#zorder)。

FWIW,我的建议是不要低估在尝试在Windows中重新创建现有设施时所承担的负担。对于你所知道的每一种行为,通常至少有你不知道的行为。例如,您的应用程序将如何在基于笔的设备上运行?可访问性扩展如何?屏幕阅读器能够正确处理吗?所有这些东西都已经被烘焙到对话管理器中了。

  

我不确定我是否跟着......我想   对话框只是一个浮动的窗口   在“常规”(?)之上。是吗   应用程序可能使用的   只是一个对话,而不是正确的   CreateWindow的()?

对话框可以是主应用程序窗口的模态或无模式子项,但它们也可以 主应用程序窗口。这通常称为基于对话框的应用程序

如果你想要一个基于对话框的应用程序(也就是一个带有对话框作为主窗口的应用程序),你可以这样做:

int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow )
{
    MSG msg;
    HWND hDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc);
    if (hDlg != NULL)
    {
        ShowWindow(hDlg, SW_SHOWNORMAL);

        while (GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return 0;
}

完整示例可能在此处列出的时间太长,但如果您使用Google for CreateDialog,则应该找到一些示例。

  

......是否有可能   在对话框中添加其他窗口?   即使使用自定义窗口程序?   (换句话说,在对话中,我不是   仅限于默认值   控件,如编辑和静态?)

是的,您可以在对话框中创建自定义控件。在.rc文件的DIALOG部分中,您可以包含以下内容:

CONTROL "",IDC_MYCUSTOM,"MyCtrlClassName",WS_TABSTOP,10,20,30,40

您还可以创建一个新控件并将其动态添加到对话框中(我将以Google为例)。

  

另外,如果我想自己动手,那怎么样   我能找出下一个控件是什么吗?   我真的不认为会有   比基本桌面更多的用例

如果您想按Tab键顺序浏览对话框中的控件,请使用GetNextDlgTabItem()http://msdn.microsoft.com/en-us/library/ms645495%28VS.85%29.aspx

如果你自己动手,那么你可能想要EnumChildWindows()函数:http://msdn.microsoft.com/en-us/library/ms633494%28VS.85%29.aspx

这可能也很有用:http://msdn.microsoft.com/en-us/library/bb775501%28VS.85%29.aspx

答案 1 :(得分:0)

此类处理可以轻松添加到应用程序中: - 在消息循环中添加对IsDialogMessage()的调用 - 所有控件都必须具有WS_TABSTOP样式。

父窗口可能必须是对话框类,因为对话框窗口类存储状态,允许它(例如)在激活丢失和恢复时将焦点恢复到正确的控件。