Release 980215
[wine/multimedia.git] / windows / dialog.c
blob59ddae6566299e3f09b751fa1d03175459fdae68
1 /*
2 * Dialog functions
4 * Copyright 1993, 1994, 1996 Alexandre Julliard
5 */
7 #include <ctype.h>
8 #include <errno.h>
9 #include <limits.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <errno.h>
14 #include "windows.h"
15 #include "dialog.h"
16 #include "drive.h"
17 #include "heap.h"
18 #include "win.h"
19 #include "ldt.h"
20 #include "user.h"
21 #include "winproc.h"
22 #include "message.h"
23 #include "sysmetrics.h"
24 #include "stddebug.h"
25 #include "debug.h"
28 /* Dialog control information */
29 typedef struct
31 DWORD style;
32 DWORD exStyle;
33 INT16 x;
34 INT16 y;
35 INT16 cx;
36 INT16 cy;
37 UINT16 id;
38 LPCSTR className;
39 LPCSTR windowName;
40 LPVOID data;
41 } DLG_CONTROL_INFO;
43 /* Dialog template */
44 typedef struct
46 DWORD style;
47 DWORD exStyle;
48 UINT16 nbItems;
49 INT16 x;
50 INT16 y;
51 INT16 cx;
52 INT16 cy;
53 LPCSTR menuName;
54 LPCSTR className;
55 LPCSTR caption;
56 WORD pointSize;
57 LPCSTR faceName;
58 } DLG_TEMPLATE;
60 /* Dialog base units */
61 static WORD xBaseUnit = 0, yBaseUnit = 0;
64 /***********************************************************************
65 * DIALOG_Init
67 * Initialisation of the dialog manager.
69 BOOL32 DIALOG_Init(void)
71 TEXTMETRIC16 tm;
72 HDC16 hdc;
74 /* Calculate the dialog base units */
76 if (!(hdc = CreateDC16( "DISPLAY", NULL, NULL, NULL ))) return FALSE;
77 GetTextMetrics16( hdc, &tm );
78 DeleteDC32( hdc );
79 xBaseUnit = tm.tmAveCharWidth;
80 yBaseUnit = tm.tmHeight;
82 /* Dialog units are based on a proportional system font */
83 /* so we adjust them a bit for a fixed font. */
84 if (!(tm.tmPitchAndFamily & TMPF_FIXED_PITCH))
85 xBaseUnit = xBaseUnit * 5 / 4;
87 dprintf_dialog( stddeb, "DIALOG_Init: base units = %d,%d\n",
88 xBaseUnit, yBaseUnit );
89 return TRUE;
93 /***********************************************************************
94 * DIALOG_GetControl16
96 * Return the class and text of the control pointed to by ptr,
97 * fill the header structure and return a pointer to the next control.
99 static LPCSTR DIALOG_GetControl16( LPCSTR p, DLG_CONTROL_INFO *info )
101 static char buffer[10];
102 int int_id;
104 info->x = GET_WORD(p); p += sizeof(WORD);
105 info->y = GET_WORD(p); p += sizeof(WORD);
106 info->cx = GET_WORD(p); p += sizeof(WORD);
107 info->cy = GET_WORD(p); p += sizeof(WORD);
108 info->id = GET_WORD(p); p += sizeof(WORD);
109 info->style = GET_DWORD(p); p += sizeof(DWORD);
110 info->exStyle = 0;
112 if (*p & 0x80)
114 switch((BYTE)*p)
116 case 0x80: strcpy( buffer, "BUTTON" ); break;
117 case 0x81: strcpy( buffer, "EDIT" ); break;
118 case 0x82: strcpy( buffer, "STATIC" ); break;
119 case 0x83: strcpy( buffer, "LISTBOX" ); break;
120 case 0x84: strcpy( buffer, "SCROLLBAR" ); break;
121 case 0x85: strcpy( buffer, "COMBOBOX" ); break;
122 default: buffer[0] = '\0'; break;
124 info->className = buffer;
125 p++;
127 else
129 info->className = p;
130 p += strlen(p) + 1;
133 int_id = ((BYTE)*p == 0xff);
134 if (int_id)
136 /* Integer id, not documented (?). Only works for SS_ICON controls */
137 info->windowName = (LPCSTR)(UINT32)GET_WORD(p+1);
138 p += 3;
140 else
142 info->windowName = p;
143 p += strlen(p) + 1;
146 info->data = (LPVOID)(*p ? p + 1 : NULL); /* FIXME: should be a segptr */
147 p += *p + 1;
149 if(int_id)
150 dprintf_dialog( stddeb," %s %04x %d, %d, %d, %d, %d, %08lx, %08lx\n",
151 info->className, LOWORD(info->windowName),
152 info->id, info->x, info->y, info->cx, info->cy,
153 info->style, (DWORD)info->data);
154 else
155 dprintf_dialog( stddeb," %s '%s' %d, %d, %d, %d, %d, %08lx, %08lx\n",
156 info->className, info->windowName,
157 info->id, info->x, info->y, info->cx, info->cy,
158 info->style, (DWORD)info->data);
160 return p;
164 /***********************************************************************
165 * DIALOG_GetControl32
167 * Return the class and text of the control pointed to by ptr,
168 * fill the header structure and return a pointer to the next control.
170 static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info )
172 static WCHAR buffer[10];
173 int int_id;
175 info->style = GET_DWORD(p); p += 2;
176 info->exStyle = GET_DWORD(p); p += 2;
177 info->x = GET_WORD(p); p++;
178 info->y = GET_WORD(p); p++;
179 info->cx = GET_WORD(p); p++;
180 info->cy = GET_WORD(p); p++;
181 info->id = GET_WORD(p); p++;
183 if (GET_WORD(p) == 0xffff)
185 switch(GET_WORD(p+1))
187 case 0x80: lstrcpyAtoW( buffer, "Button" ); break;
188 case 0x81: lstrcpyAtoW( buffer, "Edit" ); break;
189 case 0x82: lstrcpyAtoW( buffer, "Static" ); break;
190 case 0x83: lstrcpyAtoW( buffer, "ListBox" ); break;
191 case 0x84: lstrcpyAtoW( buffer, "ScrollBar" ); break;
192 case 0x85: lstrcpyAtoW( buffer, "ComboBox" ); break;
193 default: buffer[0] = '\0'; break;
195 info->className = (LPCSTR)buffer;
196 p += 2;
198 else
200 info->className = (LPCSTR)p;
201 p += lstrlen32W( (LPCWSTR)p ) + 1;
204 int_id = (GET_WORD(p) == 0xffff);
205 if (int_id)
207 info->windowName = (LPCSTR)(p + 1);
208 p += 2;
210 else
212 info->windowName = (LPCSTR)p;
213 p += lstrlen32W( (LPCWSTR)p ) + 1;
216 if (GET_WORD(p))
218 info->data = (LPVOID)(p + 1);
219 p += GET_WORD(p) / sizeof(WORD);
221 else info->data = NULL;
222 p++;
224 if(int_id)
225 dprintf_dialog( stddeb," %p %04x %d, %d, %d, %d, %d, %08lx, %08lx, %08lx\n",
226 info->className, LOWORD(info->windowName),
227 info->id, info->x, info->y, info->cx, info->cy,
228 info->style, info->exStyle, (DWORD)info->data);
229 else
230 dprintf_dialog( stddeb," %p '%p' %d, %d, %d, %d, %d, %08lx, %08lx, %08lx\n",
231 info->className, info->windowName,
232 info->id, info->x, info->y, info->cx, info->cy,
233 info->style, info->exStyle, (DWORD)info->data);
235 /* Next control is on dword boundary */
236 return (const WORD *)((((int)p) + 3) & ~3);
240 /***********************************************************************
241 * DIALOG_CreateControls
243 * Create the control windows for a dialog.
245 static BOOL32 DIALOG_CreateControls( WND *pWnd, LPCSTR template, INT32 items,
246 HINSTANCE32 hInst, BOOL32 win32 )
248 DIALOGINFO *dlgInfo = (DIALOGINFO *)pWnd->wExtra;
249 DLG_CONTROL_INFO info;
250 HWND32 hwndCtrl, hwndDefButton = 0;
252 dprintf_dialog(stddeb, " BEGIN\n" );
253 while (items--)
255 if (!win32)
257 HINSTANCE16 instance;
258 template = DIALOG_GetControl16( template, &info );
259 if (HIWORD(info.className) && !strcmp( info.className, "EDIT") &&
260 ((pWnd->dwStyle & DS_LOCALEDIT) != DS_LOCALEDIT))
262 if (!dlgInfo->hDialogHeap)
264 dlgInfo->hDialogHeap = GlobalAlloc16(GMEM_FIXED, 0x10000);
265 if (!dlgInfo->hDialogHeap)
267 fprintf( stderr, "CreateDialogIndirectParam: Insufficient memory to create heap for edit control\n" );
268 continue;
270 LocalInit(dlgInfo->hDialogHeap, 0, 0xffff);
272 instance = dlgInfo->hDialogHeap;
274 else instance = (HINSTANCE16)hInst;
276 hwndCtrl = CreateWindowEx16( info.exStyle | WS_EX_NOPARENTNOTIFY,
277 info.className, info.windowName,
278 info.style | WS_CHILD,
279 info.x * dlgInfo->xBaseUnit / 4,
280 info.y * dlgInfo->yBaseUnit / 8,
281 info.cx * dlgInfo->xBaseUnit / 4,
282 info.cy * dlgInfo->yBaseUnit / 8,
283 pWnd->hwndSelf, (HMENU16)info.id,
284 instance, info.data );
286 else
288 template = (LPCSTR)DIALOG_GetControl32( (WORD *)template, &info );
289 hwndCtrl = CreateWindowEx32W( info.exStyle | WS_EX_NOPARENTNOTIFY,
290 (LPCWSTR)info.className,
291 (LPCWSTR)info.windowName,
292 info.style | WS_CHILD,
293 info.x * dlgInfo->xBaseUnit / 4,
294 info.y * dlgInfo->yBaseUnit / 8,
295 info.cx * dlgInfo->xBaseUnit / 4,
296 info.cy * dlgInfo->yBaseUnit / 8,
297 pWnd->hwndSelf, (HMENU32)info.id,
298 hInst, info.data );
300 if (!hwndCtrl) return FALSE;
302 /* Send initialisation messages to the control */
303 if (dlgInfo->hUserFont) SendMessage32A( hwndCtrl, WM_SETFONT,
304 (WPARAM32)dlgInfo->hUserFont, 0 );
305 if (SendMessage32A(hwndCtrl, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
307 /* If there's already a default push-button, set it back */
308 /* to normal and use this one instead. */
309 if (hwndDefButton)
310 SendMessage32A( hwndDefButton, BM_SETSTYLE32,
311 BS_PUSHBUTTON,FALSE );
312 hwndDefButton = hwndCtrl;
313 dlgInfo->idResult = GetWindowWord32( hwndCtrl, GWW_ID );
316 dprintf_dialog(stddeb, " END\n" );
317 return TRUE;
321 /***********************************************************************
322 * DIALOG_ParseTemplate16
324 * Fill a DLG_TEMPLATE structure from the dialog template, and return
325 * a pointer to the first control.
327 static LPCSTR DIALOG_ParseTemplate16( LPCSTR p, DLG_TEMPLATE * result )
329 result->style = GET_DWORD(p); p += sizeof(DWORD);
330 result->exStyle = 0;
331 result->nbItems = *p++;
332 result->x = GET_WORD(p); p += sizeof(WORD);
333 result->y = GET_WORD(p); p += sizeof(WORD);
334 result->cx = GET_WORD(p); p += sizeof(WORD);
335 result->cy = GET_WORD(p); p += sizeof(WORD);
336 dprintf_dialog( stddeb, "DIALOG %d, %d, %d, %d\n",
337 result->x, result->y, result->cx, result->cy );
338 dprintf_dialog( stddeb, " STYLE %08lx\n", result->style );
340 /* Get the menu name */
342 switch( (BYTE)*p )
344 case 0:
345 result->menuName = 0;
346 p++;
347 break;
348 case 0xff:
349 result->menuName = (LPCSTR)(UINT32)GET_WORD( p + 1 );
350 p += 3;
351 dprintf_dialog(stddeb, " MENU %04x\n", LOWORD(result->menuName) );
352 break;
353 default:
354 result->menuName = p;
355 dprintf_dialog( stddeb, " MENU '%s'\n", p );
356 p += strlen(p) + 1;
357 break;
360 /* Get the class name */
362 if (*p)
364 result->className = p;
365 dprintf_dialog( stddeb, " CLASS '%s'\n", result->className );
367 else result->className = DIALOG_CLASS_ATOM;
368 p += strlen(p) + 1;
370 /* Get the window caption */
372 result->caption = p;
373 p += strlen(p) + 1;
374 dprintf_dialog( stddeb, " CAPTION '%s'\n", result->caption );
376 /* Get the font name */
378 if (result->style & DS_SETFONT)
380 result->pointSize = GET_WORD(p);
381 p += sizeof(WORD);
382 result->faceName = p;
383 p += strlen(p) + 1;
384 dprintf_dialog( stddeb, " FONT %d,'%s'\n",
385 result->pointSize, result->faceName );
387 return p;
391 /***********************************************************************
392 * DIALOG_ParseTemplate32
394 * Fill a DLG_TEMPLATE structure from the dialog template, and return
395 * a pointer to the first control.
397 static LPCSTR DIALOG_ParseTemplate32( LPCSTR template, DLG_TEMPLATE * result )
399 const WORD *p = (const WORD *)template;
401 result->style = GET_DWORD(p); p += 2;
402 result->exStyle = GET_DWORD(p); p += 2;
403 result->nbItems = GET_WORD(p); p++;
404 result->x = GET_WORD(p); p++;
405 result->y = GET_WORD(p); p++;
406 result->cx = GET_WORD(p); p++;
407 result->cy = GET_WORD(p); p++;
408 dprintf_dialog( stddeb, "DIALOG %d, %d, %d, %d\n",
409 result->x, result->y, result->cx, result->cy );
410 dprintf_dialog( stddeb, " STYLE %08lx\n", result->style );
411 dprintf_dialog( stddeb, " EXSTYLE %08lx\n", result->exStyle );
413 /* Get the menu name */
415 switch(GET_WORD(p))
417 case 0x0000:
418 result->menuName = NULL;
419 p++;
420 break;
421 case 0xffff:
422 result->menuName = (LPCSTR)(UINT32)GET_WORD( p + 1 );
423 p += 2;
424 dprintf_dialog(stddeb, " MENU %04x\n", LOWORD(result->menuName) );
425 break;
426 default:
427 result->menuName = (LPCSTR)p;
428 dprintf_dialog( stddeb, " MENU '%p'\n", p );
429 p += lstrlen32W( (LPCWSTR)p ) + 1;
430 break;
433 /* Get the class name */
435 switch(GET_WORD(p))
437 case 0x0000:
438 result->className = DIALOG_CLASS_ATOM;
439 p++;
440 break;
441 case 0xffff:
442 result->className = (LPCSTR)(UINT32)GET_WORD( p + 1 );
443 p += 2;
444 dprintf_dialog(stddeb, " CLASS %04x\n", LOWORD(result->className) );
445 break;
446 default:
447 result->className = (LPCSTR)p;
448 dprintf_dialog( stddeb, " CLASS '%p'\n", p );
449 p += lstrlen32W( (LPCWSTR)p ) + 1;
450 break;
453 /* Get the window caption */
455 result->caption = (LPCSTR)p;
456 p += lstrlen32W( (LPCWSTR)p ) + 1;
457 dprintf_dialog( stddeb, " CAPTION '%p'\n", result->caption );
459 /* Get the font name */
461 if (result->style & DS_SETFONT)
463 result->pointSize = GET_WORD(p);
464 p++;
465 result->faceName = (LPCSTR)p;
466 p += lstrlen32W( (LPCWSTR)p ) + 1;
467 dprintf_dialog( stddeb, " FONT %d,'%p'\n",
468 result->pointSize, result->faceName );
470 /* First control is on dword boundary */
471 return (LPCSTR)((((int)p) + 3) & ~3);
475 /***********************************************************************
476 * DIALOG_CreateIndirect
478 HWND32 DIALOG_CreateIndirect( HINSTANCE32 hInst, LPCSTR dlgTemplate,
479 BOOL32 win32Template, HWND32 owner,
480 DLGPROC16 dlgProc, LPARAM param,
481 WINDOWPROCTYPE procType )
483 HMENU16 hMenu = 0;
484 HFONT16 hFont = 0;
485 HWND32 hwnd;
486 RECT32 rect;
487 WND * wndPtr;
488 DLG_TEMPLATE template;
489 DIALOGINFO * dlgInfo;
490 WORD xUnit = xBaseUnit;
491 WORD yUnit = yBaseUnit;
493 /* Parse dialog template */
495 if (!dlgTemplate) return 0;
496 if (win32Template)
497 dlgTemplate = DIALOG_ParseTemplate32( dlgTemplate, &template );
498 else
499 dlgTemplate = DIALOG_ParseTemplate16( dlgTemplate, &template );
501 /* Load menu */
503 if (template.menuName)
505 if (!win32Template)
507 LPSTR str = SEGPTR_STRDUP( template.menuName );
508 hMenu = LoadMenu16( hInst, SEGPTR_GET(str) );
509 SEGPTR_FREE( str );
511 else hMenu = LoadMenu32W( hInst, (LPCWSTR)template.menuName );
514 /* Create custom font if needed */
516 if (template.style & DS_SETFONT)
518 /* The font height must be negative as it is a point size */
519 /* (see CreateFont() documentation in the Windows SDK). */
520 if (win32Template)
521 hFont = CreateFont32W( -template.pointSize, 0, 0, 0, FW_DONTCARE,
522 FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
523 PROOF_QUALITY, FF_DONTCARE,
524 (LPCWSTR)template.faceName );
525 else
526 hFont = CreateFont16( -template.pointSize, 0, 0, 0, FW_DONTCARE,
527 FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
528 PROOF_QUALITY, FF_DONTCARE,
529 template.faceName );
530 if (hFont)
532 TEXTMETRIC16 tm;
533 HFONT16 oldFont;
535 HDC32 hdc = GetDC32(0);
536 oldFont = SelectObject32( hdc, hFont );
537 GetTextMetrics16( hdc, &tm );
538 SelectObject32( hdc, oldFont );
539 ReleaseDC32( 0, hdc );
540 xUnit = tm.tmAveCharWidth;
541 yUnit = tm.tmHeight;
542 if (!(tm.tmPitchAndFamily & TMPF_FIXED_PITCH))
543 xBaseUnit = xBaseUnit * 5 / 4; /* See DIALOG_Init() */
547 /* Create dialog main window */
549 rect.left = rect.top = 0;
550 rect.right = template.cx * xUnit / 4;
551 rect.bottom = template.cy * yUnit / 8;
552 if (template.style & DS_MODALFRAME)
553 template.exStyle |= WS_EX_DLGMODALFRAME;
554 AdjustWindowRectEx32( &rect, template.style,
555 hMenu ? TRUE : FALSE , template.exStyle );
556 rect.right -= rect.left;
557 rect.bottom -= rect.top;
559 if ((INT16)template.x == CW_USEDEFAULT16)
561 rect.left = rect.top = (procType == WIN_PROC_16) ? CW_USEDEFAULT16
562 : CW_USEDEFAULT32;
564 else
566 rect.left += template.x * xUnit / 4;
567 rect.top += template.y * yUnit / 8;
568 if ( !(template.style & WS_CHILD) )
570 INT16 dX, dY;
572 if( !(template.style & DS_ABSALIGN) )
573 ClientToScreen32( owner, (POINT32 *)&rect );
575 /* try to fit it into the desktop */
577 if( (dX = rect.left + rect.right + SYSMETRICS_CXDLGFRAME
578 - SYSMETRICS_CXSCREEN) > 0 ) rect.left -= dX;
579 if( (dY = rect.top + rect.bottom + SYSMETRICS_CYDLGFRAME
580 - SYSMETRICS_CYSCREEN) > 0 ) rect.top -= dY;
581 if( rect.left < 0 ) rect.left = 0;
582 if( rect.top < 0 ) rect.top = 0;
586 if (procType == WIN_PROC_16)
587 hwnd = CreateWindowEx16(template.exStyle, template.className,
588 template.caption, template.style & ~WS_VISIBLE,
589 rect.left, rect.top, rect.right, rect.bottom,
590 owner, hMenu, hInst, NULL );
591 else
592 hwnd = CreateWindowEx32W(template.exStyle, (LPCWSTR)template.className,
593 (LPCWSTR)template.caption,
594 template.style & ~WS_VISIBLE,
595 rect.left, rect.top, rect.right, rect.bottom,
596 owner, hMenu, hInst, NULL );
598 if (!hwnd)
600 if (hFont) DeleteObject32( hFont );
601 if (hMenu) DestroyMenu32( hMenu );
602 return 0;
604 wndPtr = WIN_FindWndPtr( hwnd );
605 wndPtr->flags |= WIN_ISDIALOG;
607 /* Initialise dialog extra data */
609 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
610 WINPROC_SetProc( &dlgInfo->dlgProc, dlgProc, procType, WIN_PROC_WINDOW );
611 dlgInfo->hUserFont = hFont;
612 dlgInfo->hMenu = hMenu;
613 dlgInfo->xBaseUnit = xUnit;
614 dlgInfo->yBaseUnit = yUnit;
615 dlgInfo->msgResult = 0;
616 dlgInfo->idResult = 0;
617 dlgInfo->flags = 0;
618 dlgInfo->hDialogHeap = 0;
620 if (dlgInfo->hUserFont)
621 SendMessage32A( hwnd, WM_SETFONT, (WPARAM32)dlgInfo->hUserFont, 0 );
623 /* Create controls */
625 if (DIALOG_CreateControls( wndPtr, dlgTemplate, template.nbItems,
626 hInst, win32Template ))
628 /* Send initialisation messages and set focus */
630 dlgInfo->hwndFocus = GetNextDlgTabItem32( hwnd, 0, FALSE );
632 if (SendMessage32A( hwnd, WM_INITDIALOG, (WPARAM32)dlgInfo->hwndFocus, param ))
633 SetFocus32( dlgInfo->hwndFocus );
635 if (template.style & WS_VISIBLE && !(wndPtr->dwStyle & WS_VISIBLE))
637 ShowWindow32( hwnd, SW_SHOWNORMAL ); /* SW_SHOW doesn't always work */
638 UpdateWindow32( hwnd );
640 return hwnd;
643 if( IsWindow32(hwnd) ) DestroyWindow32( hwnd );
644 return 0;
648 /***********************************************************************
649 * CreateDialog16 (USER.89)
651 HWND16 WINAPI CreateDialog16( HINSTANCE16 hInst, SEGPTR dlgTemplate,
652 HWND16 owner, DLGPROC16 dlgProc )
654 return CreateDialogParam16( hInst, dlgTemplate, owner, dlgProc, 0 );
658 /***********************************************************************
659 * CreateDialogParam16 (USER.241)
661 HWND16 WINAPI CreateDialogParam16( HINSTANCE16 hInst, SEGPTR dlgTemplate,
662 HWND16 owner, DLGPROC16 dlgProc,
663 LPARAM param )
665 HWND16 hwnd = 0;
666 HRSRC16 hRsrc;
667 HGLOBAL16 hmem;
668 LPCVOID data;
670 dprintf_dialog(stddeb, "CreateDialogParam16: %04x,%08lx,%04x,%08lx,%ld\n",
671 hInst, (DWORD)dlgTemplate, owner, (DWORD)dlgProc, param );
673 if (!(hRsrc = FindResource16( hInst, dlgTemplate, RT_DIALOG ))) return 0;
674 if (!(hmem = LoadResource16( hInst, hRsrc ))) return 0;
675 if (!(data = LockResource16( hmem ))) hwnd = 0;
676 else hwnd = CreateDialogIndirectParam16( hInst, data, owner,
677 dlgProc, param );
678 FreeResource16( hmem );
679 return hwnd;
683 /***********************************************************************
684 * CreateDialogParam32A (USER32.72)
686 HWND32 WINAPI CreateDialogParam32A( HINSTANCE32 hInst, LPCSTR name,
687 HWND32 owner, DLGPROC32 dlgProc,
688 LPARAM param )
690 if (HIWORD(name))
692 LPWSTR str = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
693 HWND32 hwnd = CreateDialogParam32W( hInst, str, owner, dlgProc, param);
694 HeapFree( GetProcessHeap(), 0, str );
695 return hwnd;
697 return CreateDialogParam32W( hInst, (LPCWSTR)name, owner, dlgProc, param );
701 /***********************************************************************
702 * CreateDialogParam32W (USER32.73)
704 HWND32 WINAPI CreateDialogParam32W( HINSTANCE32 hInst, LPCWSTR name,
705 HWND32 owner, DLGPROC32 dlgProc,
706 LPARAM param )
708 HANDLE32 hrsrc = FindResource32W( hInst, name, (LPWSTR)RT_DIALOG );
709 if (!hrsrc) return 0;
710 return CreateDialogIndirectParam32W( hInst,
711 (LPVOID)LoadResource32(hInst, hrsrc),
712 owner, dlgProc, param );
716 /***********************************************************************
717 * CreateDialogIndirect16 (USER.219)
719 HWND16 WINAPI CreateDialogIndirect16( HINSTANCE16 hInst, LPCVOID dlgTemplate,
720 HWND16 owner, DLGPROC16 dlgProc )
722 return CreateDialogIndirectParam16( hInst, dlgTemplate, owner, dlgProc, 0);
726 /***********************************************************************
727 * CreateDialogIndirectParam16 (USER.242)
729 HWND16 WINAPI CreateDialogIndirectParam16( HINSTANCE16 hInst,
730 LPCVOID dlgTemplate,
731 HWND16 owner, DLGPROC16 dlgProc,
732 LPARAM param )
734 return DIALOG_CreateIndirect( hInst, dlgTemplate, FALSE, owner,
735 dlgProc, param, WIN_PROC_16 );
739 /***********************************************************************
740 * CreateDialogIndirectParam32A (USER32.69)
742 HWND32 WINAPI CreateDialogIndirectParam32A( HINSTANCE32 hInst,
743 LPCVOID dlgTemplate,
744 HWND32 owner, DLGPROC32 dlgProc,
745 LPARAM param )
747 return DIALOG_CreateIndirect( hInst, dlgTemplate, TRUE, owner,
748 (DLGPROC16)dlgProc, param, WIN_PROC_32A );
752 /***********************************************************************
753 * CreateDialogIndirectParam32W (USER32.71)
755 HWND32 WINAPI CreateDialogIndirectParam32W( HINSTANCE32 hInst,
756 LPCVOID dlgTemplate,
757 HWND32 owner, DLGPROC32 dlgProc,
758 LPARAM param )
760 return DIALOG_CreateIndirect( hInst, dlgTemplate, TRUE, owner,
761 (DLGPROC16)dlgProc, param, WIN_PROC_32W );
765 /***********************************************************************
766 * DIALOG_DoDialogBox
768 INT32 DIALOG_DoDialogBox( HWND32 hwnd, HWND32 owner )
770 WND * wndPtr;
771 DIALOGINFO * dlgInfo;
772 MSG16 msg;
773 INT32 retval;
775 /* Owner must be a top-level window */
776 owner = WIN_GetTopParent( owner );
777 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1;
778 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
779 EnableWindow32( owner, FALSE );
780 ShowWindow32( hwnd, SW_SHOW );
782 while (MSG_InternalGetMessage(&msg, hwnd, owner, MSGF_DIALOGBOX, PM_REMOVE,
783 !(wndPtr->dwStyle & DS_NOIDLEMSG) ))
785 if (!IsDialogMessage16( hwnd, &msg))
787 TranslateMessage16( &msg );
788 DispatchMessage16( &msg );
790 if (dlgInfo->flags & DF_END) break;
792 retval = dlgInfo->idResult;
793 EnableWindow32( owner, TRUE );
794 DestroyWindow32( hwnd );
795 return retval;
799 /***********************************************************************
800 * DialogBox16 (USER.87)
802 INT16 WINAPI DialogBox16( HINSTANCE16 hInst, SEGPTR dlgTemplate,
803 HWND16 owner, DLGPROC16 dlgProc )
805 return DialogBoxParam16( hInst, dlgTemplate, owner, dlgProc, 0 );
809 /***********************************************************************
810 * DialogBoxParam16 (USER.239)
812 INT16 WINAPI DialogBoxParam16( HINSTANCE16 hInst, SEGPTR template,
813 HWND16 owner, DLGPROC16 dlgProc, LPARAM param )
815 HWND16 hwnd = CreateDialogParam16( hInst, template, owner, dlgProc, param);
816 if (hwnd) return (INT16)DIALOG_DoDialogBox( hwnd, owner );
817 return -1;
821 /***********************************************************************
822 * DialogBoxParam32A (USER32.138)
824 INT32 WINAPI DialogBoxParam32A( HINSTANCE32 hInst, LPCSTR name,
825 HWND32 owner, DLGPROC32 dlgProc, LPARAM param )
827 HWND32 hwnd = CreateDialogParam32A( hInst, name, owner, dlgProc, param );
828 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
829 return -1;
833 /***********************************************************************
834 * DialogBoxParam32W (USER32.139)
836 INT32 WINAPI DialogBoxParam32W( HINSTANCE32 hInst, LPCWSTR name,
837 HWND32 owner, DLGPROC32 dlgProc, LPARAM param )
839 HWND32 hwnd = CreateDialogParam32W( hInst, name, owner, dlgProc, param );
840 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
841 return -1;
845 /***********************************************************************
846 * DialogBoxIndirect16 (USER.218)
848 INT16 WINAPI DialogBoxIndirect16( HINSTANCE16 hInst, HANDLE16 dlgTemplate,
849 HWND16 owner, DLGPROC16 dlgProc )
851 return DialogBoxIndirectParam16( hInst, dlgTemplate, owner, dlgProc, 0 );
855 /***********************************************************************
856 * DialogBoxIndirectParam16 (USER.240)
858 INT16 WINAPI DialogBoxIndirectParam16( HINSTANCE16 hInst, HANDLE16 dlgTemplate,
859 HWND16 owner, DLGPROC16 dlgProc,
860 LPARAM param )
862 HWND16 hwnd;
863 LPCVOID ptr;
865 if (!(ptr = GlobalLock16( dlgTemplate ))) return -1;
866 hwnd = CreateDialogIndirectParam16( hInst, ptr, owner, dlgProc, param );
867 GlobalUnlock16( dlgTemplate );
868 if (hwnd) return (INT16)DIALOG_DoDialogBox( hwnd, owner );
869 return -1;
873 /***********************************************************************
874 * DialogBoxIndirectParam32A (USER32.135)
876 INT32 WINAPI DialogBoxIndirectParam32A(HINSTANCE32 hInstance, LPCVOID template,
877 HWND32 owner, DLGPROC32 dlgProc,
878 LPARAM param )
880 HWND32 hwnd = CreateDialogIndirectParam32A( hInstance, template,
881 owner, dlgProc, param );
882 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
883 return -1;
887 /***********************************************************************
888 * DialogBoxIndirectParam32W (USER32.137)
890 INT32 WINAPI DialogBoxIndirectParam32W(HINSTANCE32 hInstance, LPCVOID template,
891 HWND32 owner, DLGPROC32 dlgProc,
892 LPARAM param )
894 HWND32 hwnd = CreateDialogIndirectParam32W( hInstance, template,
895 owner, dlgProc, param );
896 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
897 return -1;
901 /***********************************************************************
902 * EndDialog16 (USER32.173)
904 BOOL16 WINAPI EndDialog16( HWND16 hwnd, INT16 retval )
906 return EndDialog32( hwnd, retval );
910 /***********************************************************************
911 * EndDialog32 (USER32.173)
913 BOOL32 WINAPI EndDialog32( HWND32 hwnd, INT32 retval )
915 WND * wndPtr = WIN_FindWndPtr( hwnd );
916 DIALOGINFO * dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
918 dprintf_dialog(stddeb, "EndDialog: %04x %d\n", hwnd, retval );
920 if( dlgInfo )
922 dlgInfo->idResult = retval;
923 dlgInfo->flags |= DF_END;
925 return TRUE;
929 /***********************************************************************
930 * DIALOG_IsDialogMessage
932 static BOOL32 DIALOG_IsDialogMessage( HWND32 hwnd, HWND32 hwndDlg,
933 UINT32 message, WPARAM32 wParam,
934 LPARAM lParam, BOOL32 *translate,
935 BOOL32 *dispatch )
937 INT32 dlgCode;
939 *translate = *dispatch = FALSE;
941 if (message == WM_PAINT)
943 /* Apparently, we have to handle this one as well */
944 *dispatch = TRUE;
945 return TRUE;
948 /* Only the key messages get special processing */
949 if ((message != WM_KEYDOWN) &&
950 (message != WM_SYSCHAR) &&
951 (message != WM_CHAR))
952 return FALSE;
954 dlgCode = SendMessage32A( hwnd, WM_GETDLGCODE, 0, 0 );
955 if (dlgCode & DLGC_WANTMESSAGE)
957 *translate = *dispatch = TRUE;
958 return TRUE;
961 switch(message)
963 case WM_KEYDOWN:
964 if (dlgCode & DLGC_WANTALLKEYS) break;
965 switch(wParam)
967 case VK_TAB:
968 if (!(dlgCode & DLGC_WANTTAB))
970 SendMessage32A( hwndDlg, WM_NEXTDLGCTL,
971 (GetKeyState32(VK_SHIFT) & 0x8000), 0 );
972 return TRUE;
974 break;
976 case VK_RIGHT:
977 case VK_DOWN:
978 if (!(dlgCode & DLGC_WANTARROWS))
980 SetFocus32( GetNextDlgGroupItem32( hwndDlg, GetFocus32(),
981 FALSE ) );
982 return TRUE;
984 break;
986 case VK_LEFT:
987 case VK_UP:
988 if (!(dlgCode & DLGC_WANTARROWS))
990 SetFocus32( GetNextDlgGroupItem32( hwndDlg, GetFocus32(),
991 TRUE ) );
992 return TRUE;
994 break;
996 case VK_ESCAPE:
997 SendMessage32A( hwndDlg, WM_COMMAND, IDCANCEL,
998 (LPARAM)GetDlgItem32( hwndDlg, IDCANCEL ) );
999 break;
1001 case VK_RETURN:
1003 DWORD dw = SendMessage16( hwndDlg, DM_GETDEFID, 0, 0 );
1004 if (HIWORD(dw) == DC_HASDEFID)
1005 SendMessage32A( hwndDlg, WM_COMMAND,
1006 MAKEWPARAM( LOWORD(dw), BN_CLICKED ),
1007 (LPARAM)GetDlgItem32(hwndDlg, LOWORD(dw)));
1008 else
1009 SendMessage32A( hwndDlg, WM_COMMAND, IDOK,
1010 (LPARAM)GetDlgItem32( hwndDlg, IDOK ) );
1012 break;
1014 default:
1015 *translate = TRUE;
1016 break;
1018 break; /* case WM_KEYDOWN */
1021 case WM_CHAR:
1022 if (dlgCode & (DLGC_WANTALLKEYS | DLGC_WANTCHARS)) break;
1023 break;
1025 case WM_SYSCHAR:
1026 if (dlgCode & DLGC_WANTALLKEYS) break;
1027 break;
1030 /* If we get here, the message has not been treated specially */
1031 /* and can be sent to its destination window. */
1032 *dispatch = TRUE;
1033 return TRUE;
1037 /***********************************************************************
1038 * IsDialogMessage16 (USER.90)
1040 BOOL16 WINAPI IsDialogMessage16( HWND16 hwndDlg, LPMSG16 msg )
1042 BOOL32 ret, translate, dispatch;
1044 if ((hwndDlg != msg->hwnd) && !IsChild16( hwndDlg, msg->hwnd ))
1045 return FALSE;
1047 ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message,
1048 msg->wParam, msg->lParam,
1049 &translate, &dispatch );
1050 if (translate) TranslateMessage16( msg );
1051 if (dispatch) DispatchMessage16( msg );
1052 return ret;
1056 /***********************************************************************
1057 * IsDialogMessage32A (USER32.341)
1059 BOOL32 WINAPI IsDialogMessage32A( HWND32 hwndDlg, LPMSG32 msg )
1061 BOOL32 ret, translate, dispatch;
1063 if ((hwndDlg != msg->hwnd) && !IsChild32( hwndDlg, msg->hwnd ))
1064 return FALSE;
1066 ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message,
1067 msg->wParam, msg->lParam,
1068 &translate, &dispatch );
1069 if (translate) TranslateMessage32( msg );
1070 if (dispatch) DispatchMessage32A( msg );
1071 return ret;
1075 /***********************************************************************
1076 * IsDialogMessage32W (USER32.342)
1078 BOOL32 WINAPI IsDialogMessage32W( HWND32 hwndDlg, LPMSG32 msg )
1080 BOOL32 ret, translate, dispatch;
1082 if ((hwndDlg != msg->hwnd) && !IsChild32( hwndDlg, msg->hwnd ))
1083 return FALSE;
1085 ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message,
1086 msg->wParam, msg->lParam,
1087 &translate, &dispatch );
1088 if (translate) TranslateMessage32( msg );
1089 if (dispatch) DispatchMessage32W( msg );
1090 return ret;
1094 /****************************************************************
1095 * GetDlgCtrlID16 (USER.277)
1097 INT16 WINAPI GetDlgCtrlID16( HWND16 hwnd )
1099 WND *wndPtr = WIN_FindWndPtr(hwnd);
1100 if (wndPtr) return wndPtr->wIDmenu;
1101 else return 0;
1105 /****************************************************************
1106 * GetDlgCtrlID32 (USER32.233)
1108 INT32 WINAPI GetDlgCtrlID32( HWND32 hwnd )
1110 WND *wndPtr = WIN_FindWndPtr(hwnd);
1111 if (wndPtr) return wndPtr->wIDmenu;
1112 else return 0;
1116 /***********************************************************************
1117 * GetDlgItem16 (USER.91)
1119 HWND16 WINAPI GetDlgItem16( HWND16 hwndDlg, INT16 id )
1121 WND *pWnd;
1123 if (!(pWnd = WIN_FindWndPtr( hwndDlg ))) return 0;
1124 for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
1125 if (pWnd->wIDmenu == (UINT16)id) return pWnd->hwndSelf;
1126 return 0;
1130 /***********************************************************************
1131 * GetDlgItem32 (USER32.234)
1133 HWND32 WINAPI GetDlgItem32( HWND32 hwndDlg, INT32 id )
1135 WND *pWnd;
1137 if (!(pWnd = WIN_FindWndPtr( hwndDlg ))) return 0;
1138 for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
1139 if (pWnd->wIDmenu == (UINT16)id) return pWnd->hwndSelf;
1140 return 0;
1144 /*******************************************************************
1145 * SendDlgItemMessage16 (USER.101)
1147 LRESULT WINAPI SendDlgItemMessage16( HWND16 hwnd, INT16 id, UINT16 msg,
1148 WPARAM16 wParam, LPARAM lParam )
1150 HWND16 hwndCtrl = GetDlgItem16( hwnd, id );
1151 if (hwndCtrl) return SendMessage16( hwndCtrl, msg, wParam, lParam );
1152 else return 0;
1156 /*******************************************************************
1157 * SendDlgItemMessage32A (USER32.451)
1159 LRESULT WINAPI SendDlgItemMessage32A( HWND32 hwnd, INT32 id, UINT32 msg,
1160 WPARAM32 wParam, LPARAM lParam )
1162 HWND32 hwndCtrl = GetDlgItem32( hwnd, id );
1163 if (hwndCtrl) return SendMessage32A( hwndCtrl, msg, wParam, lParam );
1164 else return 0;
1168 /*******************************************************************
1169 * SendDlgItemMessage32W (USER32.452)
1171 LRESULT WINAPI SendDlgItemMessage32W( HWND32 hwnd, INT32 id, UINT32 msg,
1172 WPARAM32 wParam, LPARAM lParam )
1174 HWND32 hwndCtrl = GetDlgItem32( hwnd, id );
1175 if (hwndCtrl) return SendMessage32W( hwndCtrl, msg, wParam, lParam );
1176 else return 0;
1180 /*******************************************************************
1181 * SetDlgItemText16 (USER.92)
1183 void WINAPI SetDlgItemText16( HWND16 hwnd, INT16 id, SEGPTR lpString )
1185 SendDlgItemMessage16( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString );
1189 /*******************************************************************
1190 * SetDlgItemText32A (USER32.477)
1192 void WINAPI SetDlgItemText32A( HWND32 hwnd, INT32 id, LPCSTR lpString )
1194 SendDlgItemMessage32A( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString );
1198 /*******************************************************************
1199 * SetDlgItemText32W (USER32.478)
1201 void WINAPI SetDlgItemText32W( HWND32 hwnd, INT32 id, LPCWSTR lpString )
1203 SendDlgItemMessage32W( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString );
1207 /***********************************************************************
1208 * GetDlgItemText16 (USER.93)
1210 INT16 WINAPI GetDlgItemText16( HWND16 hwnd, INT16 id, SEGPTR str, UINT16 len )
1212 return (INT16)SendDlgItemMessage16( hwnd, id, WM_GETTEXT,
1213 len, (LPARAM)str );
1217 /***********************************************************************
1218 * GetDlgItemText32A (USER32.236)
1220 INT32 WINAPI GetDlgItemText32A( HWND32 hwnd, INT32 id, LPSTR str, UINT32 len )
1222 return (INT32)SendDlgItemMessage32A( hwnd, id, WM_GETTEXT,
1223 len, (LPARAM)str );
1227 /***********************************************************************
1228 * GetDlgItemText32W (USER32.237)
1230 INT32 WINAPI GetDlgItemText32W( HWND32 hwnd, INT32 id, LPWSTR str, UINT32 len )
1232 return (INT32)SendDlgItemMessage32W( hwnd, id, WM_GETTEXT,
1233 len, (LPARAM)str );
1237 /*******************************************************************
1238 * SetDlgItemInt16 (USER.94)
1240 void WINAPI SetDlgItemInt16( HWND16 hwnd, INT16 id, UINT16 value, BOOL16 fSigned )
1242 return SetDlgItemInt32( hwnd, (UINT32)(UINT16)id, value, fSigned );
1246 /*******************************************************************
1247 * SetDlgItemInt32 (USER32.476)
1249 void WINAPI SetDlgItemInt32( HWND32 hwnd, INT32 id, UINT32 value,
1250 BOOL32 fSigned )
1252 char str[20];
1254 if (fSigned) sprintf( str, "%d", (INT32)value );
1255 else sprintf( str, "%u", value );
1256 SendDlgItemMessage32A( hwnd, id, WM_SETTEXT, 0, (LPARAM)str );
1260 /***********************************************************************
1261 * GetDlgItemInt16 (USER.95)
1263 UINT16 WINAPI GetDlgItemInt16( HWND16 hwnd, INT16 id, BOOL16 *translated,
1264 BOOL16 fSigned )
1266 UINT32 result;
1267 BOOL32 ok;
1269 if (translated) *translated = FALSE;
1270 result = GetDlgItemInt32( hwnd, (UINT32)(UINT16)id, &ok, fSigned );
1271 if (!ok) return 0;
1272 if (fSigned)
1274 if (((INT32)result < -32767) || ((INT32)result > 32767)) return 0;
1276 else
1278 if (result > 65535) return 0;
1280 if (translated) *translated = TRUE;
1281 return (UINT16)result;
1285 /***********************************************************************
1286 * GetDlgItemInt32 (USER32.235)
1288 UINT32 WINAPI GetDlgItemInt32( HWND32 hwnd, INT32 id, BOOL32 *translated,
1289 BOOL32 fSigned )
1291 char str[30];
1292 char * endptr;
1293 long result = 0;
1295 if (translated) *translated = FALSE;
1296 if (!SendDlgItemMessage32A(hwnd, id, WM_GETTEXT, sizeof(str), (LPARAM)str))
1297 return 0;
1298 if (fSigned)
1300 result = strtol( str, &endptr, 10 );
1301 if (!endptr || (endptr == str)) /* Conversion was unsuccessful */
1302 return 0;
1303 if (((result == LONG_MIN) || (result == LONG_MAX)) && (errno==ERANGE))
1304 return 0;
1306 else
1308 result = strtoul( str, &endptr, 10 );
1309 if (!endptr || (endptr == str)) /* Conversion was unsuccessful */
1310 return 0;
1311 if ((result == ULONG_MAX) && (errno == ERANGE)) return 0;
1313 if (translated) *translated = TRUE;
1314 return (UINT32)result;
1318 /***********************************************************************
1319 * CheckDlgButton16 (USER.97)
1321 BOOL16 WINAPI CheckDlgButton16( HWND16 hwnd, INT16 id, UINT16 check )
1323 SendDlgItemMessage32A( hwnd, id, BM_SETCHECK32, check, 0 );
1324 return TRUE;
1328 /***********************************************************************
1329 * CheckDlgButton32 (USER32.44)
1331 BOOL32 WINAPI CheckDlgButton32( HWND32 hwnd, INT32 id, UINT32 check )
1333 SendDlgItemMessage32A( hwnd, id, BM_SETCHECK32, check, 0 );
1334 return TRUE;
1338 /***********************************************************************
1339 * IsDlgButtonChecked16 (USER.98)
1341 UINT16 WINAPI IsDlgButtonChecked16( HWND16 hwnd, UINT16 id )
1343 return (UINT16)SendDlgItemMessage32A( hwnd, id, BM_GETCHECK32, 0, 0 );
1347 /***********************************************************************
1348 * IsDlgButtonChecked32 (USER32.343)
1350 UINT32 WINAPI IsDlgButtonChecked32( HWND32 hwnd, UINT32 id )
1352 return (UINT32)SendDlgItemMessage32A( hwnd, id, BM_GETCHECK32, 0, 0 );
1356 /***********************************************************************
1357 * CheckRadioButton16 (USER.96)
1359 BOOL16 WINAPI CheckRadioButton16( HWND16 hwndDlg, UINT16 firstID,
1360 UINT16 lastID, UINT16 checkID )
1362 return CheckRadioButton32( hwndDlg, firstID, lastID, checkID );
1366 /***********************************************************************
1367 * CheckRadioButton32 (USER32.47)
1369 BOOL32 WINAPI CheckRadioButton32( HWND32 hwndDlg, UINT32 firstID,
1370 UINT32 lastID, UINT32 checkID )
1372 WND *pWnd = WIN_FindWndPtr( hwndDlg );
1373 if (!pWnd) return FALSE;
1375 for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
1376 if ((pWnd->wIDmenu == firstID) || (pWnd->wIDmenu == lastID)) break;
1377 if (!pWnd) return FALSE;
1379 if (pWnd->wIDmenu == lastID)
1380 lastID = firstID; /* Buttons are in reverse order */
1381 while (pWnd)
1383 SendMessage32A( pWnd->hwndSelf, BM_SETCHECK32,
1384 (pWnd->wIDmenu == checkID), 0 );
1385 if (pWnd->wIDmenu == lastID) break;
1386 pWnd = pWnd->next;
1388 return TRUE;
1392 /***********************************************************************
1393 * GetDialogBaseUnits (USER.243) (USER32.232)
1395 DWORD WINAPI GetDialogBaseUnits(void)
1397 return MAKELONG( xBaseUnit, yBaseUnit );
1401 /***********************************************************************
1402 * MapDialogRect16 (USER.103)
1404 void WINAPI MapDialogRect16( HWND16 hwnd, LPRECT16 rect )
1406 DIALOGINFO * dlgInfo;
1407 WND * wndPtr = WIN_FindWndPtr( hwnd );
1408 if (!wndPtr) return;
1409 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
1410 rect->left = (rect->left * dlgInfo->xBaseUnit) / 4;
1411 rect->right = (rect->right * dlgInfo->xBaseUnit) / 4;
1412 rect->top = (rect->top * dlgInfo->yBaseUnit) / 8;
1413 rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8;
1417 /***********************************************************************
1418 * MapDialogRect32 (USER32.381)
1420 void WINAPI MapDialogRect32( HWND32 hwnd, LPRECT32 rect )
1422 DIALOGINFO * dlgInfo;
1423 WND * wndPtr = WIN_FindWndPtr( hwnd );
1424 if (!wndPtr) return;
1425 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
1426 rect->left = (rect->left * dlgInfo->xBaseUnit) / 4;
1427 rect->right = (rect->right * dlgInfo->xBaseUnit) / 4;
1428 rect->top = (rect->top * dlgInfo->yBaseUnit) / 8;
1429 rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8;
1433 /***********************************************************************
1434 * GetNextDlgGroupItem16 (USER.227)
1436 HWND16 WINAPI GetNextDlgGroupItem16( HWND16 hwndDlg, HWND16 hwndCtrl,
1437 BOOL16 fPrevious )
1439 return (HWND16)GetNextDlgGroupItem32( hwndDlg, hwndCtrl, fPrevious );
1443 /***********************************************************************
1444 * GetNextDlgGroupItem32 (USER32.274)
1446 HWND32 WINAPI GetNextDlgGroupItem32( HWND32 hwndDlg, HWND32 hwndCtrl,
1447 BOOL32 fPrevious )
1449 WND *pWnd, *pWndLast, *pWndCtrl, *pWndDlg;
1451 if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0;
1452 if (hwndCtrl)
1454 if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0;
1455 /* Make sure hwndCtrl is a top-level child */
1456 while ((pWndCtrl->dwStyle & WS_CHILD) && (pWndCtrl->parent != pWndDlg))
1457 pWndCtrl = pWndCtrl->parent;
1458 if (pWndCtrl->parent != pWndDlg) return 0;
1460 else
1462 /* No ctrl specified -> start from the beginning */
1463 if (!(pWndCtrl = pWndDlg->child)) return 0;
1464 if (fPrevious) while (pWndCtrl->next) pWndCtrl = pWndCtrl->next;
1467 pWndLast = pWndCtrl;
1468 pWnd = pWndCtrl->next;
1469 while (1)
1471 if (!pWnd || (pWnd->dwStyle & WS_GROUP))
1473 /* Wrap-around to the beginning of the group */
1474 WND *pWndStart = pWndDlg->child;
1475 for (pWnd = pWndStart; pWnd; pWnd = pWnd->next)
1477 if (pWnd->dwStyle & WS_GROUP) pWndStart = pWnd;
1478 if (pWnd == pWndCtrl) break;
1480 pWnd = pWndStart;
1482 if (pWnd == pWndCtrl) break;
1483 if ((pWnd->dwStyle & WS_VISIBLE) && !(pWnd->dwStyle & WS_DISABLED))
1485 pWndLast = pWnd;
1486 if (!fPrevious) break;
1488 pWnd = pWnd->next;
1490 return pWndLast->hwndSelf;
1494 /***********************************************************************
1495 * GetNextDlgTabItem16 (USER.228)
1497 HWND16 WINAPI GetNextDlgTabItem16( HWND16 hwndDlg, HWND16 hwndCtrl,
1498 BOOL16 fPrevious )
1500 return (HWND16)GetNextDlgTabItem32( hwndDlg, hwndCtrl, fPrevious );
1504 /***********************************************************************
1505 * GetNextDlgTabItem32 (USER32.275)
1507 HWND32 WINAPI GetNextDlgTabItem32( HWND32 hwndDlg, HWND32 hwndCtrl,
1508 BOOL32 fPrevious )
1510 WND *pWnd, *pWndLast, *pWndCtrl, *pWndDlg;
1512 if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0;
1513 if (hwndCtrl)
1515 if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0;
1516 /* Make sure hwndCtrl is a top-level child */
1517 while ((pWndCtrl->dwStyle & WS_CHILD) && (pWndCtrl->parent != pWndDlg))
1518 pWndCtrl = pWndCtrl->parent;
1519 if (pWndCtrl->parent != pWndDlg) return 0;
1521 else
1523 /* No ctrl specified -> start from the beginning */
1524 if (!(pWndCtrl = pWndDlg->child)) return 0;
1525 if (fPrevious) while (pWndCtrl->next) pWndCtrl = pWndCtrl->next;
1528 pWndLast = pWndCtrl;
1529 pWnd = pWndCtrl->next;
1530 while (1)
1532 if (!pWnd) pWnd = pWndDlg->child;
1533 if (pWnd == pWndCtrl) break;
1534 if ((pWnd->dwStyle & WS_TABSTOP) && (pWnd->dwStyle & WS_VISIBLE) &&
1535 !(pWnd->dwStyle & WS_DISABLED))
1537 pWndLast = pWnd;
1538 if (!fPrevious) break;
1540 pWnd = pWnd->next;
1542 return pWndLast->hwndSelf;
1546 /**********************************************************************
1547 * DIALOG_DlgDirSelect
1549 * Helper function for DlgDirSelect*
1551 static BOOL32 DIALOG_DlgDirSelect( HWND32 hwnd, LPSTR str, INT32 len,
1552 INT32 id, BOOL32 win32, BOOL32 unicode,
1553 BOOL32 combo )
1555 char *buffer, *ptr;
1556 INT32 item, size;
1557 BOOL32 ret;
1558 HWND32 listbox = GetDlgItem32( hwnd, id );
1560 dprintf_dialog( stddeb, "DlgDirSelect: %04x '%s' %d\n", hwnd, str, id );
1561 if (!listbox) return FALSE;
1562 if (win32)
1564 item = SendMessage32A(listbox, combo ? CB_GETCURSEL32
1565 : LB_GETCURSEL32, 0, 0 );
1566 if (item == LB_ERR) return FALSE;
1567 size = SendMessage32A(listbox, combo ? CB_GETLBTEXTLEN32
1568 : LB_GETTEXTLEN32, 0, 0 );
1569 if (size == LB_ERR) return FALSE;
1571 else
1573 item = SendMessage32A(listbox, combo ? CB_GETCURSEL16
1574 : LB_GETCURSEL16, 0, 0 );
1575 if (item == LB_ERR) return FALSE;
1576 size = SendMessage32A(listbox, combo ? CB_GETLBTEXTLEN16
1577 : LB_GETTEXTLEN16, 0, 0 );
1578 if (size == LB_ERR) return FALSE;
1581 if (!(buffer = SEGPTR_ALLOC( size+1 ))) return FALSE;
1583 if (win32)
1584 SendMessage32A( listbox, combo ? CB_GETLBTEXT32 : LB_GETTEXT32,
1585 item, (LPARAM)buffer );
1586 else
1587 SendMessage16( listbox, combo ? CB_GETLBTEXT16 : LB_GETTEXT16,
1588 item, (LPARAM)SEGPTR_GET(buffer) );
1590 if ((ret = (buffer[0] == '['))) /* drive or directory */
1592 if (buffer[1] == '-') /* drive */
1594 buffer[3] = ':';
1595 buffer[4] = 0;
1596 ptr = buffer + 2;
1598 else
1600 buffer[strlen(buffer)-1] = '\\';
1601 ptr = buffer + 1;
1604 else ptr = buffer;
1606 if (unicode) lstrcpynAtoW( (LPWSTR)str, ptr, len );
1607 else lstrcpyn32A( str, ptr, len );
1608 SEGPTR_FREE( buffer );
1609 dprintf_dialog( stddeb, "Returning %d '%s'\n", ret, str );
1610 return ret;
1614 /**********************************************************************
1615 * DIALOG_DlgDirList
1617 * Helper function for DlgDirList*
1619 static INT32 DIALOG_DlgDirList( HWND32 hDlg, LPSTR spec, INT32 idLBox,
1620 INT32 idStatic, UINT32 attrib, BOOL32 combo )
1622 int drive;
1623 HWND32 hwnd;
1624 LPSTR orig_spec = spec;
1626 #define SENDMSG(msg,wparam,lparam) \
1627 ((attrib & DDL_POSTMSGS) ? PostMessage32A( hwnd, msg, wparam, lparam ) \
1628 : SendMessage32A( hwnd, msg, wparam, lparam ))
1630 dprintf_dialog( stddeb, "DlgDirList: %04x '%s' %d %d %04x\n",
1631 hDlg, spec ? spec : "NULL", idLBox, idStatic, attrib );
1633 if (spec && spec[0] && (spec[1] == ':'))
1635 drive = toupper( spec[0] ) - 'A';
1636 spec += 2;
1637 if (!DRIVE_SetCurrentDrive( drive )) return FALSE;
1639 else drive = DRIVE_GetCurrentDrive();
1641 /* If the path exists and is a directory, chdir to it */
1642 if (!spec || !spec[0] || DRIVE_Chdir( drive, spec )) spec = "*.*";
1643 else
1645 char *p, *p2;
1646 p = spec;
1647 if ((p2 = strrchr( p, '\\' ))) p = p2;
1648 if ((p2 = strrchr( p, '/' ))) p = p2;
1649 if (p != spec)
1651 char sep = *p;
1652 *p = 0;
1653 if (!DRIVE_Chdir( drive, spec ))
1655 *p = sep; /* Restore the original spec */
1656 return FALSE;
1658 spec = p + 1;
1662 dprintf_dialog( stddeb, "ListBoxDirectory: path=%c:\\%s mask=%s\n",
1663 'A' + drive, DRIVE_GetDosCwd(drive), spec );
1665 if (idLBox && ((hwnd = GetDlgItem32( hDlg, idLBox )) != 0))
1667 SENDMSG( combo ? CB_RESETCONTENT32 : LB_RESETCONTENT32, 0, 0 );
1668 if (attrib & DDL_DIRECTORY)
1670 if (!(attrib & DDL_EXCLUSIVE))
1672 if (SENDMSG( combo ? CB_DIR32 : LB_DIR32,
1673 attrib & ~(DDL_DIRECTORY | DDL_DRIVES),
1674 (LPARAM)spec ) == LB_ERR)
1675 return FALSE;
1677 if (SENDMSG( combo ? CB_DIR32 : LB_DIR32,
1678 (attrib & (DDL_DIRECTORY | DDL_DRIVES)) | DDL_EXCLUSIVE,
1679 (LPARAM)"*.*" ) == LB_ERR)
1680 return FALSE;
1682 else
1684 if (SENDMSG( combo ? CB_DIR32 : LB_DIR32, attrib,
1685 (LPARAM)spec ) == LB_ERR)
1686 return FALSE;
1690 if (idStatic && ((hwnd = GetDlgItem32( hDlg, idStatic )) != 0))
1692 char temp[512];
1693 int drive = DRIVE_GetCurrentDrive();
1694 strcpy( temp, "A:\\" );
1695 temp[0] += drive;
1696 lstrcpyn32A( temp + 3, DRIVE_GetDosCwd(drive), sizeof(temp)-3 );
1697 CharLower32A( temp );
1698 /* Can't use PostMessage() here, because the string is on the stack */
1699 SetDlgItemText32A( hDlg, idStatic, temp );
1702 if (orig_spec && (spec != orig_spec))
1704 /* Update the original file spec */
1705 char *p = spec;
1706 while ((*orig_spec++ = *p++));
1709 return TRUE;
1710 #undef SENDMSG
1714 /**********************************************************************
1715 * DIALOG_DlgDirListW
1717 * Helper function for DlgDirList*32W
1719 static INT32 DIALOG_DlgDirListW( HWND32 hDlg, LPWSTR spec, INT32 idLBox,
1720 INT32 idStatic, UINT32 attrib, BOOL32 combo )
1722 if (spec)
1724 LPSTR specA = HEAP_strdupWtoA( GetProcessHeap(), 0, spec );
1725 INT32 ret = DIALOG_DlgDirList( hDlg, specA, idLBox, idStatic,
1726 attrib, combo );
1727 lstrcpyAtoW( spec, specA );
1728 HeapFree( GetProcessHeap(), 0, specA );
1729 return ret;
1731 return DIALOG_DlgDirList( hDlg, NULL, idLBox, idStatic, attrib, combo );
1735 /**********************************************************************
1736 * DlgDirSelect (USER.99)
1738 BOOL16 WINAPI DlgDirSelect( HWND16 hwnd, LPSTR str, INT16 id )
1740 return DlgDirSelectEx16( hwnd, str, 128, id );
1744 /**********************************************************************
1745 * DlgDirSelectComboBox (USER.194)
1747 BOOL16 WINAPI DlgDirSelectComboBox( HWND16 hwnd, LPSTR str, INT16 id )
1749 return DlgDirSelectComboBoxEx16( hwnd, str, 128, id );
1753 /**********************************************************************
1754 * DlgDirSelectEx16 (USER.422)
1756 BOOL16 WINAPI DlgDirSelectEx16( HWND16 hwnd, LPSTR str, INT16 len, INT16 id )
1758 return DIALOG_DlgDirSelect( hwnd, str, len, id, FALSE, FALSE, FALSE );
1762 /**********************************************************************
1763 * DlgDirSelectEx32A (USER32.148)
1765 BOOL32 WINAPI DlgDirSelectEx32A( HWND32 hwnd, LPSTR str, INT32 len, INT32 id )
1767 return DIALOG_DlgDirSelect( hwnd, str, len, id, TRUE, FALSE, FALSE );
1771 /**********************************************************************
1772 * DlgDirSelectEx32W (USER32.149)
1774 BOOL32 WINAPI DlgDirSelectEx32W( HWND32 hwnd, LPWSTR str, INT32 len, INT32 id )
1776 return DIALOG_DlgDirSelect( hwnd, (LPSTR)str, len, id, TRUE, TRUE, FALSE );
1780 /**********************************************************************
1781 * DlgDirSelectComboBoxEx16 (USER.423)
1783 BOOL16 WINAPI DlgDirSelectComboBoxEx16( HWND16 hwnd, LPSTR str, INT16 len,
1784 INT16 id )
1786 return DIALOG_DlgDirSelect( hwnd, str, len, id, FALSE, FALSE, TRUE );
1790 /**********************************************************************
1791 * DlgDirSelectComboBoxEx32A (USER32.146)
1793 BOOL32 WINAPI DlgDirSelectComboBoxEx32A( HWND32 hwnd, LPSTR str, INT32 len,
1794 INT32 id )
1796 return DIALOG_DlgDirSelect( hwnd, str, len, id, TRUE, FALSE, TRUE );
1800 /**********************************************************************
1801 * DlgDirSelectComboBoxEx32W (USER32.147)
1803 BOOL32 WINAPI DlgDirSelectComboBoxEx32W( HWND32 hwnd, LPWSTR str, INT32 len,
1804 INT32 id)
1806 return DIALOG_DlgDirSelect( hwnd, (LPSTR)str, len, id, TRUE, TRUE, TRUE );
1810 /**********************************************************************
1811 * DlgDirList16 (USER.100)
1813 INT16 WINAPI DlgDirList16( HWND16 hDlg, LPSTR spec, INT16 idLBox,
1814 INT16 idStatic, UINT16 attrib )
1816 return DIALOG_DlgDirList( hDlg, spec, idLBox, idStatic, attrib, FALSE );
1820 /**********************************************************************
1821 * DlgDirList32A (USER32.142)
1823 INT32 WINAPI DlgDirList32A( HWND32 hDlg, LPSTR spec, INT32 idLBox,
1824 INT32 idStatic, UINT32 attrib )
1826 return DIALOG_DlgDirList( hDlg, spec, idLBox, idStatic, attrib, FALSE );
1830 /**********************************************************************
1831 * DlgDirList32W (USER32.145)
1833 INT32 WINAPI DlgDirList32W( HWND32 hDlg, LPWSTR spec, INT32 idLBox,
1834 INT32 idStatic, UINT32 attrib )
1836 return DIALOG_DlgDirListW( hDlg, spec, idLBox, idStatic, attrib, FALSE );
1840 /**********************************************************************
1841 * DlgDirListComboBox16 (USER.195)
1843 INT16 WINAPI DlgDirListComboBox16( HWND16 hDlg, LPSTR spec, INT16 idCBox,
1844 INT16 idStatic, UINT16 attrib )
1846 return DIALOG_DlgDirList( hDlg, spec, idCBox, idStatic, attrib, TRUE );
1850 /**********************************************************************
1851 * DlgDirListComboBox32A (USER32.143)
1853 INT32 WINAPI DlgDirListComboBox32A( HWND32 hDlg, LPSTR spec, INT32 idCBox,
1854 INT32 idStatic, UINT32 attrib )
1856 return DIALOG_DlgDirList( hDlg, spec, idCBox, idStatic, attrib, TRUE );
1860 /**********************************************************************
1861 * DlgDirListComboBox32W (USER32.144)
1863 INT32 WINAPI DlgDirListComboBox32W( HWND32 hDlg, LPWSTR spec, INT32 idCBox,
1864 INT32 idStatic, UINT32 attrib )
1866 return DIALOG_DlgDirListW( hDlg, spec, idCBox, idStatic, attrib, TRUE );