source: trunk/src/user32/win32dlg.cpp@ 1060

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

Set text + dialog bugfixes

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