C + WinAPI: как переключаться между элементами управления с помощью клавиши табуляции?

Я создал небольшое приложение на C с использованием WinAPI, и у меня возникла небольшая проблема. Клавиша табуляции не переключает между элементами управления. Должен ли он быть автоматическим? Если нет, подскажите, как это реализовать? Я создал алгоритм переключения между полями редактирования, вот заглушка:

case WM_NOTIFY
{
if tab key
{
control_id++;
SetFocus(GetDlgItem(hwnd, control id));
if control_id = max_control_id 
{ control_id = min_control_id; }

Если нет простого способа, следует ли мне использовать свой алгоритм?

P.S .: Пробовал добавить TABSTOP, не работает. Вот некоторые элементы управления, которые не работают. Я использую VS 2010 Express, 64-разрядную версию Windows 7.

hwnduser = CreateWindow (TEXT("EDIT"), NULL, 
WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP | WS_GROUP,
220, 80, 80, 20,
hwnd, (HMENU) 3, NULL, NULL);
hwndpass = CreateWindow (TEXT("EDIT"), NULL, 
WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP,
220, 130, 80, 20,
hwnd, (HMENU) 4, NULL, NULL);
CreateWindow(TEXT("button"), TEXT("Login"),
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP,
80,200,100,30,
hwnd, (HMENU) 1, NULL, NULL);
CreateWindow(TEXT("button"), TEXT("Exit"),
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
220,200,100,30,
hwnd, (HMENU) 2, NULL, NULL);

person Ishan Sharma    schedule 17.04.2011    source источник
comment
Что случилось с проверенным методом установки табуляции и разрешением wndproc по умолчанию обрабатывать это?   -  person Ignacio Vazquez-Abrams    schedule 17.04.2011
comment
@Ignacio Vazquez-Abrams Этот проверенный метод не работает для меня. См. Редактировать.   -  person Ishan Sharma    schedule 17.04.2011


Ответы (3)


Вы должны вызвать IsDialogMessage () в своем цикле сообщений. См. Эту статью о том, как это сделать.

person Stefan    schedule 17.04.2011
comment
решил мою проблему, так что +1. Кстати, это также позволяет клавишам со стрелками перемещать фокус между элементами управления. Краткая версия статьи: в цикле сообщений сразу после GetMessage () вызовите IsDialogMessage (), и если это вернет истину, не беспокойтесь о переводе и отправке. - person JustJeff; 11.06.2011
comment
для использования с WS_TABSTOP Window Style. - person Ujjwal Singh; 12.02.2013
comment
Ссылка мертва - person gonutz; 03.08.2018

Вам нужно дать вашим элементам управления стиль WS_TABSTOP. Подробную информацию можно найти в MSDN .

person zdan    schedule 17.04.2011

Используйте SetFocus (GetNextDlgTabItem (GetParent ((HWND) wParam), (HWND) wParam, FALSE)); в WndProc:

LRESULT WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {

switch (message)
{
case WM_CREATE:
{
      CreateWindow(L"button", L"", WS_BORDER | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_GROUP, 60, 50, 200, 20, hwnd, (HMENU)101, NULL, NULL);
      CreateWindow(L"EDIT", L"", WS_BORDER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 60, 72, 200, 20, hwnd, (HMENU)102, NULL, NULL);
      CreateWindow(L"EDIT", L"", WS_BORDER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 60, 92, 200, 20, hwnd, (HMENU)103, NULL, NULL);
      CreateWindow(L"EDIT", L"", WS_BORDER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 60, 112, 200, 20, hwnd, (HMENU)104, NULL, NULL);

}
break;

case WM_SETFOCUS:
    SetFocus(GetNextDlgTabItem(GetParent((HWND)wParam), (HWND)wParam, FALSE));

    break;

default:
    return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
person SaeidMo7    schedule 11.05.2016