msi: Select the first item in the SelectionTree control.
[wine.git] / programs / wineconsole / dialog.c
blob50fd3a8ff301a811580b21588726976f0e92ee6f
1 /* dialog management for wineconsole
2 * USER32 backend
3 * Copyright (c) 2001, 2002 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdarg.h>
24 #define NONAMELESSUNION
25 #define NONAMELESSSTRUCT
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "winnls.h"
31 #include "commctrl.h"
32 #include "prsht.h"
33 #include "winecon_user.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wineconsole);
39 struct dialog_info
41 struct config_data config; /* configuration used for dialog box */
42 struct inner_data* data; /* pointer to current winecon info */
43 HWND hDlg; /* handle to active propsheet */
44 int nFont; /* number of font size in size LB */
45 struct font_info
47 UINT height;
48 UINT weight;
49 WCHAR faceName[LF_FACESIZE];
50 } *font; /* array of nFont. index sync'ed with SIZE LB */
53 /******************************************************************
54 * WCUSER_OptionDlgProc
56 * Dialog prop for the option property sheet
58 static INT_PTR WINAPI WCUSER_OptionDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
60 struct dialog_info* di;
61 unsigned idc;
63 switch (msg)
65 case WM_INITDIALOG:
66 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
67 di->hDlg = hDlg;
68 SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)di);
70 if (di->config.cursor_size <= 25) idc = IDC_OPT_CURSOR_SMALL;
71 else if (di->config.cursor_size <= 50) idc = IDC_OPT_CURSOR_MEDIUM;
72 else idc = IDC_OPT_CURSOR_LARGE;
73 SendDlgItemMessage(hDlg, idc, BM_SETCHECK, BST_CHECKED, 0L);
74 SetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, WINECON_GetHistorySize(di->data->hConIn), FALSE);
75 SendDlgItemMessage(hDlg, IDC_OPT_HIST_NODOUBLE, BM_SETCHECK,
76 (di->config.history_nodup) ? BST_CHECKED : BST_UNCHECKED, 0L);
77 SendDlgItemMessage(hDlg, IDC_OPT_CONF_CTRL, BM_SETCHECK,
78 (di->config.menu_mask & MK_CONTROL) ? BST_CHECKED : BST_UNCHECKED, 0L);
79 SendDlgItemMessage(hDlg, IDC_OPT_CONF_SHIFT, BM_SETCHECK,
80 (di->config.menu_mask & MK_SHIFT) ? BST_CHECKED : BST_UNCHECKED, 0L);
81 SendDlgItemMessage(hDlg, IDC_OPT_QUICK_EDIT, BM_SETCHECK,
82 (di->config.quick_edit) ? BST_CHECKED : BST_UNCHECKED, 0L);
83 return FALSE; /* because we set the focus */
84 case WM_COMMAND:
85 break;
86 case WM_NOTIFY:
88 NMHDR* nmhdr = (NMHDR*)lParam;
89 DWORD val;
90 BOOL done;
92 di = (struct dialog_info*)GetWindowLongPtr(hDlg, DWLP_USER);
94 switch (nmhdr->code)
96 case PSN_SETACTIVE:
97 /* needed in propsheet to keep properly the selected radio button
98 * otherwise, the focus would be set to the first tab stop in the
99 * propsheet, which would always activate the first radio button
101 if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED)
102 idc = IDC_OPT_CURSOR_SMALL;
103 else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED)
104 idc = IDC_OPT_CURSOR_MEDIUM;
105 else
106 idc = IDC_OPT_CURSOR_LARGE;
107 PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, idc), TRUE);
108 di->hDlg = hDlg;
109 break;
110 case PSN_APPLY:
111 if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED) val = 25;
112 else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED) val = 50;
113 else val = 100;
114 di->config.cursor_size = val;
116 val = GetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, &done, FALSE);
117 if (done) di->config.history_size = val;
119 val = (IsDlgButtonChecked(hDlg, IDC_OPT_HIST_NODOUBLE) & BST_CHECKED) ? TRUE : FALSE;
120 di->config.history_nodup = val;
122 val = 0;
123 if (IsDlgButtonChecked(hDlg, IDC_OPT_CONF_CTRL) & BST_CHECKED) val |= MK_CONTROL;
124 if (IsDlgButtonChecked(hDlg, IDC_OPT_CONF_SHIFT) & BST_CHECKED) val |= MK_SHIFT;
125 di->config.menu_mask = val;
127 val = (IsDlgButtonChecked(hDlg, IDC_OPT_QUICK_EDIT) & BST_CHECKED) ? TRUE : FALSE;
128 di->config.quick_edit = val;
130 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
131 return TRUE;
132 default:
133 return FALSE;
135 break;
137 default:
138 return FALSE;
140 return TRUE;
143 /******************************************************************
144 * WCUSER_FontPreviewProc
146 * Window proc for font previewer in font property sheet
148 static LRESULT WINAPI WCUSER_FontPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
150 switch (msg)
152 case WM_CREATE:
153 SetWindowLongPtr(hWnd, 0, 0);
154 break;
155 case WM_GETFONT:
156 return GetWindowLongPtr(hWnd, 0);
157 case WM_SETFONT:
158 SetWindowLongPtr(hWnd, 0, wParam);
159 if (LOWORD(lParam))
161 InvalidateRect(hWnd, NULL, TRUE);
162 UpdateWindow(hWnd);
164 break;
165 case WM_DESTROY:
167 HFONT hFont = (HFONT)GetWindowLongPtr(hWnd, 0L);
168 if (hFont) DeleteObject(hFont);
170 break;
171 case WM_PAINT:
173 PAINTSTRUCT ps;
174 int font_idx;
175 int size_idx;
176 struct dialog_info* di;
177 HFONT hFont, hOldFont;
179 di = (struct dialog_info*)GetWindowLongPtr(GetParent(hWnd), DWLP_USER);
180 BeginPaint(hWnd, &ps);
182 font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
183 size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
185 hFont = (HFONT)GetWindowLongPtr(hWnd, 0L);
186 if (hFont)
188 WCHAR buf1[256];
189 WCHAR buf2[256];
190 int len1, len2;
192 len1 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_1,
193 buf1, sizeof(buf1) / sizeof(WCHAR));
194 len2 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_2,
195 buf2, sizeof(buf2) / sizeof(WCHAR));
196 buf1[len1] = buf2[len2] = 0;
197 if (len1)
199 hOldFont = SelectObject(ps.hdc, hFont);
200 SetBkColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_BK), 0)]);
201 SetTextColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_FG), 0)]);
202 TextOut(ps.hdc, 0, 0, buf1, len1);
203 if (len2)
204 TextOut(ps.hdc, 0, di->font[size_idx].height, buf2, len2);
205 SelectObject(ps.hdc, hOldFont);
208 EndPaint(hWnd, &ps);
210 break;
211 default:
212 return DefWindowProc(hWnd, msg, wParam, lParam);
214 return 0L;
217 /******************************************************************
218 * WCUSER_ColorPreviewProc
220 * Window proc for color previewer in font property sheet
222 static LRESULT WINAPI WCUSER_ColorPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
224 switch (msg)
226 case WM_PAINT:
228 PAINTSTRUCT ps;
229 int i, step;
230 RECT client, r;
231 HBRUSH hbr;
233 BeginPaint(hWnd, &ps);
234 GetClientRect(hWnd, &client);
235 step = client.right / 8;
237 for (i = 0; i < 16; i++)
239 r.top = (i / 8) * (client.bottom / 2);
240 r.bottom = r.top + client.bottom / 2;
241 r.left = (i & 7) * step;
242 r.right = r.left + step;
243 hbr = CreateSolidBrush(WCUSER_ColorMap[i]);
244 FillRect(ps.hdc, &r, hbr);
245 DeleteObject(hbr);
246 if (GetWindowLong(hWnd, 0) == i)
248 HPEN hOldPen;
249 int i = 2;
251 hOldPen = SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
252 r.right--; r.bottom--;
253 for (;;)
255 MoveToEx(ps.hdc, r.left, r.bottom, NULL);
256 LineTo(ps.hdc, r.left, r.top);
257 LineTo(ps.hdc, r.right, r.top);
258 SelectObject(ps.hdc, GetStockObject(BLACK_PEN));
259 LineTo(ps.hdc, r.right, r.bottom);
260 LineTo(ps.hdc, r.left, r.bottom);
262 if (--i == 0) break;
263 r.left++; r.top++; r.right--; r.bottom--;
264 SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
266 SelectObject(ps.hdc, hOldPen);
269 EndPaint(hWnd, &ps);
270 break;
272 case WM_LBUTTONDOWN:
274 int i, step;
275 RECT client;
277 GetClientRect(hWnd, &client);
278 step = client.right / 8;
279 i = (HIWORD(lParam) >= client.bottom / 2) ? 8 : 0;
280 i += LOWORD(lParam) / step;
281 SetWindowLong(hWnd, 0, i);
282 InvalidateRect(GetDlgItem(GetParent(hWnd), IDC_FNT_PREVIEW), NULL, FALSE);
283 InvalidateRect(hWnd, NULL, FALSE);
285 break;
286 default:
287 return DefWindowProc(hWnd, msg, wParam, lParam);
289 return 0L;
292 /******************************************************************
293 * font_enum
295 * enumerates all the font names with at least one valid font
297 static int CALLBACK font_enum_size2(const LOGFONT* lf, const TEXTMETRIC* tm,
298 DWORD FontType, LPARAM lParam)
300 struct dialog_info* di = (struct dialog_info*)lParam;
302 WCUSER_DumpTextMetric(tm, FontType);
303 if (WCUSER_ValidateFontMetric(di->data, tm, FontType))
305 di->nFont++;
308 return 1;
311 static int CALLBACK font_enum(const LOGFONT* lf, const TEXTMETRIC* tm,
312 DWORD FontType, LPARAM lParam)
314 struct dialog_info* di = (struct dialog_info*)lParam;
316 WCUSER_DumpLogFont("DlgFamily: ", lf, FontType);
317 if (WCUSER_ValidateFont(di->data, lf))
319 if (FontType & RASTER_FONTTYPE)
321 di->nFont = 0;
322 EnumFontFamilies(PRIVATE(di->data)->hMemDC, lf->lfFaceName, font_enum_size2, (LPARAM)di);
324 else
325 di->nFont = 1;
327 if (di->nFont)
329 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_ADDSTRING,
330 0, (LPARAM)lf->lfFaceName);
334 return 1;
337 /******************************************************************
338 * font_enum_size
342 static int CALLBACK font_enum_size(const LOGFONT* lf, const TEXTMETRIC* tm,
343 DWORD FontType, LPARAM lParam)
345 struct dialog_info* di = (struct dialog_info*)lParam;
346 WCHAR buf[32];
347 static const WCHAR fmt[] = {'%','l','d',0};
349 WCUSER_DumpTextMetric(tm, FontType);
350 if (di->nFont == 0 && !(FontType & RASTER_FONTTYPE))
352 static const int sizes[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
353 int i;
355 di->nFont = sizeof(sizes) / sizeof(sizes[0]);
356 di->font = HeapAlloc(GetProcessHeap(), 0, di->nFont * sizeof(di->font[0]));
357 for (i = 0; i < di->nFont; i++)
359 /* drop sizes where window size wouldn't fit on screen */
360 if (sizes[i] * di->data->curcfg.win_height > GetSystemMetrics(SM_CYSCREEN))
362 di->nFont = i;
363 break;
365 di->font[i].height = sizes[i];
366 di->font[i].weight = 400;
367 lstrcpy(di->font[i].faceName, lf->lfFaceName);
368 wsprintf(buf, fmt, sizes[i]);
369 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, i, (LPARAM)buf);
371 /* don't need to enumerate other */
372 return 0;
375 if (WCUSER_ValidateFontMetric(di->data, tm, FontType))
377 int idx;
379 /* we want the string to be sorted with a numeric order, not a lexicographic...
380 * do the job by hand... get where to insert the new string
382 for (idx = 0; idx < di->nFont && tm->tmHeight > di->font[idx].height; idx++);
383 while (idx < di->nFont &&
384 tm->tmHeight == di->font[idx].height &&
385 tm->tmWeight > di->font[idx].weight)
386 idx++;
387 if (idx == di->nFont ||
388 tm->tmHeight != di->font[idx].height ||
389 tm->tmWeight < di->font[idx].weight)
391 /* here we need to add the new entry */
392 wsprintf(buf, fmt, tm->tmHeight);
393 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, idx, (LPARAM)buf);
395 /* now grow our arrays and insert the values at the same index than in the list box */
396 if (di->nFont)
398 di->font = HeapReAlloc(GetProcessHeap(), 0, di->font, sizeof(*di->font) * (di->nFont + 1));
399 if (idx != di->nFont)
400 memmove(&di->font[idx + 1], &di->font[idx], (di->nFont - idx) * sizeof(*di->font));
402 else
403 di->font = HeapAlloc(GetProcessHeap(), 0, sizeof(*di->font));
404 di->font[idx].height = tm->tmHeight;
405 di->font[idx].weight = tm->tmWeight;
406 lstrcpy(di->font[idx].faceName, lf->lfFaceName);
407 di->nFont++;
410 return 1;
413 /******************************************************************
414 * select_font
418 static BOOL select_font(struct dialog_info* di)
420 int font_idx, size_idx;
421 WCHAR buf[256];
422 WCHAR fmt[128];
423 LOGFONT lf;
424 HFONT hFont, hOldFont;
425 struct config_data config;
427 font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
428 size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
430 if (font_idx < 0 || size_idx < 0 || size_idx >= di->nFont)
431 return FALSE;
433 WCUSER_FillLogFont(&lf, di->font[size_idx].faceName,
434 di->font[size_idx].height, di->font[size_idx].weight);
435 hFont = WCUSER_CopyFont(&config, PRIVATE(di->data)->hWnd, &lf, NULL);
436 if (!hFont) return FALSE;
438 if (config.cell_height != di->font[size_idx].height)
439 WINE_TRACE("mismatched heights (%u<>%u)\n",
440 config.cell_height, di->font[size_idx].height);
441 hOldFont = (HFONT)SendDlgItemMessage(di->hDlg, IDC_FNT_PREVIEW, WM_GETFONT, 0L, 0L);
443 SendDlgItemMessage(di->hDlg, IDC_FNT_PREVIEW, WM_SETFONT, (WPARAM)hFont, TRUE);
444 if (hOldFont) DeleteObject(hOldFont);
446 LoadString(GetModuleHandle(NULL), IDS_FNT_DISPLAY, fmt, sizeof(fmt) / sizeof(WCHAR));
447 wsprintf(buf, fmt, config.cell_width, config.cell_height);
449 SendDlgItemMessage(di->hDlg, IDC_FNT_FONT_INFO, WM_SETTEXT, 0, (LPARAM)buf);
451 return TRUE;
454 /******************************************************************
455 * fill_list_size
457 * fills the size list box according to selected family in font LB
459 static BOOL fill_list_size(struct dialog_info* di, BOOL doInit)
461 int idx;
462 WCHAR lfFaceName[LF_FACESIZE];
464 idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
465 if (idx < 0) return FALSE;
467 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETTEXT, idx, (LPARAM)lfFaceName);
468 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_RESETCONTENT, 0L, 0L);
469 HeapFree(GetProcessHeap(), 0, di->font);
470 di->nFont = 0;
471 di->font = NULL;
473 EnumFontFamilies(PRIVATE(di->data)->hMemDC, lfFaceName, font_enum_size, (LPARAM)di);
475 if (doInit)
477 int ref = -1;
479 for (idx = 0; idx < di->nFont; idx++)
481 if (!lstrcmp(di->font[idx].faceName, di->config.face_name) &&
482 di->font[idx].height == di->config.cell_height &&
483 di->font[idx].weight == di->config.font_weight)
485 if (ref == -1) ref = idx;
486 else WINE_TRACE("Several matches found: ref=%d idx=%d\n", ref, idx);
489 idx = (ref == -1) ? 0 : ref;
491 else
492 idx = 0;
493 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_SETCURSEL, idx, 0L);
494 select_font(di);
495 return TRUE;
498 /******************************************************************
499 * fill_list_font
501 * Fills the font LB
503 static BOOL fill_list_font(struct dialog_info* di)
505 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_RESETCONTENT, 0L, 0L);
506 EnumFontFamilies(PRIVATE(di->data)->hMemDC, NULL, font_enum, (LPARAM)di);
507 if (SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SELECTSTRING,
508 (WPARAM)-1, (LPARAM)di->config.face_name) == LB_ERR)
509 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SETCURSEL, 0L, 0L);
510 fill_list_size(di, TRUE);
511 return TRUE;
514 /******************************************************************
515 * WCUSER_FontDlgProc
517 * Dialog proc for the Font property sheet
519 static INT_PTR WINAPI WCUSER_FontDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
521 struct dialog_info* di;
523 switch (msg)
525 case WM_INITDIALOG:
526 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
527 di->hDlg = hDlg;
528 SetWindowLongPtr(hDlg, DWLP_USER, (DWORD_PTR)di);
529 /* remove dialog from this control, font will be reset when listboxes are filled */
530 SendDlgItemMessage(hDlg, IDC_FNT_PREVIEW, WM_SETFONT, 0L, 0L);
531 fill_list_font(di);
532 SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0, (di->config.def_attr >> 4) & 0x0F);
533 SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0, di->config.def_attr & 0x0F);
534 break;
535 case WM_COMMAND:
536 di = (struct dialog_info*)GetWindowLongPtr(hDlg, DWLP_USER);
537 switch (LOWORD(wParam))
539 case IDC_FNT_LIST_FONT:
540 if (HIWORD(wParam) == LBN_SELCHANGE)
542 fill_list_size(di, FALSE);
544 break;
545 case IDC_FNT_LIST_SIZE:
546 if (HIWORD(wParam) == LBN_SELCHANGE)
548 select_font(di);
550 break;
552 break;
553 case WM_NOTIFY:
555 NMHDR* nmhdr = (NMHDR*)lParam;
556 DWORD val;
558 di = (struct dialog_info*)GetWindowLongPtr(hDlg, DWLP_USER);
559 switch (nmhdr->code)
561 case PSN_SETACTIVE:
562 di->hDlg = hDlg;
563 break;
564 case PSN_APPLY:
565 val = SendDlgItemMessage(hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
567 if (val < di->nFont)
569 LOGFONT lf;
571 WCUSER_FillLogFont(&lf, di->font[val].faceName,
572 di->font[val].height, di->font[val].weight);
573 DeleteObject(WCUSER_CopyFont(&di->config,
574 PRIVATE(di->data)->hWnd, &lf, NULL));
577 val = (GetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0) << 4) |
578 GetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0);
579 di->config.def_attr = val;
581 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
582 return TRUE;
583 default:
584 return FALSE;
586 break;
588 default:
589 return FALSE;
591 return TRUE;
594 /******************************************************************
595 * WCUSER_ConfigDlgProc
597 * Dialog proc for the config property sheet
599 static INT_PTR WINAPI WCUSER_ConfigDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
601 struct dialog_info* di;
603 switch (msg)
605 case WM_INITDIALOG:
606 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
607 di->hDlg = hDlg;
608 SetWindowLongPtr(hDlg, DWLP_USER, (DWORD_PTR)di);
609 SetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH, di->config.sb_width, FALSE);
610 SetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, di->config.sb_height, FALSE);
611 SetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH, di->config.win_width, FALSE);
612 SetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, di->config.win_height, FALSE);
613 SendDlgItemMessage(hDlg, IDC_CNF_CLOSE_EXIT, BM_SETCHECK,
614 (di->config.exit_on_die) ? BST_CHECKED : BST_UNCHECKED, 0L);
616 static const WCHAR s1[] = {'W','i','n','3','2',0};
617 static const WCHAR s2[] = {'E','m','a','c','s',0};
619 SendDlgItemMessage(hDlg, IDC_CNF_EDITION_MODE, CB_ADDSTRING,
620 0, (LPARAM)s1);
621 SendDlgItemMessage(hDlg, IDC_CNF_EDITION_MODE, CB_ADDSTRING,
622 0, (LPARAM)s2);
623 SendDlgItemMessage(hDlg, IDC_CNF_EDITION_MODE, CB_SETCURSEL,
624 di->config.edition_mode, 0);
627 break;
628 case WM_COMMAND:
629 di = (struct dialog_info*)GetWindowLongPtr(hDlg, DWLP_USER);
630 switch (LOWORD(wParam))
633 break;
634 case WM_NOTIFY:
636 NMHDR* nmhdr = (NMHDR*)lParam;
637 int win_w, win_h, sb_w, sb_h;
638 BOOL st1, st2;
640 di = (struct dialog_info*)GetWindowLongPtr(hDlg, DWLP_USER);
641 switch (nmhdr->code)
643 case PSN_SETACTIVE:
644 di->hDlg = hDlg;
645 break;
646 case PSN_APPLY:
647 sb_w = GetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH, &st1, FALSE);
648 sb_h = GetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, &st2, FALSE);
649 if (!st1 || ! st2)
651 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
652 return TRUE;
654 win_w = GetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH, &st1, FALSE);
655 win_h = GetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, &st2, FALSE);
656 if (!st1 || !st2)
658 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
659 return TRUE;
661 if (win_w > sb_w || win_h > sb_h)
663 WCHAR cap[256];
664 WCHAR txt[256];
666 LoadString(GetModuleHandle(NULL), IDS_DLG_TIT_ERROR,
667 cap, sizeof(cap) / sizeof(WCHAR));
668 LoadString(GetModuleHandle(NULL), IDS_DLG_ERR_SBWINSIZE,
669 txt, sizeof(txt) / sizeof(WCHAR));
671 MessageBox(hDlg, txt, cap, MB_OK);
672 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
673 return TRUE;
675 di->config.win_width = win_w;
676 di->config.win_height = win_h;
677 di->config.sb_width = sb_w;
678 di->config.sb_height = sb_h;
680 di->config.exit_on_die = IsDlgButtonChecked(hDlg, IDC_CNF_CLOSE_EXIT) ? 1 : 0;
681 di->config.edition_mode = SendDlgItemMessage(hDlg, IDC_CNF_EDITION_MODE, CB_GETCURSEL,
682 0, 0);
683 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
684 return TRUE;
685 default:
686 return FALSE;
688 break;
690 default:
691 return FALSE;
693 return TRUE;
696 /******************************************************************
697 * WCUSER_SaveDlgProc
699 * Dialog Procedure for choosing how to handle modification to the
700 * console settings.
702 static INT_PTR WINAPI WCUSER_SaveDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
704 switch (msg)
706 case WM_INITDIALOG:
707 break;
708 case WM_COMMAND:
709 switch (LOWORD(wParam))
711 case IDOK:
712 EndDialog(hDlg,
713 (IsDlgButtonChecked(hDlg, IDC_SAV_SAVE) == BST_CHECKED) ?
714 IDC_SAV_SAVE : IDC_SAV_SESSION);
715 break;
716 case IDCANCEL:
717 EndDialog(hDlg, IDCANCEL); break;
719 break;
720 default:
721 return FALSE;
723 return TRUE;
726 /******************************************************************
727 * WCUSER_GetProperties
729 * Runs the dialog box to set up the wineconsole options
731 BOOL WCUSER_GetProperties(struct inner_data* data, BOOL current)
733 HPROPSHEETPAGE psPage[3];
734 PROPSHEETPAGE psp;
735 PROPSHEETHEADER psHead;
736 WCHAR buff[256];
737 WNDCLASS wndclass;
738 static const WCHAR szFntPreview[] = {'W','i','n','e','C','o','n','F','o','n','t','P','r','e','v','i','e','w',0};
739 static const WCHAR szColorPreview[] = {'W','i','n','e','C','o','n','C','o','l','o','r','P','r','e','v','i','e','w',0};
740 struct dialog_info di;
741 struct config_data defcfg;
742 struct config_data* refcfg;
743 BOOL save, modify_session;
745 InitCommonControls();
747 di.data = data;
748 if (current)
750 refcfg = &data->curcfg;
751 save = FALSE;
753 else
755 WINECON_RegLoad(NULL, refcfg = &defcfg);
756 save = TRUE;
758 di.config = *refcfg;
759 di.nFont = 0;
760 di.font = NULL;
762 modify_session = FALSE;
764 wndclass.style = 0;
765 wndclass.lpfnWndProc = WCUSER_FontPreviewProc;
766 wndclass.cbClsExtra = 0;
767 wndclass.cbWndExtra = sizeof (DWORD_PTR); /* for hFont */
768 wndclass.hInstance = GetModuleHandle(NULL);
769 wndclass.hIcon = 0;
770 wndclass.hCursor = LoadCursor(0, IDC_ARROW);
771 wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
772 wndclass.lpszMenuName = NULL;
773 wndclass.lpszClassName = szFntPreview;
774 RegisterClass(&wndclass);
776 wndclass.style = 0;
777 wndclass.lpfnWndProc = WCUSER_ColorPreviewProc;
778 wndclass.cbClsExtra = 0;
779 wndclass.cbWndExtra = sizeof(DWORD);
780 wndclass.hInstance = GetModuleHandle(NULL);
781 wndclass.hIcon = 0;
782 wndclass.hCursor = LoadCursor(0, IDC_ARROW);
783 wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
784 wndclass.lpszMenuName = NULL;
785 wndclass.lpszClassName = szColorPreview;
786 RegisterClass(&wndclass);
788 memset(&psp, 0, sizeof(psp));
789 psp.dwSize = sizeof(psp);
790 psp.dwFlags = 0;
791 psp.hInstance = wndclass.hInstance;
792 psp.lParam = (LPARAM)&di;
794 psp.u.pszTemplate = MAKEINTRESOURCE(IDD_OPTION);
795 psp.pfnDlgProc = WCUSER_OptionDlgProc;
796 psPage[0] = CreatePropertySheetPage(&psp);
798 psp.u.pszTemplate = MAKEINTRESOURCE(IDD_FONT);
799 psp.pfnDlgProc = WCUSER_FontDlgProc;
800 psPage[1] = CreatePropertySheetPage(&psp);
802 psp.u.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG);
803 psp.pfnDlgProc = WCUSER_ConfigDlgProc;
804 psPage[2] = CreatePropertySheetPage(&psp);
806 memset(&psHead, 0, sizeof(psHead));
807 psHead.dwSize = sizeof(psHead);
809 if (!LoadString(GetModuleHandle(NULL),
810 (current) ? IDS_DLG_TIT_CURRENT : IDS_DLG_TIT_DEFAULT,
811 buff, sizeof(buff) / sizeof(buff[0])))
813 buff[0] = 'S';
814 buff[1] = 'e';
815 buff[2] = 't';
816 buff[3] = 'u';
817 buff[4] = 'p';
818 buff[5] = '\0';
821 psHead.pszCaption = buff;
822 psHead.nPages = 3;
823 psHead.hwndParent = PRIVATE(data)->hWnd;
824 psHead.u3.phpage = psPage;
826 WINECON_DumpConfig("init", refcfg);
828 PropertySheet(&psHead);
830 if (memcmp(refcfg, &di.config, sizeof(*refcfg)) == 0)
831 return TRUE;
833 WINECON_DumpConfig("ref", refcfg);
834 WINECON_DumpConfig("cur", &di.config);
835 if (refcfg == &data->curcfg)
837 switch (DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_SAVE_SETTINGS),
838 PRIVATE(data)->hWnd, WCUSER_SaveDlgProc))
840 case IDC_SAV_SAVE: save = TRUE; modify_session = TRUE; break;
841 case IDC_SAV_SESSION: modify_session = TRUE; break;
842 case IDCANCEL: break;
843 default: WINE_ERR("ooch\n");
847 if (modify_session) WINECON_SetConfig(data, &di.config);
848 if (save) WINECON_RegSave(&di.config);
850 return TRUE;