#c #windows #winapi
#c #Windows #winapi
Вопрос:
Я добавил IsDialogMessage()
в свой основной цикл клавишу tab, но она застряла в верхней части элемента управления tab и не переходила к элементам управления внутри диалогового окна. Как я могу это исправить? Я пробовал WS_GROUP
в первом элементе управления и WS_TABSTOP
во всех последующих созданных элементах управления, но это не сработало.
Элемент управления табуляцией создается следующим образом:
hTabControl =
CreateWindowW(WC_TABCONTROLW, NULL,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP | WS_GROUP | WS_EX_CONTROLPARENT,
10, 30, 400, 250,
hwnd,
(HMENU) ID_MAIN_TABCONTROL,
NULL,
NULL);
и диалоговое окно:
CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT,
"DialogBox",
L"Dialog Box",
WS_SYSMENU | WS_CHILD | WS_GROUP | WS_TABSTOP | WS_VISIBLE,
10, 30, 350, 150,
hTabControl, NULL, ghInstance, NULL
);
// ...
WNDCLASSEXW wc = {0};
wc.cbSize = sizeof(WNDCLASSEXW);
wc.lpfnWndProc = DialogProc;
wc.hInstance = ghInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpszClassName = "DialogClass";
RegisterClassExW(amp;wc);
затем процедура DialogProc:
LRESULT CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
CreateWindowW(L"button", L"A",
WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_GROUP,
50, 50, 80, 25, hwnd, (HMENU) ID_TAB1_BUTTONA, NULL, NULL);
CreateWindowW(L"button", L"B",
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
150, 50, 80, 25, hwnd, (HMENU) ID_TAB1_BUTTONB, NULL, NULL);
CreateWindowW(L"button", L"C",
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
250, 50, 80, 25, hwnd, (HMENU) ID_TAB1_BUTTONC, NULL, NULL);
CreateWindowW(L"button", L"D",
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
50, 100, 80, 25, hwnd, (HMENU) ID_TAB1_BUTTOND, NULL, NULL);
CreateWindow(L"Edit", NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL | WS_TABSTOP,
150, 100, 80, 20, hwnd, (HMENU) ID_TAB1_EDIT1, NULL, NULL);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
// didn't do anything
default:
break;
case ID_TAB1_BUTTONA:
{
MessageBox(NULL, L"Click on A button", L"Welcome to the jungle!", MB_OK);
}
break;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
И основной цикл:
while (GetMessage(amp;msg, NULL, 0, 0))
{
if (!IsDialogMessage(hwnd, amp;msg)) {
TranslateMessage(amp;msg);
DispatchMessage(amp;msg);
}
}
Комментарии:
1. Почему ваш (внутренний) диалог имеет стиль WS_EX_TOOLWINDOW?
2. Я предполагаю, что это было упущено при моей попытке скрыть элемент управления tab из ALT TAB
Ответ №1:
Обычно вы не создаете интерактивные окна / элементы управления как дочерние элементы элемента управления tab, странно, но это правда. Создайте внутренний диалог как дочерний элемент внешнего диалога, а не элемент управления табуляцией.
Этот пример MSDN создает внутренние диалоги как дочерние элементы основного диалога.
Как объясняется в этом сообщении в блоге, WS_EX_CONTROLPARENT
выводит окно / элемент управления из порядка табуляции.
Это чисто Win32, Delphi / C Builder и другие среды с пользовательскими наборами инструментов пользовательского интерфейса часто реализуют элемент управления tab как реальный контейнер.
Комментарии:
1. Это действительно странно, я пришел из мира C #, поэтому я пытался имитировать то, что, по моему мнению, было правильным поведением, делая дочерние элементы управления вкладками Windows. Но, читая сообщение в блоге Рэймонда, я понимаю, почему это так и насколько распространена эта ошибка. Для того, чтобы сделать эти элементы управления tab control родными, я изменил
CreateWindowExW(WS_EX_CONTROLPARENT,... , hwnd)
в процедуре WindowsLRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { ... }
. Правильно ли это сейчас? Я не знал оWS_EX_CONTROLPARENT
take tab of order, удалил это2. С помощью этого диалогового окна я пытался эмулировать контейнер с помощью WINAPI, поскольку я не нашел ничего подобного в WINAPI. Но как это обычно делается с WINAPI, это тема для другого вопроса. Клавиши табуляции работают нормально, теперь я объединил их с
WS_GROUP
первым элементом управления, за которым следуютWS_TABSTOP
все последующие окна, созданные в процедуре. Так ли выполняется табуляция с помощью WINAPI?3. Обычно вы используете стиль группы только с переключателями, это единственное место, где они требуются. Другие места предназначены только для поддержки навигации по клавишам со стрелками, если вы используете стиль группы. Для обычных элементов управления вы обычно просто используете вкладки сверху на каждом.
4. Я вижу, тогда удалили WS_GROUP. То, что я прочитал, вводит в заблуждение.
5. но то, как я создаю эти элементы управления, это правильный путь?