Release 980413
[wine] / windows / dialog.c
1 /*
2  * Dialog functions
3  *
4  * Copyright 1993, 1994, 1996 Alexandre Julliard
5  */
6
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 "debug.h"
25
26
27   /* Dialog control information */
28 typedef struct
29 {
30     DWORD      style;
31     DWORD      exStyle;
32     DWORD      helpId;
33     INT16      x;
34     INT16      y;
35     INT16      cx;
36     INT16      cy;
37     UINT32     id;
38     LPCSTR     className;
39     LPCSTR     windowName;
40     LPVOID     data;
41 } DLG_CONTROL_INFO;
42
43   /* Dialog template */
44 typedef struct
45 {
46     DWORD      style;
47     DWORD      exStyle;
48     DWORD      helpId;
49     UINT16     nbItems;
50     INT16      x;
51     INT16      y;
52     INT16      cx;
53     INT16      cy;
54     LPCSTR     menuName;
55     LPCSTR     className;
56     LPCSTR     caption;
57     WORD       pointSize;
58     WORD       weight;
59     BOOL32     italic;
60     LPCSTR     faceName;
61     BOOL32     dialogEx;
62 } DLG_TEMPLATE;
63
64   /* Dialog base units */
65 static WORD xBaseUnit = 0, yBaseUnit = 0;
66
67
68 /***********************************************************************
69  *           DIALOG_Init
70  *
71  * Initialisation of the dialog manager.
72  */
73 BOOL32 DIALOG_Init(void)
74 {
75     TEXTMETRIC16 tm;
76     HDC16 hdc;
77     
78       /* Calculate the dialog base units */
79
80     if (!(hdc = CreateDC16( "DISPLAY", NULL, NULL, NULL ))) return FALSE;
81     GetTextMetrics16( hdc, &tm );
82     DeleteDC32( hdc );
83     xBaseUnit = tm.tmAveCharWidth;
84     yBaseUnit = tm.tmHeight;
85
86       /* Dialog units are based on a proportional system font */
87       /* so we adjust them a bit for a fixed font. */
88     if (!(tm.tmPitchAndFamily & TMPF_FIXED_PITCH))
89         xBaseUnit = xBaseUnit * 5 / 4;
90
91     TRACE(dialog, "base units = %d,%d\n",
92                     xBaseUnit, yBaseUnit );
93     return TRUE;
94 }
95
96
97 /***********************************************************************
98  *           DIALOG_GetControl16
99  *
100  * Return the class and text of the control pointed to by ptr,
101  * fill the header structure and return a pointer to the next control.
102  */
103 static LPCSTR DIALOG_GetControl16( LPCSTR p, DLG_CONTROL_INFO *info )
104 {
105     static char buffer[10];
106     int int_id;
107
108     info->x       = GET_WORD(p);  p += sizeof(WORD);
109     info->y       = GET_WORD(p);  p += sizeof(WORD);
110     info->cx      = GET_WORD(p);  p += sizeof(WORD);
111     info->cy      = GET_WORD(p);  p += sizeof(WORD);
112     info->id      = GET_WORD(p);  p += sizeof(WORD);
113     info->style   = GET_DWORD(p); p += sizeof(DWORD);
114     info->exStyle = 0;
115
116     if (*p & 0x80)
117     {
118         switch((BYTE)*p)
119         {
120             case 0x80: strcpy( buffer, "BUTTON" ); break;
121             case 0x81: strcpy( buffer, "EDIT" ); break;
122             case 0x82: strcpy( buffer, "STATIC" ); break;
123             case 0x83: strcpy( buffer, "LISTBOX" ); break;
124             case 0x84: strcpy( buffer, "SCROLLBAR" ); break;
125             case 0x85: strcpy( buffer, "COMBOBOX" ); break;
126             default:   buffer[0] = '\0'; break;
127         }
128         info->className = buffer;
129         p++;
130     }
131     else 
132     {
133         info->className = p;
134         p += strlen(p) + 1;
135     }
136
137     int_id = ((BYTE)*p == 0xff);
138     if (int_id)
139     {
140           /* Integer id, not documented (?). Only works for SS_ICON controls */
141         info->windowName = (LPCSTR)(UINT32)GET_WORD(p+1);
142         p += 3;
143     }
144     else
145     {
146         info->windowName = p;
147         p += strlen(p) + 1;
148     }
149
150     info->data = (LPVOID)(*p ? p + 1 : NULL);  /* FIXME: should be a segptr */
151     p += *p + 1;
152
153     if(int_id)
154       TRACE(dialog,"   %s %04x %d, %d, %d, %d, %d, %08lx, %08lx\n", 
155                       info->className,  LOWORD(info->windowName),
156                       info->id, info->x, info->y, info->cx, info->cy,
157                       info->style, (DWORD)info->data);
158     else
159       TRACE(dialog,"   %s '%s' %d, %d, %d, %d, %d, %08lx, %08lx\n", 
160                       info->className,  info->windowName,
161                       info->id, info->x, info->y, info->cx, info->cy,
162                       info->style, (DWORD)info->data);
163
164     return p;
165 }
166
167
168 /***********************************************************************
169  *           DIALOG_GetControl32
170  *
171  * Return the class and text of the control pointed to by ptr,
172  * fill the header structure and return a pointer to the next control.
173  */
174 static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info,
175                                         BOOL32 dialogEx )
176 {
177     if (dialogEx)
178     {
179         info->helpId  = GET_DWORD(p); p += 2;
180         info->exStyle = GET_DWORD(p); p += 2;
181         info->style   = GET_DWORD(p); p += 2;
182     }
183     else
184     {
185         info->helpId  = 0;
186         info->style   = GET_DWORD(p); p += 2;
187         info->exStyle = GET_DWORD(p); p += 2;
188     }
189     info->x       = GET_WORD(p); p++;
190     info->y       = GET_WORD(p); p++;
191     info->cx      = GET_WORD(p); p++;
192     info->cy      = GET_WORD(p); p++;
193
194     if (dialogEx)
195     {
196         /* id is a DWORD for DIALOGEX */
197         info->id = GET_DWORD(p);
198         p += 2;
199     }
200     else
201     {
202         info->id = GET_WORD(p);
203         p++;
204     }
205
206     if (GET_WORD(p) == 0xffff)
207     {
208         static const WCHAR class_names[6][10] =
209         {
210             { 'B','u','t','t','o','n', },             /* 0x80 */
211             { 'E','d','i','t', },                     /* 0x81 */
212             { 'S','t','a','t','i','c', },             /* 0x82 */
213             { 'L','i','s','t','B','o','x', },         /* 0x83 */
214             { 'S','c','r','o','l','l','B','a','r', }, /* 0x84 */
215             { 'C','o','m','b','o','B','o','x', }      /* 0x85 */
216         };
217         WORD id = GET_WORD(p+1);
218         if ((id >= 0x80) && (id <= 0x85))
219             info->className = (LPCSTR)class_names[id - 0x80];
220         else
221         {
222             info->className = NULL;
223             ERR( dialog, "Unknown built-in class id %04x\n", id );
224         }
225         p += 2;
226     }
227     else
228     {
229         info->className = (LPCSTR)p;
230         p += lstrlen32W( (LPCWSTR)p ) + 1;
231     }
232
233     if (GET_WORD(p) == 0xffff)  /* Is it an integer id? */
234     {
235         info->windowName = (LPCSTR)(UINT32)GET_WORD(p + 1);
236         p += 2;
237     }
238     else
239     {
240         info->windowName = (LPCSTR)p;
241         p += lstrlen32W( (LPCWSTR)p ) + 1;
242     }
243
244     TRACE(dialog,"    %s %s %d, %d, %d, %d, %d, %08lx, %08lx, %08lx\n", 
245           debugstr_w( (LPCWSTR)info->className ),
246           debugres_w( (LPCWSTR)info->windowName ),
247           info->id, info->x, info->y, info->cx, info->cy,
248           info->style, info->exStyle, info->helpId );
249
250     if (GET_WORD(p))
251     {
252         if (TRACE_ON(dialog))
253         {
254             WORD i, count = GET_WORD(p) / sizeof(WORD);
255             TRACE(dialog, "  BEGIN\n");
256             TRACE(dialog, "    ");
257             for (i = 0; i < count; i++) DUMP( "%04x,", GET_WORD(p+i+1) );
258             DUMP("\n");
259             TRACE(dialog, "  END\n" );
260         }
261         info->data = (LPVOID)(p + 1);
262         p += GET_WORD(p) / sizeof(WORD);
263     }
264     else info->data = NULL;
265     p++;
266
267     /* Next control is on dword boundary */
268     return (const WORD *)((((int)p) + 3) & ~3);
269 }
270
271
272 /***********************************************************************
273  *           DIALOG_CreateControls
274  *
275  * Create the control windows for a dialog.
276  */
277 static BOOL32 DIALOG_CreateControls( WND *pWnd, LPCSTR template,
278                                      const DLG_TEMPLATE *dlgTemplate,
279                                      HINSTANCE32 hInst, BOOL32 win32 )
280 {
281     DIALOGINFO *dlgInfo = (DIALOGINFO *)pWnd->wExtra;
282     DLG_CONTROL_INFO info;
283     HWND32 hwndCtrl, hwndDefButton = 0;
284     INT32 items = dlgTemplate->nbItems;
285
286     TRACE(dialog, " BEGIN\n" );
287     while (items--)
288     {
289         if (!win32)
290         {
291             HINSTANCE16 instance;
292             template = DIALOG_GetControl16( template, &info );
293             if (HIWORD(info.className) && !strcmp( info.className, "EDIT") &&
294                 ((pWnd->dwStyle & DS_LOCALEDIT) != DS_LOCALEDIT))
295             {
296                 if (!dlgInfo->hDialogHeap)
297                 {
298                     dlgInfo->hDialogHeap = GlobalAlloc16(GMEM_FIXED, 0x10000);
299                     if (!dlgInfo->hDialogHeap)
300                     {
301                         fprintf( stderr, "CreateDialogIndirectParam: Insufficient memory to create heap for edit control\n" );
302                         continue;
303                     }
304                     LocalInit(dlgInfo->hDialogHeap, 0, 0xffff);
305                 }
306                 instance = dlgInfo->hDialogHeap;
307             }
308             else instance = (HINSTANCE16)hInst;
309
310             hwndCtrl = CreateWindowEx16( info.exStyle | WS_EX_NOPARENTNOTIFY,
311                                          info.className, info.windowName,
312                                          info.style | WS_CHILD,
313                                          info.x * dlgInfo->xBaseUnit / 4,
314                                          info.y * dlgInfo->yBaseUnit / 8,
315                                          info.cx * dlgInfo->xBaseUnit / 4,
316                                          info.cy * dlgInfo->yBaseUnit / 8,
317                                          pWnd->hwndSelf, (HMENU16)info.id,
318                                          instance, info.data );
319         }
320         else
321         {
322             template = (LPCSTR)DIALOG_GetControl32( (WORD *)template, &info,
323                                                     dlgTemplate->dialogEx );
324             hwndCtrl = CreateWindowEx32W( info.exStyle | WS_EX_NOPARENTNOTIFY,
325                                           (LPCWSTR)info.className,
326                                           (LPCWSTR)info.windowName,
327                                           info.style | WS_CHILD,
328                                           info.x * dlgInfo->xBaseUnit / 4,
329                                           info.y * dlgInfo->yBaseUnit / 8,
330                                           info.cx * dlgInfo->xBaseUnit / 4,
331                                           info.cy * dlgInfo->yBaseUnit / 8,
332                                           pWnd->hwndSelf, (HMENU32)info.id,
333                                           hInst, info.data );
334         }
335         if (!hwndCtrl) return FALSE;
336
337             /* Send initialisation messages to the control */
338         if (dlgInfo->hUserFont) SendMessage32A( hwndCtrl, WM_SETFONT,
339                                              (WPARAM32)dlgInfo->hUserFont, 0 );
340         if (SendMessage32A(hwndCtrl, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
341         {
342               /* If there's already a default push-button, set it back */
343               /* to normal and use this one instead. */
344             if (hwndDefButton)
345                 SendMessage32A( hwndDefButton, BM_SETSTYLE32,
346                                 BS_PUSHBUTTON,FALSE );
347             hwndDefButton = hwndCtrl;
348             dlgInfo->idResult = GetWindowWord32( hwndCtrl, GWW_ID );
349         }
350     }    
351     TRACE(dialog, " END\n" );
352     return TRUE;
353 }
354
355
356 /***********************************************************************
357  *           DIALOG_ParseTemplate16
358  *
359  * Fill a DLG_TEMPLATE structure from the dialog template, and return
360  * a pointer to the first control.
361  */
362 static LPCSTR DIALOG_ParseTemplate16( LPCSTR p, DLG_TEMPLATE * result )
363 {
364     result->style   = GET_DWORD(p); p += sizeof(DWORD);
365     result->exStyle = 0;
366     result->nbItems = *p++;
367     result->x       = GET_WORD(p);  p += sizeof(WORD);
368     result->y       = GET_WORD(p);  p += sizeof(WORD);
369     result->cx      = GET_WORD(p);  p += sizeof(WORD);
370     result->cy      = GET_WORD(p);  p += sizeof(WORD);
371     TRACE(dialog, "DIALOG %d, %d, %d, %d\n",
372                     result->x, result->y, result->cx, result->cy );
373     TRACE(dialog, " STYLE %08lx\n", result->style );
374
375     /* Get the menu name */
376
377     switch( (BYTE)*p )
378     {
379     case 0:
380         result->menuName = 0;
381         p++;
382         break;
383     case 0xff:
384         result->menuName = (LPCSTR)(UINT32)GET_WORD( p + 1 );
385         p += 3;
386         TRACE(dialog, " MENU %04x\n", LOWORD(result->menuName) );
387         break;
388     default:
389         result->menuName = p;
390         TRACE(dialog, " MENU '%s'\n", p );
391         p += strlen(p) + 1;
392         break;
393     }
394
395     /* Get the class name */
396
397     if (*p)
398     {
399         result->className = p;
400         TRACE(dialog, " CLASS '%s'\n", result->className );
401     }
402     else result->className = DIALOG_CLASS_ATOM;
403     p += strlen(p) + 1;
404
405     /* Get the window caption */
406
407     result->caption = p;
408     p += strlen(p) + 1;
409     TRACE(dialog, " CAPTION '%s'\n", result->caption );
410
411     /* Get the font name */
412
413     if (result->style & DS_SETFONT)
414     {
415         result->pointSize = GET_WORD(p);
416         p += sizeof(WORD);
417         result->faceName = p;
418         p += strlen(p) + 1;
419         TRACE(dialog, " FONT %d,'%s'\n",
420                         result->pointSize, result->faceName );
421     }
422     return p;
423 }
424
425
426 /***********************************************************************
427  *           DIALOG_ParseTemplate32
428  *
429  * Fill a DLG_TEMPLATE structure from the dialog template, and return
430  * a pointer to the first control.
431  */
432 static LPCSTR DIALOG_ParseTemplate32( LPCSTR template, DLG_TEMPLATE * result )
433 {
434     const WORD *p = (const WORD *)template;
435
436     result->style = GET_DWORD(p); p += 2;
437     if (result->style == 0xffff0001)  /* DIALOGEX resource */
438     {
439         result->dialogEx = TRUE;
440         result->helpId   = GET_DWORD(p); p += 2;
441         result->exStyle  = GET_DWORD(p); p += 2;
442         result->style    = GET_DWORD(p); p += 2;
443     }
444     else
445     {
446         result->dialogEx = FALSE;
447         result->helpId   = 0;
448         result->exStyle  = GET_DWORD(p); p += 2;
449     }
450     result->nbItems = GET_WORD(p); p++;
451     result->x       = GET_WORD(p); p++;
452     result->y       = GET_WORD(p); p++;
453     result->cx      = GET_WORD(p); p++;
454     result->cy      = GET_WORD(p); p++;
455     TRACE( dialog, "DIALOG%s %d, %d, %d, %d, %ld\n",
456            result->dialogEx ? "EX" : "", result->x, result->y,
457            result->cx, result->cy, result->helpId );
458     TRACE( dialog, " STYLE 0x%08lx\n", result->style );
459     TRACE( dialog, " EXSTYLE 0x%08lx\n", result->exStyle );
460
461     /* Get the menu name */
462
463     switch(GET_WORD(p))
464     {
465     case 0x0000:
466         result->menuName = NULL;
467         p++;
468         break;
469     case 0xffff:
470         result->menuName = (LPCSTR)(UINT32)GET_WORD( p + 1 );
471         p += 2;
472         TRACE(dialog, " MENU %04x\n", LOWORD(result->menuName) );
473         break;
474     default:
475         result->menuName = (LPCSTR)p;
476         TRACE(dialog, " MENU %s\n", debugstr_w( (LPCWSTR)p ));
477         p += lstrlen32W( (LPCWSTR)p ) + 1;
478         break;
479     }
480
481     /* Get the class name */
482
483     switch(GET_WORD(p))
484     {
485     case 0x0000:
486         result->className = DIALOG_CLASS_ATOM;
487         p++;
488         break;
489     case 0xffff:
490         result->className = (LPCSTR)(UINT32)GET_WORD( p + 1 );
491         p += 2;
492         TRACE(dialog, " CLASS %04x\n", LOWORD(result->className) );
493         break;
494     default:
495         result->className = (LPCSTR)p;
496         TRACE(dialog, " CLASS %s\n", debugstr_w( (LPCWSTR)p ));
497         p += lstrlen32W( (LPCWSTR)p ) + 1;
498         break;
499     }
500
501     /* Get the window caption */
502
503     result->caption = (LPCSTR)p;
504     p += lstrlen32W( (LPCWSTR)p ) + 1;
505     TRACE(dialog, " CAPTION %s\n", debugstr_w( (LPCWSTR)result->caption ) );
506
507     /* Get the font name */
508
509     if (result->style & DS_SETFONT)
510     {
511         result->pointSize = GET_WORD(p);
512         p++;
513         if (result->dialogEx)
514         {
515             result->weight = GET_WORD(p); p++;
516             result->italic = LOBYTE(GET_WORD(p)); p++;
517         }
518         else
519         {
520             result->weight = FW_DONTCARE;
521             result->italic = FALSE;
522         }
523         result->faceName = (LPCSTR)p;
524         p += lstrlen32W( (LPCWSTR)p ) + 1;
525         TRACE(dialog, " FONT %d, %s, %d, %s\n",
526               result->pointSize, debugstr_w( (LPCWSTR)result->faceName ),
527               result->weight, result->italic ? "TRUE" : "FALSE" );
528     }
529
530     /* First control is on dword boundary */
531     return (LPCSTR)((((int)p) + 3) & ~3);
532 }
533
534
535 /***********************************************************************
536  *           DIALOG_CreateIndirect
537  */
538 HWND32 DIALOG_CreateIndirect( HINSTANCE32 hInst, LPCSTR dlgTemplate,
539                               BOOL32 win32Template, HWND32 owner,
540                               DLGPROC16 dlgProc, LPARAM param,
541                               WINDOWPROCTYPE procType )
542 {
543     HMENU16 hMenu = 0;
544     HFONT16 hFont = 0;
545     HWND32 hwnd;
546     RECT32 rect;
547     WND * wndPtr;
548     DLG_TEMPLATE template;
549     DIALOGINFO * dlgInfo;
550     WORD xUnit = xBaseUnit;
551     WORD yUnit = yBaseUnit;
552
553       /* Parse dialog template */
554
555     if (!dlgTemplate) return 0;
556     if (win32Template)
557         dlgTemplate = DIALOG_ParseTemplate32( dlgTemplate, &template );
558     else
559         dlgTemplate = DIALOG_ParseTemplate16( dlgTemplate, &template );
560
561       /* Load menu */
562
563     if (template.menuName)
564     {
565         if (!win32Template)
566         {
567             LPSTR str = SEGPTR_STRDUP( template.menuName );
568             hMenu = LoadMenu16( hInst, SEGPTR_GET(str) );
569             SEGPTR_FREE( str );
570         }
571         else hMenu = LoadMenu32W( hInst, (LPCWSTR)template.menuName );
572     }
573
574       /* Create custom font if needed */
575
576     if (template.style & DS_SETFONT)
577     {
578           /* The font height must be negative as it is a point size */
579           /* (see CreateFont() documentation in the Windows SDK).   */
580         if (win32Template)
581             hFont = CreateFont32W( -template.pointSize, 0, 0, 0,
582                                    template.weight, template.italic, FALSE,
583                                    FALSE, DEFAULT_CHARSET, 0, 0, PROOF_QUALITY,
584                                    FF_DONTCARE, (LPCWSTR)template.faceName );
585         else
586             hFont = CreateFont16( -template.pointSize, 0, 0, 0, FW_DONTCARE,
587                             FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
588                             PROOF_QUALITY, FF_DONTCARE,
589                             template.faceName );
590         if (hFont)
591         {
592             TEXTMETRIC16 tm;
593             HFONT16 oldFont;
594
595             HDC32 hdc = GetDC32(0);
596             oldFont = SelectObject32( hdc, hFont );
597             GetTextMetrics16( hdc, &tm );
598             SelectObject32( hdc, oldFont );
599             ReleaseDC32( 0, hdc );
600             xUnit = tm.tmAveCharWidth;
601             yUnit = tm.tmHeight;
602             if (!(tm.tmPitchAndFamily & TMPF_FIXED_PITCH))
603                 xBaseUnit = xBaseUnit * 5 / 4;  /* See DIALOG_Init() */
604         }
605     }
606     
607     /* Create dialog main window */
608
609     rect.left = rect.top = 0;
610     rect.right = template.cx * xUnit / 4;
611     rect.bottom = template.cy * yUnit / 8;
612     if (template.style & DS_MODALFRAME)
613         template.exStyle |= WS_EX_DLGMODALFRAME;
614     AdjustWindowRectEx32( &rect, template.style, 
615                           hMenu ? TRUE : FALSE , template.exStyle );
616     rect.right -= rect.left;
617     rect.bottom -= rect.top;
618
619     if ((INT16)template.x == CW_USEDEFAULT16)
620     {
621         rect.left = rect.top = (procType == WIN_PROC_16) ? CW_USEDEFAULT16
622                                                          : CW_USEDEFAULT32;
623     }
624     else
625     {
626         rect.left += template.x * xUnit / 4;
627         rect.top += template.y * yUnit / 8;
628         if ( !(template.style & WS_CHILD) )
629         {
630             INT16 dX, dY;
631
632             if( !(template.style & DS_ABSALIGN) )
633                 ClientToScreen32( owner, (POINT32 *)&rect );
634             
635             /* try to fit it into the desktop */
636
637             if( (dX = rect.left + rect.right + SYSMETRICS_CXDLGFRAME 
638                  - SYSMETRICS_CXSCREEN) > 0 ) rect.left -= dX;
639             if( (dY = rect.top + rect.bottom + SYSMETRICS_CYDLGFRAME
640                  - SYSMETRICS_CYSCREEN) > 0 ) rect.top -= dY;
641             if( rect.left < 0 ) rect.left = 0;
642             if( rect.top < 0 ) rect.top = 0;
643         }
644     }
645
646     if (procType == WIN_PROC_16)
647         hwnd = CreateWindowEx16(template.exStyle, template.className,
648                                 template.caption, template.style & ~WS_VISIBLE,
649                                 rect.left, rect.top, rect.right, rect.bottom,
650                                 owner, hMenu, hInst, NULL );
651     else
652         hwnd = CreateWindowEx32W(template.exStyle, (LPCWSTR)template.className,
653                                  (LPCWSTR)template.caption,
654                                  template.style & ~WS_VISIBLE,
655                                  rect.left, rect.top, rect.right, rect.bottom,
656                                  owner, hMenu, hInst, NULL );
657         
658     if (!hwnd)
659     {
660         if (hFont) DeleteObject32( hFont );
661         if (hMenu) DestroyMenu32( hMenu );
662         return 0;
663     }
664     wndPtr = WIN_FindWndPtr( hwnd );
665     wndPtr->flags |= WIN_ISDIALOG;
666     wndPtr->helpContext = template.helpId;
667
668       /* Initialise dialog extra data */
669
670     dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
671     WINPROC_SetProc( &dlgInfo->dlgProc, dlgProc, procType, WIN_PROC_WINDOW );
672     dlgInfo->hUserFont = hFont;
673     dlgInfo->hMenu     = hMenu;
674     dlgInfo->xBaseUnit = xUnit;
675     dlgInfo->yBaseUnit = yUnit;
676     dlgInfo->msgResult = 0;
677     dlgInfo->idResult  = 0;
678     dlgInfo->flags     = 0;
679     dlgInfo->hDialogHeap = 0;
680
681     if (dlgInfo->hUserFont)
682         SendMessage32A( hwnd, WM_SETFONT, (WPARAM32)dlgInfo->hUserFont, 0 );
683
684     /* Create controls */
685
686     if (DIALOG_CreateControls( wndPtr, dlgTemplate, &template,
687                                hInst, win32Template ))
688     {
689        /* Send initialisation messages and set focus */
690
691         dlgInfo->hwndFocus = GetNextDlgTabItem32( hwnd, 0, FALSE );
692
693         if (SendMessage32A( hwnd, WM_INITDIALOG, (WPARAM32)dlgInfo->hwndFocus, param ))
694             SetFocus32( dlgInfo->hwndFocus );
695
696         if (template.style & WS_VISIBLE && !(wndPtr->dwStyle & WS_VISIBLE)) 
697         {
698            ShowWindow32( hwnd, SW_SHOWNORMAL ); /* SW_SHOW doesn't always work */
699            UpdateWindow32( hwnd );
700         }
701         return hwnd;
702     }
703
704     if( IsWindow32(hwnd) ) DestroyWindow32( hwnd );
705     return 0;
706 }
707
708
709 /***********************************************************************
710  *           CreateDialog16   (USER.89)
711  */
712 HWND16 WINAPI CreateDialog16( HINSTANCE16 hInst, SEGPTR dlgTemplate,
713                               HWND16 owner, DLGPROC16 dlgProc )
714 {
715     return CreateDialogParam16( hInst, dlgTemplate, owner, dlgProc, 0 );
716 }
717
718
719 /***********************************************************************
720  *           CreateDialogParam16   (USER.241)
721  */
722 HWND16 WINAPI CreateDialogParam16( HINSTANCE16 hInst, SEGPTR dlgTemplate,
723                                    HWND16 owner, DLGPROC16 dlgProc,
724                                    LPARAM param )
725 {
726     HWND16 hwnd = 0;
727     HRSRC16 hRsrc;
728     HGLOBAL16 hmem;
729     LPCVOID data;
730
731     TRACE(dialog, "%04x,%08lx,%04x,%08lx,%ld\n",
732                    hInst, (DWORD)dlgTemplate, owner, (DWORD)dlgProc, param );
733
734     if (!(hRsrc = FindResource16( hInst, dlgTemplate, RT_DIALOG16 ))) return 0;
735     if (!(hmem = LoadResource16( hInst, hRsrc ))) return 0;
736     if (!(data = LockResource16( hmem ))) hwnd = 0;
737     else hwnd = CreateDialogIndirectParam16( hInst, data, owner,
738                                              dlgProc, param );
739     FreeResource16( hmem );
740     return hwnd;
741 }
742
743
744 /***********************************************************************
745  *           CreateDialogParam32A   (USER32.73)
746  */
747 HWND32 WINAPI CreateDialogParam32A( HINSTANCE32 hInst, LPCSTR name,
748                                     HWND32 owner, DLGPROC32 dlgProc,
749                                     LPARAM param )
750 {
751     if (HIWORD(name))
752     {
753         LPWSTR str = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
754         HWND32 hwnd = CreateDialogParam32W( hInst, str, owner, dlgProc, param);
755         HeapFree( GetProcessHeap(), 0, str );
756         return hwnd;
757     }
758     return CreateDialogParam32W( hInst, (LPCWSTR)name, owner, dlgProc, param );
759 }
760
761
762 /***********************************************************************
763  *           CreateDialogParam32W   (USER32.74)
764  */
765 HWND32 WINAPI CreateDialogParam32W( HINSTANCE32 hInst, LPCWSTR name,
766                                     HWND32 owner, DLGPROC32 dlgProc,
767                                     LPARAM param )
768 {
769     HANDLE32 hrsrc = FindResource32W( hInst, name, RT_DIALOG32W );
770     if (!hrsrc) return 0;
771     return CreateDialogIndirectParam32W( hInst,
772                                          (LPVOID)LoadResource32(hInst, hrsrc),
773                                          owner, dlgProc, param );
774 }
775
776
777 /***********************************************************************
778  *           CreateDialogIndirect16   (USER.219)
779  */
780 HWND16 WINAPI CreateDialogIndirect16( HINSTANCE16 hInst, LPCVOID dlgTemplate,
781                                       HWND16 owner, DLGPROC16 dlgProc )
782 {
783     return CreateDialogIndirectParam16( hInst, dlgTemplate, owner, dlgProc, 0);
784 }
785
786
787 /***********************************************************************
788  *           CreateDialogIndirectParam16   (USER.242)
789  */
790 HWND16 WINAPI CreateDialogIndirectParam16( HINSTANCE16 hInst,
791                                            LPCVOID dlgTemplate,
792                                            HWND16 owner, DLGPROC16 dlgProc,
793                                            LPARAM param )
794 {
795     return DIALOG_CreateIndirect( hInst, dlgTemplate, FALSE, owner,
796                                   dlgProc, param, WIN_PROC_16 );
797 }
798
799
800 /***********************************************************************
801  *           CreateDialogIndirectParam32A   (USER32.69)
802  */
803 HWND32 WINAPI CreateDialogIndirectParam32A( HINSTANCE32 hInst,
804                                             LPCVOID dlgTemplate,
805                                             HWND32 owner, DLGPROC32 dlgProc,
806                                             LPARAM param )
807 {
808     return DIALOG_CreateIndirect( hInst, dlgTemplate, TRUE, owner,
809                                   (DLGPROC16)dlgProc, param, WIN_PROC_32A );
810 }
811
812
813 /***********************************************************************
814  *           CreateDialogIndirectParam32W   (USER32.72)
815  */
816 HWND32 WINAPI CreateDialogIndirectParam32W( HINSTANCE32 hInst,
817                                             LPCVOID dlgTemplate,
818                                             HWND32 owner, DLGPROC32 dlgProc,
819                                             LPARAM param )
820 {
821     return DIALOG_CreateIndirect( hInst, dlgTemplate, TRUE, owner,
822                                   (DLGPROC16)dlgProc, param, WIN_PROC_32W );
823 }
824
825
826 /***********************************************************************
827  *           DIALOG_DoDialogBox
828  */
829 INT32 DIALOG_DoDialogBox( HWND32 hwnd, HWND32 owner )
830 {
831     WND * wndPtr;
832     DIALOGINFO * dlgInfo;
833     MSG16 msg;
834     INT32 retval;
835
836       /* Owner must be a top-level window */
837     owner = WIN_GetTopParent( owner );
838     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1;
839     dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
840     EnableWindow32( owner, FALSE );
841     ShowWindow32( hwnd, SW_SHOW );
842
843     while (MSG_InternalGetMessage(&msg, hwnd, owner, MSGF_DIALOGBOX, PM_REMOVE,
844                                   !(wndPtr->dwStyle & DS_NOIDLEMSG) ))
845     {
846         if (!IsDialogMessage16( hwnd, &msg))
847         {
848             TranslateMessage16( &msg );
849             DispatchMessage16( &msg );
850         }
851         if (dlgInfo->flags & DF_END) break;
852     }
853     retval = dlgInfo->idResult;
854     EnableWindow32( owner, TRUE );
855     DestroyWindow32( hwnd );
856     return retval;
857 }
858
859
860 /***********************************************************************
861  *           DialogBox16   (USER.87)
862  */
863 INT16 WINAPI DialogBox16( HINSTANCE16 hInst, SEGPTR dlgTemplate,
864                           HWND16 owner, DLGPROC16 dlgProc )
865 {
866     return DialogBoxParam16( hInst, dlgTemplate, owner, dlgProc, 0 );
867 }
868
869
870 /***********************************************************************
871  *           DialogBoxParam16   (USER.239)
872  */
873 INT16 WINAPI DialogBoxParam16( HINSTANCE16 hInst, SEGPTR template,
874                                HWND16 owner, DLGPROC16 dlgProc, LPARAM param )
875 {
876     HWND16 hwnd = CreateDialogParam16( hInst, template, owner, dlgProc, param);
877     if (hwnd) return (INT16)DIALOG_DoDialogBox( hwnd, owner );
878     return -1;
879 }
880
881
882 /***********************************************************************
883  *           DialogBoxParam32A   (USER32.139)
884  */
885 INT32 WINAPI DialogBoxParam32A( HINSTANCE32 hInst, LPCSTR name,
886                                 HWND32 owner, DLGPROC32 dlgProc, LPARAM param )
887 {
888     HWND32 hwnd = CreateDialogParam32A( hInst, name, owner, dlgProc, param );
889     if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
890     return -1;
891 }
892
893
894 /***********************************************************************
895  *           DialogBoxParam32W   (USER32.140)
896  */
897 INT32 WINAPI DialogBoxParam32W( HINSTANCE32 hInst, LPCWSTR name,
898                                 HWND32 owner, DLGPROC32 dlgProc, LPARAM param )
899 {
900     HWND32 hwnd = CreateDialogParam32W( hInst, name, owner, dlgProc, param );
901     if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
902     return -1;
903 }
904
905
906 /***********************************************************************
907  *           DialogBoxIndirect16   (USER.218)
908  */
909 INT16 WINAPI DialogBoxIndirect16( HINSTANCE16 hInst, HANDLE16 dlgTemplate,
910                                   HWND16 owner, DLGPROC16 dlgProc )
911 {
912     return DialogBoxIndirectParam16( hInst, dlgTemplate, owner, dlgProc, 0 );
913 }
914
915
916 /***********************************************************************
917  *           DialogBoxIndirectParam16   (USER.240)
918  */
919 INT16 WINAPI DialogBoxIndirectParam16( HINSTANCE16 hInst, HANDLE16 dlgTemplate,
920                                        HWND16 owner, DLGPROC16 dlgProc,
921                                        LPARAM param )
922 {
923     HWND16 hwnd;
924     LPCVOID ptr;
925
926     if (!(ptr = GlobalLock16( dlgTemplate ))) return -1;
927     hwnd = CreateDialogIndirectParam16( hInst, ptr, owner, dlgProc, param );
928     GlobalUnlock16( dlgTemplate );
929     if (hwnd) return (INT16)DIALOG_DoDialogBox( hwnd, owner );
930     return -1;
931 }
932
933
934 /***********************************************************************
935  *           DialogBoxIndirectParam32A   (USER32.136)
936  */
937 INT32 WINAPI DialogBoxIndirectParam32A(HINSTANCE32 hInstance, LPCVOID template,
938                                        HWND32 owner, DLGPROC32 dlgProc,
939                                        LPARAM param )
940 {
941     HWND32 hwnd = CreateDialogIndirectParam32A( hInstance, template,
942                                                 owner, dlgProc, param );
943     if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
944     return -1;
945 }
946
947
948 /***********************************************************************
949  *           DialogBoxIndirectParam32W   (USER32.138)
950  */
951 INT32 WINAPI DialogBoxIndirectParam32W(HINSTANCE32 hInstance, LPCVOID template,
952                                        HWND32 owner, DLGPROC32 dlgProc,
953                                        LPARAM param )
954 {
955     HWND32 hwnd = CreateDialogIndirectParam32W( hInstance, template,
956                                                 owner, dlgProc, param );
957     if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
958     return -1;
959 }
960
961
962 /***********************************************************************
963  *           EndDialog16   (USER32.173)
964  */
965 BOOL16 WINAPI EndDialog16( HWND16 hwnd, INT16 retval )
966 {
967     return EndDialog32( hwnd, retval );
968 }
969
970
971 /***********************************************************************
972  *           EndDialog32   (USER.88)
973  */
974 BOOL32 WINAPI EndDialog32( HWND32 hwnd, INT32 retval )
975 {
976     WND * wndPtr = WIN_FindWndPtr( hwnd );
977     DIALOGINFO * dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
978
979     TRACE(dialog, "%04x %d\n", hwnd, retval );
980
981     if( dlgInfo )
982     {
983         dlgInfo->idResult = retval;
984         dlgInfo->flags |= DF_END;
985     }
986     return TRUE;
987 }
988
989
990 /***********************************************************************
991  *           DIALOG_IsDialogMessage
992  */
993 static BOOL32 DIALOG_IsDialogMessage( HWND32 hwnd, HWND32 hwndDlg,
994                                       UINT32 message, WPARAM32 wParam,
995                                       LPARAM lParam, BOOL32 *translate,
996                                       BOOL32 *dispatch )
997 {
998     INT32 dlgCode;
999
1000     *translate = *dispatch = FALSE;
1001
1002     if (message == WM_PAINT)
1003     {
1004         /* Apparently, we have to handle this one as well */
1005         *dispatch = TRUE;
1006         return TRUE;
1007     }
1008
1009       /* Only the key messages get special processing */
1010     if ((message != WM_KEYDOWN) &&
1011         (message != WM_SYSCHAR) &&
1012         (message != WM_CHAR))
1013         return FALSE;
1014
1015     dlgCode = SendMessage32A( hwnd, WM_GETDLGCODE, 0, 0 );
1016     if (dlgCode & DLGC_WANTMESSAGE)
1017     {
1018         *translate = *dispatch = TRUE;
1019         return TRUE;
1020     }
1021
1022     switch(message)
1023     {
1024     case WM_KEYDOWN:
1025         if (dlgCode & DLGC_WANTALLKEYS) break;
1026         switch(wParam)
1027         {
1028         case VK_TAB:
1029             if (!(dlgCode & DLGC_WANTTAB))
1030             {
1031                 SendMessage32A( hwndDlg, WM_NEXTDLGCTL,
1032                                 (GetKeyState32(VK_SHIFT) & 0x8000), 0 );
1033                 return TRUE;
1034             }
1035             break;
1036             
1037         case VK_RIGHT:
1038         case VK_DOWN:
1039             if (!(dlgCode & DLGC_WANTARROWS))
1040             {
1041                 SetFocus32( GetNextDlgGroupItem32( hwndDlg, GetFocus32(),
1042                                                    FALSE ) );
1043                 return TRUE;
1044             }
1045             break;
1046
1047         case VK_LEFT:
1048         case VK_UP:
1049             if (!(dlgCode & DLGC_WANTARROWS))
1050             {
1051                 SetFocus32( GetNextDlgGroupItem32( hwndDlg, GetFocus32(),
1052                                                    TRUE ) );
1053                 return TRUE;
1054             }
1055             break;
1056
1057         case VK_ESCAPE:
1058             SendMessage32A( hwndDlg, WM_COMMAND, IDCANCEL,
1059                             (LPARAM)GetDlgItem32( hwndDlg, IDCANCEL ) );
1060             break;
1061
1062         case VK_RETURN:
1063             {
1064                 DWORD dw = SendMessage16( hwndDlg, DM_GETDEFID, 0, 0 );
1065                 if (HIWORD(dw) == DC_HASDEFID)
1066                     SendMessage32A( hwndDlg, WM_COMMAND, 
1067                                     MAKEWPARAM( LOWORD(dw), BN_CLICKED ),
1068                                     (LPARAM)GetDlgItem32(hwndDlg, LOWORD(dw)));
1069                 else
1070                     SendMessage32A( hwndDlg, WM_COMMAND, IDOK,
1071                                     (LPARAM)GetDlgItem32( hwndDlg, IDOK ) );
1072             }
1073             break;
1074
1075         default:
1076             *translate = TRUE;
1077             break;
1078         }
1079         break;  /* case WM_KEYDOWN */
1080
1081         
1082     case WM_CHAR:
1083         if (dlgCode & (DLGC_WANTALLKEYS | DLGC_WANTCHARS)) break;
1084         break;
1085
1086     case WM_SYSCHAR:
1087         if (dlgCode & DLGC_WANTALLKEYS) break;
1088         break;
1089     }
1090
1091     /* If we get here, the message has not been treated specially */
1092     /* and can be sent to its destination window. */
1093     *dispatch = TRUE;
1094     return TRUE;
1095 }
1096
1097
1098 /***********************************************************************
1099  *           IsDialogMessage16   (USER.90)
1100  */
1101 BOOL16 WINAPI IsDialogMessage16( HWND16 hwndDlg, LPMSG16 msg )
1102 {
1103     BOOL32 ret, translate, dispatch;
1104
1105     if ((hwndDlg != msg->hwnd) && !IsChild16( hwndDlg, msg->hwnd ))
1106         return FALSE;
1107
1108     ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message,
1109                                   msg->wParam, msg->lParam,
1110                                   &translate, &dispatch );
1111     if (translate) TranslateMessage16( msg );
1112     if (dispatch) DispatchMessage16( msg );
1113     return ret;
1114 }
1115
1116
1117 /***********************************************************************
1118  *           IsDialogMessage32A   (USER32.342)
1119  */
1120 BOOL32 WINAPI IsDialogMessage32A( HWND32 hwndDlg, LPMSG32 msg )
1121 {
1122     BOOL32 ret, translate, dispatch;
1123
1124     if ((hwndDlg != msg->hwnd) && !IsChild32( hwndDlg, msg->hwnd ))
1125         return FALSE;
1126
1127     ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message,
1128                                   msg->wParam, msg->lParam,
1129                                   &translate, &dispatch );
1130     if (translate) TranslateMessage32( msg );
1131     if (dispatch) DispatchMessage32A( msg );
1132     return ret;
1133 }
1134
1135
1136 /***********************************************************************
1137  *           IsDialogMessage32W   (USER32.343)
1138  */
1139 BOOL32 WINAPI IsDialogMessage32W( HWND32 hwndDlg, LPMSG32 msg )
1140 {
1141     BOOL32 ret, translate, dispatch;
1142
1143     if ((hwndDlg != msg->hwnd) && !IsChild32( hwndDlg, msg->hwnd ))
1144         return FALSE;
1145
1146     ret = DIALOG_IsDialogMessage( msg->hwnd, hwndDlg, msg->message,
1147                                   msg->wParam, msg->lParam,
1148                                   &translate, &dispatch );
1149     if (translate) TranslateMessage32( msg );
1150     if (dispatch) DispatchMessage32W( msg );
1151     return ret;
1152 }
1153
1154
1155 /****************************************************************
1156  *         GetDlgCtrlID16   (USER.277)
1157  */
1158 INT16 WINAPI GetDlgCtrlID16( HWND16 hwnd )
1159 {
1160     WND *wndPtr = WIN_FindWndPtr(hwnd);
1161     if (wndPtr) return wndPtr->wIDmenu;
1162     else return 0;
1163 }
1164  
1165
1166 /****************************************************************
1167  *         GetDlgCtrlID32   (USER32.234)
1168  */
1169 INT32 WINAPI GetDlgCtrlID32( HWND32 hwnd )
1170 {
1171     WND *wndPtr = WIN_FindWndPtr(hwnd);
1172     if (wndPtr) return wndPtr->wIDmenu;
1173     else return 0;
1174 }
1175  
1176
1177 /***********************************************************************
1178  *           GetDlgItem16   (USER.91)
1179  */
1180 HWND16 WINAPI GetDlgItem16( HWND16 hwndDlg, INT16 id )
1181 {
1182     WND *pWnd;
1183
1184     if (!(pWnd = WIN_FindWndPtr( hwndDlg ))) return 0;
1185     for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
1186         if (pWnd->wIDmenu == (UINT16)id) return pWnd->hwndSelf;
1187     return 0;
1188 }
1189
1190
1191 /***********************************************************************
1192  *           GetDlgItem32   (USER32.235)
1193  */
1194 HWND32 WINAPI GetDlgItem32( HWND32 hwndDlg, INT32 id )
1195 {
1196     WND *pWnd;
1197
1198     if (!(pWnd = WIN_FindWndPtr( hwndDlg ))) return 0;
1199     for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
1200         if (pWnd->wIDmenu == (UINT16)id) return pWnd->hwndSelf;
1201     return 0;
1202 }
1203
1204
1205 /*******************************************************************
1206  *           SendDlgItemMessage16   (USER.101)
1207  */
1208 LRESULT WINAPI SendDlgItemMessage16( HWND16 hwnd, INT16 id, UINT16 msg,
1209                                      WPARAM16 wParam, LPARAM lParam )
1210 {
1211     HWND16 hwndCtrl = GetDlgItem16( hwnd, id );
1212     if (hwndCtrl) return SendMessage16( hwndCtrl, msg, wParam, lParam );
1213     else return 0;
1214 }
1215
1216
1217 /*******************************************************************
1218  *           SendDlgItemMessage32A   (USER32.452)
1219  */
1220 LRESULT WINAPI SendDlgItemMessage32A( HWND32 hwnd, INT32 id, UINT32 msg,
1221                                       WPARAM32 wParam, LPARAM lParam )
1222 {
1223     HWND32 hwndCtrl = GetDlgItem32( hwnd, id );
1224     if (hwndCtrl) return SendMessage32A( hwndCtrl, msg, wParam, lParam );
1225     else return 0;
1226 }
1227
1228
1229 /*******************************************************************
1230  *           SendDlgItemMessage32W   (USER32.453)
1231  */
1232 LRESULT WINAPI SendDlgItemMessage32W( HWND32 hwnd, INT32 id, UINT32 msg,
1233                                       WPARAM32 wParam, LPARAM lParam )
1234 {
1235     HWND32 hwndCtrl = GetDlgItem32( hwnd, id );
1236     if (hwndCtrl) return SendMessage32W( hwndCtrl, msg, wParam, lParam );
1237     else return 0;
1238 }
1239
1240
1241 /*******************************************************************
1242  *           SetDlgItemText16   (USER.92)
1243  */
1244 void WINAPI SetDlgItemText16( HWND16 hwnd, INT16 id, SEGPTR lpString )
1245 {
1246     SendDlgItemMessage16( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString );
1247 }
1248
1249
1250 /*******************************************************************
1251  *           SetDlgItemText32A   (USER32.478)
1252  */
1253 void WINAPI SetDlgItemText32A( HWND32 hwnd, INT32 id, LPCSTR lpString )
1254 {
1255     SendDlgItemMessage32A( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString );
1256 }
1257
1258
1259 /*******************************************************************
1260  *           SetDlgItemText32W   (USER32.479)
1261  */
1262 void WINAPI SetDlgItemText32W( HWND32 hwnd, INT32 id, LPCWSTR lpString )
1263 {
1264     SendDlgItemMessage32W( hwnd, id, WM_SETTEXT, 0, (LPARAM)lpString );
1265 }
1266
1267
1268 /***********************************************************************
1269  *           GetDlgItemText16   (USER.93)
1270  */
1271 INT16 WINAPI GetDlgItemText16( HWND16 hwnd, INT16 id, SEGPTR str, UINT16 len )
1272 {
1273     return (INT16)SendDlgItemMessage16( hwnd, id, WM_GETTEXT,
1274                                         len, (LPARAM)str );
1275 }
1276
1277
1278 /***********************************************************************
1279  *           GetDlgItemText32A   (USER32.237)
1280  */
1281 INT32 WINAPI GetDlgItemText32A( HWND32 hwnd, INT32 id, LPSTR str, UINT32 len )
1282 {
1283     return (INT32)SendDlgItemMessage32A( hwnd, id, WM_GETTEXT,
1284                                          len, (LPARAM)str );
1285 }
1286
1287
1288 /***********************************************************************
1289  *           GetDlgItemText32W   (USER32.238)
1290  */
1291 INT32 WINAPI GetDlgItemText32W( HWND32 hwnd, INT32 id, LPWSTR str, UINT32 len )
1292 {
1293     return (INT32)SendDlgItemMessage32W( hwnd, id, WM_GETTEXT,
1294                                          len, (LPARAM)str );
1295 }
1296
1297
1298 /*******************************************************************
1299  *           SetDlgItemInt16   (USER.94)
1300  */
1301 void WINAPI SetDlgItemInt16( HWND16 hwnd, INT16 id, UINT16 value, BOOL16 fSigned )
1302 {
1303     return SetDlgItemInt32( hwnd, (UINT32)(UINT16)id, value, fSigned );
1304 }
1305
1306
1307 /*******************************************************************
1308  *           SetDlgItemInt32   (USER32.477)
1309  */
1310 void WINAPI SetDlgItemInt32( HWND32 hwnd, INT32 id, UINT32 value,
1311                              BOOL32 fSigned )
1312 {
1313     char str[20];
1314
1315     if (fSigned) sprintf( str, "%d", (INT32)value );
1316     else sprintf( str, "%u", value );
1317     SendDlgItemMessage32A( hwnd, id, WM_SETTEXT, 0, (LPARAM)str );
1318 }
1319
1320
1321 /***********************************************************************
1322  *           GetDlgItemInt16   (USER.95)
1323  */
1324 UINT16 WINAPI GetDlgItemInt16( HWND16 hwnd, INT16 id, BOOL16 *translated,
1325                                BOOL16 fSigned )
1326 {
1327     UINT32 result;
1328     BOOL32 ok;
1329
1330     if (translated) *translated = FALSE;
1331     result = GetDlgItemInt32( hwnd, (UINT32)(UINT16)id, &ok, fSigned );
1332     if (!ok) return 0;
1333     if (fSigned)
1334     {
1335         if (((INT32)result < -32767) || ((INT32)result > 32767)) return 0;
1336     }
1337     else
1338     {
1339         if (result > 65535) return 0;
1340     }
1341     if (translated) *translated = TRUE;
1342     return (UINT16)result;
1343 }
1344
1345
1346 /***********************************************************************
1347  *           GetDlgItemInt32   (USER32.236)
1348  */
1349 UINT32 WINAPI GetDlgItemInt32( HWND32 hwnd, INT32 id, BOOL32 *translated,
1350                                BOOL32 fSigned )
1351 {
1352     char str[30];
1353     char * endptr;
1354     long result = 0;
1355     
1356     if (translated) *translated = FALSE;
1357     if (!SendDlgItemMessage32A(hwnd, id, WM_GETTEXT, sizeof(str), (LPARAM)str))
1358         return 0;
1359     if (fSigned)
1360     {
1361         result = strtol( str, &endptr, 10 );
1362         if (!endptr || (endptr == str))  /* Conversion was unsuccessful */
1363             return 0;
1364         if (((result == LONG_MIN) || (result == LONG_MAX)) && (errno==ERANGE))
1365             return 0;
1366     }
1367     else
1368     {
1369         result = strtoul( str, &endptr, 10 );
1370         if (!endptr || (endptr == str))  /* Conversion was unsuccessful */
1371             return 0;
1372         if ((result == ULONG_MAX) && (errno == ERANGE)) return 0;
1373     }
1374     if (translated) *translated = TRUE;
1375     return (UINT32)result;
1376 }
1377
1378
1379 /***********************************************************************
1380  *           CheckDlgButton16   (USER.97)
1381  */
1382 BOOL16 WINAPI CheckDlgButton16( HWND16 hwnd, INT16 id, UINT16 check )
1383 {
1384     SendDlgItemMessage32A( hwnd, id, BM_SETCHECK32, check, 0 );
1385     return TRUE;
1386 }
1387
1388
1389 /***********************************************************************
1390  *           CheckDlgButton32   (USER32.45)
1391  */
1392 BOOL32 WINAPI CheckDlgButton32( HWND32 hwnd, INT32 id, UINT32 check )
1393 {
1394     SendDlgItemMessage32A( hwnd, id, BM_SETCHECK32, check, 0 );
1395     return TRUE;
1396 }
1397
1398
1399 /***********************************************************************
1400  *           IsDlgButtonChecked16   (USER.98)
1401  */
1402 UINT16 WINAPI IsDlgButtonChecked16( HWND16 hwnd, UINT16 id )
1403 {
1404     return (UINT16)SendDlgItemMessage32A( hwnd, id, BM_GETCHECK32, 0, 0 );
1405 }
1406
1407
1408 /***********************************************************************
1409  *           IsDlgButtonChecked32   (USER32.344)
1410  */
1411 UINT32 WINAPI IsDlgButtonChecked32( HWND32 hwnd, UINT32 id )
1412 {
1413     return (UINT32)SendDlgItemMessage32A( hwnd, id, BM_GETCHECK32, 0, 0 );
1414 }
1415
1416
1417 /***********************************************************************
1418  *           CheckRadioButton16   (USER.96)
1419  */
1420 BOOL16 WINAPI CheckRadioButton16( HWND16 hwndDlg, UINT16 firstID,
1421                                   UINT16 lastID, UINT16 checkID )
1422 {
1423     return CheckRadioButton32( hwndDlg, firstID, lastID, checkID );
1424 }
1425
1426
1427 /***********************************************************************
1428  *           CheckRadioButton32   (USER32.48)
1429  */
1430 BOOL32 WINAPI CheckRadioButton32( HWND32 hwndDlg, UINT32 firstID,
1431                                   UINT32 lastID, UINT32 checkID )
1432 {
1433     WND *pWnd = WIN_FindWndPtr( hwndDlg );
1434     if (!pWnd) return FALSE;
1435
1436     for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
1437         if ((pWnd->wIDmenu == firstID) || (pWnd->wIDmenu == lastID)) break;
1438     if (!pWnd) return FALSE;
1439
1440     if (pWnd->wIDmenu == lastID)
1441         lastID = firstID;  /* Buttons are in reverse order */
1442     while (pWnd)
1443     {
1444         SendMessage32A( pWnd->hwndSelf, BM_SETCHECK32,
1445                         (pWnd->wIDmenu == checkID), 0 );
1446         if (pWnd->wIDmenu == lastID) break;
1447         pWnd = pWnd->next;
1448     }
1449     return TRUE;
1450 }
1451
1452
1453 /***********************************************************************
1454  *           GetDialogBaseUnits   (USER.243) (USER32.233)
1455  */
1456 DWORD WINAPI GetDialogBaseUnits(void)
1457 {
1458     return MAKELONG( xBaseUnit, yBaseUnit );
1459 }
1460
1461
1462 /***********************************************************************
1463  *           MapDialogRect16   (USER.103)
1464  */
1465 void WINAPI MapDialogRect16( HWND16 hwnd, LPRECT16 rect )
1466 {
1467     DIALOGINFO * dlgInfo;
1468     WND * wndPtr = WIN_FindWndPtr( hwnd );
1469     if (!wndPtr) return;
1470     dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
1471     rect->left   = (rect->left * dlgInfo->xBaseUnit) / 4;
1472     rect->right  = (rect->right * dlgInfo->xBaseUnit) / 4;
1473     rect->top    = (rect->top * dlgInfo->yBaseUnit) / 8;
1474     rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8;
1475 }
1476
1477
1478 /***********************************************************************
1479  *           MapDialogRect32   (USER32.382)
1480  */
1481 void WINAPI MapDialogRect32( HWND32 hwnd, LPRECT32 rect )
1482 {
1483     DIALOGINFO * dlgInfo;
1484     WND * wndPtr = WIN_FindWndPtr( hwnd );
1485     if (!wndPtr) return;
1486     dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
1487     rect->left   = (rect->left * dlgInfo->xBaseUnit) / 4;
1488     rect->right  = (rect->right * dlgInfo->xBaseUnit) / 4;
1489     rect->top    = (rect->top * dlgInfo->yBaseUnit) / 8;
1490     rect->bottom = (rect->bottom * dlgInfo->yBaseUnit) / 8;
1491 }
1492
1493
1494 /***********************************************************************
1495  *           GetNextDlgGroupItem16   (USER.227)
1496  */
1497 HWND16 WINAPI GetNextDlgGroupItem16( HWND16 hwndDlg, HWND16 hwndCtrl,
1498                                      BOOL16 fPrevious )
1499 {
1500     return (HWND16)GetNextDlgGroupItem32( hwndDlg, hwndCtrl, fPrevious );
1501 }
1502
1503
1504 /***********************************************************************
1505  *           GetNextDlgGroupItem32   (USER32.275)
1506  */
1507 HWND32 WINAPI GetNextDlgGroupItem32( HWND32 hwndDlg, HWND32 hwndCtrl,
1508                                      BOOL32 fPrevious )
1509 {
1510     WND *pWnd, *pWndLast, *pWndCtrl, *pWndDlg;
1511
1512     if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0;
1513     if (hwndCtrl)
1514     {
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;
1520     }
1521     else
1522     {
1523         /* No ctrl specified -> start from the beginning */
1524         if (!(pWndCtrl = pWndDlg->child)) return 0;
1525         if (fPrevious) while (pWndCtrl->next) pWndCtrl = pWndCtrl->next;
1526     }
1527
1528     pWndLast = pWndCtrl;
1529     pWnd = pWndCtrl->next;
1530     while (1)
1531     {
1532         if (!pWnd || (pWnd->dwStyle & WS_GROUP))
1533         {
1534             /* Wrap-around to the beginning of the group */
1535             WND *pWndStart = pWndDlg->child;
1536             for (pWnd = pWndStart; pWnd; pWnd = pWnd->next)
1537             {
1538                 if (pWnd->dwStyle & WS_GROUP) pWndStart = pWnd;
1539                 if (pWnd == pWndCtrl) break;
1540             }
1541             pWnd = pWndStart;
1542         }
1543         if (pWnd == pWndCtrl) break;
1544         if ((pWnd->dwStyle & WS_VISIBLE) && !(pWnd->dwStyle & WS_DISABLED))
1545         {
1546             pWndLast = pWnd;
1547             if (!fPrevious) break;
1548         }
1549         pWnd = pWnd->next;
1550     }
1551     return pWndLast->hwndSelf;
1552 }
1553
1554
1555 /***********************************************************************
1556  *           GetNextDlgTabItem16   (USER.228)
1557  */
1558 HWND16 WINAPI GetNextDlgTabItem16( HWND16 hwndDlg, HWND16 hwndCtrl,
1559                                    BOOL16 fPrevious )
1560 {
1561     return (HWND16)GetNextDlgTabItem32( hwndDlg, hwndCtrl, fPrevious );
1562 }
1563
1564
1565 /***********************************************************************
1566  *           GetNextDlgTabItem32   (USER32.276)
1567  */
1568 HWND32 WINAPI GetNextDlgTabItem32( HWND32 hwndDlg, HWND32 hwndCtrl,
1569                                    BOOL32 fPrevious )
1570 {
1571     WND *pWnd, *pWndLast, *pWndCtrl, *pWndDlg;
1572
1573     if (!(pWndDlg = WIN_FindWndPtr( hwndDlg ))) return 0;
1574     if (hwndCtrl)
1575     {
1576         if (!(pWndCtrl = WIN_FindWndPtr( hwndCtrl ))) return 0;
1577         /* Make sure hwndCtrl is a top-level child */
1578         while ((pWndCtrl->dwStyle & WS_CHILD) && (pWndCtrl->parent != pWndDlg))
1579             pWndCtrl = pWndCtrl->parent;
1580         if (pWndCtrl->parent != pWndDlg) return 0;
1581     }
1582     else
1583     {
1584         /* No ctrl specified -> start from the beginning */
1585         if (!(pWndCtrl = pWndDlg->child)) return 0;
1586         if (fPrevious) while (pWndCtrl->next) pWndCtrl = pWndCtrl->next;
1587     }
1588
1589     pWndLast = pWndCtrl;
1590     pWnd = pWndCtrl->next;
1591     while (1)
1592     {
1593         if (!pWnd) pWnd = pWndDlg->child;
1594         if (pWnd == pWndCtrl) break;
1595         if ((pWnd->dwStyle & WS_TABSTOP) && (pWnd->dwStyle & WS_VISIBLE) &&
1596             !(pWnd->dwStyle & WS_DISABLED))
1597         {
1598             pWndLast = pWnd;
1599             if (!fPrevious) break;
1600         }
1601         pWnd = pWnd->next;
1602     }
1603     return pWndLast->hwndSelf;
1604 }
1605
1606
1607 /**********************************************************************
1608  *           DIALOG_DlgDirSelect
1609  *
1610  * Helper function for DlgDirSelect*
1611  */
1612 static BOOL32 DIALOG_DlgDirSelect( HWND32 hwnd, LPSTR str, INT32 len,
1613                                    INT32 id, BOOL32 win32, BOOL32 unicode,
1614                                    BOOL32 combo )
1615 {
1616     char *buffer, *ptr;
1617     INT32 item, size;
1618     BOOL32 ret;
1619     HWND32 listbox = GetDlgItem32( hwnd, id );
1620
1621     TRACE(dialog, "%04x '%s' %d\n", hwnd, str, id );
1622     if (!listbox) return FALSE;
1623     if (win32)
1624     {
1625         item = SendMessage32A(listbox, combo ? CB_GETCURSEL32
1626                                              : LB_GETCURSEL32, 0, 0 );
1627         if (item == LB_ERR) return FALSE;
1628         size = SendMessage32A(listbox, combo ? CB_GETLBTEXTLEN32
1629                                              : LB_GETTEXTLEN32, 0, 0 );
1630         if (size == LB_ERR) return FALSE;
1631     }
1632     else
1633     {
1634         item = SendMessage32A(listbox, combo ? CB_GETCURSEL16
1635                                              : LB_GETCURSEL16, 0, 0 );
1636         if (item == LB_ERR) return FALSE;
1637         size = SendMessage32A(listbox, combo ? CB_GETLBTEXTLEN16
1638                                              : LB_GETTEXTLEN16, 0, 0 );
1639         if (size == LB_ERR) return FALSE;
1640     }
1641
1642     if (!(buffer = SEGPTR_ALLOC( size+1 ))) return FALSE;
1643
1644     if (win32)
1645         SendMessage32A( listbox, combo ? CB_GETLBTEXT32 : LB_GETTEXT32,
1646                         item, (LPARAM)buffer );
1647     else
1648         SendMessage16( listbox, combo ? CB_GETLBTEXT16 : LB_GETTEXT16,
1649                        item, (LPARAM)SEGPTR_GET(buffer) );
1650
1651     if ((ret = (buffer[0] == '[')))  /* drive or directory */
1652     {
1653         if (buffer[1] == '-')  /* drive */
1654         {
1655             buffer[3] = ':';
1656             buffer[4] = 0;
1657             ptr = buffer + 2;
1658         }
1659         else
1660         {
1661             buffer[strlen(buffer)-1] = '\\';
1662             ptr = buffer + 1;
1663         }
1664     }
1665     else ptr = buffer;
1666
1667     if (unicode) lstrcpynAtoW( (LPWSTR)str, ptr, len );
1668     else lstrcpyn32A( str, ptr, len );
1669     SEGPTR_FREE( buffer );
1670     TRACE(dialog, "Returning %d '%s'\n", ret, str );
1671     return ret;
1672 }
1673
1674
1675 /**********************************************************************
1676  *          DIALOG_DlgDirList
1677  *
1678  * Helper function for DlgDirList*
1679  */
1680 static INT32 DIALOG_DlgDirList( HWND32 hDlg, LPSTR spec, INT32 idLBox,
1681                                 INT32 idStatic, UINT32 attrib, BOOL32 combo )
1682 {
1683     int drive;
1684     HWND32 hwnd;
1685     LPSTR orig_spec = spec;
1686
1687 #define SENDMSG(msg,wparam,lparam) \
1688     ((attrib & DDL_POSTMSGS) ? PostMessage32A( hwnd, msg, wparam, lparam ) \
1689                              : SendMessage32A( hwnd, msg, wparam, lparam ))
1690
1691     TRACE(dialog, "%04x '%s' %d %d %04x\n",
1692                     hDlg, spec ? spec : "NULL", idLBox, idStatic, attrib );
1693
1694     if (spec && spec[0] && (spec[1] == ':'))
1695     {
1696         drive = toupper( spec[0] ) - 'A';
1697         spec += 2;
1698         if (!DRIVE_SetCurrentDrive( drive )) return FALSE;
1699     }
1700     else drive = DRIVE_GetCurrentDrive();
1701
1702     /* If the path exists and is a directory, chdir to it */
1703     if (!spec || !spec[0] || DRIVE_Chdir( drive, spec )) spec = "*.*";
1704     else
1705     {
1706         char *p, *p2;
1707         p = spec;
1708         if ((p2 = strrchr( p, '\\' ))) p = p2;
1709         if ((p2 = strrchr( p, '/' ))) p = p2;
1710         if (p != spec)
1711         {
1712             char sep = *p;
1713             *p = 0;
1714             if (!DRIVE_Chdir( drive, spec ))
1715             {
1716                 *p = sep;  /* Restore the original spec */
1717                 return FALSE;
1718             }
1719             spec = p + 1;
1720         }
1721     }
1722
1723     TRACE(dialog, "path=%c:\\%s mask=%s\n",
1724                     'A' + drive, DRIVE_GetDosCwd(drive), spec );
1725
1726     if (idLBox && ((hwnd = GetDlgItem32( hDlg, idLBox )) != 0))
1727     {
1728         SENDMSG( combo ? CB_RESETCONTENT32 : LB_RESETCONTENT32, 0, 0 );
1729         if (attrib & DDL_DIRECTORY)
1730         {
1731             if (!(attrib & DDL_EXCLUSIVE))
1732             {
1733                 if (SENDMSG( combo ? CB_DIR32 : LB_DIR32,
1734                              attrib & ~(DDL_DIRECTORY | DDL_DRIVES),
1735                              (LPARAM)spec ) == LB_ERR)
1736                     return FALSE;
1737             }
1738             if (SENDMSG( combo ? CB_DIR32 : LB_DIR32,
1739                        (attrib & (DDL_DIRECTORY | DDL_DRIVES)) | DDL_EXCLUSIVE,
1740                          (LPARAM)"*.*" ) == LB_ERR)
1741                 return FALSE;
1742         }
1743         else
1744         {
1745             if (SENDMSG( combo ? CB_DIR32 : LB_DIR32, attrib,
1746                          (LPARAM)spec ) == LB_ERR)
1747                 return FALSE;
1748         }
1749     }
1750
1751     if (idStatic && ((hwnd = GetDlgItem32( hDlg, idStatic )) != 0))
1752     {
1753         char temp[512];
1754         int drive = DRIVE_GetCurrentDrive();
1755         strcpy( temp, "A:\\" );
1756         temp[0] += drive;
1757         lstrcpyn32A( temp + 3, DRIVE_GetDosCwd(drive), sizeof(temp)-3 );
1758         CharLower32A( temp );
1759         /* Can't use PostMessage() here, because the string is on the stack */
1760         SetDlgItemText32A( hDlg, idStatic, temp );
1761     }
1762
1763     if (orig_spec && (spec != orig_spec))
1764     {
1765         /* Update the original file spec */
1766         char *p = spec;
1767         while ((*orig_spec++ = *p++));
1768     }
1769
1770     return TRUE;
1771 #undef SENDMSG
1772 }
1773
1774
1775 /**********************************************************************
1776  *          DIALOG_DlgDirListW
1777  *
1778  * Helper function for DlgDirList*32W
1779  */
1780 static INT32 DIALOG_DlgDirListW( HWND32 hDlg, LPWSTR spec, INT32 idLBox,
1781                                  INT32 idStatic, UINT32 attrib, BOOL32 combo )
1782 {
1783     if (spec)
1784     {
1785         LPSTR specA = HEAP_strdupWtoA( GetProcessHeap(), 0, spec );
1786         INT32 ret = DIALOG_DlgDirList( hDlg, specA, idLBox, idStatic,
1787                                        attrib, combo );
1788         lstrcpyAtoW( spec, specA );
1789         HeapFree( GetProcessHeap(), 0, specA );
1790         return ret;
1791     }
1792     return DIALOG_DlgDirList( hDlg, NULL, idLBox, idStatic, attrib, combo );
1793 }
1794
1795
1796 /**********************************************************************
1797  *          DlgDirSelect    (USER.99)
1798  */
1799 BOOL16 WINAPI DlgDirSelect( HWND16 hwnd, LPSTR str, INT16 id )
1800 {
1801     return DlgDirSelectEx16( hwnd, str, 128, id );
1802 }
1803
1804
1805 /**********************************************************************
1806  *          DlgDirSelectComboBox    (USER.194)
1807  */
1808 BOOL16 WINAPI DlgDirSelectComboBox( HWND16 hwnd, LPSTR str, INT16 id )
1809 {
1810     return DlgDirSelectComboBoxEx16( hwnd, str, 128, id );
1811 }
1812
1813
1814 /**********************************************************************
1815  *           DlgDirSelectEx16    (USER.422)
1816  */
1817 BOOL16 WINAPI DlgDirSelectEx16( HWND16 hwnd, LPSTR str, INT16 len, INT16 id )
1818 {
1819     return DIALOG_DlgDirSelect( hwnd, str, len, id, FALSE, FALSE, FALSE );
1820 }
1821
1822
1823 /**********************************************************************
1824  *           DlgDirSelectEx32A    (USER32.149)
1825  */
1826 BOOL32 WINAPI DlgDirSelectEx32A( HWND32 hwnd, LPSTR str, INT32 len, INT32 id )
1827 {
1828     return DIALOG_DlgDirSelect( hwnd, str, len, id, TRUE, FALSE, FALSE );
1829 }
1830
1831
1832 /**********************************************************************
1833  *           DlgDirSelectEx32W    (USER32.150)
1834  */
1835 BOOL32 WINAPI DlgDirSelectEx32W( HWND32 hwnd, LPWSTR str, INT32 len, INT32 id )
1836 {
1837     return DIALOG_DlgDirSelect( hwnd, (LPSTR)str, len, id, TRUE, TRUE, FALSE );
1838 }
1839
1840
1841 /**********************************************************************
1842  *           DlgDirSelectComboBoxEx16    (USER.423)
1843  */
1844 BOOL16 WINAPI DlgDirSelectComboBoxEx16( HWND16 hwnd, LPSTR str, INT16 len,
1845                                         INT16 id )
1846 {
1847     return DIALOG_DlgDirSelect( hwnd, str, len, id, FALSE, FALSE, TRUE );
1848 }
1849
1850
1851 /**********************************************************************
1852  *           DlgDirSelectComboBoxEx32A    (USER32.147)
1853  */
1854 BOOL32 WINAPI DlgDirSelectComboBoxEx32A( HWND32 hwnd, LPSTR str, INT32 len,
1855                                          INT32 id )
1856 {
1857     return DIALOG_DlgDirSelect( hwnd, str, len, id, TRUE, FALSE, TRUE );
1858 }
1859
1860
1861 /**********************************************************************
1862  *           DlgDirSelectComboBoxEx32W    (USER32.148)
1863  */
1864 BOOL32 WINAPI DlgDirSelectComboBoxEx32W( HWND32 hwnd, LPWSTR str, INT32 len,
1865                                          INT32 id)
1866 {
1867     return DIALOG_DlgDirSelect( hwnd, (LPSTR)str, len, id, TRUE, TRUE, TRUE );
1868 }
1869
1870
1871 /**********************************************************************
1872  *          DlgDirList16    (USER.100)
1873  */
1874 INT16 WINAPI DlgDirList16( HWND16 hDlg, LPSTR spec, INT16 idLBox,
1875                            INT16 idStatic, UINT16 attrib )
1876 {
1877     return DIALOG_DlgDirList( hDlg, spec, idLBox, idStatic, attrib, FALSE );
1878 }
1879
1880
1881 /**********************************************************************
1882  *          DlgDirList32A    (USER32.143)
1883  */
1884 INT32 WINAPI DlgDirList32A( HWND32 hDlg, LPSTR spec, INT32 idLBox,
1885                             INT32 idStatic, UINT32 attrib )
1886 {
1887     return DIALOG_DlgDirList( hDlg, spec, idLBox, idStatic, attrib, FALSE );
1888 }
1889
1890
1891 /**********************************************************************
1892  *          DlgDirList32W    (USER32.146)
1893  */
1894 INT32 WINAPI DlgDirList32W( HWND32 hDlg, LPWSTR spec, INT32 idLBox,
1895                             INT32 idStatic, UINT32 attrib )
1896 {
1897     return DIALOG_DlgDirListW( hDlg, spec, idLBox, idStatic, attrib, FALSE );
1898 }
1899
1900
1901 /**********************************************************************
1902  *          DlgDirListComboBox16    (USER.195)
1903  */
1904 INT16 WINAPI DlgDirListComboBox16( HWND16 hDlg, LPSTR spec, INT16 idCBox,
1905                                    INT16 idStatic, UINT16 attrib )
1906 {
1907     return DIALOG_DlgDirList( hDlg, spec, idCBox, idStatic, attrib, TRUE );
1908 }
1909
1910
1911 /**********************************************************************
1912  *          DlgDirListComboBox32A    (USER32.144)
1913  */
1914 INT32 WINAPI DlgDirListComboBox32A( HWND32 hDlg, LPSTR spec, INT32 idCBox,
1915                                     INT32 idStatic, UINT32 attrib )
1916 {
1917     return DIALOG_DlgDirList( hDlg, spec, idCBox, idStatic, attrib, TRUE );
1918 }
1919
1920
1921 /**********************************************************************
1922  *          DlgDirListComboBox32W    (USER32.145)
1923  */
1924 INT32 WINAPI DlgDirListComboBox32W( HWND32 hDlg, LPWSTR spec, INT32 idCBox,
1925                                     INT32 idStatic, UINT32 attrib )
1926 {
1927     return DIALOG_DlgDirListW( hDlg, spec, idCBox, idStatic, attrib, TRUE );
1928 }