Release 1.5.0.
[wine/multimedia.git] / programs / wineconsole / dialog.c
blob831b2a9e7c74c5379f12b679d5b193d4601f2c4d
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 SetWindowLongPtrW(hDlg, DWLP_USER, (LONG_PTR)di);
70 SendMessageW(GetDlgItem(hDlg,IDC_OPT_HIST_SIZE_UD), UDM_SETRANGE, 0, MAKELPARAM(500, 0));
72 if (di->config.cursor_size <= 25) idc = IDC_OPT_CURSOR_SMALL;
73 else if (di->config.cursor_size <= 50) idc = IDC_OPT_CURSOR_MEDIUM;
74 else idc = IDC_OPT_CURSOR_LARGE;
75 SendDlgItemMessageW(hDlg, idc, BM_SETCHECK, BST_CHECKED, 0);
76 SetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, di->config.history_size, FALSE);
77 SendDlgItemMessageW(hDlg, IDC_OPT_HIST_NODOUBLE, BM_SETCHECK,
78 (di->config.history_nodup) ? BST_CHECKED : BST_UNCHECKED, 0);
79 SendDlgItemMessageW(hDlg, IDC_OPT_CONF_CTRL, BM_SETCHECK,
80 (di->config.menu_mask & MK_CONTROL) ? BST_CHECKED : BST_UNCHECKED, 0);
81 SendDlgItemMessageW(hDlg, IDC_OPT_CONF_SHIFT, BM_SETCHECK,
82 (di->config.menu_mask & MK_SHIFT) ? BST_CHECKED : BST_UNCHECKED, 0);
83 SendDlgItemMessageW(hDlg, IDC_OPT_QUICK_EDIT, BM_SETCHECK,
84 (di->config.quick_edit) ? BST_CHECKED : BST_UNCHECKED, 0);
85 return FALSE; /* because we set the focus */
86 case WM_COMMAND:
87 break;
88 case WM_NOTIFY:
90 NMHDR* nmhdr = (NMHDR*)lParam;
91 DWORD val;
92 BOOL done;
94 di = (struct dialog_info*)GetWindowLongPtrW(hDlg, DWLP_USER);
96 switch (nmhdr->code)
98 case PSN_SETACTIVE:
99 /* needed in propsheet to keep properly the selected radio button
100 * otherwise, the focus would be set to the first tab stop in the
101 * propsheet, which would always activate the first radio button
103 if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED)
104 idc = IDC_OPT_CURSOR_SMALL;
105 else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED)
106 idc = IDC_OPT_CURSOR_MEDIUM;
107 else
108 idc = IDC_OPT_CURSOR_LARGE;
109 PostMessageW(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, idc), TRUE);
110 di->hDlg = hDlg;
111 break;
112 case PSN_APPLY:
113 if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED) val = 25;
114 else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED) val = 50;
115 else val = 100;
116 di->config.cursor_size = val;
118 val = GetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, &done, FALSE);
119 if (done) di->config.history_size = val;
121 val = (IsDlgButtonChecked(hDlg, IDC_OPT_HIST_NODOUBLE) & BST_CHECKED) ? TRUE : FALSE;
122 di->config.history_nodup = val;
124 val = 0;
125 if (IsDlgButtonChecked(hDlg, IDC_OPT_CONF_CTRL) & BST_CHECKED) val |= MK_CONTROL;
126 if (IsDlgButtonChecked(hDlg, IDC_OPT_CONF_SHIFT) & BST_CHECKED) val |= MK_SHIFT;
127 di->config.menu_mask = val;
129 val = (IsDlgButtonChecked(hDlg, IDC_OPT_QUICK_EDIT) & BST_CHECKED) ? TRUE : FALSE;
130 di->config.quick_edit = val;
132 SetWindowLongPtrW(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
133 return TRUE;
134 default:
135 return FALSE;
137 break;
139 default:
140 return FALSE;
142 return TRUE;
145 /******************************************************************
146 * WCUSER_FontPreviewProc
148 * Window proc for font previewer in font property sheet
150 static LRESULT WINAPI WCUSER_FontPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
152 switch (msg)
154 case WM_CREATE:
155 SetWindowLongPtrW(hWnd, 0, 0);
156 break;
157 case WM_GETFONT:
158 return GetWindowLongPtrW(hWnd, 0);
159 case WM_SETFONT:
160 SetWindowLongPtrW(hWnd, 0, wParam);
161 if (LOWORD(lParam))
163 InvalidateRect(hWnd, NULL, TRUE);
164 UpdateWindow(hWnd);
166 break;
167 case WM_DESTROY:
169 HFONT hFont = (HFONT)GetWindowLongPtrW(hWnd, 0);
170 if (hFont) DeleteObject(hFont);
172 break;
173 case WM_PAINT:
175 PAINTSTRUCT ps;
176 int size_idx;
177 struct dialog_info* di;
178 HFONT hFont, hOldFont;
180 di = (struct dialog_info*)GetWindowLongPtrW(GetParent(hWnd), DWLP_USER);
181 BeginPaint(hWnd, &ps);
183 size_idx = SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0, 0);
185 hFont = (HFONT)GetWindowLongPtrW(hWnd, 0);
186 if (hFont)
188 WCHAR ascii[] = {'A','S','C','I','I',':',' ','a','b','c','X','Y','Z','\0'};
189 WCHAR buf[256];
190 int len;
192 hOldFont = SelectObject(ps.hdc, hFont);
193 SetBkColor(ps.hdc, WCUSER_ColorMap[GetWindowLongW(GetDlgItem(di->hDlg, IDC_FNT_COLOR_BK), 0)]);
194 SetTextColor(ps.hdc, WCUSER_ColorMap[GetWindowLongW(GetDlgItem(di->hDlg, IDC_FNT_COLOR_FG), 0)]);
195 len = LoadStringW(GetModuleHandleW(NULL), IDS_FNT_PREVIEW,
196 buf, sizeof(buf) / sizeof(buf[0]));
197 if (len)
198 TextOutW(ps.hdc, 0, 0, buf, len);
199 TextOutW(ps.hdc, 0, di->font[size_idx].height, ascii,
200 sizeof(ascii)/sizeof(ascii[0]) - 1);
201 SelectObject(ps.hdc, hOldFont);
203 EndPaint(hWnd, &ps);
205 break;
206 default:
207 return DefWindowProcW(hWnd, msg, wParam, lParam);
209 return 0L;
212 /******************************************************************
213 * WCUSER_ColorPreviewProc
215 * Window proc for color previewer in font property sheet
217 static LRESULT WINAPI WCUSER_ColorPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
219 switch (msg)
221 case WM_PAINT:
223 PAINTSTRUCT ps;
224 int i, step;
225 RECT client, r;
226 HBRUSH hbr;
228 BeginPaint(hWnd, &ps);
229 GetClientRect(hWnd, &client);
230 step = client.right / 8;
232 for (i = 0; i < 16; i++)
234 r.top = (i / 8) * (client.bottom / 2);
235 r.bottom = r.top + client.bottom / 2;
236 r.left = (i & 7) * step;
237 r.right = r.left + step;
238 hbr = CreateSolidBrush(WCUSER_ColorMap[i]);
239 FillRect(ps.hdc, &r, hbr);
240 DeleteObject(hbr);
241 if (GetWindowLongW(hWnd, 0) == i)
243 HPEN hOldPen;
244 int i = 2;
246 hOldPen = SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
247 r.right--; r.bottom--;
248 for (;;)
250 MoveToEx(ps.hdc, r.left, r.bottom, NULL);
251 LineTo(ps.hdc, r.left, r.top);
252 LineTo(ps.hdc, r.right, r.top);
253 SelectObject(ps.hdc, GetStockObject(BLACK_PEN));
254 LineTo(ps.hdc, r.right, r.bottom);
255 LineTo(ps.hdc, r.left, r.bottom);
257 if (--i == 0) break;
258 r.left++; r.top++; r.right--; r.bottom--;
259 SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
261 SelectObject(ps.hdc, hOldPen);
264 EndPaint(hWnd, &ps);
265 break;
267 case WM_LBUTTONDOWN:
269 int i, step;
270 RECT client;
272 GetClientRect(hWnd, &client);
273 step = client.right / 8;
274 i = (HIWORD(lParam) >= client.bottom / 2) ? 8 : 0;
275 i += LOWORD(lParam) / step;
276 SetWindowLongW(hWnd, 0, i);
277 InvalidateRect(GetDlgItem(GetParent(hWnd), IDC_FNT_PREVIEW), NULL, FALSE);
278 InvalidateRect(hWnd, NULL, FALSE);
280 break;
281 default:
282 return DefWindowProcW(hWnd, msg, wParam, lParam);
284 return 0L;
287 /******************************************************************
288 * font_enum
290 * enumerates all the font names with at least one valid font
292 static int CALLBACK font_enum_size2(const LOGFONTW* lf, const TEXTMETRICW* tm,
293 DWORD FontType, LPARAM lParam)
295 struct dialog_info* di = (struct dialog_info*)lParam;
297 WCUSER_DumpTextMetric(tm, FontType);
298 if (WCUSER_ValidateFontMetric(di->data, tm, FontType))
300 di->nFont++;
303 return 1;
306 static int CALLBACK font_enum(const LOGFONTW* lf, const TEXTMETRICW* tm,
307 DWORD FontType, LPARAM lParam)
309 struct dialog_info* di = (struct dialog_info*)lParam;
311 WCUSER_DumpLogFont("DlgFamily: ", lf, FontType);
312 if (WCUSER_ValidateFont(di->data, lf))
314 if (FontType & RASTER_FONTTYPE)
316 di->nFont = 0;
317 EnumFontFamiliesW(PRIVATE(di->data)->hMemDC, lf->lfFaceName, font_enum_size2, (LPARAM)di);
319 else
320 di->nFont = 1;
322 if (di->nFont)
324 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_FONT, LB_ADDSTRING,
325 0, (LPARAM)lf->lfFaceName);
329 return 1;
332 /******************************************************************
333 * font_enum_size
337 static int CALLBACK font_enum_size(const LOGFONTW* lf, const TEXTMETRICW* tm,
338 DWORD FontType, LPARAM lParam)
340 struct dialog_info* di = (struct dialog_info*)lParam;
341 WCHAR buf[32];
342 static const WCHAR fmt[] = {'%','l','d',0};
344 WCUSER_DumpTextMetric(tm, FontType);
345 if (di->nFont == 0 && !(FontType & RASTER_FONTTYPE))
347 static const int sizes[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
348 int i;
350 di->nFont = sizeof(sizes) / sizeof(sizes[0]);
351 di->font = HeapAlloc(GetProcessHeap(), 0, di->nFont * sizeof(di->font[0]));
352 for (i = 0; i < di->nFont; i++)
354 /* drop sizes where window size wouldn't fit on screen */
355 if (sizes[i] * di->data->curcfg.win_height > GetSystemMetrics(SM_CYSCREEN))
357 di->nFont = i;
358 break;
360 di->font[i].height = sizes[i];
361 di->font[i].weight = 400;
362 lstrcpyW(di->font[i].faceName, lf->lfFaceName);
363 wsprintfW(buf, fmt, sizes[i]);
364 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, i, (LPARAM)buf);
366 /* don't need to enumerate other */
367 return 0;
370 if (WCUSER_ValidateFontMetric(di->data, tm, FontType))
372 int idx;
374 /* we want the string to be sorted with a numeric order, not a lexicographic...
375 * do the job by hand... get where to insert the new string
377 for (idx = 0; idx < di->nFont && tm->tmHeight > di->font[idx].height; idx++);
378 while (idx < di->nFont &&
379 tm->tmHeight == di->font[idx].height &&
380 tm->tmWeight > di->font[idx].weight)
381 idx++;
382 if (idx == di->nFont ||
383 tm->tmHeight != di->font[idx].height ||
384 tm->tmWeight < di->font[idx].weight)
386 /* here we need to add the new entry */
387 wsprintfW(buf, fmt, tm->tmHeight);
388 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, idx, (LPARAM)buf);
390 /* now grow our arrays and insert the values at the same index than in the list box */
391 if (di->nFont)
393 di->font = HeapReAlloc(GetProcessHeap(), 0, di->font, sizeof(*di->font) * (di->nFont + 1));
394 if (idx != di->nFont)
395 memmove(&di->font[idx + 1], &di->font[idx], (di->nFont - idx) * sizeof(*di->font));
397 else
398 di->font = HeapAlloc(GetProcessHeap(), 0, sizeof(*di->font));
399 di->font[idx].height = tm->tmHeight;
400 di->font[idx].weight = tm->tmWeight;
401 lstrcpyW(di->font[idx].faceName, lf->lfFaceName);
402 di->nFont++;
405 return 1;
408 /******************************************************************
409 * select_font
413 static BOOL select_font(struct dialog_info* di)
415 int font_idx, size_idx;
416 WCHAR buf[256];
417 WCHAR fmt[128];
418 DWORD_PTR args[2];
419 LOGFONTW lf;
420 HFONT hFont, hOldFont;
421 struct config_data config;
423 font_idx = SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0, 0);
424 size_idx = SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0, 0);
426 if (font_idx < 0 || size_idx < 0 || size_idx >= di->nFont)
427 return FALSE;
429 WCUSER_FillLogFont(&lf, di->font[size_idx].faceName,
430 di->font[size_idx].height, di->font[size_idx].weight);
431 hFont = WCUSER_CopyFont(&config, di->data->hWnd, &lf, NULL);
432 if (!hFont) return FALSE;
434 if (config.cell_height != di->font[size_idx].height)
435 WINE_TRACE("mismatched heights (%u<>%u)\n",
436 config.cell_height, di->font[size_idx].height);
437 hOldFont = (HFONT)SendDlgItemMessageW(di->hDlg, IDC_FNT_PREVIEW, WM_GETFONT, 0, 0);
439 SendDlgItemMessageW(di->hDlg, IDC_FNT_PREVIEW, WM_SETFONT, (WPARAM)hFont, TRUE);
440 if (hOldFont) DeleteObject(hOldFont);
442 LoadStringW(GetModuleHandleW(NULL), IDS_FNT_DISPLAY, fmt, sizeof(fmt) / sizeof(fmt[0]));
443 args[0] = config.cell_width;
444 args[1] = config.cell_height;
445 FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
446 fmt, 0, 0, buf, sizeof(buf)/sizeof(*buf), (__ms_va_list*)args);
448 SendDlgItemMessageW(di->hDlg, IDC_FNT_FONT_INFO, WM_SETTEXT, 0, (LPARAM)buf);
450 return TRUE;
453 /******************************************************************
454 * fill_list_size
456 * fills the size list box according to selected family in font LB
458 static BOOL fill_list_size(struct dialog_info* di, BOOL doInit)
460 int idx;
461 WCHAR lfFaceName[LF_FACESIZE];
463 idx = SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0, 0);
464 if (idx < 0) return FALSE;
466 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_FONT, LB_GETTEXT, idx, (LPARAM)lfFaceName);
467 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_SIZE, LB_RESETCONTENT, 0, 0);
468 HeapFree(GetProcessHeap(), 0, di->font);
469 di->nFont = 0;
470 di->font = NULL;
472 EnumFontFamiliesW(PRIVATE(di->data)->hMemDC, lfFaceName, font_enum_size, (LPARAM)di);
474 if (doInit)
476 int ref = -1;
478 for (idx = 0; idx < di->nFont; idx++)
480 if (!lstrcmpW(di->font[idx].faceName, di->config.face_name) &&
481 di->font[idx].height == di->config.cell_height &&
482 di->font[idx].weight == di->config.font_weight)
484 if (ref == -1) ref = idx;
485 else WINE_TRACE("Several matches found: ref=%d idx=%d\n", ref, idx);
488 idx = (ref == -1) ? 0 : ref;
490 else
491 idx = 0;
492 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_SIZE, LB_SETCURSEL, idx, 0);
493 select_font(di);
494 return TRUE;
497 /******************************************************************
498 * fill_list_font
500 * Fills the font LB
502 static BOOL fill_list_font(struct dialog_info* di)
504 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_FONT, LB_RESETCONTENT, 0, 0);
505 EnumFontFamiliesW(PRIVATE(di->data)->hMemDC, NULL, font_enum, (LPARAM)di);
506 if (SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_FONT, LB_SELECTSTRING,
507 -1, (LPARAM)di->config.face_name) == LB_ERR)
508 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_FONT, LB_SETCURSEL, 0, 0);
509 fill_list_size(di, TRUE);
510 return TRUE;
513 /******************************************************************
514 * WCUSER_FontDlgProc
516 * Dialog proc for the Font property sheet
518 static INT_PTR WINAPI WCUSER_FontDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
520 struct dialog_info* di;
522 switch (msg)
524 case WM_INITDIALOG:
525 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
526 di->hDlg = hDlg;
527 SetWindowLongPtrW(hDlg, DWLP_USER, (DWORD_PTR)di);
528 /* remove dialog from this control, font will be reset when listboxes are filled */
529 SendDlgItemMessageW(hDlg, IDC_FNT_PREVIEW, WM_SETFONT, 0, 0);
530 fill_list_font(di);
531 SetWindowLongW(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0, (di->config.def_attr >> 4) & 0x0F);
532 SetWindowLongW(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0, di->config.def_attr & 0x0F);
533 break;
534 case WM_COMMAND:
535 di = (struct dialog_info*)GetWindowLongPtrW(hDlg, DWLP_USER);
536 switch (LOWORD(wParam))
538 case IDC_FNT_LIST_FONT:
539 if (HIWORD(wParam) == LBN_SELCHANGE)
541 fill_list_size(di, FALSE);
543 break;
544 case IDC_FNT_LIST_SIZE:
545 if (HIWORD(wParam) == LBN_SELCHANGE)
547 select_font(di);
549 break;
551 break;
552 case WM_NOTIFY:
554 NMHDR* nmhdr = (NMHDR*)lParam;
555 DWORD val;
557 di = (struct dialog_info*)GetWindowLongPtrW(hDlg, DWLP_USER);
558 switch (nmhdr->code)
560 case PSN_SETACTIVE:
561 di->hDlg = hDlg;
562 break;
563 case PSN_APPLY:
564 val = SendDlgItemMessageW(hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0, 0);
566 if (val < di->nFont)
568 LOGFONTW lf;
570 WCUSER_FillLogFont(&lf, di->font[val].faceName,
571 di->font[val].height, di->font[val].weight);
572 DeleteObject(WCUSER_CopyFont(&di->config,
573 di->data->hWnd, &lf, NULL));
576 val = (GetWindowLongW(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0) << 4) |
577 GetWindowLongW(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0);
578 di->config.def_attr = val;
580 SetWindowLongPtrW(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
581 return TRUE;
582 default:
583 return FALSE;
585 break;
587 default:
588 return FALSE;
590 return TRUE;
593 /******************************************************************
594 * WCUSER_ConfigDlgProc
596 * Dialog proc for the config property sheet
598 static INT_PTR WINAPI WCUSER_ConfigDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
600 struct dialog_info* di;
601 int nMaxUD = 2000;
603 switch (msg)
605 case WM_INITDIALOG:
606 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
607 di->hDlg = hDlg;
609 SetWindowLongPtrW(hDlg, DWLP_USER, (DWORD_PTR)di);
610 SetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH, di->config.sb_width, FALSE);
611 SetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, di->config.sb_height, FALSE);
612 SetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH, di->config.win_width, FALSE);
613 SetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, di->config.win_height, FALSE);
615 SendMessageW(GetDlgItem(hDlg,IDC_CNF_WIN_HEIGHT_UD), UDM_SETRANGE, 0, MAKELPARAM(nMaxUD, 0));
616 SendMessageW(GetDlgItem(hDlg,IDC_CNF_WIN_WIDTH_UD), UDM_SETRANGE, 0, MAKELPARAM(nMaxUD, 0));
617 SendMessageW(GetDlgItem(hDlg,IDC_CNF_SB_HEIGHT_UD), UDM_SETRANGE, 0, MAKELPARAM(nMaxUD, 0));
618 SendMessageW(GetDlgItem(hDlg,IDC_CNF_SB_WIDTH_UD), UDM_SETRANGE, 0, MAKELPARAM(nMaxUD, 0));
620 SendDlgItemMessageW(hDlg, IDC_CNF_CLOSE_EXIT, BM_SETCHECK,
621 (di->config.exit_on_die) ? BST_CHECKED : BST_UNCHECKED, 0);
623 static const WCHAR s1[] = {'W','i','n','3','2',0};
624 static const WCHAR s2[] = {'E','m','a','c','s',0};
626 SendDlgItemMessageW(hDlg, IDC_CNF_EDITION_MODE, CB_ADDSTRING, 0, (LPARAM)s1);
627 SendDlgItemMessageW(hDlg, IDC_CNF_EDITION_MODE, CB_ADDSTRING, 0, (LPARAM)s2);
628 SendDlgItemMessageW(hDlg, IDC_CNF_EDITION_MODE, CB_SETCURSEL, di->config.edition_mode, 0);
631 break;
632 case WM_COMMAND:
633 di = (struct dialog_info*)GetWindowLongPtrW(hDlg, DWLP_USER);
634 switch (LOWORD(wParam))
637 break;
638 case WM_NOTIFY:
640 NMHDR* nmhdr = (NMHDR*)lParam;
641 int win_w, win_h, sb_w, sb_h;
642 BOOL st1, st2;
644 di = (struct dialog_info*)GetWindowLongPtrW(hDlg, DWLP_USER);
645 switch (nmhdr->code)
647 case PSN_SETACTIVE:
648 di->hDlg = hDlg;
649 break;
650 case PSN_APPLY:
651 sb_w = GetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH, &st1, FALSE);
652 sb_h = GetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, &st2, FALSE);
653 if (!st1 || ! st2)
655 SetWindowLongPtrW(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
656 return TRUE;
658 win_w = GetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH, &st1, FALSE);
659 win_h = GetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, &st2, FALSE);
660 if (!st1 || !st2)
662 SetWindowLongPtrW(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
663 return TRUE;
665 if (win_w > sb_w || win_h > sb_h)
667 WCHAR cap[256];
668 WCHAR txt[256];
670 LoadStringW(GetModuleHandleW(NULL), IDS_DLG_TIT_ERROR,
671 cap, sizeof(cap) / sizeof(cap[0]));
672 LoadStringW(GetModuleHandleW(NULL), IDS_DLG_ERR_SBWINSIZE,
673 txt, sizeof(txt) / sizeof(cap[0]));
675 MessageBoxW(hDlg, txt, cap, MB_OK);
676 SetWindowLongPtrW(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
677 return TRUE;
679 di->config.win_width = win_w;
680 di->config.win_height = win_h;
681 di->config.sb_width = sb_w;
682 di->config.sb_height = sb_h;
684 di->config.exit_on_die = IsDlgButtonChecked(hDlg, IDC_CNF_CLOSE_EXIT) ? 1 : 0;
685 di->config.edition_mode = SendDlgItemMessageW(hDlg, IDC_CNF_EDITION_MODE,
686 CB_GETCURSEL, 0, 0);
687 SetWindowLongPtrW(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
688 return TRUE;
689 default:
690 return FALSE;
692 break;
694 default:
695 return FALSE;
697 return TRUE;
700 /******************************************************************
701 * WCUSER_SaveDlgProc
703 * Dialog Procedure for choosing how to handle modification to the
704 * console settings.
706 static INT_PTR WINAPI WCUSER_SaveDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
708 switch (msg)
710 case WM_INITDIALOG:
711 SendDlgItemMessageW(hDlg, IDC_SAV_SESSION, BM_SETCHECK, BST_CHECKED, 0);
712 break;
713 case WM_COMMAND:
714 switch (LOWORD(wParam))
716 case IDOK:
717 EndDialog(hDlg,
718 (IsDlgButtonChecked(hDlg, IDC_SAV_SAVE) == BST_CHECKED) ?
719 IDC_SAV_SAVE : IDC_SAV_SESSION);
720 break;
721 case IDCANCEL:
722 EndDialog(hDlg, IDCANCEL); break;
724 break;
725 default:
726 return FALSE;
728 return TRUE;
731 /******************************************************************
732 * WCUSER_GetProperties
734 * Runs the dialog box to set up the wineconsole options
736 BOOL WCUSER_GetProperties(struct inner_data* data, BOOL current)
738 HPROPSHEETPAGE psPage[3];
739 PROPSHEETPAGEW psp;
740 PROPSHEETHEADERW psHead;
741 WCHAR buff[256];
742 WNDCLASSW wndclass;
743 static const WCHAR szFntPreview[] = {'W','i','n','e','C','o','n','F','o','n','t','P','r','e','v','i','e','w',0};
744 static const WCHAR szColorPreview[] = {'W','i','n','e','C','o','n','C','o','l','o','r','P','r','e','v','i','e','w',0};
745 struct dialog_info di;
746 struct config_data defcfg;
747 struct config_data* refcfg;
748 BOOL save, modify_session;
750 InitCommonControls();
752 di.data = data;
753 if (current)
755 refcfg = &data->curcfg;
756 save = FALSE;
758 else
760 WINECON_RegLoad(NULL, refcfg = &defcfg);
761 save = TRUE;
763 di.config = *refcfg;
764 di.nFont = 0;
765 di.font = NULL;
767 modify_session = FALSE;
769 wndclass.style = 0;
770 wndclass.lpfnWndProc = WCUSER_FontPreviewProc;
771 wndclass.cbClsExtra = 0;
772 wndclass.cbWndExtra = sizeof (DWORD_PTR); /* for hFont */
773 wndclass.hInstance = GetModuleHandleW(NULL);
774 wndclass.hIcon = 0;
775 wndclass.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
776 wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
777 wndclass.lpszMenuName = NULL;
778 wndclass.lpszClassName = szFntPreview;
779 RegisterClassW(&wndclass);
781 wndclass.style = 0;
782 wndclass.lpfnWndProc = WCUSER_ColorPreviewProc;
783 wndclass.cbClsExtra = 0;
784 wndclass.cbWndExtra = sizeof(DWORD);
785 wndclass.hInstance = GetModuleHandleW(NULL);
786 wndclass.hIcon = 0;
787 wndclass.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
788 wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
789 wndclass.lpszMenuName = NULL;
790 wndclass.lpszClassName = szColorPreview;
791 RegisterClassW(&wndclass);
793 memset(&psp, 0, sizeof(psp));
794 psp.dwSize = sizeof(psp);
795 psp.dwFlags = 0;
796 psp.hInstance = wndclass.hInstance;
797 psp.lParam = (LPARAM)&di;
799 psp.u.pszTemplate = MAKEINTRESOURCEW(IDD_OPTION);
800 psp.pfnDlgProc = WCUSER_OptionDlgProc;
801 psPage[0] = CreatePropertySheetPageW(&psp);
803 psp.u.pszTemplate = MAKEINTRESOURCEW(IDD_FONT);
804 psp.pfnDlgProc = WCUSER_FontDlgProc;
805 psPage[1] = CreatePropertySheetPageW(&psp);
807 psp.u.pszTemplate = MAKEINTRESOURCEW(IDD_CONFIG);
808 psp.pfnDlgProc = WCUSER_ConfigDlgProc;
809 psPage[2] = CreatePropertySheetPageW(&psp);
811 memset(&psHead, 0, sizeof(psHead));
812 psHead.dwSize = sizeof(psHead);
814 if (!LoadStringW(GetModuleHandleW(NULL),
815 (current) ? IDS_DLG_TIT_CURRENT : IDS_DLG_TIT_DEFAULT,
816 buff, sizeof(buff) / sizeof(buff[0])))
818 buff[0] = 'S';
819 buff[1] = 'e';
820 buff[2] = 't';
821 buff[3] = 'u';
822 buff[4] = 'p';
823 buff[5] = '\0';
826 psHead.pszCaption = buff;
827 psHead.nPages = 3;
828 psHead.hwndParent = data->hWnd;
829 psHead.u3.phpage = psPage;
830 psHead.dwFlags = PSH_NOAPPLYNOW;
832 WINECON_DumpConfig("init", refcfg);
834 PropertySheetW(&psHead);
836 if (memcmp(refcfg, &di.config, sizeof(*refcfg)) == 0)
837 return TRUE;
839 WINECON_DumpConfig("ref", refcfg);
840 WINECON_DumpConfig("cur", &di.config);
841 if (refcfg == &data->curcfg)
843 switch (DialogBoxW(GetModuleHandleW(NULL), MAKEINTRESOURCEW(IDD_SAVE_SETTINGS),
844 data->hWnd, WCUSER_SaveDlgProc))
846 case IDC_SAV_SAVE: save = TRUE; modify_session = TRUE; break;
847 case IDC_SAV_SESSION: modify_session = TRUE; break;
848 case IDCANCEL: break;
849 default: WINE_ERR("ooch\n");
853 if (modify_session) WINECON_SetConfig(data, &di.config);
854 if (save) WINECON_RegSave(&di.config);
856 return TRUE;