Allow ANSI charset in font enumeration.
[wine.git] / programs / wineconsole / dialog.c
blob945fb31c740bcfc6759547220be5eac18ae05749
1 /* dialog management for wineconsole
2 * USER32 backend
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
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include "commctrl.h"
23 #include "prsht.h"
24 #include "winecon_user.h"
26 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(wineconsole);
30 enum WCUSER_ApplyTo {
31 /* Prop sheet CFG */
32 WCUSER_ApplyToCursorSize,
33 WCUSER_ApplyToHistorySize, WCUSER_ApplyToHistoryMode, WCUSER_ApplyToMenuMask,
34 WCUSER_ApplyToEditMode,
35 /* Prop sheet FNT */
36 WCUSER_ApplyToFont, WCUSER_ApplyToAttribute,
37 /* Prop sheep CNF */
38 WCUSER_ApplyToBufferSize, WCUSER_ApplyToWindow
41 struct dialog_info
43 struct config_data* config; /* pointer to configuration used for dialog box */
44 struct inner_data* data; /* pointer to current winecon info */
45 HWND hDlg; /* handle to active propsheet */
46 int nFont; /* number of font size in size LB */
47 struct font_info
49 UINT height;
50 UINT weight;
51 WCHAR faceName[LF_FACESIZE];
52 } *font; /* array of nFont. index sync'ed with SIZE LB */
53 void (*apply)(struct dialog_info*, HWND, enum WCUSER_ApplyTo, DWORD);
56 /******************************************************************
57 * WCUSER_ApplyDefault
61 static void WCUSER_ApplyDefault(struct dialog_info* di, HWND hDlg, enum WCUSER_ApplyTo apply, DWORD val)
63 switch (apply)
65 case WCUSER_ApplyToCursorSize:
66 case WCUSER_ApplyToHistorySize:
67 case WCUSER_ApplyToHistoryMode:
68 case WCUSER_ApplyToBufferSize:
69 case WCUSER_ApplyToWindow:
70 /* not saving those for now... */
71 break;
72 case WCUSER_ApplyToMenuMask:
73 di->config->menu_mask = val;
74 break;
75 case WCUSER_ApplyToEditMode:
76 di->config->quick_edit = val;
77 break;
78 case WCUSER_ApplyToFont:
80 LOGFONT lf;
81 HFONT hFont;
83 WCUSER_FillLogFont(&lf, di->font[val].faceName,
84 di->font[val].height, di->font[val].weight);
85 hFont = WCUSER_CopyFont(di->config, PRIVATE(di->data)->hWnd, &lf);
86 DeleteObject(hFont);
88 break;
89 case WCUSER_ApplyToAttribute:
90 di->config->def_attr = val;
91 break;
93 WINECON_RegSave(di->config);
96 /******************************************************************
97 * WCUSER_ApplyCurrent
101 static void WCUSER_ApplyCurrent(struct dialog_info* di, HWND hDlg, enum WCUSER_ApplyTo apply, DWORD val)
103 switch (apply)
105 case WCUSER_ApplyToCursorSize:
107 CONSOLE_CURSOR_INFO cinfo;
108 cinfo.dwSize = val;
109 cinfo.bVisible = di->config->cursor_visible;
110 /* this shall update (through notif) curcfg */
111 SetConsoleCursorInfo(di->data->hConOut, &cinfo);
113 break;
114 case WCUSER_ApplyToHistorySize:
115 di->config->history_size = val;
116 WINECON_SetHistorySize(di->data->hConIn, val);
117 break;
118 case WCUSER_ApplyToHistoryMode:
119 WINECON_SetHistoryMode(di->data->hConIn, val);
120 break;
121 case WCUSER_ApplyToMenuMask:
122 di->config->menu_mask = val;
123 break;
124 case WCUSER_ApplyToEditMode:
125 di->config->quick_edit = val;
126 break;
127 case WCUSER_ApplyToFont:
129 LOGFONT lf;
130 WCUSER_FillLogFont(&lf, di->font[val].faceName,
131 di->font[val].height, di->font[val].weight);
132 WCUSER_SetFont(di->data, &lf);
134 break;
135 case WCUSER_ApplyToAttribute:
136 di->config->def_attr = val;
137 SetConsoleTextAttribute(di->data->hConOut, val);
138 break;
139 case WCUSER_ApplyToBufferSize:
140 /* this shall update (through notif) curcfg */
141 SetConsoleScreenBufferSize(di->data->hConOut, *(COORD*)val);
142 break;
143 case WCUSER_ApplyToWindow:
144 /* this shall update (through notif) curcfg */
145 SetConsoleWindowInfo(di->data->hConOut, FALSE, (SMALL_RECT*)val);
146 break;
150 /******************************************************************
151 * WCUSER_OptionDlgProc
153 * Dialog prop for the option property sheet
155 static BOOL WINAPI WCUSER_OptionDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
157 struct dialog_info* di;
158 unsigned idc;
160 switch (msg)
162 case WM_INITDIALOG:
163 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
164 di->hDlg = hDlg;
165 SetWindowLong(hDlg, DWL_USER, (DWORD)di);
167 if (di->config->cursor_size <= 25) idc = IDC_OPT_CURSOR_SMALL;
168 else if (di->config->cursor_size <= 50) idc = IDC_OPT_CURSOR_MEDIUM;
169 else idc = IDC_OPT_CURSOR_LARGE;
170 SendDlgItemMessage(hDlg, idc, BM_SETCHECK, BST_CHECKED, 0L);
171 SetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, WINECON_GetHistorySize(di->data->hConIn), FALSE);
172 if (WINECON_GetHistoryMode(di->data->hConIn))
173 SendDlgItemMessage(hDlg, IDC_OPT_HIST_DOUBLE, BM_SETCHECK, BST_CHECKED, 0L);
174 SendDlgItemMessage(hDlg, IDC_OPT_CONF_CTRL, BM_SETCHECK,
175 (di->config->menu_mask & MK_CONTROL) ? BST_CHECKED : BST_UNCHECKED, 0L);
176 SendDlgItemMessage(hDlg, IDC_OPT_CONF_SHIFT, BM_SETCHECK,
177 (di->config->menu_mask & MK_SHIFT) ? BST_CHECKED : BST_UNCHECKED, 0L);
178 SendDlgItemMessage(hDlg, IDC_OPT_QUICK_EDIT, BM_SETCHECK,
179 (di->config->quick_edit) ? BST_CHECKED : BST_UNCHECKED, 0L);
180 return FALSE; /* because we set the focus */
181 case WM_COMMAND:
182 break;
183 case WM_NOTIFY:
185 NMHDR* nmhdr = (NMHDR*)lParam;
186 DWORD val;
187 BOOL done;
189 di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
191 switch (nmhdr->code)
193 case PSN_SETACTIVE:
194 /* needed in propsheet to keep properly the selected radio button
195 * otherwise, the focus would be set to the first tab stop in the
196 * propsheet, which would always activate the first radio button
198 if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED)
199 idc = IDC_OPT_CURSOR_SMALL;
200 else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED)
201 idc = IDC_OPT_CURSOR_MEDIUM;
202 else
203 idc = IDC_OPT_CURSOR_LARGE;
204 PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, idc), TRUE);
205 di->hDlg = hDlg;
206 break;
207 case PSN_APPLY:
208 if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED) val = 25;
209 else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED) val = 50;
210 else val = 99;
211 (di->apply)(di, hDlg, WCUSER_ApplyToCursorSize, val);
213 val = GetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, &done, FALSE);
214 if (done) (di->apply)(di, hDlg, WCUSER_ApplyToHistorySize, val);
216 (di->apply)(di, hDlg, WCUSER_ApplyToHistoryMode,
217 IsDlgButtonChecked(hDlg, IDC_OPT_HIST_DOUBLE) & BST_CHECKED);
219 val = 0;
220 if (IsDlgButtonChecked(hDlg, IDC_OPT_CONF_CTRL) & BST_CHECKED) val |= MK_CONTROL;
221 if (IsDlgButtonChecked(hDlg, IDC_OPT_CONF_SHIFT) & BST_CHECKED) val |= MK_SHIFT;
222 (di->apply)(di, hDlg, WCUSER_ApplyToMenuMask, val);
224 val = (IsDlgButtonChecked(hDlg, IDC_OPT_QUICK_EDIT) & BST_CHECKED) ? TRUE : FALSE;
225 (di->apply)(di, hDlg, WCUSER_ApplyToEditMode, val);
227 SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
228 return TRUE;
229 default:
230 return FALSE;
232 break;
234 default:
235 return FALSE;
237 return TRUE;
240 /******************************************************************
241 * WCUSER_FontPreviewProc
243 * Window proc for font previewer in font property sheet
245 static LRESULT WINAPI WCUSER_FontPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
247 switch (msg)
249 case WM_CREATE:
250 SetWindowLong(hWnd, 0, 0);
251 break;
252 case WM_GETFONT:
253 return GetWindowLong(hWnd, 0);
254 case WM_SETFONT:
255 SetWindowLong(hWnd, 0, wParam);
256 if (LOWORD(lParam))
258 InvalidateRect(hWnd, NULL, TRUE);
259 UpdateWindow(hWnd);
261 break;
262 case WM_DESTROY:
264 HFONT hFont = (HFONT)GetWindowLong(hWnd, 0L);
265 if (hFont) DeleteObject(hFont);
267 break;
268 case WM_PAINT:
270 PAINTSTRUCT ps;
271 int font_idx;
272 int size_idx;
273 struct dialog_info* di;
274 HFONT hFont, hOldFont;
276 di = (struct dialog_info*)GetWindowLong(GetParent(hWnd), DWL_USER);
277 BeginPaint(hWnd, &ps);
279 font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
280 size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
282 hFont = (HFONT)GetWindowLong(hWnd, 0L);
283 if (hFont)
285 WCHAR buf1[256];
286 WCHAR buf2[256];
287 int len1, len2;
289 len1 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_1,
290 buf1, sizeof(buf1) / sizeof(WCHAR));
291 len2 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_2,
292 buf2, sizeof(buf2) / sizeof(WCHAR));
293 buf1[len1] = buf2[len2] = 0;
294 if (len1)
296 hOldFont = SelectObject(ps.hdc, hFont);
297 SetBkColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_BK), 0)]);
298 SetTextColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_FG), 0)]);
299 TextOut(ps.hdc, 0, 0, buf1, len1);
300 if (len2)
301 TextOut(ps.hdc, 0, di->font[size_idx].height, buf2, len2);
302 SelectObject(ps.hdc, hOldFont);
305 EndPaint(hWnd, &ps);
307 break;
308 default:
309 return DefWindowProc(hWnd, msg, wParam, lParam);
311 return 0L;
314 /******************************************************************
315 * WCUSER_ColorPreviewProc
317 * Window proc for color previewer in font property sheet
319 static LRESULT WINAPI WCUSER_ColorPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
321 switch (msg)
323 case WM_PAINT:
325 PAINTSTRUCT ps;
326 int i, step;
327 RECT client, r;
328 HBRUSH hbr;
330 BeginPaint(hWnd, &ps);
331 GetClientRect(hWnd, &client);
332 step = client.right / 8;
334 for (i = 0; i < 16; i++)
336 r.top = (i / 8) * (client.bottom / 2);
337 r.bottom = r.top + client.bottom / 2;
338 r.left = (i & 7) * step;
339 r.right = r.left + step;
340 hbr = CreateSolidBrush(WCUSER_ColorMap[i]);
341 FillRect(ps.hdc, &r, hbr);
342 DeleteObject(hbr);
343 if (GetWindowLong(hWnd, 0) == i)
345 HPEN hOldPen;
346 int i = 2;
348 hOldPen = SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
349 r.right--; r.bottom--;
350 for (;;)
352 MoveToEx(ps.hdc, r.left, r.bottom, NULL);
353 LineTo(ps.hdc, r.left, r.top);
354 LineTo(ps.hdc, r.right, r.top);
355 SelectObject(ps.hdc, GetStockObject(BLACK_PEN));
356 LineTo(ps.hdc, r.right, r.bottom);
357 LineTo(ps.hdc, r.left, r.bottom);
359 if (--i == 0) break;
360 r.left++; r.top++; r.right--; r.bottom--;
361 SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
363 SelectObject(ps.hdc, hOldPen);
366 EndPaint(hWnd, &ps);
367 break;
369 case WM_LBUTTONDOWN:
371 int i, step;
372 RECT client;
374 GetClientRect(hWnd, &client);
375 step = client.right / 8;
376 i = (HIWORD(lParam) >= client.bottom / 2) ? 8 : 0;
377 i += LOWORD(lParam) / step;
378 SetWindowLong(hWnd, 0, i);
379 InvalidateRect(GetDlgItem(GetParent(hWnd), IDC_FNT_PREVIEW), NULL, FALSE);
380 InvalidateRect(hWnd, NULL, FALSE);
382 break;
383 default:
384 return DefWindowProc(hWnd, msg, wParam, lParam);
386 return 0L;
389 /******************************************************************
390 * font_enum
392 * enumerates all the font names with at least one valid font
394 static int CALLBACK font_enum_size2(const LOGFONT* lf, const TEXTMETRIC* tm,
395 DWORD FontType, LPARAM lParam)
397 struct dialog_info* di = (struct dialog_info*)lParam;
399 WCUSER_DumpTextMetric(tm, FontType);
400 if (WCUSER_ValidateFontMetric(di->data, tm, FontType))
402 di->nFont++;
405 return 1;
408 static int CALLBACK font_enum(const LOGFONT* lf, const TEXTMETRIC* tm,
409 DWORD FontType, LPARAM lParam)
411 struct dialog_info* di = (struct dialog_info*)lParam;
413 WCUSER_DumpLogFont("DlgFamily: ", lf, FontType);
414 if (WCUSER_ValidateFont(di->data, lf))
416 if (FontType & RASTER_FONTTYPE)
418 di->nFont = 0;
419 EnumFontFamilies(PRIVATE(di->data)->hMemDC, lf->lfFaceName, font_enum_size2, (LPARAM)di);
421 else
422 di->nFont = 1;
424 if (di->nFont)
426 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_ADDSTRING,
427 0, (LPARAM)lf->lfFaceName);
431 return 1;
434 /******************************************************************
435 * font_enum_size
439 static int CALLBACK font_enum_size(const LOGFONT* lf, const TEXTMETRIC* tm,
440 DWORD FontType, LPARAM lParam)
442 struct dialog_info* di = (struct dialog_info*)lParam;
443 WCHAR buf[32];
444 static const WCHAR fmt[] = {'%','l','d',0};
446 WCUSER_DumpTextMetric(tm, FontType);
447 if (di->nFont == 0 && !(FontType & RASTER_FONTTYPE))
449 static const int sizes[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
450 int i;
452 di->nFont = sizeof(sizes) / sizeof(sizes[0]);
453 di->font = HeapAlloc(GetProcessHeap(), 0, di->nFont * sizeof(di->font[0]));
454 for (i = 0; i < di->nFont; i++)
456 /* drop sizes where window size wouldn't fit on screen */
457 if (sizes[i] * di->data->curcfg.win_height > GetSystemMetrics(SM_CYSCREEN))
459 di->nFont = i;
460 break;
462 di->font[i].height = sizes[i];
463 di->font[i].weight = 400;
464 lstrcpy(di->font[i].faceName, lf->lfFaceName);
465 wsprintf(buf, fmt, sizes[i]);
466 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, i, (LPARAM)buf);
468 /* don't need to enumerate other */
469 return 0;
472 if (WCUSER_ValidateFontMetric(di->data, tm, FontType))
474 int idx;
476 /* we want the string to be sorted with a numeric order, not a lexicographic...
477 * do the job by hand... get where to insert the new string
479 for (idx = 0; idx < di->nFont && tm->tmHeight > di->font[idx].height; idx++);
480 while (idx < di->nFont &&
481 tm->tmHeight == di->font[idx].height &&
482 tm->tmWeight > di->font[idx].weight)
483 idx++;
484 if (idx == di->nFont ||
485 tm->tmHeight != di->font[idx].height ||
486 tm->tmWeight < di->font[idx].weight)
488 /* here we need to add the new entry */
489 wsprintf(buf, fmt, tm->tmHeight);
490 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, idx, (LPARAM)buf);
492 /* now grow our arrays and insert the values at the same index than in the list box */
493 di->font = HeapReAlloc(GetProcessHeap(), 0, di->font, sizeof(*di->font) * (di->nFont + 1));
494 if (idx != di->nFont)
495 memmove(&di->font[idx + 1], &di->font[idx], (di->nFont - idx) * sizeof(*di->font));
496 di->font[idx].height = tm->tmHeight;
497 di->font[idx].weight = tm->tmWeight;
498 lstrcpy(di->font[idx].faceName, lf->lfFaceName);
499 di->nFont++;
502 return 1;
505 /******************************************************************
506 * select_font
510 static BOOL select_font(struct dialog_info* di)
512 int font_idx, size_idx;
513 WCHAR buf[256];
514 WCHAR fmt[128];
515 LOGFONT lf;
516 HFONT hFont, hOldFont;
517 struct config_data config;
519 font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
520 size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
522 if (font_idx < 0 || size_idx < 0 || size_idx >= di->nFont)
523 return FALSE;
525 WCUSER_FillLogFont(&lf, di->font[size_idx].faceName,
526 di->font[size_idx].height, di->font[size_idx].weight);
527 hFont = WCUSER_CopyFont(&config, PRIVATE(di->data)->hWnd, &lf);
528 if (!hFont) return FALSE;
530 if (config.cell_height != di->font[size_idx].height)
531 WINE_TRACE("select_font: mismatched heights (%u<>%u)\n",
532 config.cell_height, di->font[size_idx].height);
533 hOldFont = (HFONT)SendDlgItemMessage(di->hDlg, IDC_FNT_PREVIEW, WM_GETFONT, 0L, 0L);
535 SendDlgItemMessage(di->hDlg, IDC_FNT_PREVIEW, WM_SETFONT, (DWORD)hFont, TRUE);
536 if (hOldFont) DeleteObject(hOldFont);
538 LoadString(GetModuleHandle(NULL), IDS_FNT_DISPLAY, fmt, sizeof(fmt) / sizeof(WCHAR));
539 wsprintf(buf, fmt, config.cell_width, config.cell_height);
541 SendDlgItemMessage(di->hDlg, IDC_FNT_FONT_INFO, WM_SETTEXT, 0, (LPARAM)buf);
543 return TRUE;
546 /******************************************************************
547 * fill_list_size
549 * fills the size list box according to selected family in font LB
551 static BOOL fill_list_size(struct dialog_info* di, BOOL doInit)
553 int idx;
554 WCHAR lfFaceName[LF_FACESIZE];
556 idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
557 if (idx < 0) return FALSE;
559 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETTEXT, idx, (LPARAM)lfFaceName);
560 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_RESETCONTENT, 0L, 0L);
561 if (di->font) HeapFree(GetProcessHeap(), 0, di->font);
562 di->nFont = 0;
563 di->font = NULL;
565 EnumFontFamilies(PRIVATE(di->data)->hMemDC, lfFaceName, font_enum_size, (LPARAM)di);
567 if (doInit)
569 int ref = -1;
571 for (idx = 0; idx < di->nFont; idx++)
573 if (!lstrcmp(di->font[idx].faceName, di->config->face_name) &&
574 di->font[idx].height == di->config->cell_height &&
575 di->font[idx].weight == di->config->font_weight)
577 if (ref == -1) ref = idx;
578 else WINE_TRACE("Several matches found: ref=%d idx=%d\n", ref, idx);
581 idx = (ref == -1) ? 0 : ref;
583 else
584 idx = 0;
585 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_SETCURSEL, idx, 0L);
586 select_font(di);
587 return TRUE;
590 /******************************************************************
591 * fill_list_font
593 * Fills the font LB
595 static BOOL fill_list_font(struct dialog_info* di)
597 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_RESETCONTENT, 0L, 0L);
598 EnumFontFamilies(PRIVATE(di->data)->hMemDC, NULL, font_enum, (LPARAM)di);
599 if (SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SELECTSTRING,
600 (WPARAM)-1, (LPARAM)di->config->face_name) == LB_ERR)
601 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SETCURSEL, 0L, 0L);
602 fill_list_size(di, TRUE);
603 return TRUE;
606 /******************************************************************
607 * WCUSER_FontDlgProc
609 * Dialog proc for the Font property sheet
611 static BOOL WINAPI WCUSER_FontDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
613 struct dialog_info* di;
615 switch (msg)
617 case WM_INITDIALOG:
618 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
619 di->hDlg = hDlg;
620 SetWindowLong(hDlg, DWL_USER, (DWORD)di);
621 /* remove dialog from this control, font will be reset when listboxes are filled */
622 SendDlgItemMessage(hDlg, IDC_FNT_PREVIEW, WM_SETFONT, 0L, 0L);
623 fill_list_font(di);
624 SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0, (di->config->def_attr >> 4) & 0x0F);
625 SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0, di->config->def_attr & 0x0F);
626 break;
627 case WM_COMMAND:
628 di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
629 switch (LOWORD(wParam))
631 case IDC_FNT_LIST_FONT:
632 if (HIWORD(wParam) == LBN_SELCHANGE)
634 fill_list_size(di, FALSE);
636 break;
637 case IDC_FNT_LIST_SIZE:
638 if (HIWORD(wParam) == LBN_SELCHANGE)
640 select_font(di);
642 break;
644 break;
645 case WM_NOTIFY:
647 NMHDR* nmhdr = (NMHDR*)lParam;
648 DWORD val;
650 di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
651 switch (nmhdr->code)
653 case PSN_SETACTIVE:
654 di->hDlg = hDlg;
655 break;
656 case PSN_APPLY:
657 val = SendDlgItemMessage(hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
659 if (val < di->nFont) (di->apply)(di, hDlg, WCUSER_ApplyToFont, val);
661 (di->apply)(di, hDlg, WCUSER_ApplyToAttribute,
662 (GetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0) << 4) |
663 GetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0));
665 SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
666 return TRUE;
667 default:
668 return FALSE;
670 break;
672 default:
673 return FALSE;
675 return TRUE;
678 /******************************************************************
679 * WCUSER_ConfigDlgProc
681 * Dialog proc for the config property sheet
683 static BOOL WINAPI WCUSER_ConfigDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
685 struct dialog_info* di;
687 switch (msg)
689 case WM_INITDIALOG:
690 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
691 di->hDlg = hDlg;
692 SetWindowLong(hDlg, DWL_USER, (DWORD)di);
693 SetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH, di->config->sb_width, FALSE);
694 SetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, di->config->sb_height, FALSE);
695 SetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH, di->config->win_width, FALSE);
696 SetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, di->config->win_height, FALSE);
697 break;
698 case WM_COMMAND:
699 di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
700 switch (LOWORD(wParam))
703 break;
704 case WM_NOTIFY:
706 NMHDR* nmhdr = (NMHDR*)lParam;
707 COORD sb;
708 SMALL_RECT pos;
709 BOOL st_w, st_h;
711 di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
712 switch (nmhdr->code)
714 case PSN_SETACTIVE:
715 di->hDlg = hDlg;
716 break;
717 case PSN_APPLY:
718 sb.X = GetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH, &st_w, FALSE);
719 sb.Y = GetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, &st_h, FALSE);
720 if (st_w && st_h && (sb.X != di->config->sb_width || sb.Y != di->config->sb_height))
722 (di->apply)(di, hDlg, WCUSER_ApplyToBufferSize, (DWORD)&sb);
725 pos.Right = GetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH, &st_w, FALSE);
726 pos.Bottom = GetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, &st_h, FALSE);
727 if (st_w && st_h &&
728 (pos.Right != di->config->win_width || pos.Bottom != di->config->win_height))
730 pos.Left = pos.Top = 0;
731 pos.Right--; pos.Bottom--;
732 (di->apply)(di, hDlg, WCUSER_ApplyToWindow, (DWORD)&pos);
734 SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
735 return TRUE;
736 default:
737 return FALSE;
739 break;
741 default:
742 return FALSE;
744 return TRUE;
747 /******************************************************************
748 * WCUSER_GetProperties
750 * Runs the dialog box to set up the winconsole options
752 BOOL WCUSER_GetProperties(struct inner_data* data, BOOL current)
754 HPROPSHEETPAGE psPage[3];
755 PROPSHEETPAGE psp;
756 PROPSHEETHEADER psHead;
757 WCHAR buff[256];
758 WNDCLASS wndclass;
759 static const WCHAR szFntPreview[] = {'W','i','n','e','C','o','n','F','o','n','t','P','r','e','v','i','e','w',0};
760 static const WCHAR szColorPreview[] = {'W','i','n','e','C','o','n','C','o','l','o','r','P','r','e','v','i','e','w',0};
761 struct dialog_info di;
763 InitCommonControls();
765 di.data = data;
766 if (current)
768 di.config = &data->curcfg;
769 di.apply = WCUSER_ApplyCurrent;
771 else
773 di.config = &data->defcfg;
774 di.apply = WCUSER_ApplyDefault;
776 di.nFont = 0;
777 di.font = NULL;
779 wndclass.style = 0;
780 wndclass.lpfnWndProc = WCUSER_FontPreviewProc;
781 wndclass.cbClsExtra = 0;
782 wndclass.cbWndExtra = 4; /* for hFont */
783 wndclass.hInstance = GetModuleHandle(NULL);
784 wndclass.hIcon = 0;
785 wndclass.hCursor = LoadCursor(0, IDC_ARROW);
786 wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
787 wndclass.lpszMenuName = NULL;
788 wndclass.lpszClassName = szFntPreview;
789 RegisterClass(&wndclass);
791 wndclass.style = 0;
792 wndclass.lpfnWndProc = WCUSER_ColorPreviewProc;
793 wndclass.cbClsExtra = 0;
794 wndclass.cbWndExtra = sizeof(DWORD);
795 wndclass.hInstance = GetModuleHandle(NULL);
796 wndclass.hIcon = 0;
797 wndclass.hCursor = LoadCursor(0, IDC_ARROW);
798 wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
799 wndclass.lpszMenuName = NULL;
800 wndclass.lpszClassName = szColorPreview;
801 RegisterClass(&wndclass);
803 memset(&psp, 0, sizeof(psp));
804 psp.dwSize = sizeof(psp);
805 psp.dwFlags = 0;
806 psp.hInstance = wndclass.hInstance;
807 psp.lParam = (LPARAM)&di;
809 psp.u.pszTemplate = MAKEINTRESOURCE(IDD_OPTION);
810 psp.pfnDlgProc = WCUSER_OptionDlgProc;
811 psPage[0] = CreatePropertySheetPage(&psp);
813 psp.u.pszTemplate = MAKEINTRESOURCE(IDD_FONT);
814 psp.pfnDlgProc = WCUSER_FontDlgProc;
815 psPage[1] = CreatePropertySheetPage(&psp);
817 psp.u.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG);
818 psp.pfnDlgProc = WCUSER_ConfigDlgProc;
819 psPage[2] = CreatePropertySheetPage(&psp);
821 memset(&psHead, 0, sizeof(psHead));
822 psHead.dwSize = sizeof(psHead);
824 if (!LoadString(GetModuleHandle(NULL),
825 (current) ? IDS_DLG_TIT_CURRENT : IDS_DLG_TIT_DEFAULT,
826 buff, sizeof(buff) / sizeof(buff[0])))
828 buff[0] = 'S';
829 buff[1] = 'e';
830 buff[2] = 't';
831 buff[3] = 'u';
832 buff[4] = 'p';
833 buff[5] = '\0';
836 psHead.pszCaption = buff;
837 psHead.nPages = 3;
838 psHead.hwndParent = PRIVATE(data)->hWnd;
839 psHead.u3.phpage = psPage;
841 PropertySheet(&psHead);
843 return TRUE;