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

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

More dialog update

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