Win32 GUI: последовательность вкладок для редактирования элементов управления - PullRequest
1 голос
/ 10 февраля 2010

У меня есть окно с 10 дочерними элементами редактирования. Я хочу перейти от одного элемента редактирования к другому, нажав клавишу табуляции - как мне это сделать?

Я имею в виду, даже если бы я мог узнать, нажал ли я клавишу табуляции, как мне найти следующий элемент управления для редактирования, на который можно сфокусироваться? Надеюсь, мне не нужно самостоятельно отслеживать элементы управления, так как я уже добавил их в родительское окно.

PS: под "следующим" я подразумеваю порядок, в котором я создал элементы управления для редактирования ...

Редактировать: я на Win32, используя простой C.

Редактировать 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 ]

3 голосов
/ 10 февраля 2010

Менеджер диалогов делает многое за вас, поэтому, если у вас нет веских оснований для создания собственного класса окна, вы можете вместо этого создать диалог.

Если вы все еще хотите сделать свой собственный бросок, вам придется перехватить WM_CHAR и искать VK_TAB и VK_SHIFT | VK_TAB . Менеджер диалогов использует в качестве порядка табуляции нечто, называемое z-order (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 для CreateDialog, вы должны найти несколько примеров этого.

... И возможно ли добавить другие окна внутри диалога? Даже с пользовательскими процедурами окна? (Другими словами, в диалогах я не ограничено только по умолчанию элементы управления, такие как редактировать и статические?)

Да, вы можете создавать собственные элементы управления в диалоге. В части DIALOG вашего файла .rc вы можете включить что-то вроде:

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

Вы также можете создать новый элемент управления и динамически добавить его в диалоговое окно (например, я дам вам Google).

Кроме того, если бы я хотел свернуть свой собственный, как узнать какой следующий элемент управления? Я не думаю, что будет больше вариантов использования, чем базовый рабочий стол

Используйте 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

0 голосов
/ 10 февраля 2010

Этот тип обработки может быть легко добавлен в приложение: - Добавить вызов к IsDialogMessage() в вашем цикле сообщений - все элементы управления должны иметь стиль WS_TABSTOP.

Возможно, родительское окно должно иметь класс диалога, поскольку класс диалогового окна хранит состояние, позволяющее ему (например) восстановить фокус на правильный элемент управления, когда активация потеряна и восстановлена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...