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

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

Bugfix for SetPos bugfix, Edit controls now work, experimental fix in Edit control for VPBuddy

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