4 * Copyright 1993, 1994 Alexandre Julliard
8 static char Copyright
[] = "Copyright Alexandre Julliard, 1993, 1994";
20 /* #define DEBUG_DIALOG */
21 /* #undef DEBUG_DIALOG */
25 /* Dialog base units */
26 static WORD xBaseUnit
= 0, yBaseUnit
= 0;
29 /***********************************************************************
32 * Initialisation of the dialog manager.
39 /* Calculate the dialog base units */
41 if (!(hdc
= GetDC(GetDesktopWindow()))) return FALSE
;
42 GetTextMetrics( hdc
, &tm
);
44 xBaseUnit
= tm
.tmAveCharWidth
;
45 yBaseUnit
= tm
.tmHeight
;
46 dprintf_dialog(stddeb
, "DIALOG_Init: base units = %d,%d\n", xBaseUnit
, yBaseUnit
);
51 /***********************************************************************
52 * DIALOG_GetFirstTabItem
54 * Return the first item of the dialog that has the WS_TABSTOP style.
56 HWND
DIALOG_GetFirstTabItem( HWND hwndDlg
)
59 WND
*wndPtr
= WIN_FindWndPtr( hwndDlg
);
60 hwnd
= wndPtr
->hwndChild
;
63 wndPtr
= WIN_FindWndPtr( hwnd
);
64 if (wndPtr
->dwStyle
& WS_TABSTOP
) break;
65 hwnd
= wndPtr
->hwndNext
;
71 /***********************************************************************
74 * Return the class and text of the control pointed to by ptr,
75 * and return a pointer to the next control.
77 static DLGCONTROLHEADER
* DIALOG_GetControl( DLGCONTROLHEADER
* ptr
,
78 char ** class, char ** text
)
80 unsigned char * p
= (unsigned char *)ptr
;
81 p
+= 14; /* size of control header */
87 case 0x80: *class = "BUTTON"; break;
88 case 0x81: *class = "EDIT"; break;
89 case 0x82: *class = "STATIC"; break;
90 case 0x83: *class = "LISTBOX"; break;
91 case 0x84: *class = "SCROLLBAR"; break;
92 case 0x85: *class = "COMBOBOX"; break;
93 default: *class = ""; break;
103 /* Integer id, not documented (?). Only works for SS_ICON controls */
104 *text
= (char *)MAKEINTRESOURCE( p
[1] + 256*p
[2] );
112 return (DLGCONTROLHEADER
*)p
;
116 /***********************************************************************
117 * DIALOG_ParseTemplate
119 * Fill a DLGTEMPLATE structure from the dialog template, and return
120 * a pointer to the first control.
122 static DLGCONTROLHEADER
* DIALOG_ParseTemplate( LPCSTR
template,
123 DLGTEMPLATE
* result
)
125 unsigned char * p
= (unsigned char *)template;
127 result
->header
= (DLGTEMPLATEHEADER
*)p
;
130 result
->menuName
= p
;
131 if (*p
== 0xff) p
+= 3;
132 else p
+= strlen(p
) + 1;
134 if (*p
) result
->className
= p
;
135 else result
->className
= DIALOG_CLASS_NAME
;
141 if (result
->header
->style
& DS_SETFONT
)
143 result
->pointSize
= *(WORD
*)p
; p
+= sizeof(WORD
);
144 result
->faceName
= p
; p
+= strlen(p
) + 1;
147 return (DLGCONTROLHEADER
*)p
;
151 /***********************************************************************
152 * DIALOG_DisplayTemplate
155 static void DIALOG_DisplayTemplate( DLGTEMPLATE
* result
)
157 dprintf_dialog(stddeb
, "DIALOG %d, %d, %d, %d\n", result
->header
->x
, result
->header
->y
,
158 result
->header
->cx
, result
->header
->cy
);
159 dprintf_dialog(stddeb
, " STYLE %08x\n", result
->header
->style
);
160 dprintf_dialog(stddeb
, " CAPTION '%s'\n", result
->caption
);
161 dprintf_dialog(stddeb
, " CLASS '%s'\n", result
->className
);
162 if (result
->menuName
[0] == 0xff)
163 dprintf_dialog(stddeb
, " MENU %d\n", result
->menuName
[1] + 256*result
->menuName
[2] );
165 dprintf_dialog(stddeb
, " MENU '%s'\n", result
->menuName
);
166 if (result
->header
->style
& DS_SETFONT
)
167 dprintf_dialog(stddeb
, " FONT %d,'%s'\n", result
->pointSize
, result
->faceName
);
169 #endif /* DEBUG_DIALOG */
172 /***********************************************************************
173 * CreateDialog (USER.89)
175 HWND
CreateDialog( HINSTANCE hInst
, LPCSTR dlgTemplate
,
176 HWND owner
, WNDPROC dlgProc
)
178 return CreateDialogParam( hInst
, dlgTemplate
, owner
, dlgProc
, 0 );
182 /***********************************************************************
183 * CreateDialogParam (USER.241)
185 HWND
CreateDialogParam( HINSTANCE hInst
, LPCSTR dlgTemplate
,
186 HWND owner
, WNDPROC dlgProc
, LPARAM param
)
192 dprintf_dialog(stddeb
, "CreateDialogParam: %d,'%p',%d,%p,%ld\n",
193 hInst
, dlgTemplate
, owner
, dlgProc
, param
);
195 /* FIXME: MAKEINTRESOURCE should be replaced by RT_DIALOG */
196 if (!(hres
= FindResource( hInst
, dlgTemplate
, MAKEINTRESOURCE(0x8005) )))
198 if (!(hmem
= LoadResource( hInst
, hres
))) return 0;
199 if (!(data
= LockResource( hmem
))) hwnd
= 0;
200 else hwnd
= CreateDialogIndirectParam(hInst
, data
, owner
, dlgProc
, param
);
201 FreeResource( hmem
);
206 /***********************************************************************
207 * CreateDialogIndirect (USER.219)
209 HWND
CreateDialogIndirect( HINSTANCE hInst
, LPCSTR dlgTemplate
,
210 HWND owner
, WNDPROC dlgProc
)
212 return CreateDialogIndirectParam( hInst
, dlgTemplate
, owner
, dlgProc
, 0 );
216 /***********************************************************************
217 * CreateDialogIndirectParam (USER.242)
219 HWND
CreateDialogIndirectParam( HINSTANCE hInst
, LPCSTR dlgTemplate
,
220 HWND owner
, WNDPROC dlgProc
, LPARAM param
)
228 DLGTEMPLATE
template;
229 DLGCONTROLHEADER
* header
;
230 DIALOGINFO
* dlgInfo
;
232 WORD xUnit
= xBaseUnit
;
233 WORD yUnit
= yBaseUnit
;
235 /* Parse dialog template */
237 if (!dlgTemplate
) return 0;
238 header
= DIALOG_ParseTemplate( dlgTemplate
, &template );
240 DIALOG_DisplayTemplate( &template );
245 switch (template.menuName
[0])
251 hMenu
= LoadMenu( hInst
, MAKEINTRESOURCE( template.menuName
[1] +
252 256*template.menuName
[2] ));
255 hMenu
= LoadMenu( hInst
, template.menuName
);
259 /* Create custom font if needed */
261 if (template.header
->style
& DS_SETFONT
)
263 /* The font height must be negative as it is a point size */
264 /* (see CreateFont() documentation in the Windows SDK). */
265 hFont
= CreateFont( -template.pointSize
, 0, 0, 0, FW_DONTCARE
,
266 FALSE
, FALSE
, FALSE
, DEFAULT_CHARSET
, 0, 0,
267 DEFAULT_QUALITY
, FF_DONTCARE
, template.faceName
);
275 oldFont
= SelectObject( hdc
, hFont
);
276 GetTextMetrics( hdc
, &tm
);
277 SelectObject( hdc
, oldFont
);
279 xUnit
= tm
.tmAveCharWidth
;
284 /* Create dialog main window */
286 rect
.left
= rect
.top
= 0;
287 if (!(template.header
->style
& DS_ABSALIGN
))
288 ClientToScreen( owner
, (POINT
*)&rect
);
289 rect
.right
= rect
.left
+ template.header
->cx
* xUnit
/ 4;
290 rect
.bottom
= rect
.top
+ template.header
->cy
* yUnit
/ 8;
291 if (template.header
->style
& DS_MODALFRAME
) exStyle
|= WS_EX_DLGMODALFRAME
;
292 AdjustWindowRectEx( &rect
, template.header
->style
, hMenu
, exStyle
);
294 hwnd
= CreateWindowEx( exStyle
, template.className
, template.caption
,
295 template.header
->style
,
296 rect
.left
+ template.header
->x
* xUnit
/ 4,
297 rect
.top
+ template.header
->y
* yUnit
/ 8,
298 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
303 if (hFont
) DeleteObject( hFont
);
304 if (hMenu
) DestroyMenu( hMenu
);
308 /* Create control windows */
310 dprintf_dialog(stddeb
, " BEGIN\n" );
312 wndPtr
= WIN_FindWndPtr( hwnd
);
313 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
314 dlgInfo
->msgResult
= 0; /* This is used to store the default button id */
315 dlgInfo
->hDialogHeap
= 0;
317 for (i
= 0; i
< template.header
->nbItems
; i
++)
319 DLGCONTROLHEADER
* next_header
;
321 HWND hwndDefButton
= 0;
322 next_header
= DIALOG_GetControl( header
, &class, &text
);
324 dprintf_dialog(stddeb
, " %s ", class);
325 if ((int)text
& 0xffff0000)
326 dprintf_dialog(stddeb
,"'%s'", text
);
328 dprintf_dialog(stddeb
,"%4X", (int)text
& 0xffff);
329 dprintf_dialog(stddeb
," %d, %d, %d, %d, %d, %08lx\n",
330 header
->id
, header
->x
, header
->y
,
331 header
->cx
, header
->cy
, header
->style
);
333 if ((strcmp(class, "EDIT") == 0) &&
334 ((header
->style
& DS_LOCALEDIT
) != DS_LOCALEDIT
)) {
335 if (!dlgInfo
->hDialogHeap
) {
336 dlgInfo
->hDialogHeap
= GlobalAlloc(GMEM_FIXED
, 0x10000);
337 if (!dlgInfo
->hDialogHeap
) {
338 fprintf(stderr
,"CreateDialogIndirectParam: Insufficient memory to create heap for edit control\n");
341 HEAP_LocalInit(dlgInfo
->hDialogHeap
, GlobalLock(dlgInfo
->hDialogHeap
), 0x10000);
343 header
->style
|= WS_CHILD
;
344 hwndCtrl
= CreateWindowEx( WS_EX_NOPARENTNOTIFY
,
345 class, text
, header
->style
,
346 header
->x
* xUnit
/ 4, header
->y
* yUnit
/ 8,
347 header
->cx
* xUnit
/ 4, header
->cy
* yUnit
/ 8,
348 hwnd
, header
->id
, dlgInfo
->hDialogHeap
, NULL
);
352 header
->style
|= WS_CHILD
;
353 hwndCtrl
= CreateWindowEx( WS_EX_NOPARENTNOTIFY
,
354 class, text
, header
->style
,
355 header
->x
* xUnit
/ 4, header
->y
* yUnit
/ 8,
356 header
->cx
* xUnit
/ 4, header
->cy
* yUnit
/ 8,
357 hwnd
, header
->id
, hInst
, NULL
);
359 /* Make the control last one in Z-order, so that controls remain
360 in the order in which they were created */
361 SetWindowPos( hwndCtrl
, HWND_BOTTOM
, 0, 0, 0, 0,
362 SWP_NOSIZE
| SWP_NOMOVE
| SWP_NOACTIVATE
);
364 /* Send initialisation messages to the control */
365 if (hFont
) SendMessage( hwndCtrl
, WM_SETFONT
, hFont
, 0 );
366 if (SendMessage( hwndCtrl
, WM_GETDLGCODE
, 0, 0 ) & DLGC_DEFPUSHBUTTON
)
368 /* If there's already a default push-button, set it back */
369 /* to normal and use this one instead. */
371 SendMessage( hwndDefButton
, BM_SETSTYLE
, BS_PUSHBUTTON
, FALSE
);
372 hwndDefButton
= hwndCtrl
;
373 dlgInfo
->msgResult
= header
->id
;
375 header
= next_header
;
378 dprintf_dialog(stddeb
, " END\n" );
380 /* Initialise dialog extra data */
382 dlgInfo
->dlgProc
= dlgProc
;
383 dlgInfo
->hUserFont
= hFont
;
384 dlgInfo
->hMenu
= hMenu
;
385 dlgInfo
->xBaseUnit
= xUnit
;
386 dlgInfo
->yBaseUnit
= yUnit
;
387 dlgInfo
->hwndFocus
= DIALOG_GetFirstTabItem( hwnd
);
389 /* Send initialisation messages and set focus */
391 if (dlgInfo
->hUserFont
)
392 SendMessage( hwnd
, WM_SETFONT
, dlgInfo
->hUserFont
, 0 );
393 if (SendMessage( hwnd
, WM_INITDIALOG
, dlgInfo
->hwndFocus
, param
))
394 SetFocus( dlgInfo
->hwndFocus
);
400 /***********************************************************************
403 static int DIALOG_DoDialogBox( HWND hwnd
, HWND owner
)
406 DIALOGINFO
* dlgInfo
;
411 /* Owner must be a top-level window */
412 while (owner
&& GetParent(owner
)) owner
= GetParent(owner
);
413 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return -1;
414 if (!(msgHandle
= USER_HEAP_ALLOC( GMEM_MOVEABLE
, sizeof(MSG
)))) return -1;
415 lpmsg
= (MSG
*) USER_HEAP_ADDR( msgHandle
);
416 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
417 EnableWindow( owner
, FALSE
);
418 ShowWindow( hwnd
, SW_SHOW
);
420 while (MSG_InternalGetMessage( lpmsg
, hwnd
, owner
,
421 MSGF_DIALOGBOX
, PM_REMOVE
,
422 !(wndPtr
->dwStyle
& DS_NOIDLEMSG
) ))
424 if (!IsDialogMessage( hwnd
, lpmsg
))
426 TranslateMessage( lpmsg
);
427 DispatchMessage( lpmsg
);
429 if (dlgInfo
->fEnd
) break;
431 retval
= dlgInfo
->msgResult
;
432 DestroyWindow( hwnd
);
433 USER_HEAP_FREE( msgHandle
);
434 EnableWindow( owner
, TRUE
);
439 /***********************************************************************
440 * DialogBox (USER.87)
442 int DialogBox( HINSTANCE hInst
, LPCSTR dlgTemplate
,
443 HWND owner
, WNDPROC dlgProc
)
445 return DialogBoxParam( hInst
, dlgTemplate
, owner
, dlgProc
, 0 );
449 /***********************************************************************
450 * DialogBoxParam (USER.239)
452 int DialogBoxParam( HINSTANCE hInst
, LPCSTR dlgTemplate
,
453 HWND owner
, WNDPROC dlgProc
, LPARAM param
)
457 dprintf_dialog(stddeb
, "DialogBoxParam: %d,'%p',%d,%p,%ld\n",
458 hInst
, dlgTemplate
, owner
, dlgProc
, param
);
459 hwnd
= CreateDialogParam( hInst
, dlgTemplate
, owner
, dlgProc
, param
);
460 if (hwnd
) return DIALOG_DoDialogBox( hwnd
, owner
);
465 /***********************************************************************
466 * DialogBoxIndirect (USER.218)
468 int DialogBoxIndirect( HINSTANCE hInst
, HANDLE dlgTemplate
,
469 HWND owner
, WNDPROC dlgProc
)
471 return DialogBoxIndirectParam( hInst
, dlgTemplate
, owner
, dlgProc
, 0 );
474 /***********************************************************************
475 * DialogBoxIndirectPtr
476 * like DialogBoxIndirect, but expects pointer to template
478 int DialogBoxIndirectPtr( HINSTANCE hInst
, LPCSTR dlgTemplate
,
479 HWND owner
, WNDPROC dlgProc
)
481 return DialogBoxIndirectParamPtr(hInst
, dlgTemplate
, owner
, dlgProc
, 0);
485 /***********************************************************************
486 * DialogBoxIndirectParam (USER.240)
488 int DialogBoxIndirectParam( HINSTANCE hInst
, HANDLE dlgTemplate
,
489 HWND owner
, WNDPROC dlgProc
, LPARAM param
)
494 if (!(ptr
= GlobalLock( dlgTemplate
))) return -1;
495 hwnd
= CreateDialogIndirectParam( hInst
, ptr
, owner
, dlgProc
, param
);
496 GlobalUnlock( dlgTemplate
);
497 if (hwnd
) return DIALOG_DoDialogBox( hwnd
, owner
);
501 /***********************************************************************
502 * DialogBoxIndirectParamPtr
503 * like DialogBoxIndirectParam, but expects pointer to template
505 int DialogBoxIndirectParamPtr(HINSTANCE hInst
,LPCSTR dlgTemplate
,
506 HWND owner
, WNDPROC dlgProc
, LPARAM param
)
509 hwnd
= CreateDialogIndirectParam( hInst
, dlgTemplate
, owner
, dlgProc
, param
);
510 if (hwnd
) return DIALOG_DoDialogBox( hwnd
, owner
);
515 /***********************************************************************
516 * EndDialog (USER.88)
518 void EndDialog( HWND hwnd
, short retval
)
520 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
521 DIALOGINFO
* dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
522 dlgInfo
->msgResult
= retval
;
523 dlgInfo
->fEnd
= TRUE
;
524 dprintf_dialog(stddeb
, "EndDialog: %d %d\n", hwnd
, retval
);
528 /***********************************************************************
529 * IsDialogMessage (USER.90)
531 BOOL
IsDialogMessage( HWND hwndDlg
, LPMSG msg
)
536 if (!(wndPtr
= WIN_FindWndPtr( hwndDlg
))) return FALSE
;
537 if ((hwndDlg
!= msg
->hwnd
) && !IsChild( hwndDlg
, msg
->hwnd
)) return FALSE
;
539 /* Only the key messages get special processing */
540 if ((msg
->message
== WM_KEYDOWN
) ||
541 (msg
->message
== WM_SYSCHAR
) ||
542 (msg
->message
== WM_CHAR
))
544 dlgCode
= SendMessage( msg
->hwnd
, WM_GETDLGCODE
, 0, 0 );
545 if (dlgCode
& DLGC_WANTMESSAGE
)
547 DispatchMessage( msg
);
555 if (dlgCode
& DLGC_WANTALLKEYS
) break;
559 if (!(dlgCode
& DLGC_WANTTAB
))
561 SendMessage( hwndDlg
, WM_NEXTDLGCTL
,
562 (GetKeyState(VK_SHIFT
) & 0x80), 0 );
569 if (!(dlgCode
& DLGC_WANTARROWS
))
571 SetFocus(GetNextDlgGroupItem(hwndDlg
,GetFocus(),FALSE
));
578 if (!(dlgCode
& DLGC_WANTARROWS
))
580 SetFocus(GetNextDlgGroupItem(hwndDlg
,GetFocus(),TRUE
));
586 SendMessage( hwndDlg
, WM_COMMAND
, IDCANCEL
,
587 MAKELPARAM( GetDlgItem(hwndDlg
,IDCANCEL
), 0 ));
592 DWORD dw
= SendMessage( hwndDlg
, DM_GETDEFID
, 0, 0 );
593 if (HIWORD(dw
) == DC_HASDEFID
)
594 SendMessage( hwndDlg
, WM_COMMAND
, LOWORD(dw
),
595 MAKELPARAM( GetDlgItem( hwndDlg
, LOWORD(dw
) ),
598 SendMessage( hwndDlg
, WM_COMMAND
, IDOK
,
599 MAKELPARAM( GetDlgItem(hwndDlg
,IDOK
), 0 ));
603 break; /* case WM_KEYDOWN */
607 if (dlgCode
& (DLGC_WANTALLKEYS
| DLGC_WANTCHARS
)) break;
611 if (dlgCode
& DLGC_WANTALLKEYS
) break;
615 /* If we get here, the message has not been treated specially */
616 /* and can be sent to its destination window. */
617 DispatchMessage( msg
);
622 /****************************************************************
623 * GetDlgCtrlID (USER.277)
625 int GetDlgCtrlID( HWND hwnd
)
627 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
628 if (wndPtr
) return wndPtr
->wIDmenu
;
633 /***********************************************************************
634 * GetDlgItem (USER.91)
636 HWND
GetDlgItem( HWND hwndDlg
, WORD id
)
642 if (!(wndPtr
= WIN_FindWndPtr( hwndDlg
))) return 0;
643 curChild
= wndPtr
->hwndChild
;
646 childPtr
= WIN_FindWndPtr( curChild
);
647 if (childPtr
->wIDmenu
== id
) return curChild
;
648 curChild
= childPtr
->hwndNext
;
654 /*******************************************************************
655 * SendDlgItemMessage (USER.101)
657 LONG
SendDlgItemMessage(HWND hwnd
, WORD id
, UINT msg
, WORD wParam
, LONG lParam
)
659 HWND hwndCtrl
= GetDlgItem( hwnd
, id
);
660 if (hwndCtrl
) return SendMessage( hwndCtrl
, msg
, wParam
, lParam
);
665 /*******************************************************************
666 * SetDlgItemText (USER.92)
668 void SetDlgItemText( HWND hwnd
, WORD id
, LPSTR lpString
)
670 SendDlgItemMessage( hwnd
, id
, WM_SETTEXT
, 0, (DWORD
)lpString
);
674 /***********************************************************************
675 * GetDlgItemText (USER.93)
677 int GetDlgItemText( HWND hwnd
, WORD id
, LPSTR str
, WORD max
)
679 return (int)SendDlgItemMessage( hwnd
, id
, WM_GETTEXT
, max
, (DWORD
)str
);
683 /*******************************************************************
684 * SetDlgItemInt (USER.94)
686 void SetDlgItemInt( HWND hwnd
, WORD id
, WORD value
, BOOL fSigned
)
688 HANDLE hText
= USER_HEAP_ALLOC(0, 10 );
689 char * str
= (char *) USER_HEAP_ADDR( hText
);
691 if (fSigned
) sprintf( str
, "%d", value
);
692 else sprintf( str
, "%u", value
);
693 SendDlgItemMessage( hwnd
, id
, WM_SETTEXT
, 0, (DWORD
)str
);
694 USER_HEAP_FREE( hText
);
698 /***********************************************************************
699 * GetDlgItemInt (USER.95)
701 WORD
GetDlgItemInt( HWND hwnd
, WORD id
, BOOL
* translated
, BOOL fSigned
)
708 if (translated
) *translated
= FALSE
;
709 if (!(len
= SendDlgItemMessage( hwnd
, id
, WM_GETTEXTLENGTH
, 0, 0 )))
711 if (!(hText
= USER_HEAP_ALLOC(0, len
+1 )))
713 str
= (char *) USER_HEAP_ADDR( hText
);
714 if (SendDlgItemMessage( hwnd
, id
, WM_GETTEXT
, len
+1, (DWORD
)str
))
717 result
= strtol( str
, &endptr
, 10 );
718 if (endptr
&& (endptr
!= str
)) /* Conversion was successful */
722 if ((result
< -32767) || (result
> 32767)) result
= 0;
723 else if (translated
) *translated
= TRUE
;
727 if ((result
< 0) || (result
> 65535)) result
= 0;
728 else if (translated
) *translated
= TRUE
;
732 USER_HEAP_FREE( hText
);
737 /***********************************************************************
738 * CheckDlgButton (USER.97)
740 void CheckDlgButton( HWND hwnd
, WORD id
, WORD check
)
742 SendDlgItemMessage( hwnd
, id
, BM_SETCHECK
, check
, 0 );
746 /***********************************************************************
747 * IsDlgButtonChecked (USER.98)
749 WORD
IsDlgButtonChecked( HWND hwnd
, WORD id
)
751 return (WORD
)SendDlgItemMessage( hwnd
, id
, BM_GETCHECK
, 0, 0 );
755 /***********************************************************************
756 * CheckRadioButton (USER.96)
758 void CheckRadioButton( HWND hwndDlg
, WORD firstID
, WORD lastID
, WORD checkID
)
760 HWND button
= GetWindow( hwndDlg
, GW_CHILD
);
765 if (!(wndPtr
= WIN_FindWndPtr( button
))) return;
766 if ((wndPtr
->wIDmenu
== firstID
) || (wndPtr
->wIDmenu
== lastID
)) break;
767 button
= wndPtr
->hwndNext
;
771 if (wndPtr
->wIDmenu
== lastID
)
772 lastID
= firstID
; /* Buttons are in reverse order */
775 if (!(wndPtr
= WIN_FindWndPtr( button
))) return;
776 SendMessage( button
, BM_SETCHECK
, (wndPtr
->wIDmenu
== checkID
), 0 );
777 if (wndPtr
->wIDmenu
== lastID
) break;
778 button
= wndPtr
->hwndNext
;
783 /***********************************************************************
784 * GetDialogBaseUnits (USER.243)
786 DWORD
GetDialogBaseUnits()
788 return MAKELONG( xBaseUnit
, yBaseUnit
);
792 /***********************************************************************
793 * MapDialogRect (USER.103)
795 void MapDialogRect( HWND hwnd
, LPRECT rect
)
797 DIALOGINFO
* dlgInfo
;
798 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
800 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
801 rect
->left
= (rect
->left
* dlgInfo
->xBaseUnit
) / 4;
802 rect
->right
= (rect
->right
* dlgInfo
->xBaseUnit
) / 4;
803 rect
->top
= (rect
->top
* dlgInfo
->yBaseUnit
) / 8;
804 rect
->bottom
= (rect
->bottom
* dlgInfo
->yBaseUnit
) / 8;
808 /***********************************************************************
809 * GetNextDlgGroupItem (USER.227)
811 HWND
GetNextDlgGroupItem( HWND hwndDlg
, HWND hwndCtrl
, BOOL fPrevious
)
813 HWND hwnd
, hwndStart
;
814 WND
* dlgPtr
, * ctrlPtr
, * wndPtr
;
816 if (!(dlgPtr
= WIN_FindWndPtr( hwndDlg
))) return 0;
817 if (!(ctrlPtr
= WIN_FindWndPtr( hwndCtrl
))) return 0;
818 if (ctrlPtr
->hwndParent
!= hwndDlg
) return 0;
820 if (!fPrevious
&& ctrlPtr
->hwndNext
) /*Check if next control is in group*/
822 wndPtr
= WIN_FindWndPtr( ctrlPtr
->hwndNext
);
823 if (!(wndPtr
->dwStyle
& WS_GROUP
)) return ctrlPtr
->hwndNext
;
826 if (ctrlPtr
->dwStyle
& WS_GROUP
) /* Control is the first of the group */
828 if (!fPrevious
) return hwndCtrl
; /* Control is alone in his group */
829 hwnd
= ctrlPtr
->hwndNext
;
830 while(hwnd
) /* Find last control of the group */
832 wndPtr
= WIN_FindWndPtr( hwnd
);
833 if (wndPtr
->dwStyle
& WS_GROUP
) break;
835 hwnd
= wndPtr
->hwndNext
;
840 /* Now we will have to find the start of the group */
842 hwndStart
= hwnd
= dlgPtr
->hwndChild
;
845 wndPtr
= WIN_FindWndPtr( hwnd
);
846 if (wndPtr
->dwStyle
& WS_GROUP
) hwndStart
= hwnd
; /*Start of a group*/
847 if (hwnd
== hwndCtrl
)
849 /* We found the control -> hwndStart is the first of the group */
850 if (!fPrevious
) return hwndStart
;
852 while(hwndStart
) /* Find the control placed before hwndCtrl */
854 wndPtr
= WIN_FindWndPtr( hwndStart
);
855 if (wndPtr
->hwndNext
== hwndCtrl
) return hwndStart
;
856 hwndStart
= wndPtr
->hwndNext
;
860 hwnd
= wndPtr
->hwndNext
;
862 return hwndCtrl
; /* Not found -> return original control */
866 /***********************************************************************
867 * GetNextDlgTabItem (USER.228)
869 HWND
GetNextDlgTabItem( HWND hwndDlg
, HWND hwndCtrl
, BOOL fPrevious
)
872 WND
* dlgPtr
, * ctrlPtr
, * wndPtr
;
874 if (!(dlgPtr
= WIN_FindWndPtr( hwndDlg
))) return 0;
875 if (!(ctrlPtr
= WIN_FindWndPtr( hwndCtrl
))) return 0;
876 if (ctrlPtr
->hwndParent
!= hwndDlg
) return 0;
879 hwnd
= ctrlPtr
->hwndNext
;
882 if (!hwnd
) hwnd
= dlgPtr
->hwndChild
;
883 if (hwnd
== hwndCtrl
) break;
884 wndPtr
= WIN_FindWndPtr( hwnd
);
885 if (wndPtr
->dwStyle
& WS_TABSTOP
)
888 if (!fPrevious
) break;
890 hwnd
= wndPtr
->hwndNext
;