1 /* dialog management for wineconsole
2 * USER32 backend
3 * Copyright (c) 2001, 2002 Eric Pouech
4 *
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.
9 *
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.
14 *
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
18 */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdarg.h>
23
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"
34
35 #include "wine/debug.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(wineconsole);
38
39 struct dialog_info
40 {
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
46 {
47 UINT height;
48 UINT weight;
49 WCHAR faceName[LF_FACESIZE];
50 } *font; /* array of nFont. index sync'ed with SIZE LB */
51 };
52
53 /******************************************************************
54 * WCUSER_OptionDlgProc
55 *
56 * Dialog prop for the option property sheet
57 */
58 static INT_PTR WINAPI WCUSER_OptionDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
59 {
60 struct dialog_info* di;
61 unsigned idc;
62
63 switch (msg)
64 {
65 case WM_INITDIALOG:
66 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
67 di->hDlg = hDlg;
68 SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)di);
69
70 SendMessage(GetDlgItem(hDlg,IDC_OPT_HIST_SIZE_UD), UDM_SETRANGE, 0, MAKELPARAM (500, 0));
71
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 SendDlgItemMessage(hDlg, idc, BM_SETCHECK, BST_CHECKED, 0L);
76 SetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, di->config.history_size, FALSE);
77 SendDlgItemMessage(hDlg, IDC_OPT_HIST_NODOUBLE, BM_SETCHECK,
78 (di->config.history_nodup) ? BST_CHECKED : BST_UNCHECKED, 0L);
79 SendDlgItemMessage(hDlg, IDC_OPT_CONF_CTRL, BM_SETCHECK,
80 (di->config.menu_mask & MK_CONTROL) ? BST_CHECKED : BST_UNCHECKED, 0L);
81 SendDlgItemMessage(hDlg, IDC_OPT_CONF_SHIFT, BM_SETCHECK,
82 (di->config.menu_mask & MK_SHIFT) ? BST_CHECKED : BST_UNCHECKED, 0L);
83 SendDlgItemMessage(hDlg, IDC_OPT_QUICK_EDIT, BM_SETCHECK,
84 (di->config.quick_edit) ? BST_CHECKED : BST_UNCHECKED, 0L);
85 return FALSE; /* because we set the focus */
86 case WM_COMMAND:
87 break;
88 case WM_NOTIFY:
89 {
90 NMHDR* nmhdr = (NMHDR*)lParam;
91 DWORD val;
92 BOOL done;
93
94 di = (struct dialog_info*)GetWindowLongPtr(hDlg, DWLP_USER);
95
96 switch (nmhdr->code)
97 {
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
102 */
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 PostMessage(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;
117
118 val = GetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, &done, FALSE);
119 if (done) di->config.history_size = val;
120
121 val = (IsDlgButtonChecked(hDlg, IDC_OPT_HIST_NODOUBLE) & BST_CHECKED) ? TRUE : FALSE;
122 di->config.history_nodup = val;
123
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;
128
129 val = (IsDlgButtonChecked(hDlg, IDC_OPT_QUICK_EDIT) & BST_CHECKED) ? TRUE : FALSE;
130 di->config.quick_edit = val;
131
132 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
133 return TRUE;
134 default:
135 return FALSE;
136 }
137 break;
138 }
139 default:
140 return FALSE;
141 }
142 return TRUE;
143 }
144
145 /******************************************************************
146 * WCUSER_FontPreviewProc
147 *
148 * Window proc for font previewer in font property sheet
149 */
150 static LRESULT WINAPI WCUSER_FontPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
151 {
152 switch (msg)
153 {
154 case WM_CREATE:
155 SetWindowLongPtr(hWnd, 0, 0);
156 break;
157 case WM_GETFONT:
158 return GetWindowLongPtr(hWnd, 0);
159 case WM_SETFONT:
160 SetWindowLongPtr(hWnd, 0, wParam);
161 if (LOWORD(lParam))
162 {
163 InvalidateRect(hWnd, NULL, TRUE);
164 UpdateWindow(hWnd);
165 }
166 break;
167 case WM_DESTROY:
168 {
169 HFONT hFont = (HFONT)GetWindowLongPtr(hWnd, 0L);
170 if (hFont) DeleteObject(hFont);
171 }
172 break;
173 case WM_PAINT:
174 {
175 PAINTSTRUCT ps;
176 int font_idx;
177 int size_idx;
178 struct dialog_info* di;
179 HFONT hFont, hOldFont;
180
181 di = (struct dialog_info*)GetWindowLongPtr(GetParent(hWnd), DWLP_USER);
182 BeginPaint(hWnd, &ps);
183
184 font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
185 size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
186
187 hFont = (HFONT)GetWindowLongPtr(hWnd, 0L);
188 if (hFont)
189 {
190 WCHAR buf1[256];
191 WCHAR buf2[256];
192 int len1, len2;
193
194 len1 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_1,
195 buf1, sizeof(buf1) / sizeof(WCHAR));
196 len2 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_2,
197 buf2, sizeof(buf2) / sizeof(WCHAR));
198 buf1[len1] = buf2[len2] = 0;
199 if (len1)
200 {
201 hOldFont = SelectObject(ps.hdc, hFont);
202 SetBkColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_BK), 0)]);
203 SetTextColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_FG), 0)]);
204 TextOut(ps.hdc, 0, 0, buf1, len1);
205 if (len2)
206 TextOut(ps.hdc, 0, di->font[size_idx].height, buf2, len2);
207 SelectObject(ps.hdc, hOldFont);
208 }
209 }
210 EndPaint(hWnd, &ps);
211 }
212 break;
213 default:
214 return DefWindowProc(hWnd, msg, wParam, lParam);
215 }
216 return 0L;
217 }
218
219 /******************************************************************
220 * WCUSER_ColorPreviewProc
221 *
222 * Window proc for color previewer in font property sheet
223 */
224 static LRESULT WINAPI WCUSER_ColorPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
225 {
226 switch (msg)
227 {
228 case WM_PAINT:
229 {
230 PAINTSTRUCT ps;
231 int i, step;
232 RECT client, r;
233 HBRUSH hbr;
234
235 BeginPaint(hWnd, &ps);
236 GetClientRect(hWnd, &client);
237 step = client.right / 8;
238
239 for (i = 0; i < 16; i++)
240 {
241 r.top = (i / 8) * (client.bottom / 2);
242 r.bottom = r.top + client.bottom / 2;
243 r.left = (i & 7) * step;
244 r.right = r.left + step;
245 hbr = CreateSolidBrush(WCUSER_ColorMap[i]);
246 FillRect(ps.hdc, &r, hbr);
247 DeleteObject(hbr);
248 if (GetWindowLong(hWnd, 0) == i)
249 {
250 HPEN hOldPen;
251 int i = 2;
252
253 hOldPen = SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
254 r.right--; r.bottom--;
255 for (;;)
256 {
257 MoveToEx(ps.hdc, r.left, r.bottom, NULL);
258 LineTo(ps.hdc, r.left, r.top);
259 LineTo(ps.hdc, r.right, r.top);
260 SelectObject(ps.hdc, GetStockObject(BLACK_PEN));
261 LineTo(ps.hdc, r.right, r.bottom);
262 LineTo(ps.hdc, r.left, r.bottom);
263
264 if (--i == 0) break;
265 r.left++; r.top++; r.right--; r.bottom--;
266 SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
267 }
268 SelectObject(ps.hdc, hOldPen);
269 }
270 }
271 EndPaint(hWnd, &ps);
272 break;
273 }
274 case WM_LBUTTONDOWN:
275 {
276 int i, step;
277 RECT client;
278
279 GetClientRect(hWnd, &client);
280 step = client.right / 8;
281 i = (HIWORD(lParam) >= client.bottom / 2) ? 8 : 0;
282 i += LOWORD(lParam) / step;
283 SetWindowLong(hWnd, 0, i);
284 InvalidateRect(GetDlgItem(GetParent(hWnd), IDC_FNT_PREVIEW), NULL, FALSE);
285 InvalidateRect(hWnd, NULL, FALSE);
286 }
287 break;
288 default:
289 return DefWindowProc(hWnd, msg, wParam, lParam);
290 }
291 return 0L;
292 }
293
294 /******************************************************************
295 * font_enum
296 *
297 * enumerates all the font names with at least one valid font
298 */
299 static int CALLBACK font_enum_size2(const LOGFONT* lf, const TEXTMETRIC* tm,
300 DWORD FontType, LPARAM lParam)
301 {
302 struct dialog_info* di = (struct dialog_info*)lParam;
303
304 WCUSER_DumpTextMetric(tm, FontType);
305 if (WCUSER_ValidateFontMetric(di->data, tm, FontType))
306 {
307 di->nFont++;
308 }
309
310 return 1;
311 }
312
313 static int CALLBACK font_enum(const LOGFONT* lf, const TEXTMETRIC* tm,
314 DWORD FontType, LPARAM lParam)
315 {
316 struct dialog_info* di = (struct dialog_info*)lParam;
317
318 WCUSER_DumpLogFont("DlgFamily: ", lf, FontType);
319 if (WCUSER_ValidateFont(di->data, lf))
320 {
321 if (FontType & RASTER_FONTTYPE)
322 {
323 di->nFont = 0;
324 EnumFontFamilies(PRIVATE(di->data)->hMemDC, lf->lfFaceName, font_enum_size2, (LPARAM)di);
325 }
326 else
327 di->nFont = 1;
328
329 if (di->nFont)
330 {
331 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_ADDSTRING,
332 0, (LPARAM)lf->lfFaceName);
333 }
334 }
335
336 return 1;
337 }
338
339 /******************************************************************
340 * font_enum_size
341 *
342 *
343 */
344 static int CALLBACK font_enum_size(const LOGFONT* lf, const TEXTMETRIC* tm,
345 DWORD FontType, LPARAM lParam)
346 {
347 struct dialog_info* di = (struct dialog_info*)lParam;
348 WCHAR buf[32];
349 static const WCHAR fmt[] = {'%','l','d',0};
350
351 WCUSER_DumpTextMetric(tm, FontType);
352 if (di->nFont == 0 && !(FontType & RASTER_FONTTYPE))
353 {
354 static const int sizes[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
355 int i;
356
357 di->nFont = sizeof(sizes) / sizeof(sizes[0]);
358 di->font = HeapAlloc(GetProcessHeap(), 0, di->nFont * sizeof(di->font[0]));
359 for (i = 0; i < di->nFont; i++)
360 {
361 /* drop sizes where window size wouldn't fit on screen */
362 if (sizes[i] * di->data->curcfg.win_height > GetSystemMetrics(SM_CYSCREEN))
363 {
364 di->nFont = i;
365 break;
366 }
367 di->font[i].height = sizes[i];
368 di->font[i].weight = 400;
369 lstrcpy(di->font[i].faceName, lf->lfFaceName);
370 wsprintf(buf, fmt, sizes[i]);
371 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, i, (LPARAM)buf);
372 }
373 /* don't need to enumerate other */
374 return 0;
375 }
376
377 if (WCUSER_ValidateFontMetric(di->data, tm, FontType))
378 {
379 int idx;
380
381 /* we want the string to be sorted with a numeric order, not a lexicographic...
382 * do the job by hand... get where to insert the new string
383 */
384 for (idx = 0; idx < di->nFont && tm->tmHeight > di->font[idx].height; idx++);
385 while (idx < di->nFont &&
386 tm->tmHeight == di->font[idx].height &&
387 tm->tmWeight > di->font[idx].weight)
388 idx++;
389 if (idx == di->nFont ||
390 tm->tmHeight != di->font[idx].height ||
391 tm->tmWeight < di->font[idx].weight)
392 {
393 /* here we need to add the new entry */
394 wsprintf(buf, fmt, tm->tmHeight);
395 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, idx, (LPARAM)buf);
396
397 /* now grow our arrays and insert the values at the same index than in the list box */
398 if (di->nFont)
399 {
400 di->font = HeapReAlloc(GetProcessHeap(), 0, di->font, sizeof(*di->font) * (di->nFont + 1));
401 if (idx != di->nFont)
402 memmove(&di->font[idx + 1], &di->font[idx], (di->nFont - idx) * sizeof(*di->font));
403 }
404 else
405 di->font = HeapAlloc(GetProcessHeap(), 0, sizeof(*di->font));
406 di->font[idx].height = tm->tmHeight;
407 di->font[idx].weight = tm->tmWeight;
408 lstrcpy(di->font[idx].faceName, lf->lfFaceName);
409 di->nFont++;
410 }
411 }
412 return 1;
413 }
414
415 /******************************************************************
416 * select_font
417 *
418 *
419 */
420 static BOOL select_font(struct dialog_info* di)
421 {
422 int font_idx, size_idx;
423 WCHAR buf[256];
424 WCHAR fmt[128];
425 LOGFONT lf;
426 HFONT hFont, hOldFont;
427 struct config_data config;
428
429 font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
430 size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
431
432 if (font_idx < 0 || size_idx < 0 || size_idx >= di->nFont)
433 return FALSE;
434
435 WCUSER_FillLogFont(&lf, di->font[size_idx].faceName,
436 di->font[size_idx].height, di->font[size_idx].weight);
437 hFont = WCUSER_CopyFont(&config, di->data->hWnd, &lf, NULL);
438 if (!hFont) return FALSE;
439
440 if (config.cell_height != di->font[size_idx].height)
441 WINE_TRACE("mismatched heights (%u<>%u)\n",
442 config.cell_height, di->font[size_idx].height);
443 hOldFont = (HFONT)SendDlgItemMessage(di->hDlg, IDC_FNT_PREVIEW, WM_GETFONT, 0L, 0L);
444
445 SendDlgItemMessage(di->hDlg, IDC_FNT_PREVIEW, WM_SETFONT, (WPARAM)hFont, TRUE);
446 if (hOldFont) DeleteObject(hOldFont);
447
448 LoadString(GetModuleHandle(NULL), IDS_FNT_DISPLAY, fmt, sizeof(fmt) / sizeof(WCHAR));
449 wsprintf(buf, fmt, config.cell_width, config.cell_height);
450
451 SendDlgItemMessage(di->hDlg, IDC_FNT_FONT_INFO, WM_SETTEXT, 0, (LPARAM)buf);
452
453 return TRUE;
454 }
455
456 /******************************************************************
457 * fill_list_size
458 *
459 * fills the size list box according to selected family in font LB
460 */
461 static BOOL fill_list_size(struct dialog_info* di, BOOL doInit)
462 {
463 int idx;
464 WCHAR lfFaceName[LF_FACESIZE];
465
466 idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
467 if (idx < 0) return FALSE;
468
469 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETTEXT, idx, (LPARAM)lfFaceName);
470 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_RESETCONTENT, 0L, 0L);
471 HeapFree(GetProcessHeap(), 0, di->font);
472 di->nFont = 0;
473 di->font = NULL;
474
475 EnumFontFamilies(PRIVATE(di->data)->hMemDC, lfFaceName, font_enum_size, (LPARAM)di);
476
477 if (doInit)
478 {
479 int ref = -1;
480
481 for (idx = 0; idx < di->nFont; idx++)
482 {
483 if (!lstrcmp(di->font[idx].faceName, di->config.face_name) &&
484 di->font[idx].height == di->config.cell_height &&
485 di->font[idx].weight == di->config.font_weight)
486 {
487 if (ref == -1) ref = idx;
488 else WINE_TRACE("Several matches found: ref=%d idx=%d\n", ref, idx);
489 }
490 }
491 idx = (ref == -1) ? 0 : ref;
492 }
493 else
494 idx = 0;
495 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_SETCURSEL, idx, 0L);
496 select_font(di);
497 return TRUE;
498 }
499
500 /******************************************************************
501 * fill_list_font
502 *
503 * Fills the font LB
504 */
505 static BOOL fill_list_font(struct dialog_info* di)
506 {
507 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_RESETCONTENT, 0L, 0L);
508 EnumFontFamilies(PRIVATE(di->data)->hMemDC, NULL, font_enum, (LPARAM)di);
509 if (SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SELECTSTRING,
510 (WPARAM)-1, (LPARAM)di->config.face_name) == LB_ERR)
511 SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SETCURSEL, 0L, 0L);
512 fill_list_size(di, TRUE);
513 return TRUE;
514 }
515
516 /******************************************************************
517 * WCUSER_FontDlgProc
518 *
519 * Dialog proc for the Font property sheet
520 */
521 static INT_PTR WINAPI WCUSER_FontDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
522 {
523 struct dialog_info* di;
524
525 switch (msg)
526 {
527 case WM_INITDIALOG:
528 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
529 di->hDlg = hDlg;
530 SetWindowLongPtr(hDlg, DWLP_USER, (DWORD_PTR)di);
531 /* remove dialog from this control, font will be reset when listboxes are filled */
532 SendDlgItemMessage(hDlg, IDC_FNT_PREVIEW, WM_SETFONT, 0L, 0L);
533 fill_list_font(di);
534 SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0, (di->config.def_attr >> 4) & 0x0F);
535 SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0, di->config.def_attr & 0x0F);
536 break;
537 case WM_COMMAND:
538 di = (struct dialog_info*)GetWindowLongPtr(hDlg, DWLP_USER);
539 switch (LOWORD(wParam))
540 {
541 case IDC_FNT_LIST_FONT:
542 if (HIWORD(wParam) == LBN_SELCHANGE)
543 {
544 fill_list_size(di, FALSE);
545 }
546 break;
547 case IDC_FNT_LIST_SIZE:
548 if (HIWORD(wParam) == LBN_SELCHANGE)
549 {
550 select_font(di);
551 }
552 break;
553 }
554 break;
555 case WM_NOTIFY:
556 {
557 NMHDR* nmhdr = (NMHDR*)lParam;
558 DWORD val;
559
560 di = (struct dialog_info*)GetWindowLongPtr(hDlg, DWLP_USER);
561 switch (nmhdr->code)
562 {
563 case PSN_SETACTIVE:
564 di->hDlg = hDlg;
565 break;
566 case PSN_APPLY:
567 val = SendDlgItemMessage(hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
568
569 if (val < di->nFont)
570 {
571 LOGFONT lf;
572
573 WCUSER_FillLogFont(&lf, di->font[val].faceName,
574 di->font[val].height, di->font[val].weight);
575 DeleteObject(WCUSER_CopyFont(&di->config,
576 di->data->hWnd, &lf, NULL));
577 }
578
579 val = (GetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0) << 4) |
580 GetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0);
581 di->config.def_attr = val;
582
583 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
584 return TRUE;
585 default:
586 return FALSE;
587 }
588 break;
589 }
590 default:
591 return FALSE;
592 }
593 return TRUE;
594 }
595
596 /******************************************************************
597 * WCUSER_ConfigDlgProc
598 *
599 * Dialog proc for the config property sheet
600 */
601 static INT_PTR WINAPI WCUSER_ConfigDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
602 {
603 struct dialog_info* di;
604 int nMaxUD = 2000;
605
606 switch (msg)
607 {
608 case WM_INITDIALOG:
609 di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
610 di->hDlg = hDlg;
611
612 SetWindowLongPtr(hDlg, DWLP_USER, (DWORD_PTR)di);
613 SetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH, di->config.sb_width, FALSE);
614 SetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, di->config.sb_height, FALSE);
615 SetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH, di->config.win_width, FALSE);
616 SetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, di->config.win_height, FALSE);
617
618 SendMessage(GetDlgItem(hDlg,IDC_CNF_WIN_HEIGHT_UD), UDM_SETRANGE, 0, MAKELPARAM (nMaxUD, 0));
619 SendMessage(GetDlgItem(hDlg,IDC_CNF_WIN_WIDTH_UD), UDM_SETRANGE, 0, MAKELPARAM (nMaxUD, 0));
620 SendMessage(GetDlgItem(hDlg,IDC_CNF_SB_HEIGHT_UD), UDM_SETRANGE, 0, MAKELPARAM (nMaxUD, 0));
621 SendMessage(GetDlgItem(hDlg,IDC_CNF_SB_WIDTH_UD), UDM_SETRANGE, 0, MAKELPARAM (nMaxUD, 0));
622
623 SendDlgItemMessage(hDlg, IDC_CNF_CLOSE_EXIT, BM_SETCHECK,
624 (di->config.exit_on_die) ? BST_CHECKED : BST_UNCHECKED, 0L);
625 {
626 static const WCHAR s1[] = {'W','i','n','3','2',0};
627 static const WCHAR s2[] = {'E','m','a','c','s',0};
628
629 SendDlgItemMessage(hDlg, IDC_CNF_EDITION_MODE, CB_ADDSTRING,
630 0, (LPARAM)s1);
631 SendDlgItemMessage(hDlg, IDC_CNF_EDITION_MODE, CB_ADDSTRING,
632 0, (LPARAM)s2);
633 SendDlgItemMessage(hDlg, IDC_CNF_EDITION_MODE, CB_SETCURSEL,
634 di->config.edition_mode, 0);
635 }
636
637 break;
638 case WM_COMMAND:
639 di = (struct dialog_info*)GetWindowLongPtr(hDlg, DWLP_USER);
640 switch (LOWORD(wParam))
641 {
642 }
643 break;
644 case WM_NOTIFY:
645 {
646 NMHDR* nmhdr = (NMHDR*)lParam;
647 int win_w, win_h, sb_w, sb_h;
648 BOOL st1, st2;
649
650 di = (struct dialog_info*)GetWindowLongPtr(hDlg, DWLP_USER);
651 switch (nmhdr->code)
652 {
653 case PSN_SETACTIVE:
654 di->hDlg = hDlg;
655 break;
656 case PSN_APPLY:
657 sb_w = GetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH, &st1, FALSE);
658 sb_h = GetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, &st2, FALSE);
659 if (!st1 || ! st2)
660 {
661 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
662 return TRUE;
663 }
664 win_w = GetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH, &st1, FALSE);
665 win_h = GetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, &st2, FALSE);
666 if (!st1 || !st2)
667 {
668 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
669 return TRUE;
670 }
671 if (win_w > sb_w || win_h > sb_h)
672 {
673 WCHAR cap[256];
674 WCHAR txt[256];
675
676 LoadString(GetModuleHandle(NULL), IDS_DLG_TIT_ERROR,
677 cap, sizeof(cap) / sizeof(WCHAR));
678 LoadString(GetModuleHandle(NULL), IDS_DLG_ERR_SBWINSIZE,
679 txt, sizeof(txt) / sizeof(WCHAR));
680
681 MessageBox(hDlg, txt, cap, MB_OK);
682 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_INVALID);
683 return TRUE;
684 }
685 di->config.win_width = win_w;
686 di->config.win_height = win_h;
687 di->config.sb_width = sb_w;
688 di->config.sb_height = sb_h;
689
690 di->config.exit_on_die = IsDlgButtonChecked(hDlg, IDC_CNF_CLOSE_EXIT) ? 1 : 0;
691 di->config.edition_mode = SendDlgItemMessage(hDlg, IDC_CNF_EDITION_MODE, CB_GETCURSEL,
692 0, 0);
693 SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
694 return TRUE;
695 default:
696 return FALSE;
697 }
698 break;
699 }
700 default:
701 return FALSE;
702 }
703 return TRUE;
704 }
705
706 /******************************************************************
707 * WCUSER_SaveDlgProc
708 *
709 * Dialog Procedure for choosing how to handle modification to the
710 * console settings.
711 */
712 static INT_PTR WINAPI WCUSER_SaveDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
713 {
714 switch (msg)
715 {
716 case WM_INITDIALOG:
717 SendDlgItemMessage(hDlg, IDC_SAV_SESSION, BM_SETCHECK, BST_CHECKED, 0);
718 break;
719 case WM_COMMAND:
720 switch (LOWORD(wParam))
721 {
722 case IDOK:
723 EndDialog(hDlg,
724 (IsDlgButtonChecked(hDlg, IDC_SAV_SAVE) == BST_CHECKED) ?
725 IDC_SAV_SAVE : IDC_SAV_SESSION);
726 break;
727 case IDCANCEL:
728 EndDialog(hDlg, IDCANCEL); break;
729 }
730 break;
731 default:
732 return FALSE;
733 }
734 return TRUE;
735 }
736
737 /******************************************************************
738 * WCUSER_GetProperties
739 *
740 * Runs the dialog box to set up the wineconsole options
741 */
742 BOOL WCUSER_GetProperties(struct inner_data* data, BOOL current)
743 {
744 HPROPSHEETPAGE psPage[3];
745 PROPSHEETPAGE psp;
746 PROPSHEETHEADER psHead;
747 WCHAR buff[256];
748 WNDCLASS wndclass;
749 static const WCHAR szFntPreview[] = {'W','i','n','e','C','o','n','F','o','n','t','P','r','e','v','i','e','w',0};
750 static const WCHAR szColorPreview[] = {'W','i','n','e','C','o','n','C','o','l','o','r','P','r','e','v','i','e','w',0};
751 struct dialog_info di;
752 struct config_data defcfg;
753 struct config_data* refcfg;
754 BOOL save, modify_session;
755
756 InitCommonControls();
757
758 di.data = data;
759 if (current)
760 {
761 refcfg = &data->curcfg;
762 save = FALSE;
763 }
764 else
765 {
766 WINECON_RegLoad(NULL, refcfg = &defcfg);
767 save = TRUE;
768 }
769 di.config = *refcfg;
770 di.nFont = 0;
771 di.font = NULL;
772
773 modify_session = FALSE;
774
775 wndclass.style = 0;
776 wndclass.lpfnWndProc = WCUSER_FontPreviewProc;
777 wndclass.cbClsExtra = 0;
778 wndclass.cbWndExtra = sizeof (DWORD_PTR); /* for hFont */
779 wndclass.hInstance = GetModuleHandle(NULL);
780 wndclass.hIcon = 0;
781 wndclass.hCursor = LoadCursor(0, IDC_ARROW);
782 wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
783 wndclass.lpszMenuName = NULL;
784 wndclass.lpszClassName = szFntPreview;
785 RegisterClass(&wndclass);
786
787 wndclass.style = 0;
788 wndclass.lpfnWndProc = WCUSER_ColorPreviewProc;
789 wndclass.cbClsExtra = 0;
790 wndclass.cbWndExtra = sizeof(DWORD);
791 wndclass.hInstance = GetModuleHandle(NULL);
792 wndclass.hIcon = 0;
793 wndclass.hCursor = LoadCursor(0, IDC_ARROW);
794 wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
795 wndclass.lpszMenuName = NULL;
796 wndclass.lpszClassName = szColorPreview;
797 RegisterClass(&wndclass);
798
799 memset(&psp, 0, sizeof(psp));
800 psp.dwSize = sizeof(psp);
801 psp.dwFlags = 0;
802 psp.hInstance = wndclass.hInstance;
803 psp.lParam = (LPARAM)&di;
804
805 psp.u.pszTemplate = MAKEINTRESOURCE(IDD_OPTION);
806 psp.pfnDlgProc = WCUSER_OptionDlgProc;
807 psPage[0] = CreatePropertySheetPage(&psp);
808
809 psp.u.pszTemplate = MAKEINTRESOURCE(IDD_FONT);
810 psp.pfnDlgProc = WCUSER_FontDlgProc;
811 psPage[1] = CreatePropertySheetPage(&psp);
812
813 psp.u.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG);
814 psp.pfnDlgProc = WCUSER_ConfigDlgProc;
815 psPage[2] = CreatePropertySheetPage(&psp);
816
817 memset(&psHead, 0, sizeof(psHead));
818 psHead.dwSize = sizeof(psHead);
819
820 if (!LoadString(GetModuleHandle(NULL),
821 (current) ? IDS_DLG_TIT_CURRENT : IDS_DLG_TIT_DEFAULT,
822 buff, sizeof(buff) / sizeof(buff[0])))
823 {
824 buff[0] = 'S';
825 buff[1] = 'e';
826 buff[2] = 't';
827 buff[3] = 'u';
828 buff[4] = 'p';
829 buff[5] = '\0';
830 }
831
832 psHead.pszCaption = buff;
833 psHead.nPages = 3;
834 psHead.hwndParent = data->hWnd;
835 psHead.u3.phpage = psPage;
836 psHead.dwFlags = PSH_NOAPPLYNOW;
837
838 WINECON_DumpConfig("init", refcfg);
839
840 PropertySheet(&psHead);
841
842 if (memcmp(refcfg, &di.config, sizeof(*refcfg)) == 0)
843 return TRUE;
844
845 WINECON_DumpConfig("ref", refcfg);
846 WINECON_DumpConfig("cur", &di.config);
847 if (refcfg == &data->curcfg)
848 {
849 switch (DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_SAVE_SETTINGS),
850 data->hWnd, WCUSER_SaveDlgProc))
851 {
852 case IDC_SAV_SAVE: save = TRUE; modify_session = TRUE; break;
853 case IDC_SAV_SESSION: modify_session = TRUE; break;
854 case IDCANCEL: break;
855 default: WINE_ERR("ooch\n");
856 }
857 }
858
859 if (modify_session) WINECON_SetConfig(data, &di.config);
860 if (save) WINECON_RegSave(&di.config);
861
862 return TRUE;
863 }
864
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.