blob: f8913b0bd867ab32a199341256e5945d8513d392 [file] [log] [blame]
Alexandre Julliard0e607781993-11-03 19:23:37 +00001/*
2 * Dialog functions
3 *
Alexandre Julliardaca05781994-10-17 18:12:41 +00004 * Copyright 1993, 1994 Alexandre Julliard
Alexandre Julliard234bc241994-12-10 13:02:28 +00005 *
Alexandre Julliard59730ae1996-03-24 16:20:51 +00006 */
Alexandre Julliard0e607781993-11-03 19:23:37 +00007
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00008#include <stdlib.h>
9#include <stdio.h>
10#include <string.h>
Alexandre Julliard0e607781993-11-03 19:23:37 +000011#include "windows.h"
12#include "dialog.h"
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +000013#include "heap.h"
Alexandre Julliard0e607781993-11-03 19:23:37 +000014#include "win.h"
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000015#include "ldt.h"
Alexandre Julliard2787be81995-05-22 18:23:01 +000016#include "stackframe.h"
Alexandre Julliarddba420a1994-02-02 06:48:31 +000017#include "user.h"
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +000018#include "message.h"
Alexandre Julliardaca05781994-10-17 18:12:41 +000019#include "stddebug.h"
Alexandre Julliard3a405ba1994-10-30 16:25:19 +000020/* #define DEBUG_DIALOG */
Alexandre Julliardaca05781994-10-17 18:12:41 +000021#include "debug.h"
Alexandre Julliard0e607781993-11-03 19:23:37 +000022
Alexandre Julliard0e607781993-11-03 19:23:37 +000023 /* Dialog base units */
Alexandre Julliard0c126c71996-02-18 18:44:41 +000024WORD xBaseUnit = 0, yBaseUnit = 0;
Alexandre Julliard0e607781993-11-03 19:23:37 +000025
26
27/***********************************************************************
28 * DIALOG_Init
29 *
30 * Initialisation of the dialog manager.
31 */
32BOOL DIALOG_Init()
33{
34 TEXTMETRIC tm;
35 HDC hdc;
36
37 /* Calculate the dialog base units */
38
Alexandre Julliard7cbe6571995-01-09 18:21:16 +000039 if (!(hdc = GetDC( 0 ))) return FALSE;
Alexandre Julliard0e607781993-11-03 19:23:37 +000040 GetTextMetrics( hdc, &tm );
41 ReleaseDC( 0, hdc );
42 xBaseUnit = tm.tmAveCharWidth;
43 yBaseUnit = tm.tmHeight;
Alexandre Julliard7cbe6571995-01-09 18:21:16 +000044
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;
48
49 dprintf_dialog( stddeb, "DIALOG_Init: base units = %d,%d\n",
50 xBaseUnit, yBaseUnit );
Alexandre Julliard0e607781993-11-03 19:23:37 +000051 return TRUE;
52}
53
54
55/***********************************************************************
Alexandre Julliardaca05781994-10-17 18:12:41 +000056 * DIALOG_GetFirstTabItem
57 *
58 * Return the first item of the dialog that has the WS_TABSTOP style.
59 */
60HWND DIALOG_GetFirstTabItem( HWND hwndDlg )
61{
Alexandre Julliard59730ae1996-03-24 16:20:51 +000062 WND *pWnd = WIN_FindWndPtr( hwndDlg );
63 for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
64 if (pWnd->dwStyle & WS_TABSTOP) return pWnd->hwndSelf;
65 return 0;
Alexandre Julliardaca05781994-10-17 18:12:41 +000066}
67
68
69/***********************************************************************
Alexandre Julliard0e607781993-11-03 19:23:37 +000070 * DIALOG_GetControl
71 *
72 * Return the class and text of the control pointed to by ptr,
Alexandre Julliard329f0681996-04-14 13:21:20 +000073 * fill the header structure and return a pointer to the next control.
Alexandre Julliard0e607781993-11-03 19:23:37 +000074 */
Alexandre Julliard329f0681996-04-14 13:21:20 +000075static SEGPTR DIALOG_GetControl( SEGPTR ptr, DLGCONTROLHEADER *header,
76 SEGPTR *class, SEGPTR *text )
Alexandre Julliard0e607781993-11-03 19:23:37 +000077{
Alexandre Julliardff8331e1995-09-18 11:19:54 +000078 unsigned char *base = (unsigned char *)PTR_SEG_TO_LIN( ptr );
79 unsigned char *p = base;
80
Alexandre Julliard329f0681996-04-14 13:21:20 +000081 header->x = GET_WORD(p); p += sizeof(WORD);
82 header->y = GET_WORD(p); p += sizeof(WORD);
83 header->cx = GET_WORD(p); p += sizeof(WORD);
84 header->cy = GET_WORD(p); p += sizeof(WORD);
85 header->id = GET_WORD(p); p += sizeof(WORD);
86 header->style = GET_DWORD(p); p += sizeof(DWORD);
Alexandre Julliard7e50df31994-08-06 11:22:41 +000087
Alexandre Julliard0e607781993-11-03 19:23:37 +000088 if (*p & 0x80)
89 {
Alexandre Julliardff8331e1995-09-18 11:19:54 +000090 *class = MAKEINTRESOURCE( *p );
91 p++;
Alexandre Julliard0e607781993-11-03 19:23:37 +000092 }
93 else
94 {
Alexandre Julliardff8331e1995-09-18 11:19:54 +000095 *class = ptr + (WORD)(p - base);
Alexandre Julliard0e607781993-11-03 19:23:37 +000096 p += strlen(p) + 1;
97 }
Alexandre Julliardff8331e1995-09-18 11:19:54 +000098
Alexandre Julliard940d58c1994-09-16 09:24:37 +000099 if (*p == 0xff)
100 {
101 /* Integer id, not documented (?). Only works for SS_ICON controls */
Alexandre Julliard329f0681996-04-14 13:21:20 +0000102 *text = MAKEINTRESOURCE( GET_WORD(p+1) );
Alexandre Julliard7e50df31994-08-06 11:22:41 +0000103 p += 4;
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000104 }
105 else
106 {
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000107 *text = ptr + (WORD)(p - base);
Alexandre Julliard7e50df31994-08-06 11:22:41 +0000108 p += strlen(p) + 2;
109 }
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000110 return ptr + (WORD)(p - base);
Alexandre Julliard0e607781993-11-03 19:23:37 +0000111}
112
113
114/***********************************************************************
115 * DIALOG_ParseTemplate
116 *
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000117 * Fill a DLGTEMPLATE structure from the dialog template, and return
118 * a pointer to the first control.
Alexandre Julliard0e607781993-11-03 19:23:37 +0000119 */
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000120static SEGPTR DIALOG_ParseTemplate( SEGPTR template, DLGTEMPLATE * result )
Alexandre Julliard0e607781993-11-03 19:23:37 +0000121{
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000122 unsigned char *base = (unsigned char *)PTR_SEG_TO_LIN(template);
123 unsigned char * p = base;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000124
Alexandre Julliard329f0681996-04-14 13:21:20 +0000125 result->style = GET_DWORD(p); p += sizeof(DWORD);
126 result->nbItems = *p++;
127 result->x = GET_WORD(p); p += sizeof(WORD);
128 result->y = GET_WORD(p); p += sizeof(WORD);
129 result->cx = GET_WORD(p); p += sizeof(WORD);
130 result->cy = GET_WORD(p); p += sizeof(WORD);
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000131
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000132 /* Get the menu name */
Alexandre Julliard0e607781993-11-03 19:23:37 +0000133
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000134 if (*p == 0xff)
Alexandre Julliard0e607781993-11-03 19:23:37 +0000135 {
Alexandre Julliard329f0681996-04-14 13:21:20 +0000136 result->menuName = MAKEINTRESOURCE( GET_WORD(p+1) );
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000137 p += 3;
138 }
139 else if (*p)
140 {
141 result->menuName = template + (WORD)(p - base);
142 p += strlen(p) + 1;
143 }
144 else
145 {
146 result->menuName = 0;
147 p++;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000148 }
Alexandre Julliard0e607781993-11-03 19:23:37 +0000149
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000150 /* Get the class name */
151
152 if (*p) result->className = template + (WORD)(p - base);
153 else result->className = DIALOG_CLASS_ATOM;
154 p += strlen(p) + 1;
155
156 /* Get the window caption */
157
158 result->caption = template + (WORD)(p - base);
159 p += strlen(p) + 1;
160
161 /* Get the font name */
162
Alexandre Julliard329f0681996-04-14 13:21:20 +0000163 if (result->style & DS_SETFONT)
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000164 {
Alexandre Julliard329f0681996-04-14 13:21:20 +0000165 result->pointSize = GET_WORD(p);
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000166 p += sizeof(WORD);
167 result->faceName = template + (WORD)(p - base);
168 p += strlen(p) + 1;
169 }
170
171 return template + (WORD)(p - base);
Alexandre Julliard0e607781993-11-03 19:23:37 +0000172}
173
174
175/***********************************************************************
176 * DIALOG_DisplayTemplate
177 */
Alexandre Julliard0e607781993-11-03 19:23:37 +0000178static void DIALOG_DisplayTemplate( DLGTEMPLATE * result )
179{
Alexandre Julliard329f0681996-04-14 13:21:20 +0000180 dprintf_dialog(stddeb, "DIALOG %d, %d, %d, %d\n", result->x, result->y,
181 result->cx, result->cy );
182 dprintf_dialog(stddeb, " STYLE %08lx\n", result->style );
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000183 dprintf_dialog( stddeb, " CAPTION '%s'\n",
184 (char *)PTR_SEG_TO_LIN(result->caption) );
185
186 if (HIWORD(result->className))
187 dprintf_dialog( stddeb, " CLASS '%s'\n",
188 (char *)PTR_SEG_TO_LIN(result->className) );
189 else
190 dprintf_dialog( stddeb, " CLASS #%d\n", LOWORD(result->className) );
191
192 if (HIWORD(result->menuName))
193 dprintf_dialog( stddeb, " MENU '%s'\n",
194 (char *)PTR_SEG_TO_LIN(result->menuName) );
195 else if (LOWORD(result->menuName))
196 dprintf_dialog(stddeb, " MENU %04x\n", LOWORD(result->menuName) );
197
Alexandre Julliard329f0681996-04-14 13:21:20 +0000198 if (result->style & DS_SETFONT)
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000199 dprintf_dialog( stddeb, " FONT %d,'%s'\n", result->pointSize,
200 (char *)PTR_SEG_TO_LIN(result->faceName) );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000201}
Alexandre Julliard0e607781993-11-03 19:23:37 +0000202
203
204/***********************************************************************
205 * CreateDialog (USER.89)
206 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000207HWND CreateDialog( HINSTANCE hInst, SEGPTR dlgTemplate,
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000208 HWND owner, DLGPROC dlgProc )
Alexandre Julliard0e607781993-11-03 19:23:37 +0000209{
210 return CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, 0 );
211}
212
213
214/***********************************************************************
215 * CreateDialogParam (USER.241)
216 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000217HWND CreateDialogParam( HINSTANCE hInst, SEGPTR dlgTemplate,
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000218 HWND owner, DLGPROC dlgProc, LPARAM param )
Alexandre Julliard0e607781993-11-03 19:23:37 +0000219{
220 HWND hwnd = 0;
Alexandre Julliard594997c1995-04-30 10:05:20 +0000221 HRSRC hRsrc;
222 HGLOBAL hmem;
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000223 SEGPTR data;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000224
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000225 dprintf_dialog(stddeb, "CreateDialogParam: %04x,%08lx,%04x,%08lx,%ld\n",
226 hInst, (DWORD)dlgTemplate, owner, (DWORD)dlgProc, param );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000227
Alexandre Julliard594997c1995-04-30 10:05:20 +0000228 if (!(hRsrc = FindResource( hInst, dlgTemplate, RT_DIALOG ))) return 0;
229 if (!(hmem = LoadResource( hInst, hRsrc ))) return 0;
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000230 if (!(data = WIN16_LockResource( hmem ))) hwnd = 0;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000231 else hwnd = CreateDialogIndirectParam(hInst, data, owner, dlgProc, param);
232 FreeResource( hmem );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000233 return hwnd;
234}
235
236
237/***********************************************************************
238 * CreateDialogIndirect (USER.219)
239 */
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000240HWND CreateDialogIndirect( HINSTANCE hInst, SEGPTR dlgTemplate,
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000241 HWND owner, DLGPROC dlgProc )
Alexandre Julliard0e607781993-11-03 19:23:37 +0000242{
243 return CreateDialogIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 );
244}
245
246
247/***********************************************************************
248 * CreateDialogIndirectParam (USER.242)
249 */
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000250HWND CreateDialogIndirectParam( HINSTANCE hInst, SEGPTR dlgTemplate,
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000251 HWND owner, DLGPROC dlgProc, LPARAM param )
Alexandre Julliard0e607781993-11-03 19:23:37 +0000252{
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000253 HMENU hMenu = 0;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000254 HFONT hFont = 0;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000255 HWND hwnd, hwndCtrl;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000256 RECT16 rect;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000257 WND * wndPtr;
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000258 int i;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000259 DLGTEMPLATE template;
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000260 SEGPTR headerPtr;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000261 DIALOGINFO * dlgInfo;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000262 DWORD exStyle = 0;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000263 WORD xUnit = xBaseUnit;
264 WORD yUnit = yBaseUnit;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000265
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000266 /* Parse dialog template */
267
268 if (!dlgTemplate) return 0;
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000269 headerPtr = DIALOG_ParseTemplate( dlgTemplate, &template );
270 if (debugging_dialog) DIALOG_DisplayTemplate( &template );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000271
272 /* Load menu */
273
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000274 if (template.menuName) hMenu = LoadMenu( hInst, template.menuName );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000275
276 /* Create custom font if needed */
277
Alexandre Julliard329f0681996-04-14 13:21:20 +0000278 if (template.style & DS_SETFONT)
Alexandre Julliard0e607781993-11-03 19:23:37 +0000279 {
Alexandre Julliard3ed37e01994-11-07 18:20:42 +0000280 /* The font height must be negative as it is a point size */
281 /* (see CreateFont() documentation in the Windows SDK). */
282 hFont = CreateFont( -template.pointSize, 0, 0, 0, FW_DONTCARE,
Alexandre Julliard0e607781993-11-03 19:23:37 +0000283 FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000284 DEFAULT_QUALITY, FF_DONTCARE,
285 (LPSTR)PTR_SEG_TO_LIN(template.faceName) );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000286 if (hFont)
287 {
288 TEXTMETRIC tm;
289 HFONT oldFont;
290 HDC hdc;
291
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000292 hdc = GetDC(0);
Alexandre Julliard0e607781993-11-03 19:23:37 +0000293 oldFont = SelectObject( hdc, hFont );
294 GetTextMetrics( hdc, &tm );
295 SelectObject( hdc, oldFont );
296 ReleaseDC( 0, hdc );
297 xUnit = tm.tmAveCharWidth;
298 yUnit = tm.tmHeight;
Alexandre Julliard7cbe6571995-01-09 18:21:16 +0000299 if (tm.tmPitchAndFamily & TMPF_FIXED_PITCH)
300 xBaseUnit = xBaseUnit * 5 / 4; /* See DIALOG_Init() */
Alexandre Julliard0e607781993-11-03 19:23:37 +0000301 }
302 }
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000303
Alexandre Julliard0e607781993-11-03 19:23:37 +0000304 /* Create dialog main window */
305
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000306 rect.left = rect.top = 0;
Alexandre Julliard329f0681996-04-14 13:21:20 +0000307 rect.right = template.cx * xUnit / 4;
308 rect.bottom = template.cy * yUnit / 8;
309 if (template.style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000310 AdjustWindowRectEx16( &rect, template.style,
311 hMenu ? TRUE : FALSE , exStyle );
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000312 rect.right -= rect.left;
313 rect.bottom -= rect.top;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000314
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000315 if ((INT16)template.x == CW_USEDEFAULT16)
316 rect.left = rect.top = CW_USEDEFAULT16;
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000317 else
318 {
Alexandre Julliard329f0681996-04-14 13:21:20 +0000319 rect.left += template.x * xUnit / 4;
320 rect.top += template.y * yUnit / 8;
321 if (!(template.style & DS_ABSALIGN))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000322 ClientToScreen16( owner, (POINT16 *)&rect );
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000323 }
324
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000325 hwnd = CreateWindowEx16( exStyle, template.className, template.caption,
Alexandre Julliard329f0681996-04-14 13:21:20 +0000326 template.style & ~WS_VISIBLE,
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000327 rect.left, rect.top, rect.right, rect.bottom,
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000328 owner, hMenu, hInst, (SEGPTR)0 );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000329 if (!hwnd)
330 {
331 if (hFont) DeleteObject( hFont );
332 if (hMenu) DestroyMenu( hMenu );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000333 return 0;
334 }
Alexandre Julliard902da691995-11-05 14:39:02 +0000335 wndPtr = WIN_FindWndPtr( hwnd );
336
Alexandre Julliard0e607781993-11-03 19:23:37 +0000337 /* Create control windows */
338
Alexandre Julliardaca05781994-10-17 18:12:41 +0000339 dprintf_dialog(stddeb, " BEGIN\n" );
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000340
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000341 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000342 dlgInfo->msgResult = 0; /* This is used to store the default button id */
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000343 dlgInfo->hDialogHeap = 0;
344
Alexandre Julliard329f0681996-04-14 13:21:20 +0000345 for (i = 0; i < template.nbItems; i++)
Alexandre Julliard0e607781993-11-03 19:23:37 +0000346 {
Alexandre Julliard329f0681996-04-14 13:21:20 +0000347 DLGCONTROLHEADER header;
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000348 SEGPTR className, winName;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000349 HWND hwndDefButton = 0;
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000350 char buffer[10];
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000351
Alexandre Julliard329f0681996-04-14 13:21:20 +0000352 headerPtr = DIALOG_GetControl( headerPtr, &header,
353 &className, &winName );
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000354
355 if (!HIWORD(className))
356 {
357 switch(LOWORD(className))
358 {
359 case 0x80: strcpy( buffer, "BUTTON" ); break;
360 case 0x81: strcpy( buffer, "EDIT" ); break;
361 case 0x82: strcpy( buffer, "STATIC" ); break;
362 case 0x83: strcpy( buffer, "LISTBOX" ); break;
363 case 0x84: strcpy( buffer, "SCROLLBAR" ); break;
364 case 0x85: strcpy( buffer, "COMBOBOX" ); break;
365 default: buffer[0] = '\0'; break;
366 }
367 className = MAKE_SEGPTR(buffer);
368 }
369
370 if (HIWORD(className))
371 dprintf_dialog(stddeb, " %s ", (char*)PTR_SEG_TO_LIN(className));
372 else dprintf_dialog(stddeb, " %04x ", LOWORD(className) );
373 if (HIWORD(winName))
374 dprintf_dialog(stddeb,"'%s'", (char *)PTR_SEG_TO_LIN(winName) );
375 else dprintf_dialog(stddeb,"%04x", LOWORD(winName) );
376
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000377 dprintf_dialog(stddeb," %d, %d, %d, %d, %d, %08lx\n",
Alexandre Julliard329f0681996-04-14 13:21:20 +0000378 header.id, header.x, header.y,
379 header.cx, header.cy, header.style );
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000380
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000381 if (HIWORD(className) &&
382 !strcmp( (char *)PTR_SEG_TO_LIN(className), "EDIT") &&
Alexandre Julliard329f0681996-04-14 13:21:20 +0000383 ((header.style & DS_LOCALEDIT) != DS_LOCALEDIT))
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000384 {
385 if (!dlgInfo->hDialogHeap)
386 {
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000387 dlgInfo->hDialogHeap = GlobalAlloc16(GMEM_FIXED, 0x10000);
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000388 if (!dlgInfo->hDialogHeap)
389 {
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000390 fprintf(stderr,"CreateDialogIndirectParam: Insufficient memory to create heap for edit control\n");
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000391 continue;
392 }
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000393 LocalInit(dlgInfo->hDialogHeap, 0, 0xffff);
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000394 }
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000395 hwndCtrl = CreateWindowEx16(WS_EX_NOPARENTNOTIFY, className, winName,
Alexandre Julliard329f0681996-04-14 13:21:20 +0000396 header.style | WS_CHILD,
397 header.x * xUnit / 4,
398 header.y * yUnit / 8,
399 header.cx * xUnit / 4,
400 header.cy * yUnit / 8,
401 hwnd, (HMENU)header.id,
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000402 dlgInfo->hDialogHeap, (SEGPTR)0 );
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000403 }
Alexandre Julliardaca05781994-10-17 18:12:41 +0000404 else
405 {
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000406 hwndCtrl = CreateWindowEx16( WS_EX_NOPARENTNOTIFY, className,
407 winName,
408 header.style | WS_CHILD,
409 header.x * xUnit / 4,
410 header.y * yUnit / 8,
411 header.cx * xUnit / 4,
412 header.cy * yUnit / 8,
413 hwnd, (HMENU)header.id,
414 hInst, (SEGPTR)0 );
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000415 }
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000416
Alexandre Julliardecc37121994-11-22 16:31:29 +0000417 /* Make the control last one in Z-order, so that controls remain
418 in the order in which they were created */
419 SetWindowPos( hwndCtrl, HWND_BOTTOM, 0, 0, 0, 0,
420 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
421
Alexandre Julliardaca05781994-10-17 18:12:41 +0000422 /* Send initialisation messages to the control */
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000423 if (hFont) SendMessage( hwndCtrl, WM_SETFONT, (WPARAM)hFont, 0 );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000424 if (SendMessage( hwndCtrl, WM_GETDLGCODE, 0, 0 ) & DLGC_DEFPUSHBUTTON)
425 {
426 /* If there's already a default push-button, set it back */
427 /* to normal and use this one instead. */
428 if (hwndDefButton)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000429 SendMessage(hwndDefButton, BM_SETSTYLE16, BS_PUSHBUTTON,FALSE);
Alexandre Julliardaca05781994-10-17 18:12:41 +0000430 hwndDefButton = hwndCtrl;
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000431 dlgInfo->msgResult = GetWindowWord( hwndCtrl, GWW_ID );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000432 }
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000433 }
434
Alexandre Julliardaca05781994-10-17 18:12:41 +0000435 dprintf_dialog(stddeb, " END\n" );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000436
437 /* Initialise dialog extra data */
438
Alexandre Julliard0e607781993-11-03 19:23:37 +0000439 dlgInfo->dlgProc = dlgProc;
440 dlgInfo->hUserFont = hFont;
441 dlgInfo->hMenu = hMenu;
442 dlgInfo->xBaseUnit = xUnit;
443 dlgInfo->yBaseUnit = yUnit;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000444 dlgInfo->hwndFocus = DIALOG_GetFirstTabItem( hwnd );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000445
446 /* Send initialisation messages and set focus */
447
Alexandre Julliard58199531994-04-21 01:20:00 +0000448 if (dlgInfo->hUserFont)
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000449 SendMessage( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 );
450 if (SendMessage( hwnd, WM_INITDIALOG, (WPARAM)dlgInfo->hwndFocus, param ))
Alexandre Julliard58199531994-04-21 01:20:00 +0000451 SetFocus( dlgInfo->hwndFocus );
Alexandre Julliard329f0681996-04-14 13:21:20 +0000452 if (template.style & WS_VISIBLE) ShowWindow(hwnd, SW_SHOW);
Alexandre Julliard0e607781993-11-03 19:23:37 +0000453 return hwnd;
454}
455
456
457/***********************************************************************
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000458 * DIALOG_DoDialogBox
Alexandre Julliard0e607781993-11-03 19:23:37 +0000459 */
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000460int DIALOG_DoDialogBox( HWND hwnd, HWND owner )
Alexandre Julliard0e607781993-11-03 19:23:37 +0000461{
Alexandre Julliard0e607781993-11-03 19:23:37 +0000462 WND * wndPtr;
463 DIALOGINFO * dlgInfo;
Alexandre Julliard58199531994-04-21 01:20:00 +0000464 HANDLE msgHandle;
465 MSG* lpmsg;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000466 int retval;
467
Alexandre Julliardaca05781994-10-17 18:12:41 +0000468 /* Owner must be a top-level window */
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000469 owner = WIN_GetTopParent( owner );
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000470 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000471 if (!(msgHandle = USER_HEAP_ALLOC( sizeof(MSG) ))) return -1;
472 lpmsg = (MSG *) USER_HEAP_LIN_ADDR( msgHandle );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000473 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000474 EnableWindow( owner, FALSE );
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000475 ShowWindow( hwnd, SW_SHOW );
476
Alexandre Julliard902da691995-11-05 14:39:02 +0000477 while (MSG_InternalGetMessage( (SEGPTR)USER_HEAP_SEG_ADDR(msgHandle), hwnd, owner,
Alexandre Julliardaca05781994-10-17 18:12:41 +0000478 MSGF_DIALOGBOX, PM_REMOVE,
479 !(wndPtr->dwStyle & DS_NOIDLEMSG) ))
Alexandre Julliard0e607781993-11-03 19:23:37 +0000480 {
Alexandre Julliard58199531994-04-21 01:20:00 +0000481 if (!IsDialogMessage( hwnd, lpmsg))
Alexandre Julliard0e607781993-11-03 19:23:37 +0000482 {
Alexandre Julliard58199531994-04-21 01:20:00 +0000483 TranslateMessage( lpmsg );
484 DispatchMessage( lpmsg );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000485 }
486 if (dlgInfo->fEnd) break;
487 }
488 retval = dlgInfo->msgResult;
489 DestroyWindow( hwnd );
Alexandre Julliard58199531994-04-21 01:20:00 +0000490 USER_HEAP_FREE( msgHandle );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000491 EnableWindow( owner, TRUE );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000492 return retval;
493}
494
495
496/***********************************************************************
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000497 * DialogBox (USER.87)
498 */
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000499INT DialogBox( HINSTANCE hInst, SEGPTR dlgTemplate,
500 HWND owner, DLGPROC dlgProc )
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000501{
502 return DialogBoxParam( hInst, dlgTemplate, owner, dlgProc, 0 );
503}
504
505
506/***********************************************************************
507 * DialogBoxParam (USER.239)
508 */
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000509INT DialogBoxParam( HINSTANCE hInst, SEGPTR dlgTemplate,
510 HWND owner, DLGPROC dlgProc, LPARAM param )
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000511{
512 HWND hwnd;
513
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000514 dprintf_dialog(stddeb, "DialogBoxParam: %04x,%08lx,%04x,%08lx,%ld\n",
515 hInst, (DWORD)dlgTemplate, owner, (DWORD)dlgProc, param );
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000516 hwnd = CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, param );
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000517 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000518 return -1;
519}
520
521
522/***********************************************************************
523 * DialogBoxIndirect (USER.218)
524 */
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000525INT DialogBoxIndirect( HINSTANCE hInst, HANDLE dlgTemplate,
526 HWND owner, DLGPROC dlgProc )
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000527{
528 return DialogBoxIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 );
529}
530
531
532/***********************************************************************
533 * DialogBoxIndirectParam (USER.240)
534 */
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000535INT DialogBoxIndirectParam( HINSTANCE hInst, HANDLE dlgTemplate,
536 HWND owner, DLGPROC dlgProc, LPARAM param )
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000537{
538 HWND hwnd;
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000539 SEGPTR ptr;
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000540
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000541 if (!(ptr = (SEGPTR)WIN16_GlobalLock16( dlgTemplate ))) return -1;
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000542 hwnd = CreateDialogIndirectParam( hInst, ptr, owner, dlgProc, param );
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000543 GlobalUnlock16( dlgTemplate );
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000544 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000545 return -1;
546}
547
Alexandre Julliard7cbe6571995-01-09 18:21:16 +0000548
Alexandre Julliard3ed37e01994-11-07 18:20:42 +0000549/***********************************************************************
Alexandre Julliard0e607781993-11-03 19:23:37 +0000550 * EndDialog (USER.88)
551 */
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000552BOOL EndDialog( HWND hwnd, INT retval )
Alexandre Julliard0e607781993-11-03 19:23:37 +0000553{
554 WND * wndPtr = WIN_FindWndPtr( hwnd );
555 DIALOGINFO * dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
556 dlgInfo->msgResult = retval;
557 dlgInfo->fEnd = TRUE;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000558 dprintf_dialog(stddeb, "EndDialog: %04x %d\n", hwnd, retval );
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000559 return TRUE;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000560}
561
562
563/***********************************************************************
564 * IsDialogMessage (USER.90)
565 */
566BOOL IsDialogMessage( HWND hwndDlg, LPMSG msg )
567{
568 WND * wndPtr;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000569 int dlgCode;
570
Alexandre Julliard0e607781993-11-03 19:23:37 +0000571 if (!(wndPtr = WIN_FindWndPtr( hwndDlg ))) return FALSE;
572 if ((hwndDlg != msg->hwnd) && !IsChild( hwndDlg, msg->hwnd )) return FALSE;
573
Alexandre Julliardaca05781994-10-17 18:12:41 +0000574 /* Only the key messages get special processing */
Alexandre Julliard7cbe6571995-01-09 18:21:16 +0000575 if ((msg->message != WM_KEYDOWN) &&
576 (msg->message != WM_SYSCHAR) &&
577 (msg->message != WM_CHAR))
578 return FALSE;
579
580 dlgCode = SendMessage( msg->hwnd, WM_GETDLGCODE, 0, 0 );
581 if (dlgCode & DLGC_WANTMESSAGE)
Alexandre Julliard0e607781993-11-03 19:23:37 +0000582 {
Alexandre Julliard7cbe6571995-01-09 18:21:16 +0000583 DispatchMessage( msg );
584 return TRUE;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000585 }
Alexandre Julliardaca05781994-10-17 18:12:41 +0000586
587 switch(msg->message)
Alexandre Julliard0e607781993-11-03 19:23:37 +0000588 {
Alexandre Julliardaca05781994-10-17 18:12:41 +0000589 case WM_KEYDOWN:
590 if (dlgCode & DLGC_WANTALLKEYS) break;
591 switch(msg->wParam)
592 {
593 case VK_TAB:
594 if (!(dlgCode & DLGC_WANTTAB))
595 {
596 SendMessage( hwndDlg, WM_NEXTDLGCTL,
Alexandre Julliardecc37121994-11-22 16:31:29 +0000597 (GetKeyState(VK_SHIFT) & 0x80), 0 );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000598 return TRUE;
599 }
600 break;
601
602 case VK_RIGHT:
603 case VK_DOWN:
604 if (!(dlgCode & DLGC_WANTARROWS))
605 {
Alexandre Julliardecc37121994-11-22 16:31:29 +0000606 SetFocus(GetNextDlgGroupItem(hwndDlg,GetFocus(),FALSE));
Alexandre Julliardaca05781994-10-17 18:12:41 +0000607 return TRUE;
608 }
609 break;
610
611 case VK_LEFT:
612 case VK_UP:
613 if (!(dlgCode & DLGC_WANTARROWS))
614 {
Alexandre Julliardecc37121994-11-22 16:31:29 +0000615 SetFocus(GetNextDlgGroupItem(hwndDlg,GetFocus(),TRUE));
Alexandre Julliardaca05781994-10-17 18:12:41 +0000616 return TRUE;
617 }
618 break;
619
620 case VK_ESCAPE:
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000621#ifdef WINELIB32
622 SendMessage( hwndDlg, WM_COMMAND,
623 MAKEWPARAM( IDCANCEL, 0 ),
624 (LPARAM)GetDlgItem(hwndDlg,IDCANCEL) );
625#else
Alexandre Julliardaca05781994-10-17 18:12:41 +0000626 SendMessage( hwndDlg, WM_COMMAND, IDCANCEL,
627 MAKELPARAM( GetDlgItem(hwndDlg,IDCANCEL), 0 ));
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000628#endif
Alexandre Julliardaca05781994-10-17 18:12:41 +0000629 break;
630
631 case VK_RETURN:
632 {
633 DWORD dw = SendMessage( hwndDlg, DM_GETDEFID, 0, 0 );
634 if (HIWORD(dw) == DC_HASDEFID)
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000635#ifdef WINELIB32
636 SendMessage( hwndDlg, WM_COMMAND,
637 MAKEWPARAM( LOWORD(dw), BN_CLICKED ),
638 (LPARAM)GetDlgItem( hwndDlg, LOWORD(dw) ) );
639 else
640 SendMessage( hwndDlg, WM_COMMAND,
641 MAKEWPARAM( IDOK, 0 ),
642 (LPARAM)GetDlgItem(hwndDlg,IDOK) );
643#else
Alexandre Julliardaca05781994-10-17 18:12:41 +0000644 SendMessage( hwndDlg, WM_COMMAND, LOWORD(dw),
645 MAKELPARAM( GetDlgItem( hwndDlg, LOWORD(dw) ),
646 BN_CLICKED ));
647 else
648 SendMessage( hwndDlg, WM_COMMAND, IDOK,
649 MAKELPARAM( GetDlgItem(hwndDlg,IDOK), 0 ));
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000650#endif
Alexandre Julliardaca05781994-10-17 18:12:41 +0000651 }
652 break;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000653
654 default:
655 TranslateMessage( msg );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000656 }
657 break; /* case WM_KEYDOWN */
658
659
660 case WM_CHAR:
661 if (dlgCode & (DLGC_WANTALLKEYS | DLGC_WANTCHARS)) break;
662 break;
663
664 case WM_SYSCHAR:
665 if (dlgCode & DLGC_WANTALLKEYS) break;
666 break;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000667 }
Alexandre Julliardaca05781994-10-17 18:12:41 +0000668
669 /* If we get here, the message has not been treated specially */
670 /* and can be sent to its destination window. */
671 DispatchMessage( msg );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000672 return TRUE;
673}
674
675
676/****************************************************************
677 * GetDlgCtrlID (USER.277)
678 */
679int GetDlgCtrlID( HWND hwnd )
680{
681 WND *wndPtr = WIN_FindWndPtr(hwnd);
682 if (wndPtr) return wndPtr->wIDmenu;
683 else return 0;
684}
685
686
687/***********************************************************************
688 * GetDlgItem (USER.91)
689 */
690HWND GetDlgItem( HWND hwndDlg, WORD id )
691{
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000692 WND *pWnd;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000693
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000694 if (!(pWnd = WIN_FindWndPtr( hwndDlg ))) return 0;
695 for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
696 if (pWnd->wIDmenu == id) return pWnd->hwndSelf;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000697 return 0;
698}
699
700
701/*******************************************************************
702 * SendDlgItemMessage (USER.101)
703 */
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000704LRESULT SendDlgItemMessage(HWND hwnd, INT id, UINT msg, WPARAM wParam, LPARAM lParam)
Alexandre Julliard0e607781993-11-03 19:23:37 +0000705{
706 HWND hwndCtrl = GetDlgItem( hwnd, id );
707 if (hwndCtrl) return SendMessage( hwndCtrl, msg, wParam, lParam );
708 else return 0;
709}
710
711
712/*******************************************************************
713 * SetDlgItemText (USER.92)
714 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000715void SetDlgItemText( HWND hwnd, WORD id, SEGPTR lpString )
Alexandre Julliard0e607781993-11-03 19:23:37 +0000716{
717 SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (DWORD)lpString );
718}
719
720
721/***********************************************************************
722 * GetDlgItemText (USER.93)
723 */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000724int GetDlgItemText( HWND hwnd, WORD id, SEGPTR str, WORD max )
Alexandre Julliard0e607781993-11-03 19:23:37 +0000725{
726 return (int)SendDlgItemMessage( hwnd, id, WM_GETTEXT, max, (DWORD)str );
727}
728
729
730/*******************************************************************
731 * SetDlgItemInt (USER.94)
732 */
733void SetDlgItemInt( HWND hwnd, WORD id, WORD value, BOOL fSigned )
734{
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000735 char *str = (char *)SEGPTR_ALLOC( 20 * sizeof(char) );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000736
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000737 if (!str) return;
Alexandre Julliard2787be81995-05-22 18:23:01 +0000738 if (fSigned) sprintf( str, "%d", (int)value );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000739 else sprintf( str, "%u", value );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000740 SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (LPARAM)SEGPTR_GET(str) );
741 SEGPTR_FREE(str);
Alexandre Julliard0e607781993-11-03 19:23:37 +0000742}
743
744
745/***********************************************************************
746 * GetDlgItemInt (USER.95)
747 */
748WORD GetDlgItemInt( HWND hwnd, WORD id, BOOL * translated, BOOL fSigned )
749{
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000750 char *str;
Alexandre Julliard3ed37e01994-11-07 18:20:42 +0000751 long result = 0;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000752
753 if (translated) *translated = FALSE;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000754 if (!(str = (char *)SEGPTR_ALLOC( 30 * sizeof(char) ))) return 0;
755 if (SendDlgItemMessage( hwnd, id, WM_GETTEXT, 30, (LPARAM)SEGPTR_GET(str)))
Alexandre Julliard0e607781993-11-03 19:23:37 +0000756 {
757 char * endptr;
758 result = strtol( str, &endptr, 10 );
759 if (endptr && (endptr != str)) /* Conversion was successful */
760 {
761 if (fSigned)
762 {
763 if ((result < -32767) || (result > 32767)) result = 0;
764 else if (translated) *translated = TRUE;
765 }
766 else
767 {
768 if ((result < 0) || (result > 65535)) result = 0;
769 else if (translated) *translated = TRUE;
770 }
771 }
772 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000773 SEGPTR_FREE(str);
Alexandre Julliard0e607781993-11-03 19:23:37 +0000774 return (WORD)result;
775}
776
777
778/***********************************************************************
779 * CheckDlgButton (USER.97)
780 */
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000781BOOL CheckDlgButton( HWND hwnd, INT id, UINT check )
Alexandre Julliard0e607781993-11-03 19:23:37 +0000782{
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000783 SendDlgItemMessage( hwnd, id, BM_SETCHECK16, check, 0 );
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000784 return TRUE;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000785}
786
787
788/***********************************************************************
789 * IsDlgButtonChecked (USER.98)
790 */
791WORD IsDlgButtonChecked( HWND hwnd, WORD id )
792{
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000793 return (WORD)SendDlgItemMessage( hwnd, id, BM_GETCHECK16, 0, 0 );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000794}
795
796
797/***********************************************************************
798 * CheckRadioButton (USER.96)
799 */
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000800BOOL CheckRadioButton( HWND hwndDlg, UINT firstID, UINT lastID, UINT checkID )
Alexandre Julliard0e607781993-11-03 19:23:37 +0000801{
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000802 WND *pWnd = WIN_FindWndPtr( hwndDlg );
803 if (!pWnd) return FALSE;
Alexandre Julliardecc37121994-11-22 16:31:29 +0000804
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000805 for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
806 if ((pWnd->wIDmenu == firstID) || (pWnd->wIDmenu == lastID)) break;
807 if (!pWnd) return FALSE;
Alexandre Julliardecc37121994-11-22 16:31:29 +0000808
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000809 if (pWnd->wIDmenu == lastID)
Alexandre Julliardecc37121994-11-22 16:31:29 +0000810 lastID = firstID; /* Buttons are in reverse order */
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000811 while (pWnd)
Alexandre Julliardecc37121994-11-22 16:31:29 +0000812 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000813 SendMessage(pWnd->hwndSelf,BM_SETCHECK16,(pWnd->wIDmenu == checkID),0);
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000814 if (pWnd->wIDmenu == lastID) break;
815 pWnd = pWnd->next;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000816 }
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000817 return TRUE;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000818}
819
820
821/***********************************************************************
822 * GetDialogBaseUnits (USER.243)
823 */
824DWORD GetDialogBaseUnits()
825{
826 return MAKELONG( xBaseUnit, yBaseUnit );
827}
828
829
830/***********************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000831 * MapDialogRect16 (USER.103)
Alexandre Julliard0e607781993-11-03 19:23:37 +0000832 */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000833void MapDialogRect16( HWND16 hwnd, LPRECT16 rect )
834{
835 DIALOGINFO * dlgInfo;
836 WND * wndPtr = WIN_FindWndPtr( hwnd );
837 if (!wndPtr) return;
838 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
839 rect->left = (rect->left * dlgInfo->xBaseUnit) / 4;
840 rect->right = (rect->right * dlgInfo->xBaseUnit) / 4;
841 rect->top = (rect->top * dlgInfo->yBaseUnit) / 8;
842 rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8;
843}
844
845
846/***********************************************************************
847 * MapDialogRect32 (USER32.381)
848 */
849void MapDialogRect32( HWND32 hwnd, LPRECT32 rect )
Alexandre Julliard0e607781993-11-03 19:23:37 +0000850{
851 DIALOGINFO * dlgInfo;
852 WND * wndPtr = WIN_FindWndPtr( hwnd );
853 if (!wndPtr) return;
854 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
855 rect->left = (rect->left * dlgInfo->xBaseUnit) / 4;
856 rect->right = (rect->right * dlgInfo->xBaseUnit) / 4;
857 rect->top = (rect->top * dlgInfo->yBaseUnit) / 8;
858 rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8;
859}
860
861
862/***********************************************************************
863 * GetNextDlgGroupItem (USER.227)
864 */
865HWND GetNextDlgGroupItem( HWND hwndDlg, HWND hwndCtrl, BOOL fPrevious )
866{
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000867 WND *pWnd, *pWndStart, *pWndCtrl, *pWndDlg;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000868
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000869 if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0;
870 if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0;
871 if (pWndCtrl->parent != pWndDlg) return 0;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000872
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000873 if (!fPrevious && pWndCtrl->next) /* Check if next control is in group */
Alexandre Julliard0e607781993-11-03 19:23:37 +0000874 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000875 if (!(pWndCtrl->next->dwStyle & WS_GROUP))
876 return pWndCtrl->next->hwndSelf;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000877 }
878
Alexandre Julliardaca05781994-10-17 18:12:41 +0000879 /* Now we will have to find the start of the group */
880
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000881 for (pWnd = pWndStart = pWndDlg->child; pWnd; pWnd = pWnd->next)
Alexandre Julliardaca05781994-10-17 18:12:41 +0000882 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000883 if (pWnd->dwStyle & WS_GROUP) pWndStart = pWnd; /* Start of a group */
884 if (pWnd == pWndCtrl) break;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000885 }
Alexandre Julliard808cb041995-08-17 17:11:36 +0000886
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000887 if (!pWnd) fprintf(stderr, "GetNextDlgGroupItem: hwnd not in dialog!\n");
Alexandre Julliard808cb041995-08-17 17:11:36 +0000888
889 /* only case left for forward search: wraparound */
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000890 if (!fPrevious) return pWndStart->hwndSelf;
891
892 pWnd = pWndStart->next;
893 while (pWnd && (pWnd != pWndCtrl))
Alexandre Julliard808cb041995-08-17 17:11:36 +0000894 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000895 if (pWnd->dwStyle & WS_GROUP) break;
896 pWndStart = pWnd;
897 pWnd = pWnd->next;
Alexandre Julliard808cb041995-08-17 17:11:36 +0000898 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000899 return pWndStart->hwndSelf;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000900}
901
902
903/***********************************************************************
904 * GetNextDlgTabItem (USER.228)
905 */
906HWND GetNextDlgTabItem( HWND hwndDlg, HWND hwndCtrl, BOOL fPrevious )
907{
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000908 WND *pWnd, *pWndLast, *pWndCtrl, *pWndDlg;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000909
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000910 if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0;
911 if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0;
912 if (pWndCtrl->parent != pWndDlg) return 0;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000913
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000914 pWndLast = pWndCtrl;
915 pWnd = pWndCtrl->next;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000916 while (1)
917 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000918 if (!pWnd) pWnd = pWndDlg->child;
919 if (pWnd == pWndCtrl) break;
920 if ((pWnd->dwStyle & WS_TABSTOP) && (pWnd->dwStyle & WS_VISIBLE))
Alexandre Julliard0e607781993-11-03 19:23:37 +0000921 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000922 pWndLast = pWnd;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000923 if (!fPrevious) break;
924 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000925 pWnd = pWnd->next;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000926 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000927 return pWndLast->hwndSelf;
Alexandre Julliard0e607781993-11-03 19:23:37 +0000928}