ddraw/tests: Add another invalid arguments test for surface QI.
[wine.git] / programs / wineconsole / dialog.c
blob9a14184ba48b14291426faf6b8bbb2d14fe82378
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
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_INSERT_MODE, BM_SETCHECK,
80 (di->config.insert_mode) ? BST_CHECKED : BST_UNCHECKED, 0);
81 SendDlgItemMessageW(hDlg, IDC_OPT_CONF_CTRL, BM_SETCHECK,
82 (di->config.menu_mask & MK_CONTROL) ? BST_CHECKED : BST_UNCHECKED, 0);
83 SendDlgItemMessageW(hDlg, IDC_OPT_CONF_SHIFT, BM_SETCHECK,
84 (di->config.menu_mask & MK_SHIFT) ? BST_CHECKED : BST_UNCHECKED, 0);
85 SendDlgItemMessageW(hDlg, IDC_OPT_QUICK_EDIT, BM_SETCHECK,
86 (di->config.quick_edit) ? BST_CHECKED : BST_UNCHECKED, 0);
87 return FALSE; /* because we set the focus */
88 case WM_COMMAND:
89 break;
90 case WM_NOTIFY:
92 NMHDR* nmhdr = (NMHDR*)lParam;
93 DWORD val;
94 BOOL done;
96 di = (struct dialog_info*)GetWindowLongPtrW(hDlg, DWLP_USER);
98 switch (nmhdr->code)
100 case PSN_SETACTIVE:
101 /* needed in propsheet to keep properly the selected radio button
102 * otherwise, the focus would be set to the first tab stop in the
103 * propsheet, which would always activate the first radio button
105 if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED)
106 idc = IDC_OPT_CURSOR_SMALL;
107 else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED)
108 idc = IDC_OPT_CURSOR_MEDIUM;
109 else
110 idc = IDC_OPT_CURSOR_LARGE;
111 PostMessageW(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, idc), TRUE);
112 di->hDlg = hDlg;
113 break;
114 case PSN_APPLY:
115 if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED) val = 25;
116 else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED) val = 50;
117 else val = 100;
118 di->config.cursor_size = val;
120 val = GetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, &done, FALSE);
121 if (done) di->config.history_size = val;
123 val = (IsDlgButtonChecked(hDlg, IDC_OPT_HIST_NODOUBLE) & BST_CHECKED) != 0;
124 di->config.history_nodup = val;
126 val = (IsDlgButtonChecked(hDlg, IDC_OPT_INSERT_MODE) & BST_CHECKED) != 0;
127 di->config.insert_mode = val;
129 val = 0;
130 if (IsDlgButtonChecked(hDlg, IDC_OPT_CONF_CTRL) & BST_CHECKED) val |= MK_CONTROL;
131 if (IsDlgButtonChecked(hDlg, IDC_OPT_CONF_SHIFT) & BST_CHECKED) val |= MK_SHIFT;
132 di->config.menu_mask = val;
134 val = (IsDlgButtonChecked(hDlg, IDC_OPT_QUICK_EDIT) & BST_CHECKED) != 0;
135 di->config.quick_edit = val;
137 SetWindowLongPtrW(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
138 return TRUE;
139 default:
140 return FALSE;
142 break;
144 default:
145 return FALSE;
147 return TRUE;
150 static COLORREF get_color(struct dialog_info *di, unsigned int idc)
152 LONG_PTR index;
154 index = GetWindowLongPtrW(GetDlgItem(di->hDlg, idc), 0);
155 return di->config.color_map[index];
158 /******************************************************************
159 * WCUSER_FontPreviewProc
161 * Window proc for font previewer in font property sheet
163 static LRESULT WINAPI WCUSER_FontPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
165 switch (msg)
167 case WM_CREATE:
168 SetWindowLongPtrW(hWnd, 0, 0);
169 break;
170 case WM_GETFONT:
171 return GetWindowLongPtrW(hWnd, 0);
172 case WM_SETFONT:
173 SetWindowLongPtrW(hWnd, 0, wParam);
174 if (LOWORD(lParam))
176 InvalidateRect(hWnd, NULL, TRUE);
177 UpdateWindow(hWnd);
179 break;
180 case WM_DESTROY:
182 HFONT hFont = (HFONT)GetWindowLongPtrW(hWnd, 0);
183 if (hFont) DeleteObject(hFont);
185 break;
186 case WM_PAINT:
188 PAINTSTRUCT ps;
189 int size_idx;
190 struct dialog_info* di;
191 HFONT hFont, hOldFont;
193 di = (struct dialog_info*)GetWindowLongPtrW(GetParent(hWnd), DWLP_USER);
194 BeginPaint(hWnd, &ps);
196 size_idx = SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0, 0);
198 hFont = (HFONT)GetWindowLongPtrW(hWnd, 0);
199 if (hFont)
201 COLORREF bkcolor;
202 WCHAR ascii[] = {'A','S','C','I','I',':',' ','a','b','c','X','Y','Z','\0'};
203 WCHAR buf[256];
204 int len;
206 hOldFont = SelectObject(ps.hdc, hFont);
207 bkcolor = get_color(di, IDC_FNT_COLOR_BK);
208 FillRect(ps.hdc, &ps.rcPaint, CreateSolidBrush(bkcolor));
209 SetBkColor(ps.hdc, bkcolor);
210 SetTextColor(ps.hdc, get_color(di, IDC_FNT_COLOR_FG));
211 len = LoadStringW(GetModuleHandleW(NULL), IDS_FNT_PREVIEW,
212 buf, sizeof(buf) / sizeof(buf[0]));
213 if (len)
214 TextOutW(ps.hdc, 0, 0, buf, len);
215 TextOutW(ps.hdc, 0, di->font[size_idx].height, ascii,
216 sizeof(ascii)/sizeof(ascii[0]) - 1);
217 SelectObject(ps.hdc, hOldFont);
219 EndPaint(hWnd, &ps);
221 break;
222 default:
223 return DefWindowProcW(hWnd, msg, wParam, lParam);
225 return 0L;
228 /******************************************************************
229 * WCUSER_ColorPreviewProc
231 * Window proc for color previewer in font property sheet
233 static LRESULT WINAPI WCUSER_ColorPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
235 switch (msg)
237 case WM_PAINT:
239 PAINTSTRUCT ps;
240 int i, step;
241 RECT client, r;
242 struct dialog_info *di;
243 HBRUSH hbr;
245 BeginPaint(hWnd, &ps);
246 GetClientRect(hWnd, &client);
247 step = client.right / 8;
249 di = (struct dialog_info *)GetWindowLongPtrW(GetParent(hWnd), DWLP_USER);
251 for (i = 0; i < 16; i++)
253 r.top = (i / 8) * (client.bottom / 2);
254 r.bottom = r.top + client.bottom / 2;
255 r.left = (i & 7) * step;
256 r.right = r.left + step;
257 hbr = CreateSolidBrush(di->config.color_map[i]);
258 FillRect(ps.hdc, &r, hbr);
259 DeleteObject(hbr);
260 if (GetWindowLongW(hWnd, 0) == i)
262 HPEN hOldPen;
263 int i = 2;
265 hOldPen = SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
266 r.right--; r.bottom--;
267 for (;;)
269 MoveToEx(ps.hdc, r.left, r.bottom, NULL);
270 LineTo(ps.hdc, r.left, r.top);
271 LineTo(ps.hdc, r.right, r.top);
272 SelectObject(ps.hdc, GetStockObject(BLACK_PEN));
273 LineTo(ps.hdc, r.right, r.bottom);
274 LineTo(ps.hdc, r.left, r.bottom);
276 if (--i == 0) break;
277 r.left++; r.top++; r.right--; r.bottom--;
278 SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
280 SelectObject(ps.hdc, hOldPen);
283 EndPaint(hWnd, &ps);
284 break;
286 case WM_LBUTTONDOWN:
288 int i, step;
289 RECT client;
291 GetClientRect(hWnd, &client);
292 step = client.right / 8;
293 i = (HIWORD(lParam) >= client.bottom / 2) ? 8 : 0;
294 i += LOWORD(lParam) / step;
295 SetWindowLongW(hWnd, 0, i);
296 InvalidateRect(GetDlgItem(GetParent(hWnd), IDC_FNT_PREVIEW), NULL, FALSE);
297 InvalidateRect(hWnd, NULL, FALSE);
299 break;
300 default:
301 return DefWindowProcW(hWnd, msg, wParam, lParam);
303 return 0L;
306 /******************************************************************
307 * font_enum
309 * enumerates all the font names with at least one valid font
311 static int CALLBACK font_enum_size2(const LOGFONTW* lf, const TEXTMETRICW* tm,
312 DWORD FontType, LPARAM lParam)
314 struct dialog_info* di = (struct dialog_info*)lParam;
316 WCUSER_DumpTextMetric(tm, FontType);
317 if (WCUSER_ValidateFontMetric(di->data, tm, FontType, 0))
319 di->nFont++;
322 return 1;
325 static int CALLBACK font_enum(const LOGFONTW* lf, const TEXTMETRICW* tm,
326 DWORD FontType, LPARAM lParam)
328 struct dialog_info* di = (struct dialog_info*)lParam;
330 WCUSER_DumpLogFont("DlgFamily: ", lf, FontType);
331 if (WCUSER_ValidateFont(di->data, lf, 0))
333 if (FontType & RASTER_FONTTYPE)
335 di->nFont = 0;
336 EnumFontFamiliesW(PRIVATE(di->data)->hMemDC, lf->lfFaceName, font_enum_size2, (LPARAM)di);
338 else
339 di->nFont = 1;
341 if (di->nFont)
343 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_FONT, LB_ADDSTRING,
344 0, (LPARAM)lf->lfFaceName);
348 return 1;
351 /******************************************************************
352 * font_enum_size
356 static int CALLBACK font_enum_size(const LOGFONTW* lf, const TEXTMETRICW* tm,
357 DWORD FontType, LPARAM lParam)
359 struct dialog_info* di = (struct dialog_info*)lParam;
360 WCHAR buf[32];
361 static const WCHAR fmt[] = {'%','l','d',0};
363 WCUSER_DumpTextMetric(tm, FontType);
364 if (di->nFont == 0 && !(FontType & RASTER_FONTTYPE))
366 static const int sizes[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
367 int i;
369 di->nFont = sizeof(sizes) / sizeof(sizes[0]);
370 di->font = HeapAlloc(GetProcessHeap(), 0, di->nFont * sizeof(di->font[0]));
371 for (i = 0; i < di->nFont; i++)
373 /* drop sizes where window size wouldn't fit on screen */
374 if (sizes[i] * di->data->curcfg.win_height > GetSystemMetrics(SM_CYSCREEN))
376 di->nFont = i;
377 break;
379 di->font[i].height = sizes[i];
380 di->font[i].weight = 400;
381 lstrcpyW(di->font[i].faceName, lf->lfFaceName);
382 wsprintfW(buf, fmt, sizes[i]);
383 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, i, (LPARAM)buf);
385 /* don't need to enumerate other */
386 return 0;
389 if (WCUSER_ValidateFontMetric(di->data, tm, FontType, 0))
391 int idx = 0;
393 /* we want the string to be sorted with a numeric order, not a lexicographic...
394 * do the job by hand... get where to insert the new string
396 while (idx < di->nFont && tm->tmHeight > di->font[idx].height)
397 idx++;
398 while (idx < di->nFont &&
399 tm->tmHeight == di->font[idx].height &&
400 tm->tmWeight > di->font[idx].weight)
401 idx++;
402 if (idx == di->nFont ||
403 tm->tmHeight != di->font[idx].height ||
404 tm->tmWeight < di->font[idx].weight)
406 /* here we need to add the new entry */
407 wsprintfW(buf, fmt, tm->tmHeight);
408 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, idx, (LPARAM)buf);
410 /* now grow our arrays and insert the values at the same index than in the list box */
411 if (di->nFont)
413 di->font = HeapReAlloc(GetProcessHeap(), 0, di->font, sizeof(*di->font) * (di->nFont + 1));
414 if (idx != di->nFont)
415 memmove(&di->font[idx + 1], &di->font[idx], (di->nFont - idx) * sizeof(*di->font));
417 else
418 di->font = HeapAlloc(GetProcessHeap(), 0, sizeof(*di->font));
419 di->font[idx].height = tm->tmHeight;
420 di->font[idx].weight = tm->tmWeight;
421 lstrcpyW(di->font[idx].faceName, lf->lfFaceName);
422 di->nFont++;
425 return 1;
428 /******************************************************************
429 * select_font
433 static BOOL select_font(struct dialog_info* di)
435 int font_idx, size_idx;
436 WCHAR buf[256];
437 WCHAR fmt[128];
438 DWORD_PTR args[2];
439 LOGFONTW lf;
440 HFONT hFont, hOldFont;
441 struct config_data config;
443 font_idx = SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0, 0);
444 size_idx = SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0, 0);
446 if (font_idx < 0 || size_idx < 0 || size_idx >= di->nFont)
447 return FALSE;
449 WCUSER_FillLogFont(&lf, di->font[size_idx].faceName,
450 di->font[size_idx].height, di->font[size_idx].weight);
451 hFont = WCUSER_CopyFont(&config, di->data->hWnd, &lf, NULL);
452 if (!hFont) return FALSE;
454 if (config.cell_height != di->font[size_idx].height)
455 WINE_TRACE("mismatched heights (%u<>%u)\n",
456 config.cell_height, di->font[size_idx].height);
457 hOldFont = (HFONT)SendDlgItemMessageW(di->hDlg, IDC_FNT_PREVIEW, WM_GETFONT, 0, 0);
459 SendDlgItemMessageW(di->hDlg, IDC_FNT_PREVIEW, WM_SETFONT, (WPARAM)hFont, TRUE);
460 if (hOldFont) DeleteObject(hOldFont);
462 LoadStringW(GetModuleHandleW(NULL), IDS_FNT_DISPLAY, fmt, sizeof(fmt) / sizeof(fmt[0]));
463 args[0] = config.cell_width;
464 args[1] = config.cell_height;
465 FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
466 fmt, 0, 0, buf, sizeof(buf)/sizeof(*buf), (__ms_va_list*)args);
468 SendDlgItemMessageW(di->hDlg, IDC_FNT_FONT_INFO, WM_SETTEXT, 0, (LPARAM)buf);
470 return TRUE;
473 /******************************************************************
474 * fill_list_size
476 * fills the size list box according to selected family in font LB
478 static BOOL fill_list_size(struct dialog_info* di, BOOL doInit)
480 int idx;
481 WCHAR lfFaceName[LF_FACESIZE];
483 idx = SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0, 0);
484 if (idx < 0) return FALSE;
486 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_FONT, LB_GETTEXT, idx, (LPARAM)lfFaceName);
487 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_SIZE, LB_RESETCONTENT, 0, 0);
488 HeapFree(GetProcessHeap(), 0, di->font);
489 di->nFont = 0;
490 di->font = NULL;
492 EnumFontFamiliesW(PRIVATE(di->data)->hMemDC, lfFaceName, font_enum_size, (LPARAM)di);
494 if (doInit)
496 int ref = -1;
498 for (idx = 0; idx < di->nFont; idx++)
500 if (!lstrcmpW(di->font[idx].faceName, di->config.face_name) &&
501 di->font[idx].height == di->config.cell_height &&
502 di->font[idx].weight == di->config.font_weight)
504 if (ref == -1) ref = idx;
505 else WINE_TRACE("Several matches found: ref=%d idx=%d\n", ref, idx);
508 idx = (ref == -1) ? 0 : ref;
510 else
511 idx = 0;
512 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_SIZE, LB_SETCURSEL, idx, 0);
513 select_font(di);
514 return TRUE;
517 /******************************************************************
518 * fill_list_font
520 * Fills the font LB
522 static BOOL fill_list_font(struct dialog_info* di)
524 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_FONT, LB_RESETCONTENT, 0, 0);
525 EnumFontFamiliesW(PRIVATE(di->data)->hMemDC, NULL, font_enum, (LPARAM)di);
526 if (SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_FONT, LB_SELECTSTRING,
527 -1, (LPARAM)di->config.face_name) == LB_ERR)
528 SendDlgItemMessageW(di->hDlg, IDC_FNT_LIST_FONT, LB_SETCURSEL, 0, 0);
529 fill_list_size(di, TRUE);
530 return TRUE;
533 /******************************************************************
534 * WCUSER_FontDlgProc
536 * Dialog proc for the Font property sheet
538 static INT_PTR WINAPI WCUSER_FontDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
540 struct dialog_info* di;
542 switch (msg)
544 case WM_INITDIALOG:
545 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
546 di->hDlg = hDlg;
547 SetWindowLongPtrW(hDlg, DWLP_USER, (DWORD_PTR)di);
548 /* remove dialog from this control, font will be reset when listboxes are filled */
549 SendDlgItemMessageW(hDlg, IDC_FNT_PREVIEW, WM_SETFONT, 0, 0);
550 fill_list_font(di);
551 SetWindowLongW(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0, (di->config.def_attr >> 4) & 0x0F);
552 SetWindowLongW(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0, di->config.def_attr & 0x0F);
553 break;
554 case WM_COMMAND:
555 di = (struct dialog_info*)GetWindowLongPtrW(hDlg, DWLP_USER);
556 switch (LOWORD(wParam))
558 case IDC_FNT_LIST_FONT:
559 if (HIWORD(wParam) == LBN_SELCHANGE)
561 fill_list_size(di, FALSE);
563 break;
564 case IDC_FNT_LIST_SIZE:
565 if (HIWORD(wParam) == LBN_SELCHANGE)
567 select_font(di);
569 break;
571 break;
572 case WM_NOTIFY:
574 NMHDR* nmhdr = (NMHDR*)lParam;
575 DWORD val;
577 di = (struct dialog_info*)GetWindowLongPtrW(hDlg, DWLP_USER);
578 switch (nmhdr->code)
580 case PSN_SETACTIVE:
581 di->hDlg = hDlg;
582 break;
583 case PSN_APPLY:
584 val = SendDlgItemMessageW(hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0, 0);
586 if (val < di->nFont)
588 LOGFONTW lf;
590 WCUSER_FillLogFont(&lf, di->font[val].faceName,
591 di->font[val].height, di->font[val].weight);
592 DeleteObject(WCUSER_CopyFont(&di->config,
593 di->data->hWnd, &lf, NULL));
596 val = (GetWindowLongW(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0) << 4) |
597 GetWindowLongW(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0);
598 di->config.def_attr = val;
600 SetWindowLongPtrW(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
601 return TRUE;
602 default:
603 return FALSE;
605 break;
607 default:
608 return FALSE;
610 return TRUE;
613 /******************************************************************
614 * WCUSER_ConfigDlgProc
616 * Dialog proc for the config property sheet
618 static INT_PTR WINAPI WCUSER_ConfigDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
620 struct dialog_info* di;
621 int nMaxUD = 2000;
623 switch (msg)
625 case WM_INITDIALOG:
626 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
627 di->hDlg = hDlg;
629 SetWindowLongPtrW(hDlg, DWLP_USER, (DWORD_PTR)di);
630 SetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH, di->config.sb_width, FALSE);
631 SetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, di->config.sb_height, FALSE);
632 SetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH, di->config.win_width, FALSE);
633 SetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, di->config.win_height, FALSE);
635 SendMessageW(GetDlgItem(hDlg,IDC_CNF_WIN_HEIGHT_UD), UDM_SETRANGE, 0, MAKELPARAM(nMaxUD, 0));
636 SendMessageW(GetDlgItem(hDlg,IDC_CNF_WIN_WIDTH_UD), UDM_SETRANGE, 0, MAKELPARAM(nMaxUD, 0));
637 SendMessageW(GetDlgItem(hDlg,IDC_CNF_SB_HEIGHT_UD), UDM_SETRANGE, 0, MAKELPARAM(nMaxUD, 0));
638 SendMessageW(GetDlgItem(hDlg,IDC_CNF_SB_WIDTH_UD), UDM_SETRANGE, 0, MAKELPARAM(nMaxUD, 0));
640 SendDlgItemMessageW(hDlg, IDC_CNF_CLOSE_EXIT, BM_SETCHECK,
641 (di->config.exit_on_die) ? BST_CHECKED : BST_UNCHECKED, 0);
643 static const WCHAR s1[] = {'W','i','n','3','2',0};
644 static const WCHAR s2[] = {'E','m','a','c','s',0};
646 SendDlgItemMessageW(hDlg, IDC_CNF_EDITION_MODE, CB_ADDSTRING, 0, (LPARAM)s1);
647 SendDlgItemMessageW(hDlg, IDC_CNF_EDITION_MODE, CB_ADDSTRING, 0, (LPARAM)s2);
648 SendDlgItemMessageW(hDlg, IDC_CNF_EDITION_MODE, CB_SETCURSEL, di->config.edition_mode, 0);
651 break;
652 case WM_COMMAND:
653 di = (struct dialog_info*)GetWindowLongPtrW(hDlg, DWLP_USER);
654 switch (LOWORD(wParam))
657 break;
658 case WM_NOTIFY:
660 NMHDR* nmhdr = (NMHDR*)lParam;
661 int win_w, win_h, sb_w, sb_h;
662 BOOL st1, st2;
664 di = (struct dialog_info*)GetWindowLongPtrW(hDlg, DWLP_USER);
665 switch (nmhdr->code)
667 case PSN_SETACTIVE:
668 di->hDlg = hDlg;
669 break;
670 case PSN_APPLY:
671 sb_w = GetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH, &st1, FALSE);
672 sb_h = GetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, &st2, FALSE);
673 if (!st1 || ! st2)
675 SetWindowLongPtrW(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
676 return TRUE;
678 win_w = GetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH, &st1, FALSE);
679 win_h = GetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, &st2, FALSE);
680 if (!st1 || !st2)
682 SetWindowLongPtrW(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
683 return TRUE;
685 if (win_w > sb_w || win_h > sb_h)
687 WCHAR cap[256];
688 WCHAR txt[256];
690 LoadStringW(GetModuleHandleW(NULL), IDS_DLG_TIT_ERROR,
691 cap, sizeof(cap) / sizeof(cap[0]));
692 LoadStringW(GetModuleHandleW(NULL), IDS_DLG_ERR_SBWINSIZE,
693 txt, sizeof(txt) / sizeof(cap[0]));
695 MessageBoxW(hDlg, txt, cap, MB_OK);
696 SetWindowLongPtrW(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
697 return TRUE;
699 di->config.win_width = win_w;
700 di->config.win_height = win_h;
701 di->config.sb_width = sb_w;
702 di->config.sb_height = sb_h;
704 di->config.exit_on_die = IsDlgButtonChecked(hDlg, IDC_CNF_CLOSE_EXIT) ? 1 : 0;
705 di->config.edition_mode = SendDlgItemMessageW(hDlg, IDC_CNF_EDITION_MODE,
706 CB_GETCURSEL, 0, 0);
707 SetWindowLongPtrW(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
708 return TRUE;
709 default:
710 return FALSE;
712 break;
714 default:
715 return FALSE;
717 return TRUE;
720 /******************************************************************
721 * WCUSER_SaveDlgProc
723 * Dialog Procedure for choosing how to handle modification to the
724 * console settings.
726 static INT_PTR WINAPI WCUSER_SaveDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
728 switch (msg)
730 case WM_INITDIALOG:
731 SendDlgItemMessageW(hDlg, IDC_SAV_SESSION, BM_SETCHECK, BST_CHECKED, 0);
732 break;
733 case WM_COMMAND:
734 switch (LOWORD(wParam))
736 case IDOK:
737 EndDialog(hDlg,
738 (IsDlgButtonChecked(hDlg, IDC_SAV_SAVE) == BST_CHECKED) ?
739 IDC_SAV_SAVE : IDC_SAV_SESSION);
740 break;
741 case IDCANCEL:
742 EndDialog(hDlg, IDCANCEL); break;
744 break;
745 default:
746 return FALSE;
748 return TRUE;
751 /******************************************************************
752 * WCUSER_GetProperties
754 * Runs the dialog box to set up the wineconsole options
756 BOOL WCUSER_GetProperties(struct inner_data* data, BOOL current)
758 HPROPSHEETPAGE psPage[3];
759 PROPSHEETPAGEW psp;
760 PROPSHEETHEADERW psHead;
761 WCHAR buff[256];
762 WNDCLASSW wndclass;
763 static const WCHAR szFntPreview[] = {'W','i','n','e','C','o','n','F','o','n','t','P','r','e','v','i','e','w',0};
764 static const WCHAR szColorPreview[] = {'W','i','n','e','C','o','n','C','o','l','o','r','P','r','e','v','i','e','w',0};
765 struct dialog_info di;
766 struct config_data defcfg;
767 struct config_data* refcfg;
768 BOOL save, modify_session;
770 InitCommonControls();
772 di.data = data;
773 if (current)
775 refcfg = &data->curcfg;
776 save = FALSE;
778 else
780 WINECON_RegLoad(NULL, refcfg = &defcfg);
781 save = TRUE;
783 di.config = *refcfg;
784 di.nFont = 0;
785 di.font = NULL;
787 modify_session = FALSE;
789 wndclass.style = 0;
790 wndclass.lpfnWndProc = WCUSER_FontPreviewProc;
791 wndclass.cbClsExtra = 0;
792 wndclass.cbWndExtra = sizeof (DWORD_PTR); /* for hFont */
793 wndclass.hInstance = GetModuleHandleW(NULL);
794 wndclass.hIcon = 0;
795 wndclass.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
796 wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
797 wndclass.lpszMenuName = NULL;
798 wndclass.lpszClassName = szFntPreview;
799 RegisterClassW(&wndclass);
801 wndclass.style = 0;
802 wndclass.lpfnWndProc = WCUSER_ColorPreviewProc;
803 wndclass.cbClsExtra = 0;
804 wndclass.cbWndExtra = sizeof(DWORD);
805 wndclass.hInstance = GetModuleHandleW(NULL);
806 wndclass.hIcon = 0;
807 wndclass.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
808 wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
809 wndclass.lpszMenuName = NULL;
810 wndclass.lpszClassName = szColorPreview;
811 RegisterClassW(&wndclass);
813 memset(&psp, 0, sizeof(psp));
814 psp.dwSize = sizeof(psp);
815 psp.dwFlags = 0;
816 psp.hInstance = wndclass.hInstance;
817 psp.lParam = (LPARAM)&di;
819 psp.u.pszTemplate = MAKEINTRESOURCEW(IDD_OPTION);
820 psp.pfnDlgProc = WCUSER_OptionDlgProc;
821 psPage[0] = CreatePropertySheetPageW(&psp);
823 psp.u.pszTemplate = MAKEINTRESOURCEW(IDD_FONT);
824 psp.pfnDlgProc = WCUSER_FontDlgProc;
825 psPage[1] = CreatePropertySheetPageW(&psp);
827 psp.u.pszTemplate = MAKEINTRESOURCEW(IDD_CONFIG);
828 psp.pfnDlgProc = WCUSER_ConfigDlgProc;
829 psPage[2] = CreatePropertySheetPageW(&psp);
831 memset(&psHead, 0, sizeof(psHead));
832 psHead.dwSize = sizeof(psHead);
834 if (!LoadStringW(GetModuleHandleW(NULL),
835 (current) ? IDS_DLG_TIT_CURRENT : IDS_DLG_TIT_DEFAULT,
836 buff, sizeof(buff) / sizeof(buff[0])))
838 buff[0] = 'S';
839 buff[1] = 'e';
840 buff[2] = 't';
841 buff[3] = 'u';
842 buff[4] = 'p';
843 buff[5] = '\0';
846 psHead.pszCaption = buff;
847 psHead.nPages = 3;
848 psHead.hwndParent = data->hWnd;
849 psHead.u3.phpage = psPage;
850 psHead.dwFlags = PSH_NOAPPLYNOW;
852 WINECON_DumpConfig("init", refcfg);
854 PropertySheetW(&psHead);
856 if (memcmp(refcfg, &di.config, sizeof(*refcfg)) == 0)
857 return TRUE;
859 WINECON_DumpConfig("ref", refcfg);
860 WINECON_DumpConfig("cur", &di.config);
861 if (refcfg == &data->curcfg)
863 switch (DialogBoxW(GetModuleHandleW(NULL), MAKEINTRESOURCEW(IDD_SAVE_SETTINGS),
864 data->hWnd, WCUSER_SaveDlgProc))
866 case IDC_SAV_SAVE: save = TRUE; modify_session = TRUE; break;
867 case IDC_SAV_SESSION: modify_session = TRUE; break;
868 case IDCANCEL: break;
869 default: WINE_ERR("ooch\n");
873 if (modify_session) WINECON_SetConfig(data, &di.config);
874 if (save) WINECON_RegSave(&di.config);
876 return TRUE;