Release 970112
[wine/multimedia.git] / windows / dialog.c
blobbcd73eaf3f9724432f2c61ab749a1cde68101f71
1 /*
2 * Dialog functions
4 * Copyright 1993, 1994, 1996 Alexandre Julliard
5 */
7 #include <ctype.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include "windows.h"
12 #include "dialog.h"
13 #include "drive.h"
14 #include "heap.h"
15 #include "win.h"
16 #include "ldt.h"
17 #include "user.h"
18 #include "winproc.h"
19 #include "message.h"
20 #include "sysmetrics.h"
21 #include "stddebug.h"
22 #include "debug.h"
25 /* Dialog control information */
26 typedef struct
28 DWORD style;
29 DWORD exStyle;
30 INT16 x;
31 INT16 y;
32 INT16 cx;
33 INT16 cy;
34 UINT16 id;
35 LPCSTR className;
36 LPCSTR windowName;
37 LPVOID data;
38 } DLG_CONTROL_INFO;
40 /* Dialog template */
41 typedef struct
43 DWORD style;
44 DWORD exStyle;
45 UINT16 nbItems;
46 INT16 x;
47 INT16 y;
48 INT16 cx;
49 INT16 cy;
50 LPCSTR menuName;
51 LPCSTR className;
52 LPCSTR caption;
53 WORD pointSize;
54 LPCSTR faceName;
55 } DLG_TEMPLATE;
57 /* Dialog base units */
58 static WORD xBaseUnit = 0, yBaseUnit = 0;
61 /***********************************************************************
62 * DIALOG_Init
64 * Initialisation of the dialog manager.
66 BOOL32 DIALOG_Init()
68 TEXTMETRIC16 tm;
69 HDC16 hdc;
71 /* Calculate the dialog base units */
73 if (!(hdc = CreateDC16( "DISPLAY", NULL, NULL, NULL ))) return FALSE;
74 GetTextMetrics16( hdc, &tm );
75 DeleteDC32( hdc );
76 xBaseUnit = tm.tmAveCharWidth;
77 yBaseUnit = tm.tmHeight;
79 /* Dialog units are based on a proportional system font */
80 /* so we adjust them a bit for a fixed font. */
81 if (!(tm.tmPitchAndFamily & TMPF_FIXED_PITCH))
82 xBaseUnit = xBaseUnit * 5 / 4;
84 dprintf_dialog( stddeb, "DIALOG_Init: base units = %d,%d\n",
85 xBaseUnit, yBaseUnit );
86 return TRUE;
90 /***********************************************************************
91 * DIALOG_GetControl16
93 * Return the class and text of the control pointed to by ptr,
94 * fill the header structure and return a pointer to the next control.
96 static LPCSTR DIALOG_GetControl16( LPCSTR p, DLG_CONTROL_INFO *info )
98 static char buffer[10];
100 info->x = GET_WORD(p); p += sizeof(WORD);
101 info->y = GET_WORD(p); p += sizeof(WORD);
102 info->cx = GET_WORD(p); p += sizeof(WORD);
103 info->cy = GET_WORD(p); p += sizeof(WORD);
104 info->id = GET_WORD(p); p += sizeof(WORD);
105 info->style = GET_DWORD(p); p += sizeof(DWORD);
106 info->exStyle = 0;
108 if (*p & 0x80)
110 switch((BYTE)*p)
112 case 0x80: strcpy( buffer, "BUTTON" ); break;
113 case 0x81: strcpy( buffer, "EDIT" ); break;
114 case 0x82: strcpy( buffer, "STATIC" ); break;
115 case 0x83: strcpy( buffer, "LISTBOX" ); break;
116 case 0x84: strcpy( buffer, "SCROLLBAR" ); break;
117 case 0x85: strcpy( buffer, "COMBOBOX" ); break;
118 default: buffer[0] = '\0'; break;
120 info->className = buffer;
121 p++;
123 else
125 info->className = p;
126 p += strlen(p) + 1;
128 dprintf_dialog(stddeb, " %s ", info->className );
130 if ((BYTE)*p == 0xff)
132 /* Integer id, not documented (?). Only works for SS_ICON controls */
133 info->windowName = (LPCSTR)(UINT32)GET_WORD(p+1);
134 p += 3;
135 dprintf_dialog( stddeb,"%04x", LOWORD(info->windowName) );
137 else
139 info->windowName = p;
140 p += strlen(p) + 1;
141 dprintf_dialog(stddeb,"'%s'", info->windowName );
144 info->data = (LPVOID)(*p ? p + 1 : NULL); /* FIXME: should be a segptr */
145 p += *p + 1;
147 dprintf_dialog( stddeb," %d, %d, %d, %d, %d, %08lx, %08lx\n",
148 info->id, info->x, info->y, info->cx, info->cy,
149 info->style, (DWORD)info->data);
150 return p;
154 /***********************************************************************
155 * DIALOG_GetControl32
157 * Return the class and text of the control pointed to by ptr,
158 * fill the header structure and return a pointer to the next control.
160 static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info )
162 static WCHAR buffer[10];
164 info->style = GET_DWORD(p); p += 2;
165 info->exStyle = GET_DWORD(p); p += 2;
166 info->x = GET_WORD(p); p++;
167 info->y = GET_WORD(p); p++;
168 info->cx = GET_WORD(p); p++;
169 info->cy = GET_WORD(p); p++;
170 info->id = GET_WORD(p); p++;
172 if (GET_WORD(p) == 0xffff)
174 switch(GET_WORD(p+1))
176 case 0x80: lstrcpyAtoW( buffer, "Button" ); break;
177 case 0x81: lstrcpyAtoW( buffer, "Edit" ); break;
178 case 0x82: lstrcpyAtoW( buffer, "Static" ); break;
179 case 0x83: lstrcpyAtoW( buffer, "ListBox" ); break;
180 case 0x84: lstrcpyAtoW( buffer, "ScrollBar" ); break;
181 case 0x85: lstrcpyAtoW( buffer, "ComboBox" ); break;
182 default: buffer[0] = '\0'; break;
184 info->className = (LPCSTR)buffer;
185 p += 2;
187 else
189 info->className = (LPCSTR)p;
190 p += lstrlen32W( (LPCWSTR)p ) + 1;
192 dprintf_dialog(stddeb, " %p ", info->className );
194 if (GET_WORD(p) == 0xffff)
196 info->windowName = (LPCSTR)(p + 1);
197 p += 2;
198 dprintf_dialog( stddeb,"%04x", LOWORD(info->windowName) );
200 else
202 info->windowName = (LPCSTR)p;
203 p += lstrlen32W( (LPCWSTR)p ) + 1;
204 dprintf_dialog(stddeb,"'%p'", info->windowName );
207 if (GET_WORD(p))
209 info->data = (LPVOID)(p + 1);
210 p += GET_WORD(p) / sizeof(WORD);
212 else info->data = NULL;
213 p++;
215 dprintf_dialog( stddeb," %d, %d, %d, %d, %d, %08lx, %08lx, %08lx\n",
216 info->id, info->x, info->y, info->cx, info->cy,
217 info->style, info->exStyle, (DWORD)info->data);
218 /* Next control is on dword boundary */
219 return (const WORD *)((((int)p) + 3) & ~3);
223 /***********************************************************************
224 * DIALOG_CreateControls
226 * Create the control windows for a dialog.
228 static BOOL32 DIALOG_CreateControls( WND *pWnd, LPCSTR template, INT32 items,
229 HINSTANCE32 hInst, BOOL win32 )
231 DIALOGINFO *dlgInfo = (DIALOGINFO *)pWnd->wExtra;
232 DLG_CONTROL_INFO info;
233 HWND32 hwndCtrl, hwndDefButton = 0;
235 dprintf_dialog(stddeb, " BEGIN\n" );
236 while (items--)
238 if (!win32)
240 HINSTANCE16 instance;
241 template = DIALOG_GetControl16( template, &info );
242 if (HIWORD(info.className) && !strcmp( info.className, "EDIT") &&
243 ((pWnd->dwStyle & DS_LOCALEDIT) != DS_LOCALEDIT))
245 if (!dlgInfo->hDialogHeap)
247 dlgInfo->hDialogHeap = GlobalAlloc16(GMEM_FIXED, 0x10000);
248 if (!dlgInfo->hDialogHeap)
250 fprintf( stderr, "CreateDialogIndirectParam: Insufficient memory to create heap for edit control\n" );
251 continue;
253 LocalInit(dlgInfo->hDialogHeap, 0, 0xffff);
255 instance = dlgInfo->hDialogHeap;
257 else instance = (HINSTANCE16)hInst;
259 hwndCtrl = CreateWindowEx16( info.exStyle | WS_EX_NOPARENTNOTIFY,
260 info.className, info.windowName,
261 info.style | WS_CHILD,
262 info.x * dlgInfo->xBaseUnit / 4,
263 info.y * dlgInfo->yBaseUnit / 8,
264 info.cx * dlgInfo->xBaseUnit / 4,
265 info.cy * dlgInfo->yBaseUnit / 8,
266 pWnd->hwndSelf, (HMENU16)info.id,
267 instance, info.data );
269 else
271 template = (LPCSTR)DIALOG_GetControl32( (WORD *)template, &info );
272 hwndCtrl = CreateWindowEx32W( info.exStyle | WS_EX_NOPARENTNOTIFY,
273 (LPCWSTR)info.className,
274 (LPCWSTR)info.windowName,
275 info.style | WS_CHILD,
276 info.x * dlgInfo->xBaseUnit / 4,
277 info.y * dlgInfo->yBaseUnit / 8,
278 info.cx * dlgInfo->xBaseUnit / 4,
279 info.cy * dlgInfo->yBaseUnit / 8,
280 pWnd->hwndSelf, (HMENU32)info.id,
281 hInst, info.data );
283 if (!hwndCtrl) return FALSE;
285 /* Send initialisation messages to the control */
286 if (dlgInfo->hUserFont) SendMessage32A( hwndCtrl, WM_SETFONT,
287 (WPARAM32)dlgInfo->hUserFont, 0 );
288 if (SendMessage32A(hwndCtrl, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
290 /* If there's already a default push-button, set it back */
291 /* to normal and use this one instead. */
292 if (hwndDefButton)
293 SendMessage32A( hwndDefButton, BM_SETSTYLE32,
294 BS_PUSHBUTTON,FALSE );
295 hwndDefButton = hwndCtrl;
296 dlgInfo->idResult = GetWindowWord( hwndCtrl, GWW_ID );
299 dprintf_dialog(stddeb, " END\n" );
300 return TRUE;
304 /***********************************************************************
305 * DIALOG_ParseTemplate16
307 * Fill a DLG_TEMPLATE structure from the dialog template, and return
308 * a pointer to the first control.
310 static LPCSTR DIALOG_ParseTemplate16( LPCSTR p, DLG_TEMPLATE * result )
312 result->style = GET_DWORD(p); p += sizeof(DWORD);
313 result->exStyle = 0;
314 result->nbItems = *p++;
315 result->x = GET_WORD(p); p += sizeof(WORD);
316 result->y = GET_WORD(p); p += sizeof(WORD);
317 result->cx = GET_WORD(p); p += sizeof(WORD);
318 result->cy = GET_WORD(p); p += sizeof(WORD);
319 dprintf_dialog( stddeb, "DIALOG %d, %d, %d, %d\n",
320 result->x, result->y, result->cx, result->cy );
321 dprintf_dialog( stddeb, " STYLE %08lx\n", result->style );
323 /* Get the menu name */
325 switch( (BYTE)*p )
327 case 0:
328 result->menuName = 0;
329 p++;
330 break;
331 case 0xff:
332 result->menuName = (LPCSTR)(UINT32)GET_WORD( p + 1 );
333 p += 3;
334 dprintf_dialog(stddeb, " MENU %04x\n", LOWORD(result->menuName) );
335 break;
336 default:
337 result->menuName = p;
338 dprintf_dialog( stddeb, " MENU '%s'\n", p );
339 p += strlen(p) + 1;
340 break;
343 /* Get the class name */
345 if (*p)
347 result->className = p;
348 dprintf_dialog( stddeb, " CLASS '%s'\n", result->className );
350 else result->className = DIALOG_CLASS_ATOM;
351 p += strlen(p) + 1;
353 /* Get the window caption */
355 result->caption = p;
356 p += strlen(p) + 1;
357 dprintf_dialog( stddeb, " CAPTION '%s'\n", result->caption );
359 /* Get the font name */
361 if (result->style & DS_SETFONT)
363 result->pointSize = GET_WORD(p);
364 p += sizeof(WORD);
365 result->faceName = p;
366 p += strlen(p) + 1;
367 dprintf_dialog( stddeb, " FONT %d,'%s'\n",
368 result->pointSize, result->faceName );
370 return p;
374 /***********************************************************************
375 * DIALOG_ParseTemplate32
377 * Fill a DLG_TEMPLATE structure from the dialog template, and return
378 * a pointer to the first control.
380 static LPCSTR DIALOG_ParseTemplate32( LPCSTR template, DLG_TEMPLATE * result )
382 const WORD *p = (const WORD *)template;
384 result->style = GET_DWORD(p); p += 2;
385 result->exStyle = GET_DWORD(p); p += 2;
386 result->nbItems = GET_WORD(p); p++;
387 result->x = GET_WORD(p); p++;
388 result->y = GET_WORD(p); p++;
389 result->cx = GET_WORD(p); p++;
390 result->cy = GET_WORD(p); p++;
391 dprintf_dialog( stddeb, "DIALOG %d, %d, %d, %d\n",
392 result->x, result->y, result->cx, result->cy );
393 dprintf_dialog( stddeb, " STYLE %08lx\n", result->style );
394 dprintf_dialog( stddeb, " EXSTYLE %08lx\n", result->exStyle );
396 /* Get the menu name */
398 switch(GET_WORD(p))
400 case 0x0000:
401 result->menuName = NULL;
402 p++;
403 break;
404 case 0xffff:
405 result->menuName = (LPCSTR)(UINT32)GET_WORD( p + 1 );
406 p += 2;
407 dprintf_dialog(stddeb, " MENU %04x\n", LOWORD(result->menuName) );
408 break;
409 default:
410 result->menuName = (LPCSTR)p;
411 dprintf_dialog( stddeb, " MENU '%p'\n", p );
412 p += lstrlen32W( (LPCWSTR)p ) + 1;
413 break;
416 /* Get the class name */
418 switch(GET_WORD(p))
420 case 0x0000:
421 result->className = DIALOG_CLASS_ATOM;
422 p++;
423 break;
424 case 0xffff:
425 result->className = (LPCSTR)(UINT32)GET_WORD( p + 1 );
426 p += 2;
427 dprintf_dialog(stddeb, " CLASS %04x\n", LOWORD(result->className) );
428 break;
429 default:
430 result->className = (LPCSTR)p;
431 dprintf_dialog( stddeb, " CLASS '%p'\n", p );
432 p += lstrlen32W( (LPCWSTR)p ) + 1;
433 break;
436 /* Get the window caption */
438 result->caption = (LPCSTR)p;
439 p += lstrlen32W( (LPCWSTR)p ) + 1;
440 dprintf_dialog( stddeb, " CAPTION '%p'\n", result->caption );
442 /* Get the font name */
444 if (result->style & DS_SETFONT)
446 result->pointSize = GET_WORD(p);
447 p++;
448 result->faceName = (LPCSTR)p;
449 p += lstrlen32W( (LPCWSTR)p ) + 1;
450 dprintf_dialog( stddeb, " FONT %d,'%p'\n",
451 result->pointSize, result->faceName );
453 /* First control is on dword boundary */
454 return (LPCSTR)((((int)p) + 3) & ~3);
458 /***********************************************************************
459 * DIALOG_CreateIndirect
461 HWND32 DIALOG_CreateIndirect( HINSTANCE32 hInst, LPCSTR dlgTemplate,
462 BOOL32 win32Template, HWND32 owner,
463 DLGPROC16 dlgProc, LPARAM param,
464 WINDOWPROCTYPE procType )
466 HMENU16 hMenu = 0;
467 HFONT16 hFont = 0;
468 HWND hwnd;
469 RECT16 rect;
470 WND * wndPtr;
471 DLG_TEMPLATE template;
472 DIALOGINFO * dlgInfo;
473 WORD xUnit = xBaseUnit;
474 WORD yUnit = yBaseUnit;
476 /* Parse dialog template */
478 if (!dlgTemplate) return 0;
479 if (win32Template)
480 dlgTemplate = DIALOG_ParseTemplate32( dlgTemplate, &template );
481 else
482 dlgTemplate = DIALOG_ParseTemplate16( dlgTemplate, &template );
484 /* Load menu */
486 if (template.menuName)
488 LPSTR str = SEGPTR_STRDUP( template.menuName ); /* FIXME: win32 */
489 hMenu = LoadMenu16( hInst, SEGPTR_GET(str) );
490 SEGPTR_FREE( str );
493 /* Create custom font if needed */
495 if (template.style & DS_SETFONT)
497 /* The font height must be negative as it is a point size */
498 /* (see CreateFont() documentation in the Windows SDK). */
499 hFont = CreateFont16( -template.pointSize, 0, 0, 0, FW_DONTCARE,
500 FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
501 DEFAULT_QUALITY, FF_DONTCARE,
502 template.faceName ); /* FIXME: win32 */
503 if (hFont)
505 TEXTMETRIC16 tm;
506 HFONT16 oldFont;
508 HDC32 hdc = GetDC32(0);
509 oldFont = SelectObject32( hdc, hFont );
510 GetTextMetrics16( hdc, &tm );
511 SelectObject32( hdc, oldFont );
512 ReleaseDC32( 0, hdc );
513 xUnit = tm.tmAveCharWidth;
514 yUnit = tm.tmHeight;
515 if (!(tm.tmPitchAndFamily & TMPF_FIXED_PITCH))
516 xBaseUnit = xBaseUnit * 5 / 4; /* See DIALOG_Init() */
520 /* Create dialog main window */
522 rect.left = rect.top = 0;
523 rect.right = template.cx * xUnit / 4;
524 rect.bottom = template.cy * yUnit / 8;
525 if (template.style & DS_MODALFRAME)
526 template.exStyle |= WS_EX_DLGMODALFRAME;
527 AdjustWindowRectEx16( &rect, template.style,
528 hMenu ? TRUE : FALSE , template.exStyle );
529 rect.right -= rect.left;
530 rect.bottom -= rect.top;
532 if ((INT16)template.x == CW_USEDEFAULT16)
534 rect.left = rect.top = (procType == WIN_PROC_16) ? CW_USEDEFAULT16
535 : CW_USEDEFAULT32;
537 else
539 rect.left += template.x * xUnit / 4;
540 rect.top += template.y * yUnit / 8;
541 if ( !(template.style & WS_CHILD) )
543 INT16 dX, dY;
545 if( !(template.style & DS_ABSALIGN) )
546 ClientToScreen16( owner, (POINT16 *)&rect );
548 /* try to fit it into the desktop */
550 if( (dX = rect.left + rect.right + SYSMETRICS_CXDLGFRAME
551 - SYSMETRICS_CXSCREEN) > 0 ) rect.left -= dX;
552 if( (dY = rect.top + rect.bottom + SYSMETRICS_CYDLGFRAME
553 - SYSMETRICS_CYSCREEN) > 0 ) rect.top -= dY;
554 if( rect.left < 0 ) rect.left = 0;
555 if( rect.top < 0 ) rect.top = 0;
559 if (procType != WIN_PROC_16)
560 hwnd = CreateWindowEx32W(template.exStyle, (LPCWSTR)template.className,
561 (LPCWSTR)template.caption,
562 template.style & ~WS_VISIBLE,
563 rect.left, rect.top, rect.right, rect.bottom,
564 owner, hMenu, hInst, NULL );
565 else
566 hwnd = CreateWindowEx16(template.exStyle, template.className,
567 template.caption, template.style & ~WS_VISIBLE,
568 rect.left, rect.top, rect.right, rect.bottom,
569 owner, hMenu, hInst, NULL );
570 if (!hwnd)
572 if (hFont) DeleteObject32( hFont );
573 if (hMenu) DestroyMenu32( hMenu );
574 return 0;
576 wndPtr = WIN_FindWndPtr( hwnd );
577 wndPtr->flags |= WIN_ISDIALOG;
579 /* Initialise dialog extra data */
581 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
582 WINPROC_SetProc( &dlgInfo->dlgProc, dlgProc, procType );
583 dlgInfo->hUserFont = hFont;
584 dlgInfo->hMenu = hMenu;
585 dlgInfo->xBaseUnit = xUnit;
586 dlgInfo->yBaseUnit = yUnit;
587 dlgInfo->msgResult = 0;
588 dlgInfo->idResult = 0;
589 dlgInfo->hDialogHeap = 0;
591 if (dlgInfo->hUserFont)
592 SendMessage32A( hwnd, WM_SETFONT, (WPARAM32)dlgInfo->hUserFont, 0 );
594 /* Create controls */
596 if (!DIALOG_CreateControls( wndPtr, dlgTemplate, template.nbItems,
597 hInst, win32Template ))
599 DestroyWindow( hwnd );
600 return 0;
603 /* Send initialisation messages and set focus */
605 dlgInfo->hwndFocus = GetNextDlgTabItem32( hwnd, 0, FALSE );
606 if (SendMessage32A( hwnd, WM_INITDIALOG,
607 (WPARAM32)dlgInfo->hwndFocus, param ))
608 SetFocus32( dlgInfo->hwndFocus );
609 if (template.style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
610 return hwnd;
614 /***********************************************************************
615 * CreateDialog16 (USER.89)
617 HWND16 CreateDialog16( HINSTANCE16 hInst, SEGPTR dlgTemplate,
618 HWND16 owner, DLGPROC16 dlgProc )
620 return CreateDialogParam16( hInst, dlgTemplate, owner, dlgProc, 0 );
624 /***********************************************************************
625 * CreateDialogParam16 (USER.241)
627 HWND16 CreateDialogParam16( HINSTANCE16 hInst, SEGPTR dlgTemplate,
628 HWND16 owner, DLGPROC16 dlgProc, LPARAM param )
630 HWND16 hwnd = 0;
631 HRSRC16 hRsrc;
632 HGLOBAL16 hmem;
633 LPCVOID data;
635 dprintf_dialog(stddeb, "CreateDialogParam16: %04x,%08lx,%04x,%08lx,%ld\n",
636 hInst, (DWORD)dlgTemplate, owner, (DWORD)dlgProc, param );
638 if (!(hRsrc = FindResource16( hInst, dlgTemplate, RT_DIALOG ))) return 0;
639 if (!(hmem = LoadResource16( hInst, hRsrc ))) return 0;
640 if (!(data = LockResource16( hmem ))) hwnd = 0;
641 else hwnd = CreateDialogIndirectParam16( hInst, data, owner,
642 dlgProc, param );
643 FreeResource16( hmem );
644 return hwnd;
648 /***********************************************************************
649 * CreateDialogParam32A (USER32.72)
651 HWND32 CreateDialogParam32A( HINSTANCE32 hInst, LPCSTR name,
652 HWND32 owner, DLGPROC32 dlgProc, LPARAM param )
654 if (HIWORD(name))
656 LPWSTR str = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
657 HWND32 hwnd = CreateDialogParam32W( hInst, str, owner, dlgProc, param);
658 HeapFree( GetProcessHeap(), 0, str );
659 return hwnd;
661 return CreateDialogParam32W( hInst, (LPCWSTR)name, owner, dlgProc, param );
665 /***********************************************************************
666 * CreateDialogParam32W (USER32.73)
668 HWND32 CreateDialogParam32W( HINSTANCE32 hInst, LPCWSTR name,
669 HWND32 owner, DLGPROC32 dlgProc, LPARAM param )
671 HANDLE32 hrsrc = FindResource32W( hInst, name, (LPWSTR)RT_DIALOG );
672 if (!hrsrc) return 0;
673 return CreateDialogIndirectParam32W( hInst,
674 (LPVOID)LoadResource32(hInst, hrsrc),
675 owner, dlgProc, param );
679 /***********************************************************************
680 * CreateDialogIndirect16 (USER.219)
682 HWND16 CreateDialogIndirect16( HINSTANCE16 hInst, LPCVOID dlgTemplate,
683 HWND16 owner, DLGPROC16 dlgProc )
685 return CreateDialogIndirectParam16( hInst, dlgTemplate, owner, dlgProc, 0);
689 /***********************************************************************
690 * CreateDialogIndirectParam16 (USER.242)
692 HWND16 CreateDialogIndirectParam16( HINSTANCE16 hInst, LPCVOID dlgTemplate,
693 HWND16 owner, DLGPROC16 dlgProc,
694 LPARAM param )
696 return DIALOG_CreateIndirect( hInst, dlgTemplate, FALSE, owner,
697 dlgProc, param, WIN_PROC_16 );
701 /***********************************************************************
702 * CreateDialogIndirectParam32A (USER32.69)
704 HWND32 CreateDialogIndirectParam32A( HINSTANCE32 hInst, LPCVOID dlgTemplate,
705 HWND32 owner, DLGPROC32 dlgProc,
706 LPARAM param )
708 return DIALOG_CreateIndirect( hInst, dlgTemplate, TRUE, owner,
709 (DLGPROC16)dlgProc, param, WIN_PROC_32A );
713 /***********************************************************************
714 * CreateDialogIndirectParam32W (USER32.71)
716 HWND32 CreateDialogIndirectParam32W( HINSTANCE32 hInst, LPCVOID dlgTemplate,
717 HWND32 owner, DLGPROC32 dlgProc,
718 LPARAM param )
720 return DIALOG_CreateIndirect( hInst, dlgTemplate, TRUE, owner,
721 (DLGPROC16)dlgProc, param, WIN_PROC_32W );
725 /***********************************************************************
726 * DIALOG_DoDialogBox
728 INT32 DIALOG_DoDialogBox( HWND32 hwnd, HWND32 owner )
730 WND * wndPtr;
731 DIALOGINFO * dlgInfo;
732 MSG16 msg;
733 INT32 retval;
735 /* Owner must be a top-level window */
736 owner = WIN_GetTopParent( owner );
737 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1;
738 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
739 EnableWindow( owner, FALSE );
740 ShowWindow( hwnd, SW_SHOW );
742 while (MSG_InternalGetMessage(&msg, hwnd, owner, MSGF_DIALOGBOX, PM_REMOVE,
743 !(wndPtr->dwStyle & DS_NOIDLEMSG) ))
745 if (!IsDialogMessage( hwnd, &msg))
747 TranslateMessage( &msg );
748 DispatchMessage( &msg );
750 if (dlgInfo->fEnd) break;
752 retval = dlgInfo->idResult;
753 EnableWindow( owner, TRUE );
754 DestroyWindow( hwnd );
755 return retval;
759 /***********************************************************************
760 * DialogBox16 (USER.87)
762 INT16 DialogBox16( HINSTANCE16 hInst, SEGPTR dlgTemplate,
763 HWND16 owner, DLGPROC16 dlgProc )
765 return DialogBoxParam16( hInst, dlgTemplate, owner, dlgProc, 0 );
769 /***********************************************************************
770 * DialogBoxParam16 (USER.239)
772 INT16 DialogBoxParam16( HINSTANCE16 hInst, SEGPTR template,
773 HWND16 owner, DLGPROC16 dlgProc, LPARAM param )
775 HWND16 hwnd = CreateDialogParam16( hInst, template, owner, dlgProc, param);
776 if (hwnd) return (INT16)DIALOG_DoDialogBox( hwnd, owner );
777 return -1;
781 /***********************************************************************
782 * DialogBoxParam32A (USER32.138)
784 INT32 DialogBoxParam32A( HINSTANCE32 hInst, LPCSTR name,
785 HWND32 owner, DLGPROC32 dlgProc, LPARAM param )
787 HWND32 hwnd = CreateDialogParam32A( hInst, name, owner, dlgProc, param );
788 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
789 return -1;
793 /***********************************************************************
794 * DialogBoxParam32W (USER32.139)
796 INT32 DialogBoxParam32W( HINSTANCE32 hInst, LPCWSTR name,
797 HWND32 owner, DLGPROC32 dlgProc, LPARAM param )
799 HWND32 hwnd = CreateDialogParam32W( hInst, name, owner, dlgProc, param );
800 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
801 return -1;
805 /***********************************************************************
806 * DialogBoxIndirect16 (USER.218)
808 INT16 DialogBoxIndirect16( HINSTANCE16 hInst, HANDLE16 dlgTemplate,
809 HWND16 owner, DLGPROC16 dlgProc )
811 return DialogBoxIndirectParam16( hInst, dlgTemplate, owner, dlgProc, 0 );
815 /***********************************************************************
816 * DialogBoxIndirectParam16 (USER.240)
818 INT16 DialogBoxIndirectParam16( HINSTANCE16 hInst, HANDLE16 dlgTemplate,
819 HWND16 owner, DLGPROC16 dlgProc, LPARAM param )
821 HWND16 hwnd;
822 LPCVOID ptr;
824 if (!(ptr = GlobalLock16( dlgTemplate ))) return -1;
825 hwnd = CreateDialogIndirectParam16( hInst, ptr, owner, dlgProc, param );
826 GlobalUnlock16( dlgTemplate );
827 if (hwnd) return (INT16)DIALOG_DoDialogBox( hwnd, owner );
828 return -1;
832 /***********************************************************************
833 * DialogBoxIndirectParam32A (USER32.135)
835 INT32 DialogBoxIndirectParam32A( HINSTANCE32 hInstance, LPCVOID template,
836 HWND32 owner, DLGPROC32 dlgProc, LPARAM param)
838 HWND32 hwnd = CreateDialogIndirectParam32A( hInstance, template,
839 owner, dlgProc, param );
840 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
841 return -1;
845 /***********************************************************************
846 * DialogBoxIndirectParam32W (USER32.137)
848 INT32 DialogBoxIndirectParam32W( HINSTANCE32 hInstance, LPCVOID template,
849 HWND32 owner, DLGPROC32 dlgProc, LPARAM param)
851 HWND32 hwnd = CreateDialogIndirectParam32W( hInstance, template,
852 owner, dlgProc, param );
853 if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
854 return -1;
858 /***********************************************************************
859 * EndDialog (USER.88) (USER32.173)
861 BOOL16 EndDialog( HWND32 hwnd, INT32 retval )
863 WND * wndPtr = WIN_FindWndPtr( hwnd );
864 DIALOGINFO * dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
865 dlgInfo->idResult = retval;
866 dlgInfo->fEnd = TRUE;
867 dprintf_dialog(stddeb, "EndDialog: %04x %d\n", hwnd, retval );
868 return TRUE;
872 /***********************************************************************
873 * IsDialogMessage (USER.90)
875 BOOL IsDialogMessage( HWND hwndDlg, LPMSG16 msg )
877 WND * wndPtr;
878 int dlgCode;
880 if (!(wndPtr = WIN_FindWndPtr( hwndDlg ))) return FALSE;
881 if ((hwndDlg != msg->hwnd) && !IsChild( hwndDlg, msg->hwnd )) return FALSE;
883 /* Only the key messages get special processing */
884 if ((msg->message != WM_KEYDOWN) &&
885 (msg->message != WM_SYSCHAR) &&
886 (msg->message != WM_CHAR))
887 return FALSE;
889 dlgCode = SendMessage16( msg->hwnd, WM_GETDLGCODE, 0, 0 );
890 if (dlgCode & DLGC_WANTMESSAGE)
892 DispatchMessage( msg );
893 return TRUE;
896 switch(msg->message)
898 case WM_KEYDOWN:
899 if (dlgCode & DLGC_WANTALLKEYS) break;
900 switch(msg->wParam)
902 case VK_TAB:
903 if (!(dlgCode & DLGC_WANTTAB))
905 SendMessage16( hwndDlg, WM_NEXTDLGCTL,
906 (GetKeyState(VK_SHIFT) & 0x8000), 0 );
907 return TRUE;
909 break;
911 case VK_RIGHT:
912 case VK_DOWN:
913 if (!(dlgCode & DLGC_WANTARROWS))
915 SetFocus32( GetNextDlgGroupItem32( hwndDlg, GetFocus32(),
916 FALSE ) );
917 return TRUE;
919 break;
921 case VK_LEFT:
922 case VK_UP:
923 if (!(dlgCode & DLGC_WANTARROWS))
925 SetFocus32( GetNextDlgGroupItem32( hwndDlg, GetFocus32(),
926 TRUE ) );
927 return TRUE;
929 break;
931 case VK_ESCAPE:
932 SendMessage32A( hwndDlg, WM_COMMAND, IDCANCEL,
933 (LPARAM)GetDlgItem( hwndDlg, IDCANCEL ) );
934 break;
936 case VK_RETURN:
938 DWORD dw = SendMessage16( hwndDlg, DM_GETDEFID, 0, 0 );
939 if (HIWORD(dw) == DC_HASDEFID)
940 SendMessage32A( hwndDlg, WM_COMMAND,
941 MAKEWPARAM( LOWORD(dw), BN_CLICKED ),
942 (LPARAM)GetDlgItem( hwndDlg, LOWORD(dw) ));
943 else
944 SendMessage32A( hwndDlg, WM_COMMAND, IDOK,
945 (LPARAM)GetDlgItem( hwndDlg, IDOK ) );
947 break;
949 default:
950 TranslateMessage( msg );
952 break; /* case WM_KEYDOWN */
955 case WM_CHAR:
956 if (dlgCode & (DLGC_WANTALLKEYS | DLGC_WANTCHARS)) break;
957 break;
959 case WM_SYSCHAR:
960 if (dlgCode & DLGC_WANTALLKEYS) break;
961 break;
964 /* If we get here, the message has not been treated specially */
965 /* and can be sent to its destination window. */
966 DispatchMessage( msg );
967 return TRUE;
971 /****************************************************************
972 * GetDlgCtrlID (USER.277) (USER32.233)
974 INT16 GetDlgCtrlID( HWND32 hwnd )
976 WND *wndPtr = WIN_FindWndPtr(hwnd);
977 if (wndPtr) return wndPtr->wIDmenu;
978 else return 0;
982 /***********************************************************************
983 * GetDlgItem (USER.91)
985 HWND GetDlgItem( HWND hwndDlg, WORD id )
987 WND *pWnd;
989 if (!(pWnd = WIN_FindWndPtr( hwndDlg ))) return 0;
990 for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
991 if (pWnd->wIDmenu == id) return pWnd->hwndSelf;
992 return 0;
996 /*******************************************************************
997 * SendDlgItemMessage16 (USER.101)
999 LRESULT SendDlgItemMessage16( HWND16 hwnd, INT16 id, UINT16 msg,
1000 WPARAM16 wParam, LPARAM lParam )
1002 HWND16 hwndCtrl = GetDlgItem( hwnd, id );
1003 if (hwndCtrl) return SendMessage16( hwndCtrl, msg, wParam, lParam );
1004 else return 0;
1008 /*******************************************************************
1009 * SendDlgItemMessage32A (USER32.451)
1011 LRESULT SendDlgItemMessage32A( HWND32 hwnd, INT32 id, UINT32 msg,
1012 WPARAM32 wParam, LPARAM lParam )
1014 HWND hwndCtrl = GetDlgItem( (HWND16)hwnd, (INT16)id );
1015 if (hwndCtrl) return SendMessage32A( hwndCtrl, msg, wParam, lParam );
1016 else return 0;
1020 /*******************************************************************
1021 * SendDlgItemMessage32W (USER32.452)
1023 LRESULT SendDlgItemMessage32W( HWND32 hwnd, INT32 id, UINT32 msg,
1024 WPARAM32 wParam, LPARAM lParam )
1026 HWND hwndCtrl = GetDlgItem( (HWND16)hwnd, (INT16)id );
1027 if (hwndCtrl) return SendMessage32W( hwndCtrl, msg, wParam, lParam );
1028 else return 0;
1032 /*******************************************************************
1033 * SetDlgItemText16 (USER.92)
1035 void SetDlgItemText16( HWND16 hwnd, INT16 id, SEGPTR lpString )
1037 SendDlgItemMessage16( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString );
1041 /*******************************************************************
1042 * SetDlgItemText32A (USER32.477)
1044 void SetDlgItemText32A( HWND32 hwnd, INT32 id, LPCSTR lpString )
1046 SendDlgItemMessage32A( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString );
1050 /*******************************************************************
1051 * SetDlgItemText32W (USER32.478)
1053 void SetDlgItemText32W( HWND32 hwnd, INT32 id, LPCWSTR lpString )
1055 SendDlgItemMessage32W( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString );
1059 /***********************************************************************
1060 * GetDlgItemText16 (USER.93)
1062 INT16 GetDlgItemText16( HWND16 hwnd, INT16 id, SEGPTR str, UINT16 len )
1064 return (INT16)SendDlgItemMessage16( hwnd, id, WM_GETTEXT,
1065 len, (LPARAM)str );
1069 /***********************************************************************
1070 * GetDlgItemText32A (USER32.236)
1072 INT32 GetDlgItemText32A( HWND32 hwnd, INT32 id, LPSTR str, UINT32 len )
1074 return (INT32)SendDlgItemMessage32A( hwnd, id, WM_GETTEXT,
1075 len, (LPARAM)str );
1079 /***********************************************************************
1080 * GetDlgItemText32W (USER32.237)
1082 INT32 GetDlgItemText32W( HWND32 hwnd, INT32 id, LPWSTR str, UINT32 len )
1084 return (INT32)SendDlgItemMessage32W( hwnd, id, WM_GETTEXT,
1085 len, (LPARAM)str );
1089 /*******************************************************************
1090 * SetDlgItemInt16 (USER.94)
1092 void SetDlgItemInt16( HWND16 hwnd, INT16 id, UINT16 value, BOOL16 fSigned )
1094 char *str = (char *)SEGPTR_ALLOC( 20 * sizeof(char) );
1096 if (!str) return;
1097 if (fSigned) sprintf( str, "%d", (INT32)(INT16)value );
1098 else sprintf( str, "%u", value );
1099 SendDlgItemMessage16( hwnd, id, WM_SETTEXT, 0, (LPARAM)SEGPTR_GET(str) );
1100 SEGPTR_FREE(str);
1104 /*******************************************************************
1105 * SetDlgItemInt32 (USER32.476)
1107 void SetDlgItemInt32( HWND32 hwnd, INT32 id, UINT32 value, BOOL32 fSigned )
1109 char str[20];
1111 if (fSigned) sprintf( str, "%d", (INT32)value );
1112 else sprintf( str, "%u", value );
1113 SendDlgItemMessage32A( hwnd, id, WM_SETTEXT, 0, (LPARAM)str );
1117 /***********************************************************************
1118 * GetDlgItemInt (USER.95)
1120 WORD GetDlgItemInt( HWND hwnd, WORD id, BOOL * translated, BOOL fSigned )
1122 char *str;
1123 long result = 0;
1125 if (translated) *translated = FALSE;
1126 if (!(str = (char *)SEGPTR_ALLOC( 30 * sizeof(char) ))) return 0;
1127 if (SendDlgItemMessage16( hwnd, id, WM_GETTEXT, 30, (LPARAM)SEGPTR_GET(str)))
1129 char * endptr;
1130 result = strtol( str, &endptr, 10 );
1131 if (endptr && (endptr != str)) /* Conversion was successful */
1133 if (fSigned)
1135 if ((result < -32767) || (result > 32767)) result = 0;
1136 else if (translated) *translated = TRUE;
1138 else
1140 if ((result < 0) || (result > 65535)) result = 0;
1141 else if (translated) *translated = TRUE;
1145 SEGPTR_FREE(str);
1146 return (WORD)result;
1150 /***********************************************************************
1151 * CheckDlgButton (USER.97) (USER32.44)
1153 BOOL16 CheckDlgButton( HWND32 hwnd, INT32 id, UINT32 check )
1155 SendDlgItemMessage32A( hwnd, id, BM_SETCHECK32, check, 0 );
1156 return TRUE;
1160 /***********************************************************************
1161 * IsDlgButtonChecked (USER.98)
1163 WORD IsDlgButtonChecked( HWND hwnd, WORD id )
1165 return (WORD)SendDlgItemMessage32A( hwnd, id, BM_GETCHECK32, 0, 0 );
1169 /***********************************************************************
1170 * CheckRadioButton (USER.96) (USER32.47)
1172 BOOL16 CheckRadioButton( HWND32 hwndDlg, UINT32 firstID, UINT32 lastID,
1173 UINT32 checkID )
1175 WND *pWnd = WIN_FindWndPtr( hwndDlg );
1176 if (!pWnd) return FALSE;
1178 for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
1179 if ((pWnd->wIDmenu == firstID) || (pWnd->wIDmenu == lastID)) break;
1180 if (!pWnd) return FALSE;
1182 if (pWnd->wIDmenu == lastID)
1183 lastID = firstID; /* Buttons are in reverse order */
1184 while (pWnd)
1186 SendMessage32A( pWnd->hwndSelf, BM_SETCHECK32,
1187 (pWnd->wIDmenu == checkID), 0 );
1188 if (pWnd->wIDmenu == lastID) break;
1189 pWnd = pWnd->next;
1191 return TRUE;
1195 /***********************************************************************
1196 * GetDialogBaseUnits (USER.243) (USER32.232)
1198 DWORD GetDialogBaseUnits(void)
1200 return MAKELONG( xBaseUnit, yBaseUnit );
1204 /***********************************************************************
1205 * MapDialogRect16 (USER.103)
1207 void MapDialogRect16( HWND16 hwnd, LPRECT16 rect )
1209 DIALOGINFO * dlgInfo;
1210 WND * wndPtr = WIN_FindWndPtr( hwnd );
1211 if (!wndPtr) return;
1212 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
1213 rect->left = (rect->left * dlgInfo->xBaseUnit) / 4;
1214 rect->right = (rect->right * dlgInfo->xBaseUnit) / 4;
1215 rect->top = (rect->top * dlgInfo->yBaseUnit) / 8;
1216 rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8;
1220 /***********************************************************************
1221 * MapDialogRect32 (USER32.381)
1223 void MapDialogRect32( HWND32 hwnd, LPRECT32 rect )
1225 DIALOGINFO * dlgInfo;
1226 WND * wndPtr = WIN_FindWndPtr( hwnd );
1227 if (!wndPtr) return;
1228 dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
1229 rect->left = (rect->left * dlgInfo->xBaseUnit) / 4;
1230 rect->right = (rect->right * dlgInfo->xBaseUnit) / 4;
1231 rect->top = (rect->top * dlgInfo->yBaseUnit) / 8;
1232 rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8;
1236 /***********************************************************************
1237 * GetNextDlgGroupItem16 (USER.227)
1239 HWND16 GetNextDlgGroupItem16(HWND16 hwndDlg, HWND16 hwndCtrl, BOOL16 fPrevious)
1241 return (HWND16)GetNextDlgGroupItem32( hwndDlg, hwndCtrl, fPrevious );
1245 /***********************************************************************
1246 * GetNextDlgGroupItem32 (USER32.274)
1248 HWND32 GetNextDlgGroupItem32(HWND32 hwndDlg, HWND32 hwndCtrl, BOOL32 fPrevious)
1250 WND *pWnd, *pWndLast, *pWndCtrl, *pWndDlg;
1252 if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0;
1253 if (hwndCtrl)
1255 if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0;
1256 /* Make sure hwndCtrl is a top-level child */
1257 while ((pWndCtrl->dwStyle & WS_CHILD) && (pWndCtrl->parent != pWndDlg))
1258 pWndCtrl = pWndCtrl->parent;
1259 if (pWndCtrl->parent != pWndDlg) return 0;
1261 else
1263 /* No ctrl specified -> start from the beginning */
1264 if (!(pWndCtrl = pWndDlg->child)) return 0;
1265 if (fPrevious) while (pWndCtrl->next) pWndCtrl = pWndCtrl->next;
1268 pWndLast = pWndCtrl;
1269 pWnd = pWndCtrl->next;
1270 while (1)
1272 if (!pWnd || (pWnd->dwStyle & WS_GROUP))
1274 /* Wrap-around to the beginning of the group */
1275 WND *pWndStart = pWndDlg->child;
1276 for (pWnd = pWndStart; pWnd; pWnd = pWnd->next)
1278 if (pWnd->dwStyle & WS_GROUP) pWndStart = pWnd;
1279 if (pWnd == pWndCtrl) break;
1281 pWnd = pWndStart;
1283 if (pWnd == pWndCtrl) break;
1284 if ((pWnd->dwStyle & WS_VISIBLE) && !(pWnd->dwStyle & WS_DISABLED))
1286 pWndLast = pWnd;
1287 if (!fPrevious) break;
1289 pWnd = pWnd->next;
1291 return pWndLast->hwndSelf;
1295 /***********************************************************************
1296 * GetNextDlgTabItem16 (USER.228)
1298 HWND16 GetNextDlgTabItem16( HWND16 hwndDlg, HWND16 hwndCtrl, BOOL16 fPrevious )
1300 return (HWND16)GetNextDlgTabItem32( hwndDlg, hwndCtrl, fPrevious );
1304 /***********************************************************************
1305 * GetNextDlgTabItem32 (USER32.275)
1307 HWND32 GetNextDlgTabItem32( HWND32 hwndDlg, HWND32 hwndCtrl, BOOL32 fPrevious )
1309 WND *pWnd, *pWndLast, *pWndCtrl, *pWndDlg;
1311 if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0;
1312 if (hwndCtrl)
1314 if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0;
1315 /* Make sure hwndCtrl is a top-level child */
1316 while ((pWndCtrl->dwStyle & WS_CHILD) && (pWndCtrl->parent != pWndDlg))
1317 pWndCtrl = pWndCtrl->parent;
1318 if (pWndCtrl->parent != pWndDlg) return 0;
1320 else
1322 /* No ctrl specified -> start from the beginning */
1323 if (!(pWndCtrl = pWndDlg->child)) return 0;
1324 if (fPrevious) while (pWndCtrl->next) pWndCtrl = pWndCtrl->next;
1327 pWndLast = pWndCtrl;
1328 pWnd = pWndCtrl->next;
1329 while (1)
1331 if (!pWnd) pWnd = pWndDlg->child;
1332 if (pWnd == pWndCtrl) break;
1333 if ((pWnd->dwStyle & WS_TABSTOP) && (pWnd->dwStyle & WS_VISIBLE) &&
1334 !(pWnd->dwStyle & WS_DISABLED))
1336 pWndLast = pWnd;
1337 if (!fPrevious) break;
1339 pWnd = pWnd->next;
1341 return pWndLast->hwndSelf;
1345 /**********************************************************************
1346 * DIALOG_DlgDirSelect
1348 * Helper function for DlgDirSelect*
1350 static BOOL32 DIALOG_DlgDirSelect( HWND32 hwnd, LPSTR str, INT32 len,
1351 INT32 id, BOOL32 win32, BOOL32 unicode,
1352 BOOL32 combo )
1354 char *buffer, *ptr;
1355 INT32 item, size;
1356 BOOL32 ret;
1357 HWND32 listbox = GetDlgItem( hwnd, id );
1359 dprintf_dialog( stddeb, "DlgDirSelect: %04x '%s' %d\n", hwnd, str, id );
1360 if (!listbox) return FALSE;
1361 if (win32)
1363 item = SendMessage32A(listbox, combo ? CB_GETCURSEL32
1364 : LB_GETCURSEL32, 0, 0 );
1365 if (item == LB_ERR) return FALSE;
1366 size = SendMessage32A(listbox, combo ? CB_GETLBTEXTLEN32
1367 : LB_GETTEXTLEN32, 0, 0 );
1368 if (size == LB_ERR) return FALSE;
1370 else
1372 item = SendMessage32A(listbox, combo ? CB_GETCURSEL16
1373 : LB_GETCURSEL16, 0, 0 );
1374 if (item == LB_ERR) return FALSE;
1375 size = SendMessage32A(listbox, combo ? CB_GETLBTEXTLEN16
1376 : LB_GETTEXTLEN16, 0, 0 );
1377 if (size == LB_ERR) return FALSE;
1380 if (!(buffer = SEGPTR_ALLOC( size+1 ))) return FALSE;
1382 if (win32)
1383 SendMessage32A( listbox, combo ? CB_GETLBTEXT32 : LB_GETTEXT32,
1384 item, (LPARAM)buffer );
1385 else
1386 SendMessage16( listbox, combo ? CB_GETLBTEXT16 : LB_GETTEXT16,
1387 item, (LPARAM)SEGPTR_GET(buffer) );
1389 if ((ret = (buffer[0] == '['))) /* drive or directory */
1391 if (buffer[1] == '-') /* drive */
1393 buffer[3] = ':';
1394 buffer[4] = 0;
1395 ptr = buffer + 2;
1397 else
1399 buffer[strlen(buffer)-1] = '\\';
1400 ptr = buffer + 1;
1403 else ptr = buffer;
1405 if (unicode) lstrcpynAtoW( (LPWSTR)str, ptr, len );
1406 else lstrcpyn32A( str, ptr, len );
1407 SEGPTR_FREE( buffer );
1408 dprintf_dialog( stddeb, "Returning %d '%s'\n", ret, str );
1409 return ret;
1413 /**********************************************************************
1414 * DIALOG_DlgDirList
1416 * Helper function for DlgDirList*
1418 static INT32 DIALOG_DlgDirList( HWND32 hDlg, LPCSTR spec, INT32 idLBox,
1419 INT32 idStatic, UINT32 attrib, BOOL32 combo )
1421 int drive;
1422 HWND32 hwnd;
1424 #define SENDMSG(msg,wparam,lparam) \
1425 ((attrib & DDL_POSTMSGS) ? PostMessage( hwnd, msg, wparam, lparam ) \
1426 : SendMessage32A( hwnd, msg, wparam, lparam ))
1428 dprintf_dialog( stddeb, "DlgDirList: %04x '%s' %d %d %04x\n",
1429 hDlg, spec ? spec : "NULL", idLBox, idStatic, attrib );
1431 if (spec && spec[0] && (spec[1] == ':'))
1433 drive = toupper( spec[0] ) - 'A';
1434 spec += 2;
1435 if (!DRIVE_SetCurrentDrive( drive )) return FALSE;
1437 else drive = DRIVE_GetCurrentDrive();
1439 if (idLBox && ((hwnd = GetDlgItem( hDlg, idLBox )) != 0))
1441 /* If the path exists and is a directory, chdir to it */
1442 if (!spec || !spec[0] || DRIVE_Chdir( drive, spec )) spec = "*.*";
1443 else
1445 const char *p, *p2;
1446 p = spec;
1447 if ((p2 = strrchr( p, '\\' ))) p = p2 + 1;
1448 if ((p2 = strrchr( p, '/' ))) p = p2 + 1;
1449 if (p != spec)
1451 BOOL32 ret = FALSE;
1452 char *dir = HeapAlloc( SystemHeap, 0, p - spec );
1453 if (dir)
1455 lstrcpyn32A( dir, spec, p - spec );
1456 ret = DRIVE_Chdir( drive, dir );
1457 HeapFree( SystemHeap, 0, dir );
1459 if (!ret) return FALSE;
1460 spec = p;
1464 dprintf_dialog( stddeb, "ListBoxDirectory: path=%c:\\%s mask=%s\n",
1465 'A' + drive, DRIVE_GetDosCwd(drive), spec );
1467 SENDMSG( combo ? CB_RESETCONTENT32 : LB_RESETCONTENT32, 0, 0 );
1468 if ((attrib & DDL_DIRECTORY) && !(attrib & DDL_EXCLUSIVE))
1470 if (SENDMSG( combo ? CB_DIR32 : LB_DIR32,
1471 attrib & ~(DDL_DIRECTORY | DDL_DRIVES),
1472 (LPARAM)spec ) == LB_ERR)
1473 return FALSE;
1474 if (SENDMSG( combo ? CB_DIR32 : LB_DIR32,
1475 (attrib & (DDL_DIRECTORY | DDL_DRIVES)) | DDL_EXCLUSIVE,
1476 (LPARAM)"*.*" ) == LB_ERR)
1477 return FALSE;
1479 else
1481 if (SENDMSG( combo ? CB_DIR32 : LB_DIR32, attrib,
1482 (LPARAM)spec ) == LB_ERR)
1483 return FALSE;
1487 if (idStatic && ((hwnd = GetDlgItem( hDlg, idStatic )) != 0))
1489 char temp[512];
1490 int drive = DRIVE_GetCurrentDrive();
1491 strcpy( temp, "A:\\" );
1492 temp[0] += drive;
1493 lstrcpyn32A( temp + 3, DRIVE_GetDosCwd(drive), sizeof(temp)-3 );
1494 CharLower32A( temp );
1495 /* Can't use PostMessage() here, because the string is on the stack */
1496 SetDlgItemText32A( hDlg, idStatic, temp );
1498 return TRUE;
1499 #undef SENDMSG
1503 /**********************************************************************
1504 * DlgDirSelect (USER.99)
1506 BOOL16 DlgDirSelect( HWND16 hwnd, LPSTR str, INT16 id )
1508 return DlgDirSelectEx16( hwnd, str, 128, id );
1512 /**********************************************************************
1513 * DlgDirSelectComboBox (USER.194)
1515 BOOL16 DlgDirSelectComboBox( HWND16 hwnd, LPSTR str, INT16 id )
1517 return DlgDirSelectComboBoxEx16( hwnd, str, 128, id );
1521 /**********************************************************************
1522 * DlgDirSelectEx16 (USER.422)
1524 BOOL16 DlgDirSelectEx16( HWND16 hwnd, LPSTR str, INT16 len, INT16 id )
1526 return DIALOG_DlgDirSelect( hwnd, str, len, id, FALSE, FALSE, FALSE );
1530 /**********************************************************************
1531 * DlgDirSelectEx32A (USER32.148)
1533 BOOL32 DlgDirSelectEx32A( HWND32 hwnd, LPSTR str, INT32 len, INT32 id )
1535 return DIALOG_DlgDirSelect( hwnd, str, len, id, TRUE, FALSE, FALSE );
1539 /**********************************************************************
1540 * DlgDirSelectEx32W (USER32.149)
1542 BOOL32 DlgDirSelectEx32W( HWND32 hwnd, LPWSTR str, INT32 len, INT32 id )
1544 return DIALOG_DlgDirSelect( hwnd, (LPSTR)str, len, id, TRUE, TRUE, FALSE );
1548 /**********************************************************************
1549 * DlgDirSelectComboBoxEx16 (USER.423)
1551 BOOL16 DlgDirSelectComboBoxEx16( HWND16 hwnd, LPSTR str, INT16 len, INT16 id )
1553 return DIALOG_DlgDirSelect( hwnd, str, len, id, FALSE, FALSE, TRUE );
1557 /**********************************************************************
1558 * DlgDirSelectComboBoxEx32A (USER32.146)
1560 BOOL32 DlgDirSelectComboBoxEx32A( HWND32 hwnd, LPSTR str, INT32 len, INT32 id )
1562 return DIALOG_DlgDirSelect( hwnd, str, len, id, TRUE, FALSE, TRUE );
1566 /**********************************************************************
1567 * DlgDirSelectComboBoxEx32W (USER32.147)
1569 BOOL32 DlgDirSelectComboBoxEx32W( HWND32 hwnd, LPWSTR str, INT32 len, INT32 id)
1571 return DIALOG_DlgDirSelect( hwnd, (LPSTR)str, len, id, TRUE, TRUE, TRUE );
1575 /**********************************************************************
1576 * DlgDirList16 (USER.100)
1578 INT16 DlgDirList16( HWND16 hDlg, LPCSTR spec, INT16 idLBox, INT16 idStatic,
1579 UINT16 attrib )
1581 return DIALOG_DlgDirList( hDlg, spec, idLBox, idStatic, attrib, FALSE );
1585 /**********************************************************************
1586 * DlgDirList32A (USER32.142)
1588 INT32 DlgDirList32A( HWND32 hDlg, LPCSTR spec, INT32 idLBox, INT32 idStatic,
1589 UINT32 attrib )
1591 return DIALOG_DlgDirList( hDlg, spec, idLBox, idStatic, attrib, FALSE );
1595 /**********************************************************************
1596 * DlgDirList32W (USER32.145)
1598 INT32 DlgDirList32W( HWND32 hDlg, LPCWSTR spec, INT32 idLBox, INT32 idStatic,
1599 UINT32 attrib )
1601 INT32 ret;
1602 LPSTR specA = HEAP_strdupWtoA( GetProcessHeap(), 0, spec );
1603 ret = DIALOG_DlgDirList( hDlg, specA, idLBox, idStatic, attrib, FALSE );
1604 HeapFree( GetProcessHeap(), 0, specA );
1605 return ret;
1609 /**********************************************************************
1610 * DlgDirListComboBox16 (USER.195)
1612 INT16 DlgDirListComboBox16( HWND16 hDlg, LPCSTR spec, INT16 idCBox,
1613 INT16 idStatic, UINT16 attrib )
1615 return DIALOG_DlgDirList( hDlg, spec, idCBox, idStatic, attrib, TRUE );
1619 /**********************************************************************
1620 * DlgDirListComboBox32A (USER32.143)
1622 INT32 DlgDirListComboBox32A( HWND32 hDlg, LPCSTR spec, INT32 idCBox,
1623 INT32 idStatic, UINT32 attrib )
1625 return DIALOG_DlgDirList( hDlg, spec, idCBox, idStatic, attrib, TRUE );
1629 /**********************************************************************
1630 * DlgDirListComboBox32W (USER32.144)
1632 INT32 DlgDirListComboBox32W( HWND32 hDlg, LPCWSTR spec, INT32 idCBox,
1633 INT32 idStatic, UINT32 attrib )
1635 INT32 ret;
1636 LPSTR specA = HEAP_strdupWtoA( GetProcessHeap(), 0, spec );
1637 ret = DIALOG_DlgDirList( hDlg, specA, idCBox, idStatic, attrib, FALSE );
1638 HeapFree( GetProcessHeap(), 0, specA );
1639 return ret;