4 * Copyright 1993, 1994, 1996 Alexandre Julliard
23 /* Dialog control information */
55 /* Dialog base units */
56 static WORD xBaseUnit
= 0, yBaseUnit
= 0;
59 /***********************************************************************
62 * Initialisation of the dialog manager.
69 /* Calculate the dialog base units */
71 if (!(hdc
= CreateDC( "DISPLAY", NULL
, NULL
, NULL
))) return FALSE
;
72 GetTextMetrics16( hdc
, &tm
);
74 xBaseUnit
= tm
.tmAveCharWidth
;
75 yBaseUnit
= tm
.tmHeight
;
77 /* Dialog units are based on a proportional system font */
78 /* so we adjust them a bit for a fixed font. */
79 if (tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
) xBaseUnit
= xBaseUnit
* 5 / 4;
81 dprintf_dialog( stddeb
, "DIALOG_Init: base units = %d,%d\n",
82 xBaseUnit
, yBaseUnit
);
87 /***********************************************************************
90 * Return the class and text of the control pointed to by ptr,
91 * fill the header structure and return a pointer to the next control.
93 static LPCSTR
DIALOG_GetControl16( LPCSTR p
, DLG_CONTROL_INFO
*info
)
95 static char buffer
[10];
97 info
->x
= GET_WORD(p
); p
+= sizeof(WORD
);
98 info
->y
= GET_WORD(p
); p
+= sizeof(WORD
);
99 info
->cx
= GET_WORD(p
); p
+= sizeof(WORD
);
100 info
->cy
= GET_WORD(p
); p
+= sizeof(WORD
);
101 info
->id
= GET_WORD(p
); p
+= sizeof(WORD
);
102 info
->style
= GET_DWORD(p
); p
+= sizeof(DWORD
);
109 case 0x80: strcpy( buffer
, "BUTTON" ); break;
110 case 0x81: strcpy( buffer
, "EDIT" ); break;
111 case 0x82: strcpy( buffer
, "STATIC" ); break;
112 case 0x83: strcpy( buffer
, "LISTBOX" ); break;
113 case 0x84: strcpy( buffer
, "SCROLLBAR" ); break;
114 case 0x85: strcpy( buffer
, "COMBOBOX" ); break;
115 default: buffer
[0] = '\0'; break;
117 info
->className
= buffer
;
125 dprintf_dialog(stddeb
, " %s ", info
->className
);
127 if ((BYTE
)*p
== 0xff)
129 /* Integer id, not documented (?). Only works for SS_ICON controls */
130 info
->windowName
= (LPCSTR
)(UINT32
)GET_WORD(p
+1);
132 dprintf_dialog( stddeb
,"%04x", LOWORD(info
->windowName
) );
136 info
->windowName
= p
;
138 dprintf_dialog(stddeb
,"'%s'", info
->windowName
);
141 info
->data
= (LPVOID
)(*p
? p
+ 1 : NULL
); /* FIXME: should be a segptr */
144 dprintf_dialog( stddeb
," %d, %d, %d, %d, %d, %08lx, %08lx\n",
145 info
->id
, info
->x
, info
->y
, info
->cx
, info
->cy
,
146 info
->style
, (DWORD
)info
->data
);
151 /***********************************************************************
152 * DIALOG_GetControl32
154 * Return the class and text of the control pointed to by ptr,
155 * fill the header structure and return a pointer to the next control.
157 static const WORD
*DIALOG_GetControl32( const WORD
*p
, DLG_CONTROL_INFO
*info
)
159 static WCHAR buffer
[10];
161 info
->style
= GET_DWORD(p
); p
+= 2;
162 info
->exStyle
= GET_DWORD(p
); p
+= 2;
163 info
->x
= GET_WORD(p
); p
++;
164 info
->y
= GET_WORD(p
); p
++;
165 info
->cx
= GET_WORD(p
); p
++;
166 info
->cy
= GET_WORD(p
); p
++;
167 info
->id
= GET_WORD(p
); p
++;
169 if (GET_WORD(p
) == 0xffff)
171 switch(GET_WORD(p
+1))
173 case 0x80: STRING32_AnsiToUni( buffer
, "BUTTON" ); break;
174 case 0x81: STRING32_AnsiToUni( buffer
, "EDIT" ); break;
175 case 0x82: STRING32_AnsiToUni( buffer
, "STATIC" ); break;
176 case 0x83: STRING32_AnsiToUni( buffer
, "LISTBOX" ); break;
177 case 0x84: STRING32_AnsiToUni( buffer
, "SCROLLBAR" ); break;
178 case 0x85: STRING32_AnsiToUni( buffer
, "COMBOBOX" ); break;
179 default: buffer
[0] = '\0'; break;
181 info
->className
= (LPCSTR
)buffer
;
186 info
->className
= (LPCSTR
)p
;
187 p
+= lstrlen32W( (LPCWSTR
)p
) + 1;
189 dprintf_dialog(stddeb
, " %p ", info
->className
);
191 if (GET_WORD(p
) == 0xffff)
193 info
->windowName
= (LPCSTR
)(p
+ 1);
195 dprintf_dialog( stddeb
,"%04x", LOWORD(info
->windowName
) );
199 info
->windowName
= (LPCSTR
)p
;
200 p
+= lstrlen32W( (LPCWSTR
)p
) + 1;
201 dprintf_dialog(stddeb
,"'%p'", info
->windowName
);
206 info
->data
= (LPVOID
)(p
+ 1);
207 p
+= GET_WORD(p
) / sizeof(WORD
);
209 else info
->data
= NULL
;
212 dprintf_dialog( stddeb
," %d, %d, %d, %d, %d, %08lx, %08lx, %08lx\n",
213 info
->id
, info
->x
, info
->y
, info
->cx
, info
->cy
,
214 info
->style
, info
->exStyle
, (DWORD
)info
->data
);
215 /* Next control is on dword boundary */
216 return (const WORD
*)((((int)p
) + 3) & ~3);
220 /***********************************************************************
221 * DIALOG_CreateControls
223 * Create the control windows for a dialog.
225 static BOOL32
DIALOG_CreateControls( WND
*pWnd
, LPCSTR
template, INT32 items
,
226 HINSTANCE32 hInst
, BOOL win32
)
228 DIALOGINFO
*dlgInfo
= (DIALOGINFO
*)pWnd
->wExtra
;
229 DLG_CONTROL_INFO info
;
230 HWND32 hwndCtrl
, hwndDefButton
= 0;
232 dprintf_dialog(stddeb
, " BEGIN\n" );
237 HINSTANCE16 instance
;
238 template = DIALOG_GetControl16( template, &info
);
239 if (HIWORD(info
.className
) && !strcmp( info
.className
, "EDIT") &&
240 ((pWnd
->dwStyle
& DS_LOCALEDIT
) != DS_LOCALEDIT
))
242 if (!dlgInfo
->hDialogHeap
)
244 dlgInfo
->hDialogHeap
= GlobalAlloc16(GMEM_FIXED
, 0x10000);
245 if (!dlgInfo
->hDialogHeap
)
247 fprintf( stderr
, "CreateDialogIndirectParam: Insufficient memory to create heap for edit control\n" );
250 LocalInit(dlgInfo
->hDialogHeap
, 0, 0xffff);
252 instance
= dlgInfo
->hDialogHeap
;
254 else instance
= (HINSTANCE16
)hInst
;
256 hwndCtrl
= CreateWindowEx16( info
.exStyle
| WS_EX_NOPARENTNOTIFY
,
257 info
.className
, info
.windowName
,
258 info
.style
| WS_CHILD
,
259 info
.x
* dlgInfo
->xBaseUnit
/ 4,
260 info
.y
* dlgInfo
->yBaseUnit
/ 8,
261 info
.cx
* dlgInfo
->xBaseUnit
/ 4,
262 info
.cy
* dlgInfo
->yBaseUnit
/ 8,
263 pWnd
->hwndSelf
, (HMENU16
)info
.id
,
264 instance
, info
.data
);
268 template = (LPCSTR
)DIALOG_GetControl32( (WORD
*)template, &info
);
269 hwndCtrl
= CreateWindowEx32W( info
.exStyle
| WS_EX_NOPARENTNOTIFY
,
270 (LPCWSTR
)info
.className
,
271 (LPCWSTR
)info
.windowName
,
272 info
.style
| WS_CHILD
,
273 info
.x
* dlgInfo
->xBaseUnit
/ 4,
274 info
.y
* dlgInfo
->yBaseUnit
/ 8,
275 info
.cx
* dlgInfo
->xBaseUnit
/ 4,
276 info
.cy
* dlgInfo
->yBaseUnit
/ 8,
277 pWnd
->hwndSelf
, (HMENU32
)info
.id
,
280 if (!hwndCtrl
) return FALSE
;
282 /* Send initialisation messages to the control */
283 if (dlgInfo
->hUserFont
) SendMessage32A( hwndCtrl
, WM_SETFONT
,
284 (WPARAM32
)dlgInfo
->hUserFont
, 0 );
285 if (SendMessage32A(hwndCtrl
, WM_GETDLGCODE
, 0, 0) & DLGC_DEFPUSHBUTTON
)
287 /* If there's already a default push-button, set it back */
288 /* to normal and use this one instead. */
290 SendMessage32A( hwndDefButton
, BM_SETSTYLE32
,
291 BS_PUSHBUTTON
,FALSE
);
292 hwndDefButton
= hwndCtrl
;
293 dlgInfo
->msgResult
= GetWindowWord( hwndCtrl
, GWW_ID
);
296 dprintf_dialog(stddeb
, " END\n" );
301 /***********************************************************************
302 * DIALOG_ParseTemplate16
304 * Fill a DLG_TEMPLATE structure from the dialog template, and return
305 * a pointer to the first control.
307 static LPCSTR
DIALOG_ParseTemplate16( LPCSTR p
, DLG_TEMPLATE
* result
)
309 result
->style
= GET_DWORD(p
); p
+= sizeof(DWORD
);
311 result
->nbItems
= *p
++;
312 result
->x
= GET_WORD(p
); p
+= sizeof(WORD
);
313 result
->y
= GET_WORD(p
); p
+= sizeof(WORD
);
314 result
->cx
= GET_WORD(p
); p
+= sizeof(WORD
);
315 result
->cy
= GET_WORD(p
); p
+= sizeof(WORD
);
316 dprintf_dialog( stddeb
, "DIALOG %d, %d, %d, %d\n",
317 result
->x
, result
->y
, result
->cx
, result
->cy
);
318 dprintf_dialog( stddeb
, " STYLE %08lx\n", result
->style
);
320 /* Get the menu name */
325 result
->menuName
= 0;
329 result
->menuName
= (LPCSTR
)(UINT32
)GET_WORD( p
+ 1 );
331 dprintf_dialog(stddeb
, " MENU %04x\n", LOWORD(result
->menuName
) );
334 result
->menuName
= p
;
335 dprintf_dialog( stddeb
, " MENU '%s'\n", p
);
340 /* Get the class name */
344 result
->className
= p
;
345 dprintf_dialog( stddeb
, " CLASS '%s'\n", result
->className
);
347 else result
->className
= DIALOG_CLASS_ATOM
;
350 /* Get the window caption */
354 dprintf_dialog( stddeb
, " CAPTION '%s'\n", result
->caption
);
356 /* Get the font name */
358 if (result
->style
& DS_SETFONT
)
360 result
->pointSize
= GET_WORD(p
);
362 result
->faceName
= p
;
364 dprintf_dialog( stddeb
, " FONT %d,'%s'\n",
365 result
->pointSize
, result
->faceName
);
371 /***********************************************************************
372 * DIALOG_ParseTemplate32
374 * Fill a DLG_TEMPLATE structure from the dialog template, and return
375 * a pointer to the first control.
377 static LPCSTR
DIALOG_ParseTemplate32( LPCSTR
template, DLG_TEMPLATE
* result
)
379 const WORD
*p
= (const WORD
*)template;
381 result
->style
= GET_DWORD(p
); p
+= 2;
382 result
->exStyle
= GET_DWORD(p
); p
+= 2;
383 result
->nbItems
= GET_WORD(p
); p
++;
384 result
->x
= GET_WORD(p
); p
++;
385 result
->y
= GET_WORD(p
); p
++;
386 result
->cx
= GET_WORD(p
); p
++;
387 result
->cy
= GET_WORD(p
); p
++;
388 dprintf_dialog( stddeb
, "DIALOG %d, %d, %d, %d\n",
389 result
->x
, result
->y
, result
->cx
, result
->cy
);
390 dprintf_dialog( stddeb
, " STYLE %08lx\n", result
->style
);
391 dprintf_dialog( stddeb
, " EXSTYLE %08lx\n", result
->exStyle
);
393 /* Get the menu name */
398 result
->menuName
= NULL
;
402 result
->menuName
= (LPCSTR
)(UINT32
)GET_WORD( p
+ 1 );
404 dprintf_dialog(stddeb
, " MENU %04x\n", LOWORD(result
->menuName
) );
407 result
->menuName
= (LPCSTR
)p
;
408 dprintf_dialog( stddeb
, " MENU '%p'\n", p
);
409 p
+= lstrlen32W( (LPCWSTR
)p
) + 1;
413 /* Get the class name */
418 result
->className
= DIALOG_CLASS_ATOM
;
422 result
->className
= (LPCSTR
)(UINT32
)GET_WORD( p
+ 1 );
424 dprintf_dialog(stddeb
, " CLASS %04x\n", LOWORD(result
->className
) );
427 result
->className
= (LPCSTR
)p
;
428 dprintf_dialog( stddeb
, " CLASS '%p'\n", p
);
429 p
+= lstrlen32W( (LPCWSTR
)p
) + 1;
433 /* Get the window caption */
435 result
->caption
= (LPCSTR
)p
;
436 p
+= lstrlen32W( (LPCWSTR
)p
) + 1;
437 dprintf_dialog( stddeb
, " CAPTION '%p'\n", result
->caption
);
439 /* Get the font name */
441 if (result
->style
& DS_SETFONT
)
443 result
->pointSize
= GET_WORD(p
);
445 result
->faceName
= (LPCSTR
)p
;
446 p
+= lstrlen32W( (LPCWSTR
)p
) + 1;
447 dprintf_dialog( stddeb
, " FONT %d,'%p'\n",
448 result
->pointSize
, result
->faceName
);
450 /* First control is on dword boundary */
451 return (LPCSTR
)((((int)p
) + 3) & ~3);
455 /***********************************************************************
456 * DIALOG_CreateIndirect
458 static HWND
DIALOG_CreateIndirect( HINSTANCE32 hInst
, LPCSTR dlgTemplate
,
459 HWND owner
, DLGPROC16 dlgProc
,
460 LPARAM param
, WINDOWPROCTYPE procType
)
467 DLG_TEMPLATE
template;
468 DIALOGINFO
* dlgInfo
;
469 WORD xUnit
= xBaseUnit
;
470 WORD yUnit
= yBaseUnit
;
472 /* Parse dialog template */
474 if (!dlgTemplate
) return 0;
475 if (procType
!= WIN_PROC_16
)
476 dlgTemplate
= DIALOG_ParseTemplate32( dlgTemplate
, &template );
478 dlgTemplate
= DIALOG_ParseTemplate16( dlgTemplate
, &template );
482 if (template.menuName
)
484 LPSTR str
= SEGPTR_STRDUP( template.menuName
); /* FIXME: win32 */
485 hMenu
= LoadMenu16( hInst
, SEGPTR_GET(str
) );
489 /* Create custom font if needed */
491 if (template.style
& DS_SETFONT
)
493 /* The font height must be negative as it is a point size */
494 /* (see CreateFont() documentation in the Windows SDK). */
495 hFont
= CreateFont16( -template.pointSize
, 0, 0, 0, FW_DONTCARE
,
496 FALSE
, FALSE
, FALSE
, DEFAULT_CHARSET
, 0, 0,
497 DEFAULT_QUALITY
, FF_DONTCARE
,
498 template.faceName
); /* FIXME: win32 */
504 HDC32 hdc
= GetDC32(0);
505 oldFont
= SelectObject32( hdc
, hFont
);
506 GetTextMetrics16( hdc
, &tm
);
507 SelectObject32( hdc
, oldFont
);
508 ReleaseDC32( 0, hdc
);
509 xUnit
= tm
.tmAveCharWidth
;
511 if (tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
)
512 xBaseUnit
= xBaseUnit
* 5 / 4; /* See DIALOG_Init() */
516 /* Create dialog main window */
518 rect
.left
= rect
.top
= 0;
519 rect
.right
= template.cx
* xUnit
/ 4;
520 rect
.bottom
= template.cy
* yUnit
/ 8;
521 if (template.style
& DS_MODALFRAME
)
522 template.exStyle
|= WS_EX_DLGMODALFRAME
;
523 AdjustWindowRectEx16( &rect
, template.style
,
524 hMenu
? TRUE
: FALSE
, template.exStyle
);
525 rect
.right
-= rect
.left
;
526 rect
.bottom
-= rect
.top
;
528 if ((INT16
)template.x
== CW_USEDEFAULT16
)
530 rect
.left
= rect
.top
= (procType
== WIN_PROC_16
) ? CW_USEDEFAULT16
535 rect
.left
+= template.x
* xUnit
/ 4;
536 rect
.top
+= template.y
* yUnit
/ 8;
537 if ( !(template.style
& DS_ABSALIGN
) && !(template.style
& WS_CHILD
) )
538 ClientToScreen16( owner
, (POINT16
*)&rect
);
541 if (procType
!= WIN_PROC_16
)
542 hwnd
= CreateWindowEx32W(template.exStyle
, (LPCWSTR
)template.className
,
543 (LPCWSTR
)template.caption
,
544 template.style
& ~WS_VISIBLE
,
545 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
,
546 owner
, hMenu
, hInst
, NULL
);
548 hwnd
= CreateWindowEx16(template.exStyle
, template.className
,
549 template.caption
, template.style
& ~WS_VISIBLE
,
550 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
,
551 owner
, hMenu
, hInst
, NULL
);
554 if (hFont
) DeleteObject32( hFont
);
555 if (hMenu
) DestroyMenu( hMenu
);
558 wndPtr
= WIN_FindWndPtr( hwnd
);
559 wndPtr
->flags
|= WIN_ISDIALOG
;
561 /* Initialise dialog extra data */
563 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
564 WINPROC_SetProc( &dlgInfo
->dlgProc
, dlgProc
, procType
);
565 dlgInfo
->hUserFont
= hFont
;
566 dlgInfo
->hMenu
= hMenu
;
567 dlgInfo
->xBaseUnit
= xUnit
;
568 dlgInfo
->yBaseUnit
= yUnit
;
569 dlgInfo
->msgResult
= 0; /* This is used to store the default button id */
570 dlgInfo
->hDialogHeap
= 0;
572 /* Create controls */
574 if (!DIALOG_CreateControls( wndPtr
, dlgTemplate
, template.nbItems
,
575 hInst
, (procType
!= WIN_PROC_16
) ))
577 DestroyWindow( hwnd
);
581 /* Send initialisation messages and set focus */
583 dlgInfo
->hwndFocus
= GetNextDlgTabItem32( hwnd
, 0, FALSE
);
584 if (dlgInfo
->hUserFont
)
585 SendMessage32A( hwnd
, WM_SETFONT
, (WPARAM32
)dlgInfo
->hUserFont
, 0 );
586 if (SendMessage32A( hwnd
, WM_INITDIALOG
,
587 (WPARAM32
)dlgInfo
->hwndFocus
, param
))
588 SetFocus32( dlgInfo
->hwndFocus
);
589 if (template.style
& WS_VISIBLE
) ShowWindow( hwnd
, SW_SHOW
);
594 /***********************************************************************
595 * CreateDialog16 (USER.89)
597 HWND16
CreateDialog16( HINSTANCE16 hInst
, SEGPTR dlgTemplate
,
598 HWND16 owner
, DLGPROC16 dlgProc
)
600 return CreateDialogParam16( hInst
, dlgTemplate
, owner
, dlgProc
, 0 );
604 /***********************************************************************
605 * CreateDialogParam16 (USER.241)
607 HWND16
CreateDialogParam16( HINSTANCE16 hInst
, SEGPTR dlgTemplate
,
608 HWND16 owner
, DLGPROC16 dlgProc
, LPARAM param
)
615 dprintf_dialog(stddeb
, "CreateDialogParam16: %04x,%08lx,%04x,%08lx,%ld\n",
616 hInst
, (DWORD
)dlgTemplate
, owner
, (DWORD
)dlgProc
, param
);
618 if (!(hRsrc
= FindResource16( hInst
, dlgTemplate
, RT_DIALOG
))) return 0;
619 if (!(hmem
= LoadResource16( hInst
, hRsrc
))) return 0;
620 if (!(data
= LockResource16( hmem
))) hwnd
= 0;
621 else hwnd
= CreateDialogIndirectParam16( hInst
, data
, owner
,
623 FreeResource16( hmem
);
628 /***********************************************************************
629 * CreateDialogParam32A (USER32.72)
631 HWND32
CreateDialogParam32A( HINSTANCE32 hInst
, LPCSTR name
,
632 HWND32 owner
, DLGPROC32 dlgProc
, LPARAM param
)
636 LPWSTR str
= STRING32_DupAnsiToUni( name
);
637 HWND32 hwnd
= CreateDialogParam32W( hInst
, str
, owner
, dlgProc
, param
);
641 return CreateDialogParam32W( hInst
, (LPCWSTR
)name
, owner
, dlgProc
, param
);
645 /***********************************************************************
646 * CreateDialogParam32W (USER32.73)
648 HWND32
CreateDialogParam32W( HINSTANCE32 hInst
, LPCWSTR name
,
649 HWND32 owner
, DLGPROC32 dlgProc
, LPARAM param
)
651 HANDLE32 hrsrc
= FindResource32W( hInst
, name
, (LPWSTR
)RT_DIALOG
);
652 if (!hrsrc
) return 0;
653 return CreateDialogIndirectParam32W( hInst
,
654 (LPVOID
)LoadResource32(hInst
, hrsrc
),
655 owner
, dlgProc
, param
);
659 /***********************************************************************
660 * CreateDialogIndirect16 (USER.219)
662 HWND16
CreateDialogIndirect16( HINSTANCE16 hInst
, LPCVOID dlgTemplate
,
663 HWND16 owner
, DLGPROC16 dlgProc
)
665 return CreateDialogIndirectParam16( hInst
, dlgTemplate
, owner
, dlgProc
, 0);
669 /***********************************************************************
670 * CreateDialogIndirectParam16 (USER.242)
672 HWND16
CreateDialogIndirectParam16( HINSTANCE16 hInst
, LPCVOID dlgTemplate
,
673 HWND16 owner
, DLGPROC16 dlgProc
,
676 return DIALOG_CreateIndirect( hInst
, dlgTemplate
, owner
,
677 dlgProc
, param
, WIN_PROC_16
);
681 /***********************************************************************
682 * CreateDialogIndirectParam32A (USER32.69)
684 HWND32
CreateDialogIndirectParam32A( HINSTANCE32 hInst
, LPCVOID dlgTemplate
,
685 HWND32 owner
, DLGPROC32 dlgProc
,
688 return DIALOG_CreateIndirect( hInst
, dlgTemplate
, owner
,
689 (DLGPROC16
)dlgProc
, param
, WIN_PROC_32A
);
693 /***********************************************************************
694 * CreateDialogIndirectParam32W (USER32.71)
696 HWND32
CreateDialogIndirectParam32W( HINSTANCE32 hInst
, LPCVOID dlgTemplate
,
697 HWND32 owner
, DLGPROC32 dlgProc
,
700 return DIALOG_CreateIndirect( hInst
, dlgTemplate
, owner
,
701 (DLGPROC16
)dlgProc
, param
, WIN_PROC_32W
);
705 /***********************************************************************
708 static INT32
DIALOG_DoDialogBox( HWND hwnd
, HWND owner
)
711 DIALOGINFO
* dlgInfo
;
715 /* Owner must be a top-level window */
716 owner
= WIN_GetTopParent( owner
);
717 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return -1;
718 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
719 EnableWindow( owner
, FALSE
);
720 ShowWindow( hwnd
, SW_SHOW
);
722 while (MSG_InternalGetMessage(&msg
, hwnd
, owner
, MSGF_DIALOGBOX
, PM_REMOVE
,
723 !(wndPtr
->dwStyle
& DS_NOIDLEMSG
) ))
725 if (!IsDialogMessage( hwnd
, &msg
))
727 TranslateMessage( &msg
);
728 DispatchMessage( &msg
);
730 if (dlgInfo
->fEnd
) break;
732 retval
= dlgInfo
->msgResult
;
733 EnableWindow( owner
, TRUE
);
734 DestroyWindow( hwnd
);
739 /***********************************************************************
740 * DialogBox16 (USER.87)
742 INT16
DialogBox16( HINSTANCE16 hInst
, SEGPTR dlgTemplate
,
743 HWND16 owner
, DLGPROC16 dlgProc
)
745 return DialogBoxParam16( hInst
, dlgTemplate
, owner
, dlgProc
, 0 );
749 /***********************************************************************
750 * DialogBoxParam16 (USER.239)
752 INT16
DialogBoxParam16( HINSTANCE16 hInst
, SEGPTR
template,
753 HWND16 owner
, DLGPROC16 dlgProc
, LPARAM param
)
755 HWND16 hwnd
= CreateDialogParam16( hInst
, template, owner
, dlgProc
, param
);
756 if (hwnd
) return (INT16
)DIALOG_DoDialogBox( hwnd
, owner
);
761 /***********************************************************************
762 * DialogBoxParam32A (USER32.138)
764 INT32
DialogBoxParam32A( HINSTANCE32 hInst
, LPCSTR name
,
765 HWND32 owner
, DLGPROC32 dlgProc
, LPARAM param
)
767 HWND32 hwnd
= CreateDialogParam32A( hInst
, name
, owner
, dlgProc
, param
);
768 if (hwnd
) return DIALOG_DoDialogBox( hwnd
, owner
);
773 /***********************************************************************
774 * DialogBoxParam32W (USER32.139)
776 INT32
DialogBoxParam32W( HINSTANCE32 hInst
, LPCWSTR name
,
777 HWND32 owner
, DLGPROC32 dlgProc
, LPARAM param
)
779 HWND32 hwnd
= CreateDialogParam32W( hInst
, name
, owner
, dlgProc
, param
);
780 if (hwnd
) return DIALOG_DoDialogBox( hwnd
, owner
);
785 /***********************************************************************
786 * DialogBoxIndirect16 (USER.218)
788 INT16
DialogBoxIndirect16( HINSTANCE16 hInst
, HANDLE16 dlgTemplate
,
789 HWND16 owner
, DLGPROC16 dlgProc
)
791 return DialogBoxIndirectParam16( hInst
, dlgTemplate
, owner
, dlgProc
, 0 );
795 /***********************************************************************
796 * DialogBoxIndirectParam16 (USER.240)
798 INT16
DialogBoxIndirectParam16( HINSTANCE16 hInst
, HANDLE16 dlgTemplate
,
799 HWND16 owner
, DLGPROC16 dlgProc
, LPARAM param
)
804 if (!(ptr
= GlobalLock16( dlgTemplate
))) return -1;
805 hwnd
= CreateDialogIndirectParam16( hInst
, ptr
, owner
, dlgProc
, param
);
806 GlobalUnlock16( dlgTemplate
);
807 if (hwnd
) return (INT16
)DIALOG_DoDialogBox( hwnd
, owner
);
812 /***********************************************************************
813 * DialogBoxIndirectParam32A (USER32.135)
815 INT32
DialogBoxIndirectParam32A( HINSTANCE32 hInstance
, LPCVOID
template,
816 HWND32 owner
, DLGPROC32 dlgProc
,LPARAM param
)
818 HWND32 hwnd
= CreateDialogIndirectParam32A( hInstance
, template,
819 owner
, dlgProc
, param
);
820 if (hwnd
) return DIALOG_DoDialogBox( hwnd
, owner
);
825 /***********************************************************************
826 * DialogBoxIndirectParam32W (USER32.137)
828 INT32
DialogBoxIndirectParam32W( HINSTANCE32 hInstance
, LPCVOID
template,
829 HWND32 owner
, DLGPROC32 dlgProc
,LPARAM param
)
831 HWND32 hwnd
= CreateDialogIndirectParam32W( hInstance
, template,
832 owner
, dlgProc
, param
);
833 if (hwnd
) return DIALOG_DoDialogBox( hwnd
, owner
);
838 /***********************************************************************
839 * EndDialog (USER.88) (USER32.173)
841 BOOL16
EndDialog( HWND32 hwnd
, INT32 retval
)
843 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
844 DIALOGINFO
* dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
845 dlgInfo
->msgResult
= retval
;
846 dlgInfo
->fEnd
= TRUE
;
847 dprintf_dialog(stddeb
, "EndDialog: %04x %d\n", hwnd
, retval
);
852 /***********************************************************************
853 * IsDialogMessage (USER.90)
855 BOOL
IsDialogMessage( HWND hwndDlg
, LPMSG16 msg
)
860 if (!(wndPtr
= WIN_FindWndPtr( hwndDlg
))) return FALSE
;
861 if ((hwndDlg
!= msg
->hwnd
) && !IsChild( hwndDlg
, msg
->hwnd
)) return FALSE
;
863 /* Only the key messages get special processing */
864 if ((msg
->message
!= WM_KEYDOWN
) &&
865 (msg
->message
!= WM_SYSCHAR
) &&
866 (msg
->message
!= WM_CHAR
))
869 dlgCode
= SendMessage16( msg
->hwnd
, WM_GETDLGCODE
, 0, 0 );
870 if (dlgCode
& DLGC_WANTMESSAGE
)
872 DispatchMessage( msg
);
879 if (dlgCode
& DLGC_WANTALLKEYS
) break;
883 if (!(dlgCode
& DLGC_WANTTAB
))
885 SendMessage16( hwndDlg
, WM_NEXTDLGCTL
,
886 (GetKeyState(VK_SHIFT
) & 0x8000), 0 );
893 if (!(dlgCode
& DLGC_WANTARROWS
))
895 SetFocus32( GetNextDlgGroupItem32( hwndDlg
, GetFocus32(),
903 if (!(dlgCode
& DLGC_WANTARROWS
))
905 SetFocus32( GetNextDlgGroupItem32( hwndDlg
, GetFocus32(),
912 SendMessage32A( hwndDlg
, WM_COMMAND
, IDCANCEL
,
913 (LPARAM
)GetDlgItem( hwndDlg
, IDCANCEL
) );
918 DWORD dw
= SendMessage16( hwndDlg
, DM_GETDEFID
, 0, 0 );
919 if (HIWORD(dw
) == DC_HASDEFID
)
920 SendMessage32A( hwndDlg
, WM_COMMAND
,
921 MAKEWPARAM( LOWORD(dw
), BN_CLICKED
),
922 (LPARAM
)GetDlgItem( hwndDlg
, LOWORD(dw
) ));
924 SendMessage32A( hwndDlg
, WM_COMMAND
, IDOK
,
925 (LPARAM
)GetDlgItem( hwndDlg
, IDOK
) );
930 TranslateMessage( msg
);
932 break; /* case WM_KEYDOWN */
936 if (dlgCode
& (DLGC_WANTALLKEYS
| DLGC_WANTCHARS
)) break;
940 if (dlgCode
& DLGC_WANTALLKEYS
) break;
944 /* If we get here, the message has not been treated specially */
945 /* and can be sent to its destination window. */
946 DispatchMessage( msg
);
951 /****************************************************************
952 * GetDlgCtrlID (USER.277) (USER32.233)
954 INT16
GetDlgCtrlID( HWND32 hwnd
)
956 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
957 if (wndPtr
) return wndPtr
->wIDmenu
;
962 /***********************************************************************
963 * GetDlgItem (USER.91)
965 HWND
GetDlgItem( HWND hwndDlg
, WORD id
)
969 if (!(pWnd
= WIN_FindWndPtr( hwndDlg
))) return 0;
970 for (pWnd
= pWnd
->child
; pWnd
; pWnd
= pWnd
->next
)
971 if (pWnd
->wIDmenu
== id
) return pWnd
->hwndSelf
;
976 /*******************************************************************
977 * SendDlgItemMessage16 (USER.101)
979 LRESULT
SendDlgItemMessage16( HWND16 hwnd
, INT16 id
, UINT16 msg
,
980 WPARAM16 wParam
, LPARAM lParam
)
982 HWND16 hwndCtrl
= GetDlgItem( hwnd
, id
);
983 if (hwndCtrl
) return SendMessage16( hwndCtrl
, msg
, wParam
, lParam
);
988 /*******************************************************************
989 * SendDlgItemMessage32A (USER32.451)
991 LRESULT
SendDlgItemMessage32A( HWND32 hwnd
, INT32 id
, UINT32 msg
,
992 WPARAM32 wParam
, LPARAM lParam
)
994 HWND hwndCtrl
= GetDlgItem( (HWND16
)hwnd
, (INT16
)id
);
995 if (hwndCtrl
) return SendMessage32A( hwndCtrl
, msg
, wParam
, lParam
);
1000 /*******************************************************************
1001 * SendDlgItemMessage32W (USER32.452)
1003 LRESULT
SendDlgItemMessage32W( HWND32 hwnd
, INT32 id
, UINT32 msg
,
1004 WPARAM32 wParam
, LPARAM lParam
)
1006 HWND hwndCtrl
= GetDlgItem( (HWND16
)hwnd
, (INT16
)id
);
1007 if (hwndCtrl
) return SendMessage32W( hwndCtrl
, msg
, wParam
, lParam
);
1012 /*******************************************************************
1013 * SetDlgItemText16 (USER.92)
1015 void SetDlgItemText16( HWND16 hwnd
, INT16 id
, SEGPTR lpString
)
1017 SendDlgItemMessage16( hwnd
, id
, WM_SETTEXT
, 0, (LPARAM
)lpString
);
1021 /*******************************************************************
1022 * SetDlgItemText32A (USER32.477)
1024 void SetDlgItemText32A( HWND32 hwnd
, INT32 id
, LPCSTR lpString
)
1026 SendDlgItemMessage32A( hwnd
, id
, WM_SETTEXT
, 0, (LPARAM
)lpString
);
1030 /*******************************************************************
1031 * SetDlgItemText32W (USER32.478)
1033 void SetDlgItemText32W( HWND32 hwnd
, INT32 id
, LPCWSTR lpString
)
1035 SendDlgItemMessage32W( hwnd
, id
, WM_SETTEXT
, 0, (LPARAM
)lpString
);
1039 /***********************************************************************
1040 * GetDlgItemText16 (USER.93)
1042 INT16
GetDlgItemText16( HWND16 hwnd
, INT16 id
, SEGPTR str
, UINT16 len
)
1044 return (INT16
)SendDlgItemMessage16( hwnd
, id
, WM_GETTEXT
,
1049 /***********************************************************************
1050 * GetDlgItemText32A (USER32.236)
1052 INT32
GetDlgItemText32A( HWND32 hwnd
, INT32 id
, LPSTR str
, UINT32 len
)
1054 return (INT32
)SendDlgItemMessage32A( hwnd
, id
, WM_GETTEXT
,
1059 /***********************************************************************
1060 * GetDlgItemText32W (USER32.237)
1062 INT32
GetDlgItemText32W( HWND32 hwnd
, INT32 id
, LPWSTR str
, UINT32 len
)
1064 return (INT32
)SendDlgItemMessage32W( hwnd
, id
, WM_GETTEXT
,
1069 /*******************************************************************
1070 * SetDlgItemInt16 (USER.94)
1072 void SetDlgItemInt16( HWND16 hwnd
, INT16 id
, UINT16 value
, BOOL16 fSigned
)
1074 char *str
= (char *)SEGPTR_ALLOC( 20 * sizeof(char) );
1077 if (fSigned
) sprintf( str
, "%d", (INT32
)(INT16
)value
);
1078 else sprintf( str
, "%u", value
);
1079 SendDlgItemMessage16( hwnd
, id
, WM_SETTEXT
, 0, (LPARAM
)SEGPTR_GET(str
) );
1084 /*******************************************************************
1085 * SetDlgItemInt32 (USER32.476)
1087 void SetDlgItemInt32( HWND32 hwnd
, INT32 id
, UINT32 value
, BOOL32 fSigned
)
1091 if (fSigned
) sprintf( str
, "%d", (INT32
)value
);
1092 else sprintf( str
, "%u", value
);
1093 SendDlgItemMessage32A( hwnd
, id
, WM_SETTEXT
, 0, (LPARAM
)str
);
1097 /***********************************************************************
1098 * GetDlgItemInt (USER.95)
1100 WORD
GetDlgItemInt( HWND hwnd
, WORD id
, BOOL
* translated
, BOOL fSigned
)
1105 if (translated
) *translated
= FALSE
;
1106 if (!(str
= (char *)SEGPTR_ALLOC( 30 * sizeof(char) ))) return 0;
1107 if (SendDlgItemMessage16( hwnd
, id
, WM_GETTEXT
, 30, (LPARAM
)SEGPTR_GET(str
)))
1110 result
= strtol( str
, &endptr
, 10 );
1111 if (endptr
&& (endptr
!= str
)) /* Conversion was successful */
1115 if ((result
< -32767) || (result
> 32767)) result
= 0;
1116 else if (translated
) *translated
= TRUE
;
1120 if ((result
< 0) || (result
> 65535)) result
= 0;
1121 else if (translated
) *translated
= TRUE
;
1126 return (WORD
)result
;
1130 /***********************************************************************
1131 * CheckDlgButton (USER.97) (USER32.44)
1133 BOOL16
CheckDlgButton( HWND32 hwnd
, INT32 id
, UINT32 check
)
1135 SendDlgItemMessage32A( hwnd
, id
, BM_SETCHECK32
, check
, 0 );
1140 /***********************************************************************
1141 * IsDlgButtonChecked (USER.98)
1143 WORD
IsDlgButtonChecked( HWND hwnd
, WORD id
)
1145 return (WORD
)SendDlgItemMessage32A( hwnd
, id
, BM_GETCHECK32
, 0, 0 );
1149 /***********************************************************************
1150 * CheckRadioButton (USER.96) (USER32.47)
1152 BOOL16
CheckRadioButton( HWND32 hwndDlg
, UINT32 firstID
, UINT32 lastID
,
1155 WND
*pWnd
= WIN_FindWndPtr( hwndDlg
);
1156 if (!pWnd
) return FALSE
;
1158 for (pWnd
= pWnd
->child
; pWnd
; pWnd
= pWnd
->next
)
1159 if ((pWnd
->wIDmenu
== firstID
) || (pWnd
->wIDmenu
== lastID
)) break;
1160 if (!pWnd
) return FALSE
;
1162 if (pWnd
->wIDmenu
== lastID
)
1163 lastID
= firstID
; /* Buttons are in reverse order */
1166 SendMessage32A( pWnd
->hwndSelf
, BM_SETCHECK32
,
1167 (pWnd
->wIDmenu
== checkID
), 0 );
1168 if (pWnd
->wIDmenu
== lastID
) break;
1175 /***********************************************************************
1176 * GetDialogBaseUnits (USER.243)
1178 DWORD
GetDialogBaseUnits()
1180 return MAKELONG( xBaseUnit
, yBaseUnit
);
1184 /***********************************************************************
1185 * MapDialogRect16 (USER.103)
1187 void MapDialogRect16( HWND16 hwnd
, LPRECT16 rect
)
1189 DIALOGINFO
* dlgInfo
;
1190 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1191 if (!wndPtr
) return;
1192 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
1193 rect
->left
= (rect
->left
* dlgInfo
->xBaseUnit
) / 4;
1194 rect
->right
= (rect
->right
* dlgInfo
->xBaseUnit
) / 4;
1195 rect
->top
= (rect
->top
* dlgInfo
->yBaseUnit
) / 8;
1196 rect
->bottom
= (rect
->bottom
* dlgInfo
->yBaseUnit
) / 8;
1200 /***********************************************************************
1201 * MapDialogRect32 (USER32.381)
1203 void MapDialogRect32( HWND32 hwnd
, LPRECT32 rect
)
1205 DIALOGINFO
* dlgInfo
;
1206 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1207 if (!wndPtr
) return;
1208 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
1209 rect
->left
= (rect
->left
* dlgInfo
->xBaseUnit
) / 4;
1210 rect
->right
= (rect
->right
* dlgInfo
->xBaseUnit
) / 4;
1211 rect
->top
= (rect
->top
* dlgInfo
->yBaseUnit
) / 8;
1212 rect
->bottom
= (rect
->bottom
* dlgInfo
->yBaseUnit
) / 8;
1216 /***********************************************************************
1217 * GetNextDlgGroupItem16 (USER.227)
1219 HWND16
GetNextDlgGroupItem16(HWND16 hwndDlg
, HWND16 hwndCtrl
, BOOL16 fPrevious
)
1221 return (HWND16
)GetNextDlgGroupItem32( hwndDlg
, hwndCtrl
, fPrevious
);
1225 /***********************************************************************
1226 * GetNextDlgGroupItem32 (USER32.274)
1228 HWND32
GetNextDlgGroupItem32(HWND32 hwndDlg
, HWND32 hwndCtrl
, BOOL32 fPrevious
)
1230 WND
*pWnd
, *pWndLast
, *pWndCtrl
, *pWndDlg
;
1232 if (!(pWndDlg
= WIN_FindWndPtr( hwndDlg
))) return 0;
1235 if (!(pWndCtrl
= WIN_FindWndPtr( hwndCtrl
))) return 0;
1236 /* Make sure hwndCtrl is a top-level child */
1237 while ((pWndCtrl
->dwStyle
& WS_CHILD
) && (pWndCtrl
->parent
!= pWndDlg
))
1238 pWndCtrl
= pWndCtrl
->parent
;
1239 if (pWndCtrl
->parent
!= pWndDlg
) return 0;
1243 /* No ctrl specified -> start from the beginning */
1244 if (!(pWndCtrl
= pWndDlg
->child
)) return 0;
1245 if (fPrevious
) while (pWndCtrl
->next
) pWndCtrl
= pWndCtrl
->next
;
1248 pWndLast
= pWndCtrl
;
1249 pWnd
= pWndCtrl
->next
;
1252 if (!pWnd
|| (pWnd
->dwStyle
& WS_GROUP
))
1254 /* Wrap-around to the beginning of the group */
1255 WND
*pWndStart
= pWndDlg
->child
;
1256 for (pWnd
= pWndStart
; pWnd
; pWnd
= pWnd
->next
)
1258 if (pWnd
->dwStyle
& WS_GROUP
) pWndStart
= pWnd
;
1259 if (pWnd
== pWndCtrl
) break;
1263 if (pWnd
== pWndCtrl
) break;
1264 if ((pWnd
->dwStyle
& WS_VISIBLE
) && !(pWnd
->dwStyle
& WS_DISABLED
))
1267 if (!fPrevious
) break;
1271 return pWndLast
->hwndSelf
;
1275 /***********************************************************************
1276 * GetNextDlgTabItem16 (USER.228)
1278 HWND16
GetNextDlgTabItem16( HWND16 hwndDlg
, HWND16 hwndCtrl
, BOOL16 fPrevious
)
1280 return (HWND16
)GetNextDlgTabItem32( hwndDlg
, hwndCtrl
, fPrevious
);
1284 /***********************************************************************
1285 * GetNextDlgTabItem32 (USER32.275)
1287 HWND32
GetNextDlgTabItem32( HWND32 hwndDlg
, HWND32 hwndCtrl
, BOOL32 fPrevious
)
1289 WND
*pWnd
, *pWndLast
, *pWndCtrl
, *pWndDlg
;
1291 if (!(pWndDlg
= WIN_FindWndPtr( hwndDlg
))) return 0;
1294 if (!(pWndCtrl
= WIN_FindWndPtr( hwndCtrl
))) return 0;
1295 /* Make sure hwndCtrl is a top-level child */
1296 while ((pWndCtrl
->dwStyle
& WS_CHILD
) && (pWndCtrl
->parent
!= pWndDlg
))
1297 pWndCtrl
= pWndCtrl
->parent
;
1298 if (pWndCtrl
->parent
!= pWndDlg
) return 0;
1302 /* No ctrl specified -> start from the beginning */
1303 if (!(pWndCtrl
= pWndDlg
->child
)) return 0;
1304 if (fPrevious
) while (pWndCtrl
->next
) pWndCtrl
= pWndCtrl
->next
;
1307 pWndLast
= pWndCtrl
;
1308 pWnd
= pWndCtrl
->next
;
1311 if (!pWnd
) pWnd
= pWndDlg
->child
;
1312 if (pWnd
== pWndCtrl
) break;
1313 if ((pWnd
->dwStyle
& WS_TABSTOP
) && (pWnd
->dwStyle
& WS_VISIBLE
) &&
1314 !(pWnd
->dwStyle
& WS_DISABLED
))
1317 if (!fPrevious
) break;
1321 return pWndLast
->hwndSelf
;