1 /* dialog management for wineconsole
3 * Copyright (c) 2001 Eric Pouech
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "winecon_user.h"
28 WCUSER_ApplyToCursorSize,
29 WCUSER_ApplyToHistorySize, WCUSER_ApplyToHistoryMode, WCUSER_ApplyToMenuMask,
30 WCUSER_ApplyToEditMode,
32 WCUSER_ApplyToFont, WCUSER_ApplyToAttribute,
34 WCUSER_ApplyToBufferSize, WCUSER_ApplyToWindow
39 struct config_data* config; /* pointer to configuration used for dialog box */
40 struct inner_data* data; /* pointer to current winecon info */
41 HWND hDlg; /* handle to active propsheet */
42 int nFont; /* number of font size in size LB */
47 } *font; /* array of nFont. index sync'ed with SIZE LB */
48 void (*apply)(struct dialog_info*, HWND, enum WCUSER_ApplyTo, DWORD);
51 /******************************************************************
56 static void WCUSER_ApplyDefault(struct dialog_info* di, HWND hDlg, enum WCUSER_ApplyTo apply, DWORD val)
60 case WCUSER_ApplyToCursorSize:
61 case WCUSER_ApplyToHistorySize:
62 case WCUSER_ApplyToHistoryMode:
63 case WCUSER_ApplyToBufferSize:
64 case WCUSER_ApplyToWindow:
65 /* not saving those for now... */
67 case WCUSER_ApplyToMenuMask:
68 di->config->menu_mask = val;
70 case WCUSER_ApplyToEditMode:
71 di->config->quick_edit = val;
73 case WCUSER_ApplyToFont:
74 WCUSER_CopyFont(di->config, &di->font[val].lf);
76 case WCUSER_ApplyToAttribute:
77 di->config->def_attr = val;
80 WINECON_RegSave(di->config);
83 /******************************************************************
88 static void WCUSER_ApplyCurrent(struct dialog_info* di, HWND hDlg, enum WCUSER_ApplyTo apply, DWORD val)
92 case WCUSER_ApplyToCursorSize:
94 CONSOLE_CURSOR_INFO cinfo;
96 cinfo.bVisible = di->config->cursor_visible;
97 /* this shall update (through notif) curcfg */
98 SetConsoleCursorInfo(di->data->hConOut, &cinfo);
101 case WCUSER_ApplyToHistorySize:
102 di->config->history_size = val;
103 WINECON_SetHistorySize(di->data->hConIn, val);
105 case WCUSER_ApplyToHistoryMode:
106 WINECON_SetHistoryMode(di->data->hConIn, val);
108 case WCUSER_ApplyToMenuMask:
109 di->config->menu_mask = val;
111 case WCUSER_ApplyToEditMode:
112 di->config->quick_edit = val;
114 case WCUSER_ApplyToFont:
115 WCUSER_SetFont(di->data, &di->font[val].lf);
117 case WCUSER_ApplyToAttribute:
118 di->config->def_attr = val;
119 SetConsoleTextAttribute(di->data->hConOut, val);
121 case WCUSER_ApplyToBufferSize:
122 /* this shall update (through notif) curcfg */
123 SetConsoleScreenBufferSize(di->data->hConOut, *(COORD*)val);
125 case WCUSER_ApplyToWindow:
126 /* this shall update (through notif) curcfg */
127 SetConsoleWindowInfo(di->data->hConOut, FALSE, (SMALL_RECT*)val);
132 /******************************************************************
133 * WCUSER_OptionDlgProc
135 * Dialog prop for the option property sheet
137 static BOOL WINAPI WCUSER_OptionDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
139 struct dialog_info* di;
145 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
147 SetWindowLong(hDlg, DWL_USER, (DWORD)di);
149 if (di->config->cursor_size <= 25) idc = IDC_OPT_CURSOR_SMALL;
150 else if (di->config->cursor_size <= 50) idc = IDC_OPT_CURSOR_MEDIUM;
151 else idc = IDC_OPT_CURSOR_LARGE;
152 SendDlgItemMessage(hDlg, idc, BM_SETCHECK, BST_CHECKED, 0L);
153 SetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, WINECON_GetHistorySize(di->data->hConIn), FALSE);
154 if (WINECON_GetHistoryMode(di->data->hConIn))
155 SendDlgItemMessage(hDlg, IDC_OPT_HIST_DOUBLE, BM_SETCHECK, BST_CHECKED, 0L);
156 SendDlgItemMessage(hDlg, IDC_OPT_CONF_CTRL, BM_SETCHECK,
157 (di->config->menu_mask & MK_CONTROL) ? BST_CHECKED : BST_UNCHECKED, 0L);
158 SendDlgItemMessage(hDlg, IDC_OPT_CONF_SHIFT, BM_SETCHECK,
159 (di->config->menu_mask & MK_SHIFT) ? BST_CHECKED : BST_UNCHECKED, 0L);
160 SendDlgItemMessage(hDlg, IDC_OPT_QUICK_EDIT, BM_SETCHECK,
161 (di->config->quick_edit) ? BST_CHECKED : BST_UNCHECKED, 0L);
162 return FALSE; /* because we set the focus */
167 NMHDR* nmhdr = (NMHDR*)lParam;
171 di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
176 /* needed in propsheet to keep properly the selected radio button
177 * otherwise, the focus would be set to the first tab stop in the
178 * propsheet, which would always activate the first radio button
180 if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED)
181 idc = IDC_OPT_CURSOR_SMALL;
182 else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED)
183 idc = IDC_OPT_CURSOR_MEDIUM;
185 idc = IDC_OPT_CURSOR_LARGE;
186 PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, idc), TRUE);
190 if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED) val = 25;
191 else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED) val = 50;
193 (di->apply)(di, hDlg, WCUSER_ApplyToCursorSize, val);
195 val = GetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, &done, FALSE);
196 if (done) (di->apply)(di, hDlg, WCUSER_ApplyToHistorySize, val);
198 (di->apply)(di, hDlg, WCUSER_ApplyToHistoryMode,
199 IsDlgButtonChecked(hDlg, IDC_OPT_HIST_DOUBLE) & BST_CHECKED);
202 if (IsDlgButtonChecked(hDlg, IDC_OPT_CONF_CTRL) & BST_CHECKED) val |= MK_CONTROL;
203 if (IsDlgButtonChecked(hDlg, IDC_OPT_CONF_SHIFT) & BST_CHECKED) val |= MK_SHIFT;
204 (di->apply)(di, hDlg, WCUSER_ApplyToMenuMask, val);
206 val = (IsDlgButtonChecked(hDlg, IDC_OPT_QUICK_EDIT) & BST_CHECKED) ? TRUE : FALSE;
207 (di->apply)(di, hDlg, WCUSER_ApplyToEditMode, val);
209 SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
222 /******************************************************************
223 * WCUSER_FontPreviewProc
225 * Window proc for font previewer in font property sheet
227 static LRESULT WINAPI WCUSER_FontPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
236 struct dialog_info* di;
238 di = (struct dialog_info*)GetWindowLong(GetParent(hWnd), DWL_USER);
239 BeginPaint(hWnd, &ps);
241 font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
242 size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
244 if (font_idx >= 0 && size_idx >= 0 && size_idx < di->nFont)
246 HFONT hFont, hOldFont;
251 hFont = CreateFontIndirect(&di->font[size_idx].lf);
252 len1 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_1,
253 buf1, sizeof(buf1) / sizeof(WCHAR));
254 len2 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_2,
255 buf2, sizeof(buf2) / sizeof(WCHAR));
256 buf1[len1] = buf2[len2] = 0;
259 hOldFont = SelectObject(ps.hdc, hFont);
260 SetBkColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_BK), 0)]);
261 SetTextColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_FG), 0)]);
262 TextOut(ps.hdc, 0, 0, buf1, len1);
264 TextOut(ps.hdc, 0, di->font[size_idx].tm.tmHeight, buf2, len2);
265 SelectObject(ps.hdc, hOldFont);
273 return DefWindowProc(hWnd, msg, wParam, lParam);
278 /******************************************************************
279 * WCUSER_ColorPreviewProc
281 * Window proc for color previewer in font property sheet
283 static LRESULT WINAPI WCUSER_ColorPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
294 BeginPaint(hWnd, &ps);
295 GetClientRect(hWnd, &client);
296 step = client.right / 8;
298 for (i = 0; i < 16; i++)
300 r.top = (i / 8) * (client.bottom / 2);
301 r.bottom = r.top + client.bottom / 2;
302 r.left = (i & 7) * step;
303 r.right = r.left + step;
304 hbr = CreateSolidBrush(WCUSER_ColorMap[i]);
305 FillRect(ps.hdc, &r, hbr);
307 if (GetWindowLong(hWnd, 0) == i)
312 hOldPen = SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
313 r.right--; r.bottom--;
316 MoveToEx(ps.hdc, r.left, r.bottom, NULL);
317 LineTo(ps.hdc, r.left, r.top);
318 LineTo(ps.hdc, r.right, r.top);
319 SelectObject(ps.hdc, GetStockObject(BLACK_PEN));
320 LineTo(ps.hdc, r.right, r.bottom);
321 LineTo(ps.hdc, r.left, r.bottom);
324 r.left++; r.top++; r.right--; r.bottom--;
325 SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
327 SelectObject(ps.hdc, hOldPen);
338 GetClientRect(hWnd, &client);
339 step = client.right / 8;
340 i = (HIWORD(lParam) >= client.bottom / 2) ? 8 : 0;
341 i += LOWORD(lParam) / step;
342 SetWindowLong(hWnd, 0, i);
343 InvalidateRect(GetDlgItem(GetParent(hWnd), IDC_FNT_PREVIEW), NULL, FALSE);
344 InvalidateRect(hWnd, NULL, FALSE);
348 return DefWindowProc(hWnd, msg, wParam, lParam);
353 /******************************************************************
356 * enumerates all the font names with at least one valid font
358 static int CALLBACK font_enum_size2(const LOGFONT* lf, const TEXTMETRIC* tm,
359 DWORD FontType, LPARAM lParam)
361 struct dialog_info* di = (struct dialog_info*)lParam;
363 if (WCUSER_ValidateFontMetric(di->data, tm))
370 static int CALLBACK font_enum(const LOGFONT* lf, const TEXTMETRIC* tm,
371 DWORD FontType, LPARAM lParam)
373 struct dialog_info* di = (struct dialog_info*)lParam;
376 if (WCUSER_ValidateFont(di->data, lf) && (hdc = GetDC(di->hDlg)))
379 EnumFontFamilies(hdc, lf->lfFaceName, font_enum_size2, (LPARAM)di);
383 idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_ADDSTRING,
384 0, (LPARAM)lf->lfFaceName);
386 ReleaseDC(di->hDlg, hdc);
391 /******************************************************************
396 static int CALLBACK font_enum_size(const LOGFONT* lf, const TEXTMETRIC* tm,
397 DWORD FontType, LPARAM lParam)
399 struct dialog_info* di = (struct dialog_info*)lParam;
401 if (WCUSER_ValidateFontMetric(di->data, tm))
404 static const WCHAR fmt[] = {'%','l','d',0};
407 /* we want the string to be sorted with a numeric order, not a lexicographic...
408 * do the job by hand... get where to insert the new string
410 for (idx = 0; idx < di->nFont && tm->tmHeight > di->font[idx].tm.tmHeight; idx++);
411 if (idx < di->nFont &&
412 tm->tmHeight == di->font[idx].tm.tmHeight &&
413 tm->tmMaxCharWidth == di->font[idx].tm.tmMaxCharWidth)
415 /* we already have an entry with the same width & height...
416 * try to see which TEXTMETRIC (old or new) we should keep...
418 if (di->font[idx].tm.tmWeight != tm->tmWeight)
420 /* get the weight closer to 400, the default value */
421 if (abs(tm->tmWeight - 400) < abs(di->font[idx].tm.tmWeight - 400))
423 di->font[idx].tm = *tm;
426 /* else FIXME: skip the new tm for now */
430 /* here we need to add the new entry */
431 wsprintfW(buf, fmt, tm->tmHeight);
432 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, idx, (LPARAM)buf);
434 /* now grow our arrays and insert to values at the same index than in the list box */
435 di->font = HeapReAlloc(GetProcessHeap(), 0, di->font, sizeof(*di->font) * (di->nFont + 1));
436 if (idx != di->nFont)
437 memmove(&di->font[idx + 1], &di->font[idx], (di->nFont - idx) * sizeof(*di->font));
438 di->font[idx].tm = *tm;
439 di->font[idx].lf = *lf;
446 /******************************************************************
451 static BOOL select_font(struct dialog_info* di)
453 int idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
457 if (idx < 0 || idx >= di->nFont)
460 LoadString(GetModuleHandle(NULL), IDS_FNT_DISPLAY, fmt, sizeof(fmt) / sizeof(WCHAR));
461 wsprintfW(buf, fmt, di->font[idx].tm.tmMaxCharWidth, di->font[idx].tm.tmHeight);
463 SendDlgItemMessage(di->hDlg, IDC_FNT_FONT_INFO, WM_SETTEXT, 0, (LPARAM)buf);
464 InvalidateRect(GetDlgItem(di->hDlg, IDC_FNT_PREVIEW), NULL, TRUE);
465 UpdateWindow(GetDlgItem(di->hDlg, IDC_FNT_PREVIEW));
469 /******************************************************************
472 * fills the size list box according to selected family in font LB
474 static BOOL fill_list_size(struct dialog_info* di, BOOL doInit)
478 WCHAR lfFaceName[LF_FACESIZE];
480 idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
481 if (idx < 0) return FALSE;
483 hdc = GetDC(di->hDlg);
484 if (!hdc) return FALSE;
486 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETTEXT, idx, (LPARAM)lfFaceName);
487 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_RESETCONTENT, 0L, 0L);
488 if (di->font) HeapFree(GetProcessHeap(), 0, di->font);
492 EnumFontFamilies(hdc, lfFaceName, font_enum_size, (LPARAM)di);
493 ReleaseDC(di->hDlg, hdc);
497 for (idx = 0; idx < di->nFont; idx++)
499 if (WCUSER_AreFontsEqual(di->config, &di->font[idx].lf))
502 if (idx == di->nFont) idx = 0;
506 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_SETCURSEL, idx, 0L);
511 /******************************************************************
516 static BOOL fill_list_font(struct dialog_info* di)
520 hdc = GetDC(di->hDlg);
521 if (!hdc) return FALSE;
523 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_RESETCONTENT, 0L, 0L);
524 EnumFontFamilies(hdc, NULL, font_enum, (LPARAM)di);
525 ReleaseDC(di->hDlg, hdc);
526 if (SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SELECTSTRING,
527 (WPARAM)-1, (LPARAM)di->config->face_name) == LB_ERR)
528 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SETCURSEL, 0L, 0L);
529 fill_list_size(di, TRUE);
533 /******************************************************************
536 * Dialog proc for the Font property sheet
538 static BOOL WINAPI WCUSER_FontDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
540 struct dialog_info* di;
545 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
547 SetWindowLong(hDlg, DWL_USER, (DWORD)di);
549 SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0, (di->config->def_attr >> 4) & 0x0F);
550 SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0, di->config->def_attr & 0x0F);
553 di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
554 switch (LOWORD(wParam))
556 case IDC_FNT_LIST_FONT:
557 if (HIWORD(wParam) == LBN_SELCHANGE)
559 fill_list_size(di, FALSE);
562 case IDC_FNT_LIST_SIZE:
563 if (HIWORD(wParam) == LBN_SELCHANGE)
572 NMHDR* nmhdr = (NMHDR*)lParam;
575 di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
582 val = SendDlgItemMessage(hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
584 if (val < di->nFont) (di->apply)(di, hDlg, WCUSER_ApplyToFont, val);
586 (di->apply)(di, hDlg, WCUSER_ApplyToAttribute,
587 (GetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0) << 4) |
588 GetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0));
590 SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
603 /******************************************************************
604 * WCUSER_ConfigDlgProc
606 * Dialog proc for the config property sheet
608 static BOOL WINAPI WCUSER_ConfigDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
610 struct dialog_info* di;
615 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
617 SetWindowLong(hDlg, DWL_USER, (DWORD)di);
618 SetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH, di->config->sb_width, FALSE);
619 SetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, di->config->sb_height, FALSE);
620 SetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH, di->config->win_width, FALSE);
621 SetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, di->config->win_height, FALSE);
624 di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
625 switch (LOWORD(wParam))
631 NMHDR* nmhdr = (NMHDR*)lParam;
636 di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
643 sb.X = GetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH, &st_w, FALSE);
644 sb.Y = GetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, &st_h, FALSE);
645 if (st_w && st_h && (sb.X != di->config->sb_width || sb.Y != di->config->sb_height))
647 (di->apply)(di, hDlg, WCUSER_ApplyToBufferSize, (DWORD)&sb);
650 pos.Right = GetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH, &st_w, FALSE);
651 pos.Bottom = GetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, &st_h, FALSE);
653 (pos.Right != di->config->win_width || pos.Bottom != di->config->win_height))
655 pos.Left = pos.Top = 0;
656 pos.Right--; pos.Bottom--;
657 (di->apply)(di, hDlg, WCUSER_ApplyToWindow, (DWORD)&pos);
659 SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
672 /******************************************************************
673 * WCUSER_GetProperties
675 * Runs the dialog box to set up the winconsole options
677 BOOL WCUSER_GetProperties(struct inner_data* data, BOOL current)
679 HPROPSHEETPAGE psPage[3];
681 PROPSHEETHEADER psHead;
684 static const WCHAR szFntPreview[] = {'W','i','n','e','C','o','n','F','o','n','t','P','r','e','v','i','e','w',0};
685 static const WCHAR szColorPreview[] = {'W','i','n','e','C','o','n','C','o','l','o','r','P','r','e','v','i','e','w',0};
686 struct dialog_info di;
688 InitCommonControls();
693 di.config = &data->curcfg;
694 di.apply = WCUSER_ApplyCurrent;
698 di.config = &data->defcfg;
699 di.apply = WCUSER_ApplyDefault;
705 wndclass.lpfnWndProc = WCUSER_FontPreviewProc;
706 wndclass.cbClsExtra = 0;
707 wndclass.cbWndExtra = 0;
708 wndclass.hInstance = GetModuleHandle(NULL);
710 wndclass.hCursor = LoadCursor(0, IDC_ARROW);
711 wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
712 wndclass.lpszMenuName = NULL;
713 wndclass.lpszClassName = szFntPreview;
714 RegisterClass(&wndclass);
717 wndclass.lpfnWndProc = WCUSER_ColorPreviewProc;
718 wndclass.cbClsExtra = 0;
719 wndclass.cbWndExtra = sizeof(DWORD);
720 wndclass.hInstance = GetModuleHandle(NULL);
722 wndclass.hCursor = LoadCursor(0, IDC_ARROW);
723 wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
724 wndclass.lpszMenuName = NULL;
725 wndclass.lpszClassName = szColorPreview;
726 RegisterClass(&wndclass);
728 memset(&psp, 0, sizeof(psp));
729 psp.dwSize = sizeof(psp);
731 psp.hInstance = wndclass.hInstance;
732 psp.lParam = (LPARAM)&di;
734 psp.u.pszTemplate = MAKEINTRESOURCE(IDD_OPTION);
735 psp.pfnDlgProc = WCUSER_OptionDlgProc;
736 psPage[0] = CreatePropertySheetPage(&psp);
738 psp.u.pszTemplate = MAKEINTRESOURCE(IDD_FONT);
739 psp.pfnDlgProc = WCUSER_FontDlgProc;
740 psPage[1] = CreatePropertySheetPage(&psp);
742 psp.u.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG);
743 psp.pfnDlgProc = WCUSER_ConfigDlgProc;
744 psPage[2] = CreatePropertySheetPage(&psp);
746 memset(&psHead, 0, sizeof(psHead));
747 psHead.dwSize = sizeof(psHead);
749 if (!LoadString(GetModuleHandle(NULL),
750 (current) ? IDS_DLG_TIT_CURRENT : IDS_DLG_TIT_DEFAULT,
751 buff, sizeof(buff) / sizeof(buff[0])))
761 psHead.pszCaption = buff;
763 psHead.hwndParent = PRIVATE(data)->hWnd;
764 psHead.u3.phpage = psPage;
766 PropertySheet(&psHead);