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 /***********************************************************************
88 * DIALOG_GetFirstTabItem
90 * Return the first item of the dialog that has the WS_TABSTOP style.
92 HWND
DIALOG_GetFirstTabItem( HWND hwndDlg
)
94 WND
*pWnd
= WIN_FindWndPtr( hwndDlg
);
95 for (pWnd
= pWnd
->child
; pWnd
; pWnd
= pWnd
->next
)
96 if (pWnd
->dwStyle
& WS_TABSTOP
) return pWnd
->hwndSelf
;
101 /***********************************************************************
102 * DIALOG_GetControl16
104 * Return the class and text of the control pointed to by ptr,
105 * fill the header structure and return a pointer to the next control.
107 static LPCSTR
DIALOG_GetControl16( LPCSTR p
, DLG_CONTROL_INFO
*info
)
109 static char buffer
[10];
111 info
->x
= GET_WORD(p
); p
+= sizeof(WORD
);
112 info
->y
= GET_WORD(p
); p
+= sizeof(WORD
);
113 info
->cx
= GET_WORD(p
); p
+= sizeof(WORD
);
114 info
->cy
= GET_WORD(p
); p
+= sizeof(WORD
);
115 info
->id
= GET_WORD(p
); p
+= sizeof(WORD
);
116 info
->style
= GET_DWORD(p
); p
+= sizeof(DWORD
);
123 case 0x80: strcpy( buffer
, "BUTTON" ); break;
124 case 0x81: strcpy( buffer
, "EDIT" ); break;
125 case 0x82: strcpy( buffer
, "STATIC" ); break;
126 case 0x83: strcpy( buffer
, "LISTBOX" ); break;
127 case 0x84: strcpy( buffer
, "SCROLLBAR" ); break;
128 case 0x85: strcpy( buffer
, "COMBOBOX" ); break;
129 default: buffer
[0] = '\0'; break;
131 info
->className
= buffer
;
139 dprintf_dialog(stddeb
, " %s ", info
->className
);
141 if ((BYTE
)*p
== 0xff)
143 /* Integer id, not documented (?). Only works for SS_ICON controls */
144 info
->windowName
= (LPCSTR
)(UINT32
)GET_WORD(p
+1);
146 dprintf_dialog( stddeb
,"%04x", LOWORD(info
->windowName
) );
150 info
->windowName
= p
;
152 dprintf_dialog(stddeb
,"'%s'", info
->windowName
);
155 info
->data
= (LPVOID
)(*p
? p
+ 1 : NULL
); /* FIXME: should be a segptr */
158 dprintf_dialog( stddeb
," %d, %d, %d, %d, %d, %08lx, %08lx\n",
159 info
->id
, info
->x
, info
->y
, info
->cx
, info
->cy
,
160 info
->style
, (DWORD
)info
->data
);
165 /***********************************************************************
166 * DIALOG_GetControl32
168 * Return the class and text of the control pointed to by ptr,
169 * fill the header structure and return a pointer to the next control.
171 static const WORD
*DIALOG_GetControl32( const WORD
*p
, DLG_CONTROL_INFO
*info
)
173 static WCHAR buffer
[10];
175 info
->style
= GET_DWORD(p
); p
+= 2;
176 info
->exStyle
= GET_DWORD(p
); p
+= 2;
177 info
->x
= GET_WORD(p
); p
++;
178 info
->y
= GET_WORD(p
); p
++;
179 info
->cx
= GET_WORD(p
); p
++;
180 info
->cy
= GET_WORD(p
); p
++;
181 info
->id
= GET_WORD(p
); p
++;
183 if (GET_WORD(p
) == 0xffff)
185 switch(GET_WORD(p
+1))
187 case 0x80: STRING32_AnsiToUni( buffer
, "BUTTON" ); break;
188 case 0x81: STRING32_AnsiToUni( buffer
, "EDIT" ); break;
189 case 0x82: STRING32_AnsiToUni( buffer
, "STATIC" ); break;
190 case 0x83: STRING32_AnsiToUni( buffer
, "LISTBOX" ); break;
191 case 0x84: STRING32_AnsiToUni( buffer
, "SCROLLBAR" ); break;
192 case 0x85: STRING32_AnsiToUni( buffer
, "COMBOBOX" ); break;
193 default: buffer
[0] = '\0'; break;
195 info
->className
= (LPCSTR
)buffer
;
200 info
->className
= (LPCSTR
)p
;
201 p
+= lstrlen32W( (LPCWSTR
)p
) + 1;
203 dprintf_dialog(stddeb
, " %p ", info
->className
);
205 if (GET_WORD(p
) == 0xffff)
207 info
->windowName
= (LPCSTR
)(p
+ 1);
209 dprintf_dialog( stddeb
,"%04x", LOWORD(info
->windowName
) );
213 info
->windowName
= (LPCSTR
)p
;
214 p
+= lstrlen32W( (LPCWSTR
)p
) + 1;
215 dprintf_dialog(stddeb
,"'%p'", info
->windowName
);
220 info
->data
= (LPVOID
)(p
+ 1);
221 p
+= GET_WORD(p
) / sizeof(WORD
);
223 else info
->data
= NULL
;
226 dprintf_dialog( stddeb
," %d, %d, %d, %d, %d, %08lx, %08lx, %08lx\n",
227 info
->id
, info
->x
, info
->y
, info
->cx
, info
->cy
,
228 info
->style
, info
->exStyle
, (DWORD
)info
->data
);
229 /* Next control is on dword boundary */
230 return (const WORD
*)((((int)p
) + 3) & ~3);
234 /***********************************************************************
235 * DIALOG_CreateControls
237 * Create the control windows for a dialog.
239 static BOOL32
DIALOG_CreateControls( WND
*pWnd
, LPCSTR
template, INT32 items
,
240 HINSTANCE32 hInst
, BOOL win32
)
242 DIALOGINFO
*dlgInfo
= (DIALOGINFO
*)pWnd
->wExtra
;
243 DLG_CONTROL_INFO info
;
244 HWND32 hwndCtrl
, hwndDefButton
= 0;
246 dprintf_dialog(stddeb
, " BEGIN\n" );
251 HINSTANCE16 instance
;
252 template = DIALOG_GetControl16( template, &info
);
253 if (HIWORD(info
.className
) && !strcmp( info
.className
, "EDIT") &&
254 ((info
.style
& DS_LOCALEDIT
) != DS_LOCALEDIT
))
256 if (!dlgInfo
->hDialogHeap
)
258 dlgInfo
->hDialogHeap
= GlobalAlloc16(GMEM_FIXED
, 0x10000);
259 if (!dlgInfo
->hDialogHeap
)
261 fprintf( stderr
, "CreateDialogIndirectParam: Insufficient memory to create heap for edit control\n" );
264 LocalInit(dlgInfo
->hDialogHeap
, 0, 0xffff);
266 instance
= dlgInfo
->hDialogHeap
;
268 else instance
= (HINSTANCE16
)hInst
;
270 hwndCtrl
= CreateWindowEx16( info
.exStyle
| WS_EX_NOPARENTNOTIFY
,
271 info
.className
, 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
, (HMENU
)info
.id
,
278 instance
, info
.data
);
282 template = (LPCSTR
)DIALOG_GetControl32( (WORD
*)template, &info
);
283 hwndCtrl
= CreateWindowEx32W( info
.exStyle
| WS_EX_NOPARENTNOTIFY
,
284 (LPCWSTR
)info
.className
,
285 (LPCWSTR
)info
.windowName
,
286 info
.style
| WS_CHILD
,
287 info
.x
* dlgInfo
->xBaseUnit
/ 4,
288 info
.y
* dlgInfo
->yBaseUnit
/ 8,
289 info
.cx
* dlgInfo
->xBaseUnit
/ 4,
290 info
.cy
* dlgInfo
->yBaseUnit
/ 8,
291 pWnd
->hwndSelf
, (HMENU
)info
.id
,
294 if (!hwndCtrl
) return FALSE
;
296 /* Send initialisation messages to the control */
297 if (dlgInfo
->hUserFont
) SendMessage32A( hwndCtrl
, WM_SETFONT
,
298 (WPARAM
)dlgInfo
->hUserFont
, 0 );
299 if (SendMessage32A(hwndCtrl
, WM_GETDLGCODE
, 0, 0) & DLGC_DEFPUSHBUTTON
)
301 /* If there's already a default push-button, set it back */
302 /* to normal and use this one instead. */
304 SendMessage32A( hwndDefButton
, BM_SETSTYLE32
,
305 BS_PUSHBUTTON
,FALSE
);
306 hwndDefButton
= hwndCtrl
;
307 dlgInfo
->msgResult
= GetWindowWord( hwndCtrl
, GWW_ID
);
310 dprintf_dialog(stddeb
, " END\n" );
315 /***********************************************************************
316 * DIALOG_ParseTemplate16
318 * Fill a DLG_TEMPLATE structure from the dialog template, and return
319 * a pointer to the first control.
321 static LPCSTR
DIALOG_ParseTemplate16( LPCSTR p
, DLG_TEMPLATE
* result
)
323 result
->style
= GET_DWORD(p
); p
+= sizeof(DWORD
);
325 result
->nbItems
= *p
++;
326 result
->x
= GET_WORD(p
); p
+= sizeof(WORD
);
327 result
->y
= GET_WORD(p
); p
+= sizeof(WORD
);
328 result
->cx
= GET_WORD(p
); p
+= sizeof(WORD
);
329 result
->cy
= GET_WORD(p
); p
+= sizeof(WORD
);
330 dprintf_dialog( stddeb
, "DIALOG %d, %d, %d, %d\n",
331 result
->x
, result
->y
, result
->cx
, result
->cy
);
332 dprintf_dialog( stddeb
, " STYLE %08lx\n", result
->style
);
334 /* Get the menu name */
339 result
->menuName
= 0;
343 result
->menuName
= (LPCSTR
)(UINT32
)GET_WORD( p
+ 1 );
345 dprintf_dialog(stddeb
, " MENU %04x\n", LOWORD(result
->menuName
) );
348 result
->menuName
= p
;
349 dprintf_dialog( stddeb
, " MENU '%s'\n", p
);
354 /* Get the class name */
358 result
->className
= p
;
359 dprintf_dialog( stddeb
, " CLASS '%s'\n", result
->className
);
361 else result
->className
= DIALOG_CLASS_ATOM
;
364 /* Get the window caption */
368 dprintf_dialog( stddeb
, " CAPTION '%s'\n", result
->caption
);
370 /* Get the font name */
372 if (result
->style
& DS_SETFONT
)
374 result
->pointSize
= GET_WORD(p
);
376 result
->faceName
= p
;
378 dprintf_dialog( stddeb
, " FONT %d,'%s'\n",
379 result
->pointSize
, result
->faceName
);
385 /***********************************************************************
386 * DIALOG_ParseTemplate32
388 * Fill a DLG_TEMPLATE structure from the dialog template, and return
389 * a pointer to the first control.
391 static LPCSTR
DIALOG_ParseTemplate32( LPCSTR
template, DLG_TEMPLATE
* result
)
393 const WORD
*p
= (const WORD
*)template;
395 result
->style
= GET_DWORD(p
); p
+= 2;
396 result
->exStyle
= GET_DWORD(p
); p
+= 2;
397 result
->nbItems
= GET_WORD(p
); p
++;
398 result
->x
= GET_WORD(p
); p
++;
399 result
->y
= GET_WORD(p
); p
++;
400 result
->cx
= GET_WORD(p
); p
++;
401 result
->cy
= GET_WORD(p
); p
++;
402 dprintf_dialog( stddeb
, "DIALOG %d, %d, %d, %d\n",
403 result
->x
, result
->y
, result
->cx
, result
->cy
);
404 dprintf_dialog( stddeb
, " STYLE %08lx\n", result
->style
);
405 dprintf_dialog( stddeb
, " EXSTYLE %08lx\n", result
->exStyle
);
407 /* Get the menu name */
412 result
->menuName
= NULL
;
416 result
->menuName
= (LPCSTR
)(UINT32
)GET_WORD( p
+ 1 );
418 dprintf_dialog(stddeb
, " MENU %04x\n", LOWORD(result
->menuName
) );
421 result
->menuName
= (LPCSTR
)p
;
422 dprintf_dialog( stddeb
, " MENU '%p'\n", p
);
423 p
+= lstrlen32W( (LPCWSTR
)p
) + 1;
427 /* Get the class name */
432 result
->className
= DIALOG_CLASS_ATOM
;
436 result
->className
= (LPCSTR
)(UINT32
)GET_WORD( p
+ 1 );
438 dprintf_dialog(stddeb
, " CLASS %04x\n", LOWORD(result
->className
) );
441 result
->className
= (LPCSTR
)p
;
442 dprintf_dialog( stddeb
, " CLASS '%p'\n", p
);
443 p
+= lstrlen32W( (LPCWSTR
)p
) + 1;
447 /* Get the window caption */
449 result
->caption
= (LPCSTR
)p
;
450 p
+= lstrlen32W( (LPCWSTR
)p
) + 1;
451 dprintf_dialog( stddeb
, " CAPTION '%p'\n", result
->caption
);
453 /* Get the font name */
455 if (result
->style
& DS_SETFONT
)
457 result
->pointSize
= GET_WORD(p
);
459 result
->faceName
= (LPCSTR
)p
;
460 p
+= lstrlen32W( (LPCWSTR
)p
) + 1;
461 dprintf_dialog( stddeb
, " FONT %d,'%p'\n",
462 result
->pointSize
, result
->faceName
);
464 /* First control is on dword boundary */
465 return (LPCSTR
)((((int)p
) + 3) & ~3);
469 /***********************************************************************
470 * DIALOG_CreateIndirect
472 static HWND
DIALOG_CreateIndirect( HINSTANCE hInst
, LPCSTR dlgTemplate
,
473 HWND owner
, DLGPROC16 dlgProc
,
474 LPARAM param
, WINDOWPROCTYPE procType
)
481 DLG_TEMPLATE
template;
482 DIALOGINFO
* dlgInfo
;
483 WORD xUnit
= xBaseUnit
;
484 WORD yUnit
= yBaseUnit
;
486 /* Parse dialog template */
488 if (!dlgTemplate
) return 0;
489 if (procType
!= WIN_PROC_16
)
490 dlgTemplate
= DIALOG_ParseTemplate32( dlgTemplate
, &template );
492 dlgTemplate
= DIALOG_ParseTemplate16( dlgTemplate
, &template );
496 if (template.menuName
)
498 LPSTR str
= SEGPTR_STRDUP( template.menuName
); /* FIXME: win32 */
499 hMenu
= LoadMenu16( hInst
, SEGPTR_GET(str
) );
503 /* Create custom font if needed */
505 if (template.style
& DS_SETFONT
)
507 /* The font height must be negative as it is a point size */
508 /* (see CreateFont() documentation in the Windows SDK). */
509 hFont
= CreateFont16( -template.pointSize
, 0, 0, 0, FW_DONTCARE
,
510 FALSE
, FALSE
, FALSE
, DEFAULT_CHARSET
, 0, 0,
511 DEFAULT_QUALITY
, FF_DONTCARE
,
512 template.faceName
); /* FIXME: win32 */
518 HDC32 hdc
= GetDC32(0);
519 oldFont
= SelectObject( hdc
, hFont
);
520 GetTextMetrics16( hdc
, &tm
);
521 SelectObject( hdc
, oldFont
);
522 ReleaseDC32( 0, hdc
);
523 xUnit
= tm
.tmAveCharWidth
;
525 if (tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
)
526 xBaseUnit
= xBaseUnit
* 5 / 4; /* See DIALOG_Init() */
530 /* Create dialog main window */
532 rect
.left
= rect
.top
= 0;
533 rect
.right
= template.cx
* xUnit
/ 4;
534 rect
.bottom
= template.cy
* yUnit
/ 8;
535 if (template.style
& DS_MODALFRAME
)
536 template.exStyle
|= WS_EX_DLGMODALFRAME
;
537 AdjustWindowRectEx16( &rect
, template.style
,
538 hMenu
? TRUE
: FALSE
, template.exStyle
);
539 rect
.right
-= rect
.left
;
540 rect
.bottom
-= rect
.top
;
542 if ((INT16
)template.x
== CW_USEDEFAULT16
)
544 rect
.left
= rect
.top
= (procType
== WIN_PROC_16
) ? CW_USEDEFAULT16
549 rect
.left
+= template.x
* xUnit
/ 4;
550 rect
.top
+= template.y
* yUnit
/ 8;
551 if ( !(template.style
& DS_ABSALIGN
) && !(template.style
& WS_CHILD
) )
552 ClientToScreen16( owner
, (POINT16
*)&rect
);
555 if (procType
!= WIN_PROC_16
)
556 hwnd
= CreateWindowEx32W(template.exStyle
, (LPCWSTR
)template.className
,
557 (LPCWSTR
)template.caption
,
558 template.style
& ~WS_VISIBLE
,
559 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
,
560 owner
, hMenu
, hInst
, NULL
);
562 hwnd
= CreateWindowEx16(template.exStyle
, template.className
,
563 template.caption
, template.style
& ~WS_VISIBLE
,
564 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
,
565 owner
, hMenu
, hInst
, NULL
);
568 if (hFont
) DeleteObject( hFont
);
569 if (hMenu
) DestroyMenu( hMenu
);
572 wndPtr
= WIN_FindWndPtr( hwnd
);
573 wndPtr
->flags
|= WIN_ISDIALOG
;
575 /* Initialise dialog extra data */
577 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
578 WINPROC_SetProc( &dlgInfo
->dlgProc
, dlgProc
, procType
);
579 dlgInfo
->hUserFont
= hFont
;
580 dlgInfo
->hMenu
= hMenu
;
581 dlgInfo
->xBaseUnit
= xUnit
;
582 dlgInfo
->yBaseUnit
= yUnit
;
583 dlgInfo
->msgResult
= 0; /* This is used to store the default button id */
584 dlgInfo
->hDialogHeap
= 0;
586 /* Create controls */
588 if (!DIALOG_CreateControls( wndPtr
, dlgTemplate
, template.nbItems
,
589 hInst
, (procType
!= WIN_PROC_16
) ))
591 DestroyWindow( hwnd
);
595 /* Send initialisation messages and set focus */
597 dlgInfo
->hwndFocus
= DIALOG_GetFirstTabItem( hwnd
);
598 if (dlgInfo
->hUserFont
)
599 SendMessage32A( hwnd
, WM_SETFONT
, (WPARAM
)dlgInfo
->hUserFont
, 0 );
600 if (SendMessage32A(hwnd
, WM_INITDIALOG
, (WPARAM
)dlgInfo
->hwndFocus
, param
))
601 SetFocus32( dlgInfo
->hwndFocus
);
602 if (template.style
& WS_VISIBLE
) ShowWindow( hwnd
, SW_SHOW
);
607 /***********************************************************************
608 * CreateDialog16 (USER.89)
610 HWND16
CreateDialog16( HINSTANCE16 hInst
, SEGPTR dlgTemplate
,
611 HWND16 owner
, DLGPROC16 dlgProc
)
613 return CreateDialogParam16( hInst
, dlgTemplate
, owner
, dlgProc
, 0 );
617 /***********************************************************************
618 * CreateDialogParam16 (USER.241)
620 HWND16
CreateDialogParam16( HINSTANCE16 hInst
, SEGPTR dlgTemplate
,
621 HWND16 owner
, DLGPROC16 dlgProc
, LPARAM param
)
628 dprintf_dialog(stddeb
, "CreateDialogParam16: %04x,%08lx,%04x,%08lx,%ld\n",
629 hInst
, (DWORD
)dlgTemplate
, owner
, (DWORD
)dlgProc
, param
);
631 if (!(hRsrc
= FindResource16( hInst
, dlgTemplate
, RT_DIALOG
))) return 0;
632 if (!(hmem
= LoadResource16( hInst
, hRsrc
))) return 0;
633 if (!(data
= LockResource16( hmem
))) hwnd
= 0;
634 else hwnd
= CreateDialogIndirectParam16( hInst
, data
, owner
,
636 FreeResource16( hmem
);
641 /***********************************************************************
642 * CreateDialogParam32A (USER32.72)
644 HWND32
CreateDialogParam32A( HINSTANCE32 hInst
, LPCSTR name
,
645 HWND32 owner
, DLGPROC32 dlgProc
, LPARAM param
)
649 LPWSTR str
= STRING32_DupAnsiToUni( name
);
650 HWND32 hwnd
= CreateDialogParam32W( hInst
, str
, owner
, dlgProc
, param
);
654 return CreateDialogParam32W( hInst
, (LPCWSTR
)name
, owner
, dlgProc
, param
);
658 /***********************************************************************
659 * CreateDialogParam32W (USER32.73)
661 HWND32
CreateDialogParam32W( HINSTANCE32 hInst
, LPCWSTR name
,
662 HWND32 owner
, DLGPROC32 dlgProc
, LPARAM param
)
664 HANDLE32 hrsrc
= FindResource32W( hInst
, name
, (LPWSTR
)RT_DIALOG
);
665 if (!hrsrc
) return 0;
666 return CreateDialogIndirectParam32W( hInst
,
667 (LPVOID
)LoadResource32(hInst
, hrsrc
),
668 owner
, dlgProc
, param
);
672 /***********************************************************************
673 * CreateDialogIndirect16 (USER.219)
675 HWND16
CreateDialogIndirect16( HINSTANCE16 hInst
, LPCVOID dlgTemplate
,
676 HWND16 owner
, DLGPROC16 dlgProc
)
678 return CreateDialogIndirectParam16( hInst
, dlgTemplate
, owner
, dlgProc
, 0);
682 /***********************************************************************
683 * CreateDialogIndirectParam16 (USER.242)
685 HWND16
CreateDialogIndirectParam16( HINSTANCE16 hInst
, LPCVOID dlgTemplate
,
686 HWND16 owner
, DLGPROC16 dlgProc
,
689 return DIALOG_CreateIndirect( hInst
, dlgTemplate
, owner
,
690 dlgProc
, param
, WIN_PROC_16
);
694 /***********************************************************************
695 * CreateDialogIndirectParam32A (USER32.69)
697 HWND32
CreateDialogIndirectParam32A( HINSTANCE32 hInst
, LPCVOID dlgTemplate
,
698 HWND32 owner
, DLGPROC32 dlgProc
,
701 return DIALOG_CreateIndirect( hInst
, dlgTemplate
, owner
,
702 (DLGPROC16
)dlgProc
, param
, WIN_PROC_32A
);
706 /***********************************************************************
707 * CreateDialogIndirectParam32W (USER32.71)
709 HWND32
CreateDialogIndirectParam32W( HINSTANCE32 hInst
, LPCVOID dlgTemplate
,
710 HWND32 owner
, DLGPROC32 dlgProc
,
713 return DIALOG_CreateIndirect( hInst
, dlgTemplate
, owner
,
714 (DLGPROC16
)dlgProc
, param
, WIN_PROC_32W
);
718 /***********************************************************************
721 static INT32
DIALOG_DoDialogBox( HWND hwnd
, HWND owner
)
724 DIALOGINFO
* dlgInfo
;
728 /* Owner must be a top-level window */
729 owner
= WIN_GetTopParent( owner
);
730 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return -1;
731 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
732 EnableWindow( owner
, FALSE
);
733 ShowWindow( hwnd
, SW_SHOW
);
735 while (MSG_InternalGetMessage(&msg
, hwnd
, owner
, MSGF_DIALOGBOX
, PM_REMOVE
,
736 !(wndPtr
->dwStyle
& DS_NOIDLEMSG
) ))
738 if (!IsDialogMessage( hwnd
, &msg
))
740 TranslateMessage( &msg
);
741 DispatchMessage( &msg
);
743 if (dlgInfo
->fEnd
) break;
745 retval
= dlgInfo
->msgResult
;
746 EnableWindow( owner
, TRUE
);
747 DestroyWindow( hwnd
);
752 /***********************************************************************
753 * DialogBox16 (USER.87)
755 INT16
DialogBox16( HINSTANCE16 hInst
, SEGPTR dlgTemplate
,
756 HWND16 owner
, DLGPROC16 dlgProc
)
758 return DialogBoxParam16( hInst
, dlgTemplate
, owner
, dlgProc
, 0 );
762 /***********************************************************************
763 * DialogBoxParam16 (USER.239)
765 INT16
DialogBoxParam16( HINSTANCE16 hInst
, SEGPTR
template,
766 HWND16 owner
, DLGPROC16 dlgProc
, LPARAM param
)
768 HWND16 hwnd
= CreateDialogParam16( hInst
, template, owner
, dlgProc
, param
);
769 if (hwnd
) return (INT16
)DIALOG_DoDialogBox( hwnd
, owner
);
774 /***********************************************************************
775 * DialogBoxParam32A (USER32.138)
777 INT32
DialogBoxParam32A( HINSTANCE32 hInst
, LPCSTR name
,
778 HWND32 owner
, DLGPROC32 dlgProc
, LPARAM param
)
780 HWND32 hwnd
= CreateDialogParam32A( hInst
, name
, owner
, dlgProc
, param
);
781 if (hwnd
) return DIALOG_DoDialogBox( hwnd
, owner
);
786 /***********************************************************************
787 * DialogBoxParam32W (USER32.139)
789 INT32
DialogBoxParam32W( HINSTANCE32 hInst
, LPCWSTR name
,
790 HWND32 owner
, DLGPROC32 dlgProc
, LPARAM param
)
792 HWND32 hwnd
= CreateDialogParam32W( hInst
, name
, owner
, dlgProc
, param
);
793 if (hwnd
) return DIALOG_DoDialogBox( hwnd
, owner
);
798 /***********************************************************************
799 * DialogBoxIndirect16 (USER.218)
801 INT16
DialogBoxIndirect16( HINSTANCE16 hInst
, HANDLE16 dlgTemplate
,
802 HWND16 owner
, DLGPROC16 dlgProc
)
804 return DialogBoxIndirectParam16( hInst
, dlgTemplate
, owner
, dlgProc
, 0 );
808 /***********************************************************************
809 * DialogBoxIndirectParam16 (USER.240)
811 INT16
DialogBoxIndirectParam16( HINSTANCE16 hInst
, HANDLE16 dlgTemplate
,
812 HWND16 owner
, DLGPROC16 dlgProc
, LPARAM param
)
817 if (!(ptr
= GlobalLock16( dlgTemplate
))) return -1;
818 hwnd
= CreateDialogIndirectParam16( hInst
, ptr
, owner
, dlgProc
, param
);
819 GlobalUnlock16( dlgTemplate
);
820 if (hwnd
) return (INT16
)DIALOG_DoDialogBox( hwnd
, owner
);
825 /***********************************************************************
826 * DialogBoxIndirectParam32A (USER32.135)
828 INT32
DialogBoxIndirectParam32A( HINSTANCE32 hInstance
, LPCVOID
template,
829 HWND32 owner
, DLGPROC32 dlgProc
,LPARAM param
)
831 HWND32 hwnd
= CreateDialogIndirectParam32A( hInstance
, template,
832 owner
, dlgProc
, param
);
833 if (hwnd
) return DIALOG_DoDialogBox( hwnd
, owner
);
838 /***********************************************************************
839 * DialogBoxIndirectParam32W (USER32.137)
841 INT32
DialogBoxIndirectParam32W( HINSTANCE32 hInstance
, LPCVOID
template,
842 HWND32 owner
, DLGPROC32 dlgProc
,LPARAM param
)
844 HWND32 hwnd
= CreateDialogIndirectParam32W( hInstance
, template,
845 owner
, dlgProc
, param
);
846 if (hwnd
) return DIALOG_DoDialogBox( hwnd
, owner
);
851 /***********************************************************************
852 * EndDialog (USER.88) (USER32.173)
854 BOOL16
EndDialog( HWND32 hwnd
, INT32 retval
)
856 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
857 DIALOGINFO
* dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
858 dlgInfo
->msgResult
= retval
;
859 dlgInfo
->fEnd
= TRUE
;
860 dprintf_dialog(stddeb
, "EndDialog: %04x %d\n", hwnd
, retval
);
865 /***********************************************************************
866 * IsDialogMessage (USER.90)
868 BOOL
IsDialogMessage( HWND hwndDlg
, LPMSG16 msg
)
873 if (!(wndPtr
= WIN_FindWndPtr( hwndDlg
))) return FALSE
;
874 if ((hwndDlg
!= msg
->hwnd
) && !IsChild( hwndDlg
, msg
->hwnd
)) return FALSE
;
876 /* Only the key messages get special processing */
877 if ((msg
->message
!= WM_KEYDOWN
) &&
878 (msg
->message
!= WM_SYSCHAR
) &&
879 (msg
->message
!= WM_CHAR
))
882 dlgCode
= SendMessage16( msg
->hwnd
, WM_GETDLGCODE
, 0, 0 );
883 if (dlgCode
& DLGC_WANTMESSAGE
)
885 DispatchMessage( msg
);
892 if (dlgCode
& DLGC_WANTALLKEYS
) break;
896 if (!(dlgCode
& DLGC_WANTTAB
))
898 SendMessage16( hwndDlg
, WM_NEXTDLGCTL
,
899 (GetKeyState(VK_SHIFT
) & 0x8000), 0 );
906 if (!(dlgCode
& DLGC_WANTARROWS
))
908 SetFocus32( GetNextDlgGroupItem(hwndDlg
,GetFocus32(),FALSE
) );
915 if (!(dlgCode
& DLGC_WANTARROWS
))
917 SetFocus32( GetNextDlgGroupItem(hwndDlg
,GetFocus32(),TRUE
) );
923 SendMessage32A( hwndDlg
, WM_COMMAND
, IDCANCEL
,
924 (LPARAM
)GetDlgItem( hwndDlg
, IDCANCEL
) );
929 DWORD dw
= SendMessage16( hwndDlg
, DM_GETDEFID
, 0, 0 );
930 if (HIWORD(dw
) == DC_HASDEFID
)
931 SendMessage32A( hwndDlg
, WM_COMMAND
,
932 MAKEWPARAM( LOWORD(dw
), BN_CLICKED
),
933 (LPARAM
)GetDlgItem( hwndDlg
, LOWORD(dw
) ));
935 SendMessage32A( hwndDlg
, WM_COMMAND
, IDOK
,
936 (LPARAM
)GetDlgItem( hwndDlg
, IDOK
) );
941 TranslateMessage( msg
);
943 break; /* case WM_KEYDOWN */
947 if (dlgCode
& (DLGC_WANTALLKEYS
| DLGC_WANTCHARS
)) break;
951 if (dlgCode
& DLGC_WANTALLKEYS
) break;
955 /* If we get here, the message has not been treated specially */
956 /* and can be sent to its destination window. */
957 DispatchMessage( msg
);
962 /****************************************************************
963 * GetDlgCtrlID (USER.277) (USER32.233)
965 INT16
GetDlgCtrlID( HWND32 hwnd
)
967 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
968 if (wndPtr
) return wndPtr
->wIDmenu
;
973 /***********************************************************************
974 * GetDlgItem (USER.91)
976 HWND
GetDlgItem( HWND hwndDlg
, WORD id
)
980 if (!(pWnd
= WIN_FindWndPtr( hwndDlg
))) return 0;
981 for (pWnd
= pWnd
->child
; pWnd
; pWnd
= pWnd
->next
)
982 if (pWnd
->wIDmenu
== id
) return pWnd
->hwndSelf
;
987 /*******************************************************************
988 * SendDlgItemMessage16 (USER.101)
990 LRESULT
SendDlgItemMessage16( HWND16 hwnd
, INT16 id
, UINT16 msg
,
991 WPARAM16 wParam
, LPARAM lParam
)
993 HWND16 hwndCtrl
= GetDlgItem( hwnd
, id
);
994 if (hwndCtrl
) return SendMessage16( hwndCtrl
, msg
, wParam
, lParam
);
999 /*******************************************************************
1000 * SendDlgItemMessage32A (USER32.451)
1002 LRESULT
SendDlgItemMessage32A( HWND32 hwnd
, INT32 id
, UINT32 msg
,
1003 WPARAM32 wParam
, LPARAM lParam
)
1005 HWND hwndCtrl
= GetDlgItem( (HWND16
)hwnd
, (INT16
)id
);
1006 if (hwndCtrl
) return SendMessage32A( hwndCtrl
, msg
, wParam
, lParam
);
1011 /*******************************************************************
1012 * SendDlgItemMessage32W (USER32.452)
1014 LRESULT
SendDlgItemMessage32W( HWND32 hwnd
, INT32 id
, UINT32 msg
,
1015 WPARAM32 wParam
, LPARAM lParam
)
1017 HWND hwndCtrl
= GetDlgItem( (HWND16
)hwnd
, (INT16
)id
);
1018 if (hwndCtrl
) return SendMessage32W( hwndCtrl
, msg
, wParam
, lParam
);
1023 /*******************************************************************
1024 * SetDlgItemText16 (USER.92)
1026 void SetDlgItemText16( HWND16 hwnd
, INT16 id
, SEGPTR lpString
)
1028 SendDlgItemMessage16( hwnd
, id
, WM_SETTEXT
, 0, (LPARAM
)lpString
);
1032 /*******************************************************************
1033 * SetDlgItemText32A (USER32.477)
1035 void SetDlgItemText32A( HWND32 hwnd
, INT32 id
, LPCSTR lpString
)
1037 SendDlgItemMessage32A( hwnd
, id
, WM_SETTEXT
, 0, (LPARAM
)lpString
);
1041 /*******************************************************************
1042 * SetDlgItemText32W (USER32.478)
1044 void SetDlgItemText32W( HWND32 hwnd
, INT32 id
, LPCWSTR lpString
)
1046 SendDlgItemMessage32W( hwnd
, id
, WM_SETTEXT
, 0, (LPARAM
)lpString
);
1050 /***********************************************************************
1051 * GetDlgItemText16 (USER.93)
1053 INT16
GetDlgItemText16( HWND16 hwnd
, INT16 id
, SEGPTR str
, UINT16 len
)
1055 return (INT16
)SendDlgItemMessage16( hwnd
, id
, WM_GETTEXT
,
1060 /***********************************************************************
1061 * GetDlgItemText32A (USER32.236)
1063 INT32
GetDlgItemText32A( HWND32 hwnd
, INT32 id
, LPSTR str
, UINT32 len
)
1065 return (INT32
)SendDlgItemMessage32A( hwnd
, id
, WM_GETTEXT
,
1070 /***********************************************************************
1071 * GetDlgItemText32W (USER32.237)
1073 INT32
GetDlgItemText32W( HWND32 hwnd
, INT32 id
, LPWSTR str
, UINT32 len
)
1075 return (INT32
)SendDlgItemMessage32W( hwnd
, id
, WM_GETTEXT
,
1080 /*******************************************************************
1081 * SetDlgItemInt16 (USER.94)
1083 void SetDlgItemInt16( HWND16 hwnd
, INT16 id
, UINT16 value
, BOOL16 fSigned
)
1085 char *str
= (char *)SEGPTR_ALLOC( 20 * sizeof(char) );
1088 if (fSigned
) sprintf( str
, "%d", (INT32
)(INT16
)value
);
1089 else sprintf( str
, "%u", value
);
1090 SendDlgItemMessage16( hwnd
, id
, WM_SETTEXT
, 0, (LPARAM
)SEGPTR_GET(str
) );
1095 /*******************************************************************
1096 * SetDlgItemInt32 (USER32.476)
1098 void SetDlgItemInt32( HWND32 hwnd
, INT32 id
, UINT32 value
, BOOL32 fSigned
)
1102 if (fSigned
) sprintf( str
, "%d", (INT32
)value
);
1103 else sprintf( str
, "%u", value
);
1104 SendDlgItemMessage32A( hwnd
, id
, WM_SETTEXT
, 0, (LPARAM
)str
);
1108 /***********************************************************************
1109 * GetDlgItemInt (USER.95)
1111 WORD
GetDlgItemInt( HWND hwnd
, WORD id
, BOOL
* translated
, BOOL fSigned
)
1116 if (translated
) *translated
= FALSE
;
1117 if (!(str
= (char *)SEGPTR_ALLOC( 30 * sizeof(char) ))) return 0;
1118 if (SendDlgItemMessage16( hwnd
, id
, WM_GETTEXT
, 30, (LPARAM
)SEGPTR_GET(str
)))
1121 result
= strtol( str
, &endptr
, 10 );
1122 if (endptr
&& (endptr
!= str
)) /* Conversion was successful */
1126 if ((result
< -32767) || (result
> 32767)) result
= 0;
1127 else if (translated
) *translated
= TRUE
;
1131 if ((result
< 0) || (result
> 65535)) result
= 0;
1132 else if (translated
) *translated
= TRUE
;
1137 return (WORD
)result
;
1141 /***********************************************************************
1142 * CheckDlgButton (USER.97) (USER32.44)
1144 BOOL16
CheckDlgButton( HWND32 hwnd
, INT32 id
, UINT32 check
)
1146 SendDlgItemMessage32A( hwnd
, id
, BM_SETCHECK32
, check
, 0 );
1151 /***********************************************************************
1152 * IsDlgButtonChecked (USER.98)
1154 WORD
IsDlgButtonChecked( HWND hwnd
, WORD id
)
1156 return (WORD
)SendDlgItemMessage32A( hwnd
, id
, BM_GETCHECK32
, 0, 0 );
1160 /***********************************************************************
1161 * CheckRadioButton (USER.96) (USER32.47)
1163 BOOL16
CheckRadioButton( HWND32 hwndDlg
, UINT32 firstID
, UINT32 lastID
,
1166 WND
*pWnd
= WIN_FindWndPtr( hwndDlg
);
1167 if (!pWnd
) return FALSE
;
1169 for (pWnd
= pWnd
->child
; pWnd
; pWnd
= pWnd
->next
)
1170 if ((pWnd
->wIDmenu
== firstID
) || (pWnd
->wIDmenu
== lastID
)) break;
1171 if (!pWnd
) return FALSE
;
1173 if (pWnd
->wIDmenu
== lastID
)
1174 lastID
= firstID
; /* Buttons are in reverse order */
1177 SendMessage32A( pWnd
->hwndSelf
, BM_SETCHECK32
,
1178 (pWnd
->wIDmenu
== checkID
), 0 );
1179 if (pWnd
->wIDmenu
== lastID
) break;
1186 /***********************************************************************
1187 * GetDialogBaseUnits (USER.243)
1189 DWORD
GetDialogBaseUnits()
1191 return MAKELONG( xBaseUnit
, yBaseUnit
);
1195 /***********************************************************************
1196 * MapDialogRect16 (USER.103)
1198 void MapDialogRect16( HWND16 hwnd
, LPRECT16 rect
)
1200 DIALOGINFO
* dlgInfo
;
1201 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1202 if (!wndPtr
) return;
1203 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
1204 rect
->left
= (rect
->left
* dlgInfo
->xBaseUnit
) / 4;
1205 rect
->right
= (rect
->right
* dlgInfo
->xBaseUnit
) / 4;
1206 rect
->top
= (rect
->top
* dlgInfo
->yBaseUnit
) / 8;
1207 rect
->bottom
= (rect
->bottom
* dlgInfo
->yBaseUnit
) / 8;
1211 /***********************************************************************
1212 * MapDialogRect32 (USER32.381)
1214 void MapDialogRect32( HWND32 hwnd
, LPRECT32 rect
)
1216 DIALOGINFO
* dlgInfo
;
1217 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1218 if (!wndPtr
) return;
1219 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
1220 rect
->left
= (rect
->left
* dlgInfo
->xBaseUnit
) / 4;
1221 rect
->right
= (rect
->right
* dlgInfo
->xBaseUnit
) / 4;
1222 rect
->top
= (rect
->top
* dlgInfo
->yBaseUnit
) / 8;
1223 rect
->bottom
= (rect
->bottom
* dlgInfo
->yBaseUnit
) / 8;
1227 /***********************************************************************
1228 * GetNextDlgGroupItem (USER.227)
1230 HWND
GetNextDlgGroupItem( HWND hwndDlg
, HWND hwndCtrl
, BOOL fPrevious
)
1232 WND
*pWnd
, *pWndStart
, *pWndCtrl
, *pWndDlg
;
1234 if (!(pWndDlg
= WIN_FindWndPtr( hwndDlg
))) return 0;
1235 if (!(pWndCtrl
= WIN_FindWndPtr( hwndCtrl
))) return 0;
1236 if (pWndCtrl
->parent
!= pWndDlg
) return 0;
1238 if (!fPrevious
&& pWndCtrl
->next
) /* Check if next control is in group */
1240 if (!(pWndCtrl
->next
->dwStyle
& WS_GROUP
))
1241 return pWndCtrl
->next
->hwndSelf
;
1244 /* Now we will have to find the start of the group */
1246 for (pWnd
= pWndStart
= pWndDlg
->child
; pWnd
; pWnd
= pWnd
->next
)
1248 if (pWnd
->dwStyle
& WS_GROUP
) pWndStart
= pWnd
; /* Start of a group */
1249 if (pWnd
== pWndCtrl
) break;
1252 if (!pWnd
) fprintf(stderr
, "GetNextDlgGroupItem: hwnd not in dialog!\n");
1254 /* only case left for forward search: wraparound */
1255 if (!fPrevious
) return pWndStart
->hwndSelf
;
1257 pWnd
= pWndStart
->next
;
1258 while (pWnd
&& (pWnd
!= pWndCtrl
))
1260 if (pWnd
->dwStyle
& WS_GROUP
) break;
1264 return pWndStart
->hwndSelf
;
1268 /***********************************************************************
1269 * GetNextDlgTabItem (USER.228)
1271 HWND
GetNextDlgTabItem( HWND hwndDlg
, HWND hwndCtrl
, BOOL fPrevious
)
1273 WND
*pWnd
, *pWndLast
, *pWndCtrl
, *pWndDlg
;
1275 if (!(pWndDlg
= WIN_FindWndPtr( hwndDlg
))) return 0;
1276 if (!(pWndCtrl
= WIN_FindWndPtr( hwndCtrl
))) return 0;
1277 if (pWndCtrl
->parent
!= pWndDlg
) return 0;
1279 pWndLast
= pWndCtrl
;
1280 pWnd
= pWndCtrl
->next
;
1283 if (!pWnd
) pWnd
= pWndDlg
->child
;
1284 if (pWnd
== pWndCtrl
) break;
1285 if ((pWnd
->dwStyle
& WS_TABSTOP
) && (pWnd
->dwStyle
& WS_VISIBLE
))
1288 if (!fPrevious
) break;
1292 return pWndLast
->hwndSelf
;