source: trunk/src/user32/new/win32dlg.cpp@ 821

Last change on this file since 821 was 821, checked in by sandervl, 26 years ago

Dialog changes

File size: 26.6 KB
Line 
1/* $Id: win32dlg.cpp,v 1.3 1999-09-04 19:42:28 sandervl Exp $ */
2/*
3 * Win32 Dialog Code for OS/2
4 *
5 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl) (Wine port & OS/2 adaption)
6 *
7 * Based on Wine code (990815; windows\dialog.c)
8 *
9 * Copyright 1993, 1994, 1996 Alexandre Julliard
10 *
11 * Project Odin Software License can be found in LICENSE.TXT
12 *
13 */
14#include <os2win.h>
15#include <windowsx.h>
16#include <stdlib.h>
17#include <string.h>
18#include <misc.h>
19#include <win32dlg.h>
20
21//******************************************************************************
22//******************************************************************************
23Win32Dialog::Win32Dialog(HINSTANCE hInst, LPCSTR dlgTemplate, HWND owner,
24 DLGPROC dlgProc, LPARAM param, BOOL isUnicode)
25 : Win32BaseWindow(OBJTYPE_DIALOG)
26{
27 RECT rect;
28 WORD style;
29 ATOM classAtom;
30
31 this->isUnicode = isUnicode;
32 hUserFont = 0;
33 hMenu = 0;
34 hwndFocus = 0;
35 Win32DlgProc = 0;
36 msgResult = 0;
37 userDlgData = 0;
38 idResult = 0;
39 dialogFlags = 0;
40 memset(&dlgInfo, 0, sizeof(dlgInfo));
41
42 if(fInitialized == FALSE) {
43 if(DIALOG_Init() == FALSE) {
44 dprintf(("DIALOG_Init FAILED!"));
45 DebugInt3();
46 SetLastError(ERROR_GEN_FAILURE);
47 return;
48 }
49 fInitialized = TRUE;
50 }
51 xUnit = xBaseUnit;
52 yUnit = yBaseUnit;
53
54 /* Parse dialog template */
55 dlgTemplate = parseTemplate(dlgTemplate, &dlgInfo);
56
57 /* Load menu */
58 if (dlgInfo.menuName)
59 {
60 hMenu = LoadMenuW( hInst, (LPCWSTR)dlgInfo.menuName );
61 }
62
63 /* Create custom font if needed */
64 if (dlgInfo.style & DS_SETFONT)
65 {
66 /* The font height must be negative as it is a point size */
67 /* (see CreateFont() documentation in the Windows SDK). */
68 hUserFont = CreateFontW(dlgInfo.pointSize, 0, 0, 0,
69 dlgInfo.weight, dlgInfo.italic, FALSE,
70 FALSE, DEFAULT_CHARSET, 0, 0, PROOF_QUALITY,
71 FF_DONTCARE, (LPCWSTR)dlgInfo.faceName );
72 if (hUserFont)
73 {
74 SIZE charSize;
75 getCharSize(hUserFont,&charSize);
76 xBaseUnit = charSize.cx;
77 yBaseUnit = charSize.cy;
78 }
79 }
80
81 /* Create dialog main window */
82 rect.left = rect.top = 0;
83 rect.right = dlgInfo.cx * xUnit / 4;
84 rect.bottom = dlgInfo.cy * yUnit / 8;
85 if (dlgInfo.style & DS_MODALFRAME)
86 dlgInfo.exStyle |= WS_EX_DLGMODALFRAME;
87
88 AdjustWindowRectEx( &rect, dlgInfo.style, hMenu ? TRUE : FALSE , dlgInfo.exStyle );
89 rect.right -= rect.left;
90 rect.bottom -= rect.top;
91
92 if ((INT16)dlgInfo.x == CW_USEDEFAULT16)
93 {
94 rect.left = rect.top = CW_USEDEFAULT;
95 }
96 else
97 {
98 if (dlgInfo.style & DS_CENTER)
99 {
100 rect.left = (GetSystemMetrics(SM_CXSCREEN) - rect.right) / 2;
101 rect.top = (GetSystemMetrics(SM_CYSCREEN) - rect.bottom) / 2;
102 }
103 else
104 {
105 rect.left += dlgInfo.x * xUnit / 4;
106 rect.top += dlgInfo.y * yUnit / 8;
107 }
108 if ( !(dlgInfo.style & WS_CHILD) )
109 {
110 INT dX, dY;
111
112 if( !(dlgInfo.style & DS_ABSALIGN) )
113 ClientToScreen(owner, (POINT *)&rect );
114
115 /* try to fit it into the desktop */
116
117 if( (dX = rect.left + rect.right + GetSystemMetrics(SM_CXDLGFRAME)
118 - GetSystemMetrics(SM_CXSCREEN)) > 0 ) rect.left -= dX;
119 if( (dY = rect.top + rect.bottom + GetSystemMetrics(SM_CYDLGFRAME)
120 - GetSystemMetrics(SM_CYSCREEN)) > 0 ) rect.top -= dY;
121 if( rect.left < 0 ) rect.left = 0;
122 if( rect.top < 0 ) rect.top = 0;
123 }
124 }
125
126 /* Create the dialog window */
127
128 /* Find the class atom */
129 if (HIWORD(dlgInfo.className))
130 {
131 classAtom = (ATOM)LOWORD(dlgInfo.className);
132 }
133 else
134 if(!(classAtom = GlobalFindAtomA(dlgInfo.className)))
135 {
136 SetLastError(ERROR_INVALID_PARAMETER);
137 return;
138 }
139 CREATESTRUCTA cs;
140 cs.lpCreateParams = NULL;
141 cs.hInstance = hInst;
142 cs.hMenu = hMenu;
143 cs.hwndParent = owner;
144 cs.x = rect.left;
145 cs.y = rect.top;
146 cs.cx = rect.right;
147 cs.cy = rect.bottom;
148 cs.style = dlgInfo.style & ~WS_VISIBLE;
149 cs.lpszName = dlgInfo.caption;
150 cs.lpszClass = dlgInfo.className;
151 cs.dwExStyle = dlgInfo.exStyle;
152
153 CreateWindowExA(&cs, classAtom);
154
155 if (!getWindowHandle())
156 {
157 if (hUserFont) DeleteObject( hUserFont );
158 if (hMenu) DestroyMenu( hMenu );
159 return;
160 }
161 fIsDialog = TRUE;
162
163//TODO:
164// wndPtr->helpContext = helpId;
165 Win32DlgProc = dlgProc;
166
167 if (hUserFont)
168 SendMessageA(WM_SETFONT, (WPARAM)hUserFont, 0 );
169
170 /* Create controls */
171 if (createControls(dlgTemplate, hInst))
172 {
173 /* Send initialisation messages and set focus */
174 hwndFocus = GetNextDlgTabItem( getWindowHandle(), 0, FALSE );
175
176 if (::SendMessageA(hwndFocus, WM_INITDIALOG, (WPARAM)hwndFocus, param ))
177 SetFocus( hwndFocus );
178
179 if (dlgInfo.style & WS_VISIBLE && !(getStyle() & WS_VISIBLE))
180 {
181 ShowWindow( SW_SHOWNORMAL ); /* SW_SHOW doesn't always work */
182 ::UpdateWindow( getWindowHandle() );
183 }
184 return;
185 }
186 DestroyWindow();
187}
188//******************************************************************************
189//******************************************************************************
190Win32Dialog::~Win32Dialog()
191{
192 if (hUserFont) DeleteObject( hUserFont );
193 if (hMenu) DestroyMenu( hMenu );
194
195}
196/***********************************************************************
197 * DIALOG_Init
198 *
199 * Initialisation of the dialog manager.
200 */
201BOOL Win32Dialog::DIALOG_Init(void)
202{
203 HDC hdc;
204 SIZE size;
205
206 /* Calculate the dialog base units */
207 if (!(hdc = CreateDCA( "DISPLAY", NULL, NULL, NULL ))) return FALSE;
208 if (!getCharSizeFromDC( hdc, 0, &size )) return FALSE;
209 DeleteDC( hdc );
210 xBaseUnit = size.cx;
211 yBaseUnit = size.cy;
212
213 return TRUE;
214}
215/***********************************************************************
216 * DIALOG_GetCharSizeFromDC
217 *
218 *
219 * Calculates the *true* average size of English characters in the
220 * specified font as oppposed to the one returned by GetTextMetrics.
221 */
222BOOL Win32Dialog::getCharSizeFromDC( HDC hDC, HFONT hUserFont, SIZE * pSize )
223{
224 BOOL Success = FALSE;
225 HFONT hUserFontPrev = 0;
226 pSize->cx = xBaseUnit;
227 pSize->cy = yBaseUnit;
228
229 if ( hDC )
230 {
231 /* select the font */
232 TEXTMETRICA tm;
233 memset(&tm,0,sizeof(tm));
234 if (hUserFont) hUserFontPrev = SelectFont(hDC,hUserFont);
235 if (GetTextMetricsA(hDC,&tm))
236 {
237 pSize->cx = tm.tmAveCharWidth;
238 pSize->cy = tm.tmHeight;
239
240 /* if variable width font */
241 if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH)
242 {
243 SIZE total;
244 static const char szAvgChars[53] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
245
246 /* Calculate a true average as opposed to the one returned
247 * by tmAveCharWidth. This works better when dealing with
248 * proportional spaced fonts and (more important) that's
249 * how Microsoft's dialog creation code calculates the size
250 * of the font
251 */
252 if (GetTextExtentPointA(hDC,szAvgChars,sizeof(szAvgChars),&total))
253 {
254 /* round up */
255 pSize->cx = ((2*total.cx/sizeof(szAvgChars)) + 1)/2;
256 Success = TRUE;
257 }
258 }
259 else
260 {
261 Success = TRUE;
262 }
263 }
264
265 /* select the original font */
266 if (hUserFontPrev) SelectFont(hDC,hUserFontPrev);
267 }
268 return (Success);
269}
270/***********************************************************************
271 * DIALOG_GetCharSize
272 *
273 *
274 * Calculates the *true* average size of English characters in the
275 * specified font as oppposed to the one returned by GetTextMetrics.
276 * A convenient variant of DIALOG_GetCharSizeFromDC.
277 */
278BOOL Win32Dialog::getCharSize( HFONT hUserFont, SIZE * pSize )
279{
280 HDC hDC = GetDC(0);
281 BOOL Success = getCharSizeFromDC( hDC, hUserFont, pSize );
282 ReleaseDC(0, hDC);
283 return Success;
284}
285/***********************************************************************
286 * DIALOG_ParseTemplate32
287 *
288 * Fill a DLG_TEMPLATE structure from the dialog template, and return
289 * a pointer to the first control.
290 */
291LPCSTR Win32Dialog::parseTemplate( LPCSTR dlgtemplate, DLG_TEMPLATE * result )
292{
293 const WORD *p = (const WORD *)dlgtemplate;
294
295 result->style = GET_DWORD(p); p += 2;
296 if (result->style == 0xffff0001) /* DIALOGEX resource */
297 {
298 result->dialogEx = TRUE;
299 result->helpId = GET_DWORD(p); p += 2;
300 result->exStyle = GET_DWORD(p); p += 2;
301 result->style = GET_DWORD(p); p += 2;
302 }
303 else
304 {
305 result->dialogEx = FALSE;
306 result->helpId = 0;
307 result->exStyle = GET_DWORD(p); p += 2;
308 }
309 result->nbItems = GET_WORD(p); p++;
310 result->x = GET_WORD(p); p++;
311 result->y = GET_WORD(p); p++;
312 result->cx = GET_WORD(p); p++;
313 result->cy = GET_WORD(p); p++;
314
315 /* Get the menu name */
316
317 switch(GET_WORD(p))
318 {
319 case 0x0000:
320 result->menuName = NULL;
321 p++;
322 break;
323 case 0xffff:
324 result->menuName = (LPCSTR)(UINT)GET_WORD( p + 1 );
325 p += 2;
326 break;
327 default:
328 result->menuName = (LPCSTR)p;
329 p += lstrlenW( (LPCWSTR)p ) + 1;
330 break;
331 }
332
333 /* Get the class name */
334 switch(GET_WORD(p))
335 {
336 case 0x0000:
337 result->className = (LPCSTR)DIALOG_CLASS_ATOM;
338 p++;
339 break;
340 case 0xffff:
341 result->className = (LPCSTR)(UINT)GET_WORD( p + 1 );
342 p += 2;
343 break;
344 default:
345 result->className = (LPCSTR)p;
346 p += lstrlenW( (LPCWSTR)p ) + 1;
347 break;
348 }
349
350 /* Get the window caption */
351
352 result->caption = (LPCSTR)p;
353 p += lstrlenW( (LPCWSTR)p ) + 1;
354
355 /* Get the font name */
356
357 if (result->style & DS_SETFONT)
358 {
359 result->pointSize = GET_WORD(p);
360 p++;
361 if (result->dialogEx)
362 {
363 result->weight = GET_WORD(p); p++;
364 result->italic = LOBYTE(GET_WORD(p)); p++;
365 }
366 else
367 {
368 result->weight = FW_DONTCARE;
369 result->italic = FALSE;
370 }
371 result->faceName = (LPCSTR)p;
372 p += lstrlenW( (LPCWSTR)p ) + 1;
373 }
374
375 /* First control is on dword boundary */
376 return (LPCSTR)((((int)p) + 3) & ~3);
377}
378/***********************************************************************
379 * DIALOG_GetControl32
380 *
381 * Return the class and text of the control pointed to by ptr,
382 * fill the header structure and return a pointer to the next control.
383 */
384WORD *Win32Dialog::getControl(const WORD *p, DLG_CONTROL_INFO *info, BOOL dialogEx)
385{
386 if (dialogEx)
387 {
388 info->helpId = GET_DWORD(p); p += 2;
389 info->exStyle = GET_DWORD(p); p += 2;
390 info->style = GET_DWORD(p); p += 2;
391 }
392 else
393 {
394 info->helpId = 0;
395 info->style = GET_DWORD(p); p += 2;
396 info->exStyle = GET_DWORD(p); p += 2;
397 }
398 info->x = GET_WORD(p); p++;
399 info->y = GET_WORD(p); p++;
400 info->cx = GET_WORD(p); p++;
401 info->cy = GET_WORD(p); p++;
402
403 if (dialogEx)
404 {
405 /* id is a DWORD for DIALOGEX */
406 info->id = GET_DWORD(p);
407 p += 2;
408 }
409 else
410 {
411 info->id = GET_WORD(p);
412 p++;
413 }
414
415 if (GET_WORD(p) == 0xffff)
416 {
417 static const WCHAR class_names[6][10] =
418 {
419 { 'B','u','t','t','o','n', }, /* 0x80 */
420 { 'E','d','i','t', }, /* 0x81 */
421 { 'S','t','a','t','i','c', }, /* 0x82 */
422 { 'L','i','s','t','B','o','x', }, /* 0x83 */
423 { 'S','c','r','o','l','l','B','a','r', }, /* 0x84 */
424 { 'C','o','m','b','o','B','o','x', } /* 0x85 */
425 };
426 WORD id = GET_WORD(p+1);
427 if ((id >= 0x80) && (id <= 0x85))
428 info->className = (LPCSTR)class_names[id - 0x80];
429 else
430 {
431 info->className = NULL;
432 dprintf(("Unknown built-in class id %04x\n", id ));
433 }
434 p += 2;
435 }
436 else
437 {
438 info->className = (LPCSTR)p;
439 p += lstrlenW( (LPCWSTR)p ) + 1;
440 }
441
442 if (GET_WORD(p) == 0xffff) /* Is it an integer id? */
443 {
444 info->windowName = (LPCSTR)(UINT)GET_WORD(p + 1);
445 p += 2;
446 }
447 else
448 {
449 info->windowName = (LPCSTR)p;
450 p += lstrlenW( (LPCWSTR)p ) + 1;
451 }
452
453 if (GET_WORD(p))
454 {
455 info->data = (LPVOID)(p + 1);
456 p += GET_WORD(p) / sizeof(WORD);
457 }
458 else info->data = NULL;
459 p++;
460
461 /* Next control is on dword boundary */
462 return (WORD *)((((int)p) + 3) & ~3);
463}
464
465
466/***********************************************************************
467 * DIALOG_CreateControls
468 *
469 * Create the control windows for a dialog.
470 */
471BOOL Win32Dialog::createControls(LPCSTR dlgtemplate, HINSTANCE hInst)
472{
473 DLG_CONTROL_INFO info;
474 HWND hwndCtrl, hwndDefButton = 0;
475 INT items = dlgInfo.nbItems;
476
477 while (items--)
478 {
479 dlgtemplate = (LPCSTR)getControl( (WORD *)dlgtemplate, &info, dlgInfo.dialogEx );
480
481 hwndCtrl = CreateWindowExW( info.exStyle | WS_EX_NOPARENTNOTIFY,
482 (LPCWSTR)info.className,
483 (LPCWSTR)info.windowName,
484 info.style | WS_CHILD,
485 info.x * xUnit / 4,
486 info.y * yUnit / 8,
487 info.cx * xUnit / 4,
488 info.cy * yUnit / 8,
489 getWindowHandle(), (HMENU)info.id,
490 hInst, info.data );
491
492 if (!hwndCtrl) return FALSE;
493
494 /* Send initialisation messages to the control */
495 if (hUserFont) ::SendMessageA( hwndCtrl, WM_SETFONT, (WPARAM)hUserFont, 0 );
496
497 if (::SendMessageA(hwndCtrl, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
498 {
499 /* If there's already a default push-button, set it back */
500 /* to normal and use this one instead. */
501 if (hwndDefButton)
502 ::SendMessageA( hwndDefButton, BM_SETSTYLE,
503 BS_PUSHBUTTON,FALSE );
504 hwndDefButton = hwndCtrl;
505 idResult = ::GetWindowWord( hwndCtrl, GWW_ID );
506 }
507 }
508 return TRUE;
509}
510/***********************************************************************
511 * DEFDLG_Proc
512 *
513 * Implementation of DefDlgProc(). Only handle messages that need special
514 * handling for dialogs.
515 */
516LRESULT Win32Dialog::DefDlg_Proc(UINT msg, WPARAM wParam, LPARAM lParam)
517{
518 switch(msg)
519 {
520 case WM_ERASEBKGND:
521 {
522 RECT rect;
523 int rc;
524 /* Since WM_ERASEBKGND may receive either a window dc or a */
525 /* client dc, the area to be erased has to be retrieved from */
526 /* the device context. */
527 rc = GetClipBox( (HDC)wParam, &rect );
528 if ((rc == SIMPLEREGION) || (rc == COMPLEXREGION))
529 FillRect( (HDC)wParam, &rect, windowClass->getBackgroundBrush());
530 return 1;
531 }
532 case WM_NCDESTROY:
533 /* Free dialog heap (if created) */
534#if 0
535 if (dlgInfo->hDialogHeap)
536 {
537 GlobalUnlock16(dlgInfo->hDialogHeap);
538 GlobalFree16(dlgInfo->hDialogHeap);
539 dlgInfo->hDialogHeap = 0;
540 }
541#endif
542 /* Delete font */
543 if (hUserFont)
544 {
545 DeleteObject( hUserFont );
546 hUserFont = 0;
547 }
548
549 /* Delete menu */
550 if (hMenu)
551 {
552 DestroyMenu( hMenu );
553 hMenu = 0;
554 }
555
556 /* Delete window procedure */
557 Win32DlgProc = 0;
558 dialogFlags |= DF_END; /* just in case */
559
560 /* Window clean-up */
561 return DefWindowProcA(msg, wParam, lParam );
562
563 case WM_SHOWWINDOW:
564 if (!wParam) saveFocus();
565 return DefWindowProcA(msg, wParam, lParam );
566
567 case WM_ACTIVATE:
568 if (wParam) {
569 restoreFocus();
570 }
571 else saveFocus();
572 return 0;
573
574 case WM_SETFOCUS:
575 restoreFocus();
576 return 0;
577
578 case DM_SETDEFID:
579 if (dialogFlags & DF_END)
580 return 1;
581
582 setDefButton(wParam ? GetDlgItem( getWindowHandle(), wParam ) : 0 );
583 return 1;
584
585 case DM_GETDEFID:
586 {
587 HWND hwndDefId;
588 if (dialogFlags & DF_END) return 0;
589 if (idResult)
590 return MAKELONG( idResult, DC_HASDEFID );
591 if ((hwndDefId = findDefButton()))
592 return MAKELONG( GetDlgCtrlID( hwndDefId ), DC_HASDEFID);
593
594 return 0;
595 }
596
597 case WM_NEXTDLGCTL:
598 {
599 HWND hwndDest = (HWND)wParam;
600 if (!lParam)
601 hwndDest = GetNextDlgTabItem(getWindowHandle(), GetFocus(), wParam);
602 if (hwndDest) setFocus( hwndDest );
603 setDefButton( hwndDest );
604 return 0;
605 }
606
607 case WM_ENTERMENULOOP:
608 case WM_LBUTTONDOWN:
609 case WM_NCLBUTTONDOWN:
610 {
611 HWND hwndCurFocus = GetFocus();
612 if (hwndCurFocus)
613 {
614#if 0
615 WND *wnd = WIN_FindWndPtr( hwndFocus );
616
617 if( wnd )
618 {
619 /* always make combo box hide its listbox control */
620 if( WIDGETS_IsControl( wnd, BIC32_COMBO ) )
621 SendMessageA( hwndFocus, CB_SHOWDROPDOWN, FALSE, 0 );
622 else
623 if( WIDGETS_IsControl( wnd, BIC32_EDIT ) &&
624 WIDGETS_IsControl( wnd->parent, BIC32_COMBO ))
625 SendMessageA(CB_SHOWDROPDOWN, FALSE, 0 );
626 }
627#endif
628 }
629 return DefWindowProcA( msg, wParam, lParam );
630 }
631
632 case WM_GETFONT:
633 return hUserFont;
634
635 case WM_CLOSE:
636 PostMessageA(WM_COMMAND, IDCANCEL, (LPARAM)GetDlgItem( getWindowHandle(), IDCANCEL ) );
637 return 0;
638
639 case WM_NOTIFYFORMAT:
640 return DefWindowProcA(msg, wParam, lParam );
641 }
642 return 0;
643}
644//******************************************************************************
645//******************************************************************************
646LRESULT Win32Dialog::DefDlgProcA(UINT Msg, WPARAM wParam, LPARAM lParam)
647{
648 BOOL result = FALSE;
649
650 msgResult = 0;
651
652 if (Win32DlgProc) { /* Call dialog procedure */
653 result = Win32DlgProc(getWindowHandle(), Msg, wParam, lParam);
654 }
655
656 if (!result && IsWindow())
657 {
658 /* callback didn't process this message */
659 switch(Msg)
660 {
661 case WM_ERASEBKGND:
662 case WM_SHOWWINDOW:
663 case WM_ACTIVATE:
664 case WM_SETFOCUS:
665 case DM_SETDEFID:
666 case DM_GETDEFID:
667 case WM_NEXTDLGCTL:
668 case WM_GETFONT:
669 case WM_CLOSE:
670 case WM_NCDESTROY:
671 case WM_ENTERMENULOOP:
672 case WM_LBUTTONDOWN:
673 case WM_NCLBUTTONDOWN:
674 return DefDlg_Proc(Msg, (WPARAM)wParam, lParam);
675
676 case WM_INITDIALOG:
677 case WM_VKEYTOITEM:
678 case WM_COMPAREITEM:
679 case WM_CHARTOITEM:
680 break;
681
682 default:
683 return DefWindowProcA(Msg, wParam, lParam );
684 }
685 }
686 return DefDlg_Epilog(Msg, result);
687}
688//******************************************************************************
689//******************************************************************************
690LRESULT Win32Dialog::DefDlgProcW(UINT Msg, WPARAM wParam, LPARAM lParam)
691{
692 BOOL result = FALSE;
693
694 msgResult = 0;
695
696 if (Win32DlgProc) { /* Call dialog procedure */
697 result = Win32DlgProc(getWindowHandle(), Msg, wParam, lParam);
698 }
699
700 if (!result && IsWindow())
701 {
702 /* callback didn't process this message */
703 switch(Msg)
704 {
705 case WM_ERASEBKGND:
706 case WM_SHOWWINDOW:
707 case WM_ACTIVATE:
708 case WM_SETFOCUS:
709 case DM_SETDEFID:
710 case DM_GETDEFID:
711 case WM_NEXTDLGCTL:
712 case WM_GETFONT:
713 case WM_CLOSE:
714 case WM_NCDESTROY:
715 case WM_ENTERMENULOOP:
716 case WM_LBUTTONDOWN:
717 case WM_NCLBUTTONDOWN:
718 return DefDlg_Proc(Msg, (WPARAM)wParam, lParam);
719
720 case WM_INITDIALOG:
721 case WM_VKEYTOITEM:
722 case WM_COMPAREITEM:
723 case WM_CHARTOITEM:
724 break;
725
726 default:
727 return DefWindowProcW(Msg, wParam, lParam );
728 }
729 }
730 return DefDlg_Epilog(Msg, result);
731}
732/***********************************************************************
733 * DEFDLG_Epilog
734 */
735LRESULT Win32Dialog::DefDlg_Epilog(UINT msg, BOOL fResult)
736{
737 /* see SDK 3.1 */
738 if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
739 msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
740 msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
741 msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
742 return fResult;
743
744 return msgResult;
745}
746/***********************************************************************
747 * DEFDLG_SetFocus
748 *
749 * Set the focus to a control of the dialog, selecting the text if
750 * the control is an edit dialog.
751 */
752void Win32Dialog::setFocus(HWND hwndCtrl )
753{
754 HWND hwndPrev = GetFocus();
755
756 if (IsChild( hwndPrev ))
757 {
758 if (::SendMessageA( hwndPrev, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
759 ::SendMessageA( hwndPrev, EM_SETSEL, TRUE, MAKELONG( -1, 0 ) );
760 }
761 if (::SendMessageA(hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
762 ::SendMessageA(hwndCtrl, EM_SETSEL, FALSE, MAKELONG( 0, -1 ) );
763 SetFocus( hwndCtrl );
764}
765
766
767/***********************************************************************
768 * DEFDLG_SaveFocus
769 */
770BOOL Win32Dialog::saveFocus()
771{
772 HWND hwndCurrentFocus = GetFocus();
773
774 if (!hwndCurrentFocus || !IsChild( hwndCurrentFocus )) return FALSE;
775
776 hwndFocus = hwndCurrentFocus;
777 /* Remove default button */
778 return TRUE;
779}
780
781
782/***********************************************************************
783 * DEFDLG_RestoreFocus
784 */
785BOOL Win32Dialog::restoreFocus()
786{
787 if (!hwndFocus || IsIconic()) return FALSE;
788
789 if (!::IsWindow( hwndFocus )) return FALSE;
790
791 /* Don't set the focus back to controls if EndDialog is already called.*/
792 if (!(dialogFlags & DF_END))
793 setFocus(hwndFocus);
794
795 /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
796 sometimes losing focus when receiving WM_SETFOCUS messages. */
797 return TRUE;
798}
799
800
801/***********************************************************************
802 * DEFDLG_FindDefButton
803 *
804 * Find the current default push-button.
805 */
806HWND Win32Dialog::findDefButton()
807{
808 HWND hwndChild = GetWindow( GW_CHILD );
809 while (hwndChild)
810 {
811 if (::SendMessageA( hwndChild, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
812 break;
813 hwndChild = ::GetWindow( hwndChild, GW_HWNDNEXT );
814 }
815 return hwndChild;
816}
817
818
819/***********************************************************************
820 * DEFDLG_SetDefButton
821 *
822 * Set the new default button to be hwndNew.
823 */
824BOOL Win32Dialog::setDefButton(HWND hwndNew )
825{
826 if (hwndNew &&
827 !(::SendMessageA(hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
828 return FALSE; /* Destination is not a push button */
829
830 if (idResult) /* There's already a default pushbutton */
831 {
832 HWND hwndOld = GetDlgItem( getWindowHandle(), idResult );
833 if (::SendMessageA( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
834 ::SendMessageA( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
835 }
836 if (hwndNew)
837 {
838 ::SendMessageA( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
839 idResult = GetDlgCtrlID( hwndNew );
840 }
841 else idResult = 0;
842 return TRUE;
843}
844//******************************************************************************
845//******************************************************************************
846ULONG Win32Dialog::MsgOS2Create(HWND hwndOS2, ULONG initParam)
847{
848 OS2Hwnd = hwndOS2;
849 return win32wndproc(Win32Hwnd, WM_CREATE, 0, initParam);
850}
851//******************************************************************************
852//******************************************************************************
853LONG Win32Dialog::SetWindowLongA(int index, ULONG value)
854{
855 LONG oldval;
856
857 switch(index)
858 {
859 case DWL_DLGPROC:
860 oldval = (LONG)Win32DlgProc;
861 Win32DlgProc = (DLGPROC)index;
862 return oldval;
863 case DWL_MSGRESULT:
864 oldval = msgResult;
865 msgResult = value;
866 return oldval;
867 case DWL_USER:
868 oldval = userDlgData;
869 userDlgData = value;
870 return oldval;
871 default:
872 return Win32BaseWindow::SetWindowLongA(index, value);
873 }
874}
875//******************************************************************************
876//******************************************************************************
877ULONG Win32Dialog::GetWindowLongA(int index)
878{
879 switch(index)
880 {
881 case DWL_DLGPROC:
882 return (ULONG)Win32DlgProc;
883 case DWL_MSGRESULT:
884 return msgResult;
885 case DWL_USER:
886 return userDlgData;
887 default:
888 return Win32BaseWindow::GetWindowLongA(index);
889 }
890}
891//******************************************************************************
892//******************************************************************************
893BOOL DIALOG_Register()
894{
895 WNDCLASSA wndClass;
896
897 if (GlobalFindAtomA(DIALOG_CLASS_NAME)) return FALSE;
898
899 ZeroMemory(&wndClass,sizeof(WNDCLASSA));
900 wndClass.style = CS_GLOBALCLASS | CS_SAVEBITS;
901 wndClass.lpfnWndProc = (WNDPROC)DefDlgProcA;
902 wndClass.cbClsExtra = 0;
903 wndClass.cbWndExtra = 0;
904 wndClass.hCursor = (HCURSOR)IDC_ARROWA;
905 wndClass.hbrBackground = LTGRAY_BRUSH;
906 wndClass.lpszClassName = DIALOG_CLASS_NAME;
907
908 return RegisterClassA(&wndClass);
909}
910//******************************************************************************
911//******************************************************************************
912BOOL DIALOG_Unregister()
913{
914 if (GlobalFindAtomA(DIALOG_CLASS_NAME))
915 return UnregisterClassA(DIALOG_CLASS_NAME,(HINSTANCE)NULL);
916 else return FALSE;
917}
918//******************************************************************************
919//******************************************************************************
920BOOL Win32Dialog::fInitialized = FALSE;
921int Win32Dialog::xBaseUnit = 0;
922int Win32Dialog::yBaseUnit = 0;
Note: See TracBrowser for help on using the repository browser.