В рамках расширения функциональности диалогового окна в старом приложении Windows WinAPI GUI, написанном на C, я столкнулся с еще одним добавлением нескольких флажков для каждой строки диалога ввода данных из шести строк.Я просто не выдержал хлопот с повторяющимися изменениями файлов ресурсов и файлов исходного кода и решил позаимствовать подход дизайна пользовательского интерфейса из пользовательских интерфейсов Java для создания пользовательского интерфейса из панелей.
Инструменты Visual Studio, по крайней мере Visual Studio2005, похоже, не одобряет такой подход, и в этом случае я отредактировал файл ресурсов вручную.Возможно, инструменты редактирования ресурсов Visual Studio 2017 более гибкие.
Мой вопрос заключается в том, что является альтернативой этому подходу, который, казалось бы, настолько прост и удобен и лучше соответствует философии Visual Studio..
Мне также интересно узнать о недостатках этого подхода.
Этот подход кажется необычным для приложения WinAPI Visual Studio C WinAPI, которое меня беспокоит.Я не могу утверждать, что являюсь особенно инновационным, поэтому мне интересно, чего мне не хватает, поскольку этот подход, кажется, работает хорошо, по крайней мере, при ручном редактировании файла ресурсов.
Я подумываю сделать еще одну итерацию, в которой я двигаюсьсписок элементов управления для каждой строки, который также повторяется в шаблоне немодального диалогового окна, и просто наличие исходного диалога представляет собой стек из 6 статических окон, по одному для каждой строки.
Преимущества этого подхода были меньшеи возможность повторного использования определяет.Также было проще вставить новую функциональность в существующий исходный код поведения диалога, хотя это было главным образом потому, что это были просто автоматические флажки.
Одна проблема, которую я вижу, заключается в использовании инструментов Visual Studio после внесения этого изменения,Однако файл ресурсов этого конкретного приложения не всегда хорошо работает с инструментами редактирования ресурсов Visual Studio.
Этот подход уже окупился, когда мне понадобилось добавить некоторые дополнительные флажки в немодальный шаблон диалога.Чтобы изменить файл ресурсов, мне нужно было добавить дополнительные флажки в новый шаблон диалога и отрегулировать исходный размер диалога, немодальный размер диалога и размеры статических окон, чтобы все было видно.
Реализация
Альтернатива, которую я реализовал, заключается в следующем:
- создать шаблон диалога с набором флажков
- изменить шаблон диалогастиль немодального диалога - WS_CHILD
- . Создайте статическое окно в каждой из шести строк исходного диалога для нового шаблона диалога.
- Поместите экземпляр немодального диалогового окна в статическое окно.в каждой строке
Новая версия диалога выглядит следующим образом: Когда отображается исходное диалоговое окно, обработчик для сообщения диалога инициализации создает набор из шести немодальных диалоговпо одному для каждого из вновь добавленных статических окон, причем родительское окно для диалогов является статическим окном.Это помещает немодальный диалог в статическое окно, и когда статическое окно перемещается, то же самое происходит и с немодальным диалогом.
Все шесть немодальных диалогов используют один и тот же обработчик сообщений диалогового окна.Обработчик сообщений сам не обрабатывает никаких сообщений.
Шаблон немодального диалога:
IDD_A170_DAYS DIALOG DISCARDABLE 0, 0, 240, 20
STYLE WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Ovr",IDD_A170_STR1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,1,25,10
CONTROL "AND",IDD_A170_STR2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,35,1,40,10
CONTROL "S",IDD_A170_CAPTION1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,75,1,20,10
CONTROL "M",IDD_A170_CAPTION2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,1,20,10
CONTROL "T",IDD_A170_CAPTION3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,125,1,20,10
CONTROL "W",IDD_A170_CAPTION4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,1,20,10
CONTROL "T",IDD_A170_CAPTION5,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,175,1,20,10
CONTROL "F",IDD_A170_CAPTION6,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,195,1,20,10
CONTROL "S",IDD_A170_CAPTION7,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,220,1,20,10
END
, а основной диалог со статическими окнами:
IDD_A170 DIALOG DISCARDABLE 2, 17, 530, 190
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Set Sales Code Restriction Table of PLU (AC 170)"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Address (PLU Sales Code)",IDD_A170_CAPTION1,14,10,64,20
LTEXT "Date",IDD_A170_CAPTION2,86,14,28,12
LTEXT "Day of week",IDD_A170_CAPTION3,115,10,33,21
LTEXT "Start hour",IDD_A170_CAPTION4,153,10,20,18
LTEXT "Minute",IDD_A170_CAPTION5,182,14,26,12
LTEXT "End hour",IDD_A170_CAPTION6,217,10,20,18
LTEXT "Minute",IDD_A170_CAPTION7,245,14,26,12
LTEXT "Override/Type",IDC_STATIC,290,14,50,12
LTEXT "Days To Restrict",IDC_STATIC,390,14,100,12
LTEXT "",IDD_A170_STR1,8,34,74,12 // first control on line 1
EDITTEXT IDD_A170_DATE1,87,33,18,12,ES_AUTOHSCROLL
SCROLLBAR IDD_A170_DATESPIN1,104,33,8,12,SBS_VERT
EDITTEXT IDD_A170_WEEK1,119,33,18,12,ES_AUTOHSCROLL
SCROLLBAR IDD_A170_WEEKSPIN1,136,33,8,12,SBS_VERT
EDITTEXT IDD_A170_SHOUR1,151,33,18,12,ES_AUTOHSCROLL
SCROLLBAR IDD_A170_SHOURSPIN1,168,33,8,12,SBS_VERT
EDITTEXT IDD_A170_SMINUTE1,183,33,18,12,ES_AUTOHSCROLL
SCROLLBAR IDD_A170_SMINUTESPIN1,200,33,8,12,SBS_VERT
EDITTEXT IDD_A170_EHOUR1,214,33,18,12,ES_AUTOHSCROLL
SCROLLBAR IDD_A170_EHOURSPIN1,231,33,8,12,SBS_VERT
EDITTEXT IDD_A170_EMINUTE1,246,33,18,12,ES_AUTOHSCROLL
SCROLLBAR IDD_A170_EMINUTESPIN1,263,33,8,12,SBS_VERT
LTEXT "D1",IDD_A170_DAYS_1,281,33,240,20 // static window to contain the modeless dialog box from the template IDD_A170_DAYS above
// .. repeated sequence for 5 more lines
CONTROL "MDC 298 - Sales Restriction Type is AND",IDD_A170_MDC_PLU5_ADR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,140,170,9
LTEXT "[Address : 1 - 6, Date : 0 - 31",IDD_A170_CAPTION8,9,154,99,9
LTEXT "Day of week : 0 - 7 (1 - Sunday, 7 - Saturday)]",IDD_A170_CAPTION9,110,154,167,9
LTEXT "[Hour : 0 - 24, Minute : 0 - 59 (For 0:00, enter 24:00)]",IDD_A170_CAPTION10,9,168,167,9
PUSHBUTTON "&Ok",IDOK,285,154,48,20
PUSHBUTTON "&Cancel",IDCANCEL,345,154,48,20
END
Вы можете заметить, что я только что повторно использовал некоторые определения в новом немодальном диалоговом окне, которые уже использовались в исходном диалоговом окне.Я смог сделать это, потому что идентификаторы управления являются специфическими для самого диалогового окна.Поэтому использование одного и того же определения в разных диалоговых окнах не вызывает проблем, поскольку использование GetDlgItem()
для получения дескриптора окна элемента управления в диалоговом окне требует дескриптора окна конкретного экземпляра диалога.
Iзатем создал набор вспомогательных функций, которые обрабатывают экземпляр немодального диалога.
static struct {
int iId;
HWND hWnd;
} A170DlgTabs[10] = { {0, 0} };
// modeless dialog box message handler which has nothing to do but the
// WinAPI requires it.
BOOL WINAPI A170DlgChildProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
return FALSE;
}
void A170ModeLessChildDialogClear ()
{
memset (A170DlgTabs, 0, sizeof(A170DlgTabs));
}
HWND A170ModeLessChildDialog (HWND hParentWnd, int nCmdShow, int iId)
{
int i;
HWND hWnd = DialogCreation(hResourceDll/*hActInst*/, //RPH 4-23-03 Multilingual
MAKEINTRESOURCEW(IDD_A170_DAYS),
hParentWnd,
A170DlgChildProc);
hWnd && ShowWindow (hWnd, nCmdShow);
for (i = 0; i < sizeof(A170DlgTabs)/sizeof(A170DlgTabs[0]); i++) {
if (A170DlgTabs[i].hWnd == 0) {
A170DlgTabs[i].iId = iId;
A170DlgTabs[i].hWnd = hWnd;
break;
}
}
return hWnd;
}
HWND A170ModeLessChildDialogFind (int iId)
{
int i;
HWND hWnd = NULL;
for (i = 0; i < sizeof(A170DlgTabs)/sizeof(A170DlgTabs[0]); i++) {
if (A170DlgTabs[i].iId == iId) {
hWnd = A170DlgTabs[i].hWnd;
break;
}
}
return hWnd;
}
USHORT A170ModeLessChildDialogSettings (int iId)
{
int i;
USHORT iBits = 0, kBits = 1;
HWND hWnd = A170ModeLessChildDialogFind (iId);
// least significant byte contains the bit mask for the days of the week.
// the next higher byte contains the indicators for the override type or
// whether MDC 298 is to be overriden or not.
for (i = IDD_A170_CAPTION1; i <= IDD_A170_CAPTION7; i++, (kBits <<= 1)) {
iBits |= IsDlgButtonChecked (hWnd, i) ? kBits : 0;
}
iBits |= iBits ? RESTRICT_WEEK_DAYS_ON : 0;
iBits |= IsDlgButtonChecked(hWnd, IDD_A170_STR1) ? KBITS_RESTRICT_OVERRIDE_ANDOR : 0;
iBits |= IsDlgButtonChecked(hWnd, IDD_A170_STR2) ? KBITS_RESTRICT_OVERRIDE_AND : 0;
return iBits;
}
USHORT A170ModeLessChildDialogSettingsSetMask (int iId, USHORT usMask)
{
int i;
USHORT k = 1;
HWND hWnd = A170ModeLessChildDialogFind (iId);
CheckDlgButton(hWnd, IDD_A170_STR1, (usMask & KBITS_RESTRICT_OVERRIDE_ANDOR) ? TRUE : FALSE);
CheckDlgButton(hWnd, IDD_A170_STR2, (usMask & KBITS_RESTRICT_OVERRIDE_AND) ? TRUE : FALSE);
for (i = IDD_A170_CAPTION1; i <= IDD_A170_CAPTION7; i++, (k <<= 1)) {
CheckDlgButton(hWnd, i, (usMask & k) ? TRUE : FALSE);
}
return usMask;
}