Release 950918
[wine.git] / windows / dialog.c
blobb6a3d3183275299cb56a0057e31de1f512c22ada
1 /*
2 * Dialog functions
4 * Copyright 1993, 1994 Alexandre Julliard
6 static char Copyright[] = "Copyright Alexandre Julliard, 1993, 1994";
7 */
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include "windows.h"
13 #include "dialog.h"
14 #include "win.h"
15 #include "ldt.h"
16 #include "stackframe.h"
17 #include "user.h"
18 #include "message.h"
19 #include "stddebug.h"
20 /* #define DEBUG_DIALOG */
21 #include "debug.h"
23 /* Dialog base units */
24 static WORD xBaseUnit = 0, yBaseUnit = 0;
27 /***********************************************************************
28 * DIALOG_Init
30 * Initialisation of the dialog manager.
32 BOOL DIALOG_Init()
34 TEXTMETRIC tm;
35 HDC hdc;
37 /* Calculate the dialog base units */
39 if (!(hdc = GetDC( 0 ))) return FALSE;
40 GetTextMetrics( hdc, &tm );
41 ReleaseDC( 0, hdc );
42 xBaseUnit = tm.tmAveCharWidth;
43 yBaseUnit = tm.tmHeight;
45 /* Dialog units are based on a proportional system font */
46 /* so we adjust them a bit for a fixed font. */
47 if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH) xBaseUnit = xBaseUnit * 5 / 4;
49 dprintf_dialog( stddeb, "DIALOG_Init: base units = %d,%d\n",
50 xBaseUnit, yBaseUnit );
51 return TRUE;
55 /***********************************************************************
56 * DIALOG_GetFirstTabItem
58 * Return the first item of the dialog that has the WS_TABSTOP style.
60 HWND DIALOG_GetFirstTabItem( HWND hwndDlg )
62 HWND hwnd;
63 WND *wndPtr = WIN_FindWndPtr( hwndDlg );
64 hwnd = wndPtr->hwndChild;
65 while(hwnd)
67 wndPtr = WIN_FindWndPtr( hwnd );
68 if (wndPtr->dwStyle & WS_TABSTOP) break;
69 hwnd = wndPtr->hwndNext;
71 return hwnd;
75 /***********************************************************************
76 * DIALOG_GetControl
78 * Return the class and text of the control pointed to by ptr,
79 * and return a pointer to the next control.
81 static SEGPTR DIALOG_GetControl( SEGPTR ptr, SEGPTR *class, SEGPTR *text )
83 unsigned char *base = (unsigned char *)PTR_SEG_TO_LIN( ptr );
84 unsigned char *p = base;
86 p += 14; /* size of control header */
88 if (*p & 0x80)
90 *class = MAKEINTRESOURCE( *p );
91 p++;
93 else
95 *class = ptr + (WORD)(p - base);
96 p += strlen(p) + 1;
99 if (*p == 0xff)
101 /* Integer id, not documented (?). Only works for SS_ICON controls */
102 *text = MAKEINTRESOURCE( p[1] + 256 * p[2] );
103 p += 4;
105 else
107 *text = ptr + (WORD)(p - base);
108 p += strlen(p) + 2;
110 return ptr + (WORD)(p - base);
114 /***********************************************************************
115 * DIALOG_ParseTemplate
117 * Fill a DLGTEMPLATE structure from the dialog template, and return
118 * a pointer to the first control.
120 static SEGPTR DIALOG_ParseTemplate( SEGPTR template, DLGTEMPLATE * result )
122 unsigned char *base = (unsigned char *)PTR_SEG_TO_LIN(template);
123 unsigned char * p = base;
125 result->header = *(DLGTEMPLATEHEADER *)p;
126 p += 13;
128 /* Get the menu name */
130 if (*p == 0xff)
132 result->menuName = MAKEINTRESOURCE( p[1] + 256 * p[2] );
133 p += 3;
135 else if (*p)
137 result->menuName = template + (WORD)(p - base);
138 p += strlen(p) + 1;
140 else
142 result->menuName = 0;
143 p++;
146 /* Get the class name */
148 if (*p) result->className = template + (WORD)(p - base);
149 else result->className = DIALOG_CLASS_ATOM;
150 p += strlen(p) + 1;
152 /* Get the window caption */
154 result->caption = template + (WORD)(p - base);
155 p += strlen(p) + 1;
157 /* Get the font name */
159 if (result->header.style & DS_SETFONT)
161 result->pointSize = *(WORD *)p;
162 p += sizeof(WORD);
163 result->faceName = template + (WORD)(p - base);
164 p += strlen(p) + 1;
167 return template + (WORD)(p - base);
171 /***********************************************************************
172 * DIALOG_DisplayTemplate
174 static void DIALOG_DisplayTemplate( DLGTEMPLATE * result )
176 dprintf_dialog(stddeb, "DIALOG %d, %d, %d, %d\n", result->header.x, result->header.y,
177 result->header.cx, result->header.cy );
178 dprintf_dialog(stddeb, " STYLE %08lx\n", result->header.style );
179 dprintf_dialog( stddeb, " CAPTION '%s'\n",
180 (char *)PTR_SEG_TO_LIN(result->caption) );
182 if (HIWORD(result->className))
183 dprintf_dialog( stddeb, " CLASS '%s'\n",
184 (char *)PTR_SEG_TO_LIN(result->className) );
185 else
186 dprintf_dialog( stddeb, " CLASS #%d\n", LOWORD(result->className) );
188 if (HIWORD(result->menuName))
189 dprintf_dialog( stddeb, " MENU '%s'\n",
190 (char *)PTR_SEG_TO_LIN(result->menuName) );
191 else if (LOWORD(result->menuName))
192 dprintf_dialog(stddeb, " MENU %04x\n", LOWORD(result->menuName) );
194 if (result->header.style & DS_SETFONT)
195 dprintf_dialog( stddeb, " FONT %d,'%s'\n", result->pointSize,
196 (char *)PTR_SEG_TO_LIN(result->faceName) );
200 /***********************************************************************
201 * CreateDialog (USER.89)
203 HWND CreateDialog( HINSTANCE hInst, SEGPTR dlgTemplate,
204 HWND owner, WNDPROC dlgProc )
206 return CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, 0 );
210 /***********************************************************************
211 * CreateDialogParam (USER.241)
213 HWND CreateDialogParam( HINSTANCE hInst, SEGPTR dlgTemplate,
214 HWND owner, WNDPROC dlgProc, LPARAM param )
216 HWND hwnd = 0;
217 HRSRC hRsrc;
218 HGLOBAL hmem;
219 SEGPTR data;
221 dprintf_dialog(stddeb, "CreateDialogParam: %d,%08lx,%d,%08lx,%ld\n",
222 hInst, dlgTemplate, owner, (DWORD)dlgProc, param );
224 if (!(hRsrc = FindResource( hInst, dlgTemplate, RT_DIALOG ))) return 0;
225 if (!(hmem = LoadResource( hInst, hRsrc ))) return 0;
226 if (!(data = WIN16_LockResource( hmem ))) hwnd = 0;
227 else hwnd = CreateDialogIndirectParam(hInst, data, owner, dlgProc, param);
228 FreeResource( hmem );
229 return hwnd;
233 /***********************************************************************
234 * CreateDialogIndirect (USER.219)
236 HWND CreateDialogIndirect( HINSTANCE hInst, SEGPTR dlgTemplate,
237 HWND owner, WNDPROC dlgProc )
239 return CreateDialogIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 );
243 /***********************************************************************
244 * CreateDialogIndirectParam (USER.242)
246 HWND CreateDialogIndirectParam( HINSTANCE hInst, SEGPTR dlgTemplate,
247 HWND owner, WNDPROC dlgProc, LPARAM param )
249 HMENU hMenu = 0;
250 HFONT hFont = 0;
251 HWND hwnd, hwndCtrl;
252 RECT rect;
253 WND * wndPtr;
254 int i;
255 DLGTEMPLATE template;
256 SEGPTR headerPtr;
257 DIALOGINFO * dlgInfo;
258 DWORD exStyle = 0;
259 WORD xUnit = xBaseUnit;
260 WORD yUnit = yBaseUnit;
262 /* Parse dialog template */
264 if (!dlgTemplate) return 0;
265 headerPtr = DIALOG_ParseTemplate( dlgTemplate, &template );
266 if (debugging_dialog) DIALOG_DisplayTemplate( &template );
268 /* Load menu */
270 if (template.menuName) hMenu = LoadMenu( hInst, template.menuName );
272 /* Create custom font if needed */
274 if (template.header.style & DS_SETFONT)
276 /* The font height must be negative as it is a point size */
277 /* (see CreateFont() documentation in the Windows SDK). */
278 hFont = CreateFont( -template.pointSize, 0, 0, 0, FW_DONTCARE,
279 FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
280 DEFAULT_QUALITY, FF_DONTCARE,
281 (LPSTR)PTR_SEG_TO_LIN(template.faceName) );
282 if (hFont)
284 TEXTMETRIC tm;
285 HFONT oldFont;
286 HDC hdc;
288 hdc = GetDC(0);
289 oldFont = SelectObject( hdc, hFont );
290 GetTextMetrics( hdc, &tm );
291 SelectObject( hdc, oldFont );
292 ReleaseDC( 0, hdc );
293 xUnit = tm.tmAveCharWidth;
294 yUnit = tm.tmHeight;
295 if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH)
296 xBaseUnit = xBaseUnit * 5 / 4; /* See DIALOG_Init() */
300 /* Create dialog main window */
302 rect.left = rect.top = 0;
303 rect.right = template.header.cx * xUnit / 4;
304 rect.bottom = template.header.cy * yUnit / 8;
305 if (template.header.style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME;
306 AdjustWindowRectEx( &rect, template.header.style, hMenu, exStyle );
307 rect.right -= rect.left;
308 rect.bottom -= rect.top;
310 if ((INT)template.header.x == CW_USEDEFAULT)
311 rect.left = rect.top = CW_USEDEFAULT;
312 else
314 rect.left += template.header.x * xUnit / 4;
315 rect.top += template.header.y * yUnit / 8;
316 if (!(template.header.style & DS_ABSALIGN))
317 ClientToScreen( owner, (POINT *)&rect );
320 hwnd = CreateWindowEx( exStyle, template.className, template.caption,
321 template.header.style & ~WS_VISIBLE,
322 rect.left, rect.top, rect.right, rect.bottom,
323 owner, hMenu, hInst, (SEGPTR)0 );
324 if (!hwnd)
326 if (hFont) DeleteObject( hFont );
327 if (hMenu) DestroyMenu( hMenu );
328 return 0;
331 /* Create control windows */
333 dprintf_dialog(stddeb, " BEGIN\n" );
335 wndPtr = WIN_FindWndPtr( hwnd );
336 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
337 dlgInfo->msgResult = 0; /* This is used to store the default button id */
338 dlgInfo->hDialogHeap = 0;
340 for (i = 0; i < template.header.nbItems; i++)
342 DLGCONTROLHEADER *header;
343 SEGPTR className, winName;
344 HWND hwndDefButton = 0;
345 char buffer[10];
347 header = (DLGCONTROLHEADER *)PTR_SEG_TO_LIN( headerPtr );
348 headerPtr = DIALOG_GetControl( headerPtr, &className, &winName );
350 if (!HIWORD(className))
352 switch(LOWORD(className))
354 case 0x80: strcpy( buffer, "BUTTON" ); break;
355 case 0x81: strcpy( buffer, "EDIT" ); break;
356 case 0x82: strcpy( buffer, "STATIC" ); break;
357 case 0x83: strcpy( buffer, "LISTBOX" ); break;
358 case 0x84: strcpy( buffer, "SCROLLBAR" ); break;
359 case 0x85: strcpy( buffer, "COMBOBOX" ); break;
360 default: buffer[0] = '\0'; break;
362 className = MAKE_SEGPTR(buffer);
365 if (HIWORD(className))
366 dprintf_dialog(stddeb, " %s ", (char*)PTR_SEG_TO_LIN(className));
367 else dprintf_dialog(stddeb, " %04x ", LOWORD(className) );
368 if (HIWORD(winName))
369 dprintf_dialog(stddeb,"'%s'", (char *)PTR_SEG_TO_LIN(winName) );
370 else dprintf_dialog(stddeb,"%04x", LOWORD(winName) );
372 dprintf_dialog(stddeb," %d, %d, %d, %d, %d, %08lx\n",
373 header->id, header->x, header->y,
374 header->cx, header->cy, header->style );
376 if (HIWORD(className) &&
377 !strcmp( (char *)PTR_SEG_TO_LIN(className), "EDIT") &&
378 ((header->style & DS_LOCALEDIT) != DS_LOCALEDIT))
380 if (!dlgInfo->hDialogHeap)
382 dlgInfo->hDialogHeap = GlobalAlloc(GMEM_FIXED, 0x10000);
383 if (!dlgInfo->hDialogHeap)
385 fprintf(stderr,"CreateDialogIndirectParam: Insufficient memory to create heap for edit control\n");
386 continue;
388 LocalInit(dlgInfo->hDialogHeap, 0, 0xffff);
390 hwndCtrl = CreateWindowEx(WS_EX_NOPARENTNOTIFY, className, winName,
391 header->style | WS_CHILD,
392 header->x * xUnit / 4,
393 header->y * yUnit / 8,
394 header->cx * xUnit / 4,
395 header->cy * yUnit / 8,
396 hwnd, header->id, dlgInfo->hDialogHeap,
397 (SEGPTR)0 );
399 else
401 hwndCtrl = CreateWindowEx(WS_EX_NOPARENTNOTIFY, className, winName,
402 header->style | WS_CHILD,
403 header->x * xUnit / 4,
404 header->y * yUnit / 8,
405 header->cx * xUnit / 4,
406 header->cy * yUnit / 8,
407 hwnd, header->id, hInst, (SEGPTR)0 );
410 /* Make the control last one in Z-order, so that controls remain
411 in the order in which they were created */
412 SetWindowPos( hwndCtrl, HWND_BOTTOM, 0, 0, 0, 0,
413 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
415 /* Send initialisation messages to the control */
416 if (hFont) SendMessage( hwndCtrl, WM_SETFONT, hFont, 0 );
417 if (SendMessage( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
419 /* If there's already a default push-button, set it back */
420 /* to normal and use this one instead. */
421 if (hwndDefButton)
422 SendMessage( hwndDefButton, BM_SETSTYLE, BS_PUSHBUTTON, FALSE);
423 hwndDefButton = hwndCtrl;
424 dlgInfo->msgResult = GetWindowWord( hwndCtrl, GWW_ID );
428 dprintf_dialog(stddeb, " END\n" );
430 /* Initialise dialog extra data */
432 dlgInfo->dlgProc = dlgProc;
433 dlgInfo->hUserFont = hFont;
434 dlgInfo->hMenu = hMenu;
435 dlgInfo->xBaseUnit = xUnit;
436 dlgInfo->yBaseUnit = yUnit;
437 dlgInfo->hwndFocus = DIALOG_GetFirstTabItem( hwnd );
439 /* Send initialisation messages and set focus */
441 if (dlgInfo->hUserFont)
442 SendMessage( hwnd, WM_SETFONT, dlgInfo->hUserFont, 0 );
443 if (SendMessage( hwnd, WM_INITDIALOG, dlgInfo->hwndFocus, param ))
444 SetFocus( dlgInfo->hwndFocus );
445 if (template.header.style & WS_VISIBLE) ShowWindow(hwnd, SW_SHOW);
446 return hwnd;
450 /***********************************************************************
451 * DIALOG_DoDialogBox
453 static int DIALOG_DoDialogBox( HWND hwnd, HWND owner )
455 WND * wndPtr;
456 DIALOGINFO * dlgInfo;
457 HANDLE msgHandle;
458 MSG* lpmsg;
459 int retval;
461 /* Owner must be a top-level window */
462 owner = WIN_GetTopParent( owner );
463 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1;
464 if (!(msgHandle = USER_HEAP_ALLOC( sizeof(MSG) ))) return -1;
465 lpmsg = (MSG *) USER_HEAP_LIN_ADDR( msgHandle );
466 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
467 EnableWindow( owner, FALSE );
468 ShowWindow( hwnd, SW_SHOW );
470 while (MSG_InternalGetMessage( USER_HEAP_SEG_ADDR(msgHandle), hwnd, owner,
471 MSGF_DIALOGBOX, PM_REMOVE,
472 !(wndPtr->dwStyle & DS_NOIDLEMSG) ))
474 if (!IsDialogMessage( hwnd, lpmsg))
476 TranslateMessage( lpmsg );
477 DispatchMessage( lpmsg );
479 if (dlgInfo->fEnd) break;
481 retval = dlgInfo->msgResult;
482 DestroyWindow( hwnd );
483 USER_HEAP_FREE( msgHandle );
484 EnableWindow( owner, TRUE );
485 return retval;
489 /***********************************************************************
490 * DialogBox (USER.87)
492 int DialogBox( HINSTANCE hInst, SEGPTR dlgTemplate,
493 HWND owner, WNDPROC dlgProc )
495 return DialogBoxParam( hInst, dlgTemplate, owner, dlgProc, 0 );
499 /***********************************************************************
500 * DialogBoxParam (USER.239)
502 int DialogBoxParam( HINSTANCE hInst, SEGPTR dlgTemplate,
503 HWND owner, WNDPROC dlgProc, LPARAM param )
505 HWND hwnd;
507 dprintf_dialog(stddeb, "DialogBoxParam: %d,%08lx,%d,%08lx,%ld\n",
508 hInst, dlgTemplate, owner, (DWORD)dlgProc, param );
509 hwnd = CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, param );
510 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
511 return -1;
515 /***********************************************************************
516 * DialogBoxIndirect (USER.218)
518 int DialogBoxIndirect( HINSTANCE hInst, HANDLE dlgTemplate,
519 HWND owner, WNDPROC dlgProc )
521 return DialogBoxIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 );
525 /***********************************************************************
526 * DialogBoxIndirectParam (USER.240)
528 int DialogBoxIndirectParam( HINSTANCE hInst, HANDLE dlgTemplate,
529 HWND owner, WNDPROC dlgProc, LPARAM param )
531 HWND hwnd;
532 SEGPTR ptr;
534 if (!(ptr = WIN16_GlobalLock( dlgTemplate ))) return -1;
535 hwnd = CreateDialogIndirectParam( hInst, ptr, owner, dlgProc, param );
536 GlobalUnlock( dlgTemplate );
537 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
538 return -1;
542 /***********************************************************************
543 * EndDialog (USER.88)
545 void EndDialog( HWND hwnd, short retval )
547 WND * wndPtr = WIN_FindWndPtr( hwnd );
548 DIALOGINFO * dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
549 dlgInfo->msgResult = retval;
550 dlgInfo->fEnd = TRUE;
551 dprintf_dialog(stddeb, "EndDialog: %d %d\n", hwnd, retval );
555 /***********************************************************************
556 * IsDialogMessage (USER.90)
558 BOOL IsDialogMessage( HWND hwndDlg, LPMSG msg )
560 WND * wndPtr;
561 int dlgCode;
563 if (!(wndPtr = WIN_FindWndPtr( hwndDlg ))) return FALSE;
564 if ((hwndDlg != msg->hwnd) && !IsChild( hwndDlg, msg->hwnd )) return FALSE;
566 /* Only the key messages get special processing */
567 if ((msg->message != WM_KEYDOWN) &&
568 (msg->message != WM_SYSCHAR) &&
569 (msg->message != WM_CHAR))
570 return FALSE;
572 dlgCode = SendMessage( msg->hwnd, WM_GETDLGCODE, 0, 0 );
573 if (dlgCode & DLGC_WANTMESSAGE)
575 DispatchMessage( msg );
576 return TRUE;
579 switch(msg->message)
581 case WM_KEYDOWN:
582 if (dlgCode & DLGC_WANTALLKEYS) break;
583 switch(msg->wParam)
585 case VK_TAB:
586 if (!(dlgCode & DLGC_WANTTAB))
588 SendMessage( hwndDlg, WM_NEXTDLGCTL,
589 (GetKeyState(VK_SHIFT) & 0x80), 0 );
590 return TRUE;
592 break;
594 case VK_RIGHT:
595 case VK_DOWN:
596 if (!(dlgCode & DLGC_WANTARROWS))
598 SetFocus(GetNextDlgGroupItem(hwndDlg,GetFocus(),FALSE));
599 return TRUE;
601 break;
603 case VK_LEFT:
604 case VK_UP:
605 if (!(dlgCode & DLGC_WANTARROWS))
607 SetFocus(GetNextDlgGroupItem(hwndDlg,GetFocus(),TRUE));
608 return TRUE;
610 break;
612 case VK_ESCAPE:
613 SendMessage( hwndDlg, WM_COMMAND, IDCANCEL,
614 MAKELPARAM( GetDlgItem(hwndDlg,IDCANCEL), 0 ));
615 break;
617 case VK_RETURN:
619 DWORD dw = SendMessage( hwndDlg, DM_GETDEFID, 0, 0 );
620 if (HIWORD(dw) == DC_HASDEFID)
621 SendMessage( hwndDlg, WM_COMMAND, LOWORD(dw),
622 MAKELPARAM( GetDlgItem( hwndDlg, LOWORD(dw) ),
623 BN_CLICKED ));
624 else
625 SendMessage( hwndDlg, WM_COMMAND, IDOK,
626 MAKELPARAM( GetDlgItem(hwndDlg,IDOK), 0 ));
628 break;
630 break; /* case WM_KEYDOWN */
633 case WM_CHAR:
634 if (dlgCode & (DLGC_WANTALLKEYS | DLGC_WANTCHARS)) break;
635 break;
637 case WM_SYSCHAR:
638 if (dlgCode & DLGC_WANTALLKEYS) break;
639 break;
642 /* If we get here, the message has not been treated specially */
643 /* and can be sent to its destination window. */
644 DispatchMessage( msg );
645 return TRUE;
649 /****************************************************************
650 * GetDlgCtrlID (USER.277)
652 int GetDlgCtrlID( HWND hwnd )
654 WND *wndPtr = WIN_FindWndPtr(hwnd);
655 if (wndPtr) return wndPtr->wIDmenu;
656 else return 0;
660 /***********************************************************************
661 * GetDlgItem (USER.91)
663 HWND GetDlgItem( HWND hwndDlg, WORD id )
665 HWND curChild;
666 WND * childPtr;
667 WND * wndPtr;
669 if (!(wndPtr = WIN_FindWndPtr( hwndDlg ))) return 0;
670 curChild = wndPtr->hwndChild;
671 while(curChild)
673 childPtr = WIN_FindWndPtr( curChild );
674 if (childPtr->wIDmenu == id) return curChild;
675 curChild = childPtr->hwndNext;
677 return 0;
681 /*******************************************************************
682 * SendDlgItemMessage (USER.101)
684 LONG SendDlgItemMessage(HWND hwnd, WORD id, UINT msg, WORD wParam, LONG lParam)
686 HWND hwndCtrl = GetDlgItem( hwnd, id );
687 if (hwndCtrl) return SendMessage( hwndCtrl, msg, wParam, lParam );
688 else return 0;
692 /*******************************************************************
693 * SetDlgItemText (USER.92)
695 void SetDlgItemText( HWND hwnd, WORD id, SEGPTR lpString )
697 SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (DWORD)lpString );
701 /***********************************************************************
702 * GetDlgItemText (USER.93)
704 int GetDlgItemText( HWND hwnd, WORD id, SEGPTR str, WORD max )
706 return (int)SendDlgItemMessage( hwnd, id, WM_GETTEXT, max, (DWORD)str );
710 /*******************************************************************
711 * SetDlgItemInt (USER.94)
713 void SetDlgItemInt( HWND hwnd, WORD id, WORD value, BOOL fSigned )
715 char str[20];
717 if (fSigned) sprintf( str, "%d", (int)value );
718 else sprintf( str, "%u", value );
719 SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, MAKE_SEGPTR(str) );
723 /***********************************************************************
724 * GetDlgItemInt (USER.95)
726 WORD GetDlgItemInt( HWND hwnd, WORD id, BOOL * translated, BOOL fSigned )
728 char str[30];
729 long result = 0;
731 if (translated) *translated = FALSE;
732 if (SendDlgItemMessage( hwnd, id, WM_GETTEXT, 30, MAKE_SEGPTR(str) ))
734 char * endptr;
735 result = strtol( str, &endptr, 10 );
736 if (endptr && (endptr != str)) /* Conversion was successful */
738 if (fSigned)
740 if ((result < -32767) || (result > 32767)) result = 0;
741 else if (translated) *translated = TRUE;
743 else
745 if ((result < 0) || (result > 65535)) result = 0;
746 else if (translated) *translated = TRUE;
750 return (WORD)result;
754 /***********************************************************************
755 * CheckDlgButton (USER.97)
757 void CheckDlgButton( HWND hwnd, WORD id, WORD check )
759 SendDlgItemMessage( hwnd, id, BM_SETCHECK, check, 0 );
763 /***********************************************************************
764 * IsDlgButtonChecked (USER.98)
766 WORD IsDlgButtonChecked( HWND hwnd, WORD id )
768 return (WORD)SendDlgItemMessage( hwnd, id, BM_GETCHECK, 0, 0 );
772 /***********************************************************************
773 * CheckRadioButton (USER.96)
775 void CheckRadioButton( HWND hwndDlg, WORD firstID, WORD lastID, WORD checkID )
777 HWND button = GetWindow( hwndDlg, GW_CHILD );
778 WND *wndPtr;
780 while (button)
782 if (!(wndPtr = WIN_FindWndPtr( button ))) return;
783 if ((wndPtr->wIDmenu == firstID) || (wndPtr->wIDmenu == lastID)) break;
784 button = wndPtr->hwndNext;
786 if (!button) return;
788 if (wndPtr->wIDmenu == lastID)
789 lastID = firstID; /* Buttons are in reverse order */
790 while (button)
792 if (!(wndPtr = WIN_FindWndPtr( button ))) return;
793 SendMessage( button, BM_SETCHECK, (wndPtr->wIDmenu == checkID), 0 );
794 if (wndPtr->wIDmenu == lastID) break;
795 button = wndPtr->hwndNext;
800 /***********************************************************************
801 * GetDialogBaseUnits (USER.243)
803 DWORD GetDialogBaseUnits()
805 return MAKELONG( xBaseUnit, yBaseUnit );
809 /***********************************************************************
810 * MapDialogRect (USER.103)
812 void MapDialogRect( HWND hwnd, LPRECT rect )
814 DIALOGINFO * dlgInfo;
815 WND * wndPtr = WIN_FindWndPtr( hwnd );
816 if (!wndPtr) return;
817 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
818 rect->left = (rect->left * dlgInfo->xBaseUnit) / 4;
819 rect->right = (rect->right * dlgInfo->xBaseUnit) / 4;
820 rect->top = (rect->top * dlgInfo->yBaseUnit) / 8;
821 rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8;
825 /***********************************************************************
826 * GetNextDlgGroupItem (USER.227)
828 HWND GetNextDlgGroupItem( HWND hwndDlg, HWND hwndCtrl, BOOL fPrevious )
830 HWND hwnd, hwndStart;
831 WND * dlgPtr, * ctrlPtr, * wndPtr;
833 if (!(dlgPtr = WIN_FindWndPtr( hwndDlg ))) return 0;
834 if (!(ctrlPtr = WIN_FindWndPtr( hwndCtrl ))) return 0;
835 if (ctrlPtr->hwndParent != hwndDlg) return 0;
837 if (!fPrevious && ctrlPtr->hwndNext) /*Check if next control is in group*/
839 wndPtr = WIN_FindWndPtr( ctrlPtr->hwndNext );
840 if (!(wndPtr->dwStyle & WS_GROUP)) return ctrlPtr->hwndNext;
843 /* Now we will have to find the start of the group */
845 hwndStart = hwnd = dlgPtr->hwndChild;
846 while (hwnd)
848 wndPtr = WIN_FindWndPtr( hwnd );
849 if (wndPtr->dwStyle & WS_GROUP) hwndStart = hwnd; /*Start of a group*/
850 if (hwnd == hwndCtrl) break;
851 hwnd = wndPtr->hwndNext;
854 if (!hwnd) fprintf(stderr, "GetNextDlgGroupItem: hwnd not in dialog!\n");
856 /* only case left for forward search: wraparound */
857 if (!fPrevious) return hwndStart;
859 hwnd = hwndStart;
860 wndPtr = WIN_FindWndPtr( hwnd );
861 hwnd = wndPtr->hwndNext;
862 while (hwnd && (hwnd != hwndCtrl))
864 wndPtr = WIN_FindWndPtr( hwnd );
865 if (wndPtr->dwStyle & WS_GROUP) break;
866 hwndStart = hwnd;
867 hwnd = wndPtr->hwndNext;
869 return hwndStart;
873 /***********************************************************************
874 * GetNextDlgTabItem (USER.228)
876 HWND GetNextDlgTabItem( HWND hwndDlg, HWND hwndCtrl, BOOL fPrevious )
878 HWND hwnd, hwndLast;
879 WND * dlgPtr, * ctrlPtr, * wndPtr;
881 if (!(dlgPtr = WIN_FindWndPtr( hwndDlg ))) return 0;
882 if (!(ctrlPtr = WIN_FindWndPtr( hwndCtrl ))) return 0;
883 if (ctrlPtr->hwndParent != hwndDlg) return 0;
885 hwndLast = hwndCtrl;
886 hwnd = ctrlPtr->hwndNext;
887 while (1)
889 if (!hwnd) hwnd = dlgPtr->hwndChild;
890 if (hwnd == hwndCtrl) break;
891 wndPtr = WIN_FindWndPtr( hwnd );
892 if ((wndPtr->dwStyle & WS_TABSTOP) && (wndPtr->dwStyle & WS_VISIBLE))
894 hwndLast = hwnd;
895 if (!fPrevious) break;
897 hwnd = wndPtr->hwndNext;
899 return hwndLast;