4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
16 /* Dialog base units */
17 static WORD xBaseUnit
= 0, yBaseUnit
= 0;
20 /***********************************************************************
23 * Initialisation of the dialog manager.
30 /* Calculate the dialog base units */
32 if (!(hdc
= GetDC( 0 ))) return FALSE
;
33 GetTextMetrics( hdc
, &tm
);
35 xBaseUnit
= tm
.tmAveCharWidth
;
36 yBaseUnit
= tm
.tmHeight
;
38 printf( "DIALOG_Init: base units = %d,%d\n", xBaseUnit
, yBaseUnit
);
44 /***********************************************************************
47 * Return the class and text of the control pointed to by ptr,
48 * and return a pointer to the next control.
50 static DLGCONTROLHEADER
* DIALOG_GetControl( DLGCONTROLHEADER
* ptr
,
51 char ** class, char ** text
)
53 unsigned char * p
= (unsigned char *)ptr
;
54 p
+= 14; /* size of control header */
59 case 0x80: *class = "BUTTON"; break;
60 case 0x81: *class = "EDIT"; break;
61 case 0x82: *class = "STATIC"; break;
62 case 0x83: *class = "LISTBOX"; break;
63 case 0x84: *class = "SCROLLBAR"; break;
64 case 0x85: *class = "COMBOBOX"; break;
65 default: *class = ""; break;
75 return (DLGCONTROLHEADER
*)p
;
79 /***********************************************************************
80 * DIALOG_ParseTemplate
82 * Fill a DLGTEMPLATE structure from the dialog template.
84 static void DIALOG_ParseTemplate( LPCSTR
template, DLGTEMPLATE
* result
)
87 unsigned char * p
= (unsigned char *)template;
89 result
->header
= (DLGTEMPLATEHEADER
*)p
;
92 if (*p
== 0xff) p
+= 3;
93 else p
+= strlen(p
) + 1;
95 if (*p
) result
->className
= p
;
96 else result
->className
= DIALOG_CLASS_NAME
;
102 if (result
->header
->style
& DS_SETFONT
)
104 result
->pointSize
= *(WORD
*)p
; p
+= sizeof(WORD
);
105 result
->faceName
= p
; p
+= strlen(p
) + 1;
107 result
->controls
= NULL
;
108 if (!result
->header
->nbItems
) return;
109 result
->controls
= (DLGCONTROL
*) malloc( result
->header
->nbItems
* sizeof(DLGCONTROL
) );
110 if (!result
->controls
) return;
112 for (i
= 0; i
< result
->header
->nbItems
; i
++)
114 result
->controls
[i
].header
= (DLGCONTROLHEADER
*)p
;
115 p
= (char *)DIALOG_GetControl( result
->controls
[i
].header
,
116 &result
->controls
[i
].class,
117 &result
->controls
[i
].text
);
122 /***********************************************************************
123 * DIALOG_DisplayTemplate
126 static void DIALOG_DisplayTemplate( DLGTEMPLATE
* result
)
129 DLGCONTROL
* ctrl
= result
->controls
;
131 printf( "DIALOG %d, %d, %d, %d\n", result
->header
->x
, result
->header
->y
,
132 result
->header
->cx
, result
->header
->cy
);
133 printf( " STYLE %08x\n", result
->header
->style
);
134 printf( " CAPTION '%s'\n", result
->caption
);
135 printf( " CLASS '%s'\n", result
->className
);
136 if (result
->menuName
[0] == 0xff)
137 printf( " MENU %d\n", result
->menuName
[1] + 256*result
->menuName
[2] );
138 else printf( " MENU '%s'\n", result
->menuName
);
139 if (result
->header
->style
& DS_SETFONT
)
140 printf( " FONT %d,'%s'\n", result
->pointSize
, result
->faceName
);
142 printf( " BEGIN\n" );
144 for (i
= 0; i
< result
->header
->nbItems
; i
++, ctrl
++)
146 printf( " %s '%s' %d, %d, %d, %d, %d, %08x\n",
147 ctrl
->class, ctrl
->text
, ctrl
->header
->id
,
148 ctrl
->header
->x
, ctrl
->header
->y
, ctrl
->header
->cx
,
149 ctrl
->header
->cy
, ctrl
->header
->style
);
154 #endif /* DEBUG_DIALOG */
157 /***********************************************************************
158 * CreateDialog (USER.89)
160 HWND
CreateDialog( HINSTANCE hInst
, LPCSTR dlgTemplate
,
161 HWND owner
, FARPROC dlgProc
)
163 return CreateDialogParam( hInst
, dlgTemplate
, owner
, dlgProc
, 0 );
167 /***********************************************************************
168 * CreateDialogParam (USER.241)
170 HWND
CreateDialogParam( HINSTANCE hInst
, LPCSTR dlgTemplate
,
171 HWND owner
, FARPROC dlgProc
, LPARAM param
)
179 printf( "CreateDialogParam: %d,'%s',%d,%p,%d\n",
180 hInst
, dlgTemplate
, owner
, dlgProc
, param
);
184 if (!(hres
= FindResource( hInst
, dlgTemplate
, RT_DIALOG
))) return 0;
185 if (!(hmem
= LoadResource( hInst
, hres
))) return 0;
186 if (!(data
= LockResource( hmem
))) hwnd
= 0;
187 else hwnd
= CreateDialogIndirectParam(hInst
, data
, owner
, dlgProc
, param
);
188 FreeResource( hmem
);
190 hmem
= RSC_LoadResource( hInst
, dlgTemplate
, 0x8005, &size
);
191 data
= (LPCSTR
) GlobalLock( hmem
);
192 hwnd
= CreateDialogIndirectParam( hInst
, data
, owner
, dlgProc
, param
);
199 /***********************************************************************
200 * CreateDialogIndirect (USER.219)
202 HWND
CreateDialogIndirect( HINSTANCE hInst
, LPCSTR dlgTemplate
,
203 HWND owner
, FARPROC dlgProc
)
205 return CreateDialogIndirectParam( hInst
, dlgTemplate
, owner
, dlgProc
, 0 );
209 /***********************************************************************
210 * CreateDialogIndirectParam (USER.242)
212 HWND
CreateDialogIndirectParam( HINSTANCE hInst
, LPCSTR dlgTemplate
,
213 HWND owner
, FARPROC dlgProc
, LPARAM param
)
219 DLGTEMPLATE
template;
220 DIALOGINFO
* dlgInfo
;
221 WORD xUnit
= xBaseUnit
;
222 WORD yUnit
= yBaseUnit
;
224 if (!dlgTemplate
) return 0;
225 DIALOG_ParseTemplate( dlgTemplate
, &template );
228 DIALOG_DisplayTemplate( &template );
233 if (template.menuName
[0])
235 if (template.menuName
[0] != 0xff)
236 hMenu
= LoadMenu( hInst
, template.menuName
);
238 hMenu
= LoadMenu( hInst
, MAKEINTRESOURCE( template.menuName
[1] +
239 256*template.menuName
[2] ));
242 /* Create custom font if needed */
244 if (template.header
->style
& DS_SETFONT
)
246 hFont
= CreateFont( template.pointSize
, 0, 0, 0, FW_DONTCARE
,
247 FALSE
, FALSE
, FALSE
, DEFAULT_CHARSET
, 0, 0,
248 DEFAULT_QUALITY
, FF_DONTCARE
, template.faceName
);
256 oldFont
= SelectObject( hdc
, hFont
);
257 GetTextMetrics( hdc
, &tm
);
258 SelectObject( hdc
, oldFont
);
260 xUnit
= tm
.tmAveCharWidth
;
265 /* Create dialog main window */
267 hwnd
= CreateWindow( template.className
, template.caption
,
268 template.header
->style
& ~WS_VISIBLE
,
269 template.header
->x
* xUnit
/ 4,
270 template.header
->y
* yUnit
/ 8,
271 template.header
->cx
* xUnit
/ 4,
272 template.header
->cy
* yUnit
/ 8,
277 if (hFont
) DeleteObject( hFont
);
278 if (hMenu
) DestroyMenu( hMenu
);
279 if (template.controls
) free( template.controls
);
283 /* Create control windows */
285 if (hwnd
&& template.header
->nbItems
)
288 DLGCONTROL
* ctrl
= template.controls
;
289 for (i
= 0; i
< template.header
->nbItems
; i
++, ctrl
++)
291 CreateWindowEx( WS_EX_NOPARENTNOTIFY
,
292 ctrl
->class, ctrl
->text
, ctrl
->header
->style
,
293 ctrl
->header
->x
* xUnit
/ 4,
294 ctrl
->header
->y
* yUnit
/ 8,
295 ctrl
->header
->cx
* xUnit
/ 4,
296 ctrl
->header
->cy
* yUnit
/ 8,
297 hwnd
, ctrl
->header
->id
, hInst
, NULL
);
301 /* Initialise dialog extra data */
303 wndPtr
= WIN_FindWndPtr( hwnd
);
304 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
305 dlgInfo
->dlgProc
= dlgProc
;
306 dlgInfo
->hUserFont
= hFont
;
307 dlgInfo
->hMenu
= hMenu
;
308 dlgInfo
->xBaseUnit
= xUnit
;
309 dlgInfo
->yBaseUnit
= yUnit
;
310 dlgInfo
->hwndFocus
= GetNextDlgTabItem( hwnd
,
311 GetWindow(wndPtr
->hwndChild
, GW_HWNDLAST
), FALSE
);
313 /* Send initialisation messages and set focus */
315 if (dlgInfo
->hUserFont
)
316 SendMessage( hwnd
, WM_SETFONT
, dlgInfo
->hUserFont
, 0);
317 SendMessage( hwnd
, WM_INITDIALOG
, dlgInfo
->hwndFocus
, param
);
318 if (SendMessage( hwnd
, WM_INITDIALOG
, dlgInfo
->hwndFocus
, param
))
319 SetFocus( dlgInfo
->hwndFocus
);
323 if (template.header
->style
& WS_VISIBLE
) ShowWindow( hwnd
, SW_SHOW
);
325 if (template.controls
) free( template.controls
);
330 /***********************************************************************
331 * DialogBox (USER.87)
333 int DialogBox( HINSTANCE hInst
, LPCSTR dlgTemplate
,
334 HWND owner
, FARPROC dlgProc
)
338 DIALOGINFO
* dlgInfo
;
343 printf( "DialogBox: %d,'%s',%d,%p\n", hInst
, dlgTemplate
, owner
, dlgProc
);
346 hwnd
= CreateDialog( hInst
, dlgTemplate
, owner
, dlgProc
);
347 if (!hwnd
) return -1;
348 wndPtr
= WIN_FindWndPtr( hwnd
);
349 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
350 while (GetMessage (&msg
, 0, 0, 0))
352 if (!IsDialogMessage( hwnd
, &msg
))
354 TranslateMessage(&msg
);
355 DispatchMessage(&msg
);
357 if (dlgInfo
->fEnd
) break;
359 retval
= dlgInfo
->msgResult
;
360 DestroyWindow( hwnd
);
365 /***********************************************************************
366 * EndDialog (USER.88)
368 void EndDialog( HWND hwnd
, short retval
)
370 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
371 DIALOGINFO
* dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
372 dlgInfo
->msgResult
= retval
;
373 dlgInfo
->fEnd
= TRUE
;
375 printf( "EndDialog: %d %d\n", hwnd
, retval
);
380 /***********************************************************************
381 * IsDialogMessage (USER.90)
383 BOOL
IsDialogMessage( HWND hwndDlg
, LPMSG msg
)
387 if (!(wndPtr
= WIN_FindWndPtr( hwndDlg
))) return FALSE
;
388 if ((hwndDlg
!= msg
->hwnd
) && !IsChild( hwndDlg
, msg
->hwnd
)) return FALSE
;
390 if (msg
->message
!= WM_KEYDOWN
)
392 SendMessage( msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
396 int dlgCode
= SendMessage( msg
->hwnd
, WM_GETDLGCODE
, 0, 0 );
397 /* Process key message */
404 /****************************************************************
405 * GetDlgCtrlID (USER.277)
407 int GetDlgCtrlID( HWND hwnd
)
409 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
410 if (wndPtr
) return wndPtr
->wIDmenu
;
415 /***********************************************************************
416 * GetDlgItem (USER.91)
418 HWND
GetDlgItem( HWND hwndDlg
, WORD id
)
424 if (!(wndPtr
= WIN_FindWndPtr( hwndDlg
))) return 0;
425 curChild
= wndPtr
->hwndChild
;
428 childPtr
= WIN_FindWndPtr( curChild
);
429 if (childPtr
->wIDmenu
== id
) return curChild
;
430 curChild
= childPtr
->hwndNext
;
436 /*******************************************************************
437 * SendDlgItemMessage (USER.101)
439 LONG
SendDlgItemMessage(HWND hwnd
, WORD id
, UINT msg
, WORD wParam
, LONG lParam
)
441 HWND hwndCtrl
= GetDlgItem( hwnd
, id
);
442 if (hwndCtrl
) return SendMessage( hwndCtrl
, msg
, wParam
, lParam
);
447 /*******************************************************************
448 * SetDlgItemText (USER.92)
450 void SetDlgItemText( HWND hwnd
, WORD id
, LPSTR lpString
)
452 SendDlgItemMessage( hwnd
, id
, WM_SETTEXT
, 0, (DWORD
)lpString
);
456 /***********************************************************************
457 * GetDlgItemText (USER.93)
459 int GetDlgItemText( HWND hwnd
, WORD id
, LPSTR str
, WORD max
)
461 return (int)SendDlgItemMessage( hwnd
, id
, WM_GETTEXT
, max
, (DWORD
)str
);
465 /*******************************************************************
466 * SetDlgItemInt (USER.94)
468 void SetDlgItemInt( HWND hwnd
, WORD id
, WORD value
, BOOL fSigned
)
470 HANDLE hText
= LocalAlloc( LMEM_MOVEABLE
, 10 );
471 char * str
= (char *) LocalLock( hText
);
473 if (fSigned
) sprintf( str
, "%d", value
);
474 else sprintf( str
, "%u", value
);
475 SendDlgItemMessage( hwnd
, id
, WM_SETTEXT
, 0, (DWORD
)str
);
476 LocalUnlock( hText
);
481 /***********************************************************************
482 * GetDlgItemInt (USER.95)
484 WORD
GetDlgItemInt( HWND hwnd
, WORD id
, BOOL
* translated
, BOOL fSigned
)
491 if (translated
) *translated
= FALSE
;
492 if (!(len
= SendDlgItemMessage( hwnd
, id
, WM_GETTEXTLENGTH
, 0, 0 )))
494 if (!(hText
= LocalAlloc(LMEM_MOVEABLE
, len
+1 )))
496 str
= (char *) LocalLock( hText
);
497 if (SendDlgItemMessage( hwnd
, id
, WM_GETTEXT
, len
+1, (DWORD
)str
))
500 result
= strtol( str
, &endptr
, 10 );
501 if (endptr
&& (endptr
!= str
)) /* Conversion was successful */
505 if ((result
< -32767) || (result
> 32767)) result
= 0;
506 else if (translated
) *translated
= TRUE
;
510 if ((result
< 0) || (result
> 65535)) result
= 0;
511 else if (translated
) *translated
= TRUE
;
515 LocalUnlock( hText
);
521 /***********************************************************************
522 * CheckDlgButton (USER.97)
524 void CheckDlgButton( HWND hwnd
, WORD id
, WORD check
)
526 SendDlgItemMessage( hwnd
, id
, BM_SETCHECK
, check
, 0 );
530 /***********************************************************************
531 * IsDlgButtonChecked (USER.98)
533 WORD
IsDlgButtonChecked( HWND hwnd
, WORD id
)
535 return (WORD
)SendDlgItemMessage( hwnd
, id
, BM_GETCHECK
, 0, 0 );
539 /***********************************************************************
540 * CheckRadioButton (USER.96)
542 void CheckRadioButton( HWND hwndDlg
, WORD firstID
, WORD lastID
, WORD checkID
)
544 HWND button
= GetDlgItem( hwndDlg
, firstID
);
547 WND
* wndPtr
= WIN_FindWndPtr( button
);
549 SendMessage( button
, BM_SETCHECK
, (wndPtr
->wIDmenu
== checkID
), 0 );
550 if (wndPtr
->wIDmenu
== lastID
) break;
551 button
= wndPtr
->hwndNext
;
556 /***********************************************************************
557 * GetDialogBaseUnits (USER.243)
559 DWORD
GetDialogBaseUnits()
561 return MAKELONG( xBaseUnit
, yBaseUnit
);
565 /***********************************************************************
566 * MapDialogRect (USER.103)
568 void MapDialogRect( HWND hwnd
, LPRECT rect
)
570 DIALOGINFO
* dlgInfo
;
571 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
573 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
574 rect
->left
= (rect
->left
* dlgInfo
->xBaseUnit
) / 4;
575 rect
->right
= (rect
->right
* dlgInfo
->xBaseUnit
) / 4;
576 rect
->top
= (rect
->top
* dlgInfo
->yBaseUnit
) / 8;
577 rect
->bottom
= (rect
->bottom
* dlgInfo
->yBaseUnit
) / 8;
581 /***********************************************************************
582 * GetNextDlgGroupItem (USER.227)
584 HWND
GetNextDlgGroupItem( HWND hwndDlg
, HWND hwndCtrl
, BOOL fPrevious
)
587 WND
* dlgPtr
, * ctrlPtr
, * wndPtr
;
589 if (!(dlgPtr
= WIN_FindWndPtr( hwndDlg
))) return 0;
590 if (!(ctrlPtr
= WIN_FindWndPtr( hwndCtrl
))) return 0;
591 if (ctrlPtr
->hwndParent
!= hwndDlg
) return 0;
594 hwnd
= ctrlPtr
->hwndNext
;
597 if (!hwnd
) hwnd
= dlgPtr
->hwndChild
;
598 if (hwnd
== hwndCtrl
) break;
599 wndPtr
= WIN_FindWndPtr( hwnd
);
600 if (wndPtr
->dwStyle
& WS_TABSTOP
)
603 if (!fPrevious
) break;
605 hwnd
= wndPtr
->hwndNext
;
612 /***********************************************************************
613 * GetNextDlgTabItem (USER.228)
615 HWND
GetNextDlgTabItem( HWND hwndDlg
, HWND hwndCtrl
, BOOL fPrevious
)
618 WND
* dlgPtr
, * ctrlPtr
, * wndPtr
;
620 if (!(dlgPtr
= WIN_FindWndPtr( hwndDlg
))) return 0;
621 if (!(ctrlPtr
= WIN_FindWndPtr( hwndCtrl
))) return 0;
622 if (ctrlPtr
->hwndParent
!= hwndDlg
) return 0;
625 hwnd
= ctrlPtr
->hwndNext
;
628 if (!hwnd
) hwnd
= dlgPtr
->hwndChild
;
629 if (hwnd
== hwndCtrl
) break;
630 wndPtr
= WIN_FindWndPtr( hwnd
);
631 if (wndPtr
->dwStyle
& WS_TABSTOP
)
634 if (!fPrevious
) break;
636 hwnd
= wndPtr
->hwndNext
;