Release 941122
[wine/multimedia.git] / windows / dialog.c
blobc5c10967234e0f543cc1a6f70885848b11f1d876
1 /*
2 * Dialog functions
4 * Copyright 1993, 1994 Alexandre Julliard
5 */
8 static char Copyright[] = "Copyright Alexandre Julliard, 1993, 1994";
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include "windows.h"
14 #include "dialog.h"
15 #include "win.h"
16 #include "user.h"
17 #include "message.h"
18 #include "heap.h"
19 #include "stddebug.h"
20 /* #define DEBUG_DIALOG */
21 /* #undef DEBUG_DIALOG */
22 #include "debug.h"
25 /* Dialog base units */
26 static WORD xBaseUnit = 0, yBaseUnit = 0;
29 /***********************************************************************
30 * DIALOG_Init
32 * Initialisation of the dialog manager.
34 BOOL DIALOG_Init()
36 TEXTMETRIC tm;
37 HDC hdc;
39 /* Calculate the dialog base units */
41 if (!(hdc = GetDC(GetDesktopWindow()))) return FALSE;
42 GetTextMetrics( hdc, &tm );
43 ReleaseDC( 0, hdc );
44 xBaseUnit = tm.tmAveCharWidth;
45 yBaseUnit = tm.tmHeight;
46 dprintf_dialog(stddeb, "DIALOG_Init: base units = %d,%d\n", xBaseUnit, yBaseUnit );
47 return TRUE;
51 /***********************************************************************
52 * DIALOG_GetFirstTabItem
54 * Return the first item of the dialog that has the WS_TABSTOP style.
56 HWND DIALOG_GetFirstTabItem( HWND hwndDlg )
58 HWND hwnd;
59 WND *wndPtr = WIN_FindWndPtr( hwndDlg );
60 hwnd = wndPtr->hwndChild;
61 while(hwnd)
63 wndPtr = WIN_FindWndPtr( hwnd );
64 if (wndPtr->dwStyle & WS_TABSTOP) break;
65 hwnd = wndPtr->hwndNext;
67 return hwnd;
71 /***********************************************************************
72 * DIALOG_GetControl
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 */
83 if (*p & 0x80)
85 switch(*p++)
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;
96 else
98 *class = p;
99 p += strlen(p) + 1;
101 if (*p == 0xff)
103 /* Integer id, not documented (?). Only works for SS_ICON controls */
104 *text = (char *)MAKEINTRESOURCE( p[1] + 256*p[2] );
105 p += 4;
107 else
109 *text = p;
110 p += strlen(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;
128 p += 13;
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;
136 p += strlen(p) + 1;
138 result->caption = p;
139 p += strlen(p) + 1;
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
154 #ifdef DEBUG_DIALOG
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] );
164 else
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 )
188 HWND hwnd = 0;
189 HANDLE hres, hmem;
190 LPCSTR data;
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) )))
197 return 0;
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 );
202 return hwnd;
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 )
222 HMENU hMenu;
223 HFONT hFont = 0;
224 HWND hwnd, hwndCtrl;
225 RECT rect;
226 WND * wndPtr;
227 int i;
228 DLGTEMPLATE template;
229 DLGCONTROLHEADER * header;
230 DIALOGINFO * dlgInfo;
231 DWORD exStyle = 0;
232 WORD xUnit = xBaseUnit;
233 WORD yUnit = yBaseUnit;
235 /* Parse dialog template */
237 if (!dlgTemplate) return 0;
238 header = DIALOG_ParseTemplate( dlgTemplate, &template );
239 #ifdef DEBUG_DIALOG
240 DIALOG_DisplayTemplate( &template );
241 #endif
243 /* Load menu */
245 switch (template.menuName[0])
247 case 0x00:
248 hMenu = 0;
249 break;
250 case 0xff:
251 hMenu = LoadMenu( hInst, MAKEINTRESOURCE( template.menuName[1] +
252 256*template.menuName[2] ));
253 break;
254 default:
255 hMenu = LoadMenu( hInst, template.menuName );
256 break;
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 );
268 if (hFont)
270 TEXTMETRIC tm;
271 HFONT oldFont;
272 HDC hdc;
274 hdc = GetDC(0);
275 oldFont = SelectObject( hdc, hFont );
276 GetTextMetrics( hdc, &tm );
277 SelectObject( hdc, oldFont );
278 ReleaseDC( 0, hdc );
279 xUnit = tm.tmAveCharWidth;
280 yUnit = tm.tmHeight;
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,
299 owner, hMenu, hInst,
300 NULL );
301 if (!hwnd)
303 if (hFont) DeleteObject( hFont );
304 if (hMenu) DestroyMenu( hMenu );
305 return 0;
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;
320 LPSTR class, text;
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);
327 else
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");
339 continue;
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 );
350 else
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. */
370 if (hwndDefButton)
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 );
396 return hwnd;
400 /***********************************************************************
401 * DIALOG_DoDialogBox
403 static int DIALOG_DoDialogBox( HWND hwnd, HWND owner )
405 WND * wndPtr;
406 DIALOGINFO * dlgInfo;
407 HANDLE msgHandle;
408 MSG* lpmsg;
409 int retval;
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 );
435 return retval;
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 )
455 HWND hwnd;
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 );
461 return -1;
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 )
491 HWND hwnd;
492 LPCSTR ptr;
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 );
498 return -1;
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)
508 HWND hwnd;
509 hwnd = CreateDialogIndirectParam( hInst, dlgTemplate, owner, dlgProc, param );
510 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
511 return -1;
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 )
533 WND * wndPtr;
534 int dlgCode;
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 );
548 return TRUE;
552 switch(msg->message)
554 case WM_KEYDOWN:
555 if (dlgCode & DLGC_WANTALLKEYS) break;
556 switch(msg->wParam)
558 case VK_TAB:
559 if (!(dlgCode & DLGC_WANTTAB))
561 SendMessage( hwndDlg, WM_NEXTDLGCTL,
562 (GetKeyState(VK_SHIFT) & 0x80), 0 );
563 return TRUE;
565 break;
567 case VK_RIGHT:
568 case VK_DOWN:
569 if (!(dlgCode & DLGC_WANTARROWS))
571 SetFocus(GetNextDlgGroupItem(hwndDlg,GetFocus(),FALSE));
572 return TRUE;
574 break;
576 case VK_LEFT:
577 case VK_UP:
578 if (!(dlgCode & DLGC_WANTARROWS))
580 SetFocus(GetNextDlgGroupItem(hwndDlg,GetFocus(),TRUE));
581 return TRUE;
583 break;
585 case VK_ESCAPE:
586 SendMessage( hwndDlg, WM_COMMAND, IDCANCEL,
587 MAKELPARAM( GetDlgItem(hwndDlg,IDCANCEL), 0 ));
588 break;
590 case VK_RETURN:
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) ),
596 BN_CLICKED ));
597 else
598 SendMessage( hwndDlg, WM_COMMAND, IDOK,
599 MAKELPARAM( GetDlgItem(hwndDlg,IDOK), 0 ));
601 break;
603 break; /* case WM_KEYDOWN */
606 case WM_CHAR:
607 if (dlgCode & (DLGC_WANTALLKEYS | DLGC_WANTCHARS)) break;
608 break;
610 case WM_SYSCHAR:
611 if (dlgCode & DLGC_WANTALLKEYS) break;
612 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 );
618 return TRUE;
622 /****************************************************************
623 * GetDlgCtrlID (USER.277)
625 int GetDlgCtrlID( HWND hwnd )
627 WND *wndPtr = WIN_FindWndPtr(hwnd);
628 if (wndPtr) return wndPtr->wIDmenu;
629 else return 0;
633 /***********************************************************************
634 * GetDlgItem (USER.91)
636 HWND GetDlgItem( HWND hwndDlg, WORD id )
638 HWND curChild;
639 WND * childPtr;
640 WND * wndPtr;
642 if (!(wndPtr = WIN_FindWndPtr( hwndDlg ))) return 0;
643 curChild = wndPtr->hwndChild;
644 while(curChild)
646 childPtr = WIN_FindWndPtr( curChild );
647 if (childPtr->wIDmenu == id) return curChild;
648 curChild = childPtr->hwndNext;
650 return 0;
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 );
661 else return 0;
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 )
703 int len;
704 HANDLE hText;
705 long result = 0;
706 char * str;
708 if (translated) *translated = FALSE;
709 if (!(len = SendDlgItemMessage( hwnd, id, WM_GETTEXTLENGTH, 0, 0 )))
710 return 0;
711 if (!(hText = USER_HEAP_ALLOC(0, len+1 )))
712 return 0;
713 str = (char *) USER_HEAP_ADDR( hText );
714 if (SendDlgItemMessage( hwnd, id, WM_GETTEXT, len+1, (DWORD)str ))
716 char * endptr;
717 result = strtol( str, &endptr, 10 );
718 if (endptr && (endptr != str)) /* Conversion was successful */
720 if (fSigned)
722 if ((result < -32767) || (result > 32767)) result = 0;
723 else if (translated) *translated = TRUE;
725 else
727 if ((result < 0) || (result > 65535)) result = 0;
728 else if (translated) *translated = TRUE;
732 USER_HEAP_FREE( hText );
733 return (WORD)result;
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 );
761 WND *wndPtr;
763 while (button)
765 if (!(wndPtr = WIN_FindWndPtr( button ))) return;
766 if ((wndPtr->wIDmenu == firstID) || (wndPtr->wIDmenu == lastID)) break;
767 button = wndPtr->hwndNext;
769 if (!button) return;
771 if (wndPtr->wIDmenu == lastID)
772 lastID = firstID; /* Buttons are in reverse order */
773 while (button)
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 );
799 if (!wndPtr) return;
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;
834 hwndCtrl = hwnd;
835 hwnd = wndPtr->hwndNext;
837 return hwndCtrl;
840 /* Now we will have to find the start of the group */
842 hwndStart = hwnd = dlgPtr->hwndChild;
843 while (hwnd)
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;
858 break;
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 )
871 HWND hwnd, hwndLast;
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;
878 hwndLast = hwndCtrl;
879 hwnd = ctrlPtr->hwndNext;
880 while (1)
882 if (!hwnd) hwnd = dlgPtr->hwndChild;
883 if (hwnd == hwndCtrl) break;
884 wndPtr = WIN_FindWndPtr( hwnd );
885 if (wndPtr->dwStyle & WS_TABSTOP)
887 hwndLast = hwnd;
888 if (!fPrevious) break;
890 hwnd = wndPtr->hwndNext;
892 return hwndLast;