Not everyone has <unistd.h>, some files need <io.h> too (msvc).
[wine] / programs / progman / dialog.c
1 /*
2  * Program Manager
3  *
4  * Copyright 1996 Ulrich Schmid
5  * Copyright 2002 Sylvain Petreolle
6  * Copyright 2002 Andriy Palamarchuk
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include "windows.h"
24 #include "commdlg.h"
25 #include "progman.h"
26 static BOOL    DIALOG_BrowsePrograms(HWND, LPSTR, INT);
27 static BOOL    DIALOG_BrowseSymbols(HWND, LPSTR, INT);
28 static BOOL CALLBACK DIALOG_NEW_DlgProc(HWND, UINT, WPARAM, LPARAM);
29 static BOOL CALLBACK DIALOG_COPY_MOVE_DlgProc(HWND, UINT, WPARAM, LPARAM);
30 static BOOL CALLBACK DIALOG_GROUP_DlgProc(HWND, UINT, WPARAM, LPARAM);
31 static BOOL CALLBACK DIALOG_PROGRAM_DlgProc(HWND, UINT, WPARAM, LPARAM);
32 static BOOL CALLBACK DIALOG_SYMBOL_DlgProc(HWND, UINT, WPARAM, LPARAM);
33 static BOOL CALLBACK DIALOG_EXECUTE_DlgProc(HWND, UINT, WPARAM, LPARAM);
34
35 /***********************************************************************
36  *
37  *           DIALOG_New
38  */
39
40 static struct
41 {
42   INT nDefault;
43 } New;
44
45 INT DIALOG_New(INT nDefault)
46 {
47   DLGPROC lpfnDlg = MakeProcInstance(DIALOG_NEW_DlgProc, Globals.hInstance);
48   INT ret;
49
50   New.nDefault = nDefault;
51
52   ret = DialogBox(Globals.hInstance,  STRING_NEW,
53                   Globals.hMainWnd, lpfnDlg);
54   FreeProcInstance(lpfnDlg);
55   return ret;
56 }
57
58 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
59  *
60  *           DIALOG_NEW_DlgProc
61  */
62
63 static BOOL CALLBACK DIALOG_NEW_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
64 {
65   switch (msg)
66     {
67     case WM_INITDIALOG:
68       CheckRadioButton(hDlg, PM_NEW_GROUP, PM_NEW_PROGRAM, New.nDefault);
69       break;
70
71     case WM_COMMAND:
72       switch (wParam)
73         {
74         case PM_NEW_GROUP:
75         case PM_NEW_PROGRAM:
76           CheckRadioButton(hDlg, PM_NEW_GROUP, PM_NEW_PROGRAM, wParam);
77           return TRUE;
78
79         case IDOK:
80           EndDialog(hDlg, IsDlgButtonChecked(hDlg, PM_NEW_GROUP) ?
81                     PM_NEW_GROUP : PM_NEW_PROGRAM);
82           return TRUE;
83
84         case IDCANCEL:
85           EndDialog(hDlg, IDCANCEL);
86           return TRUE;
87         }
88     }
89   return FALSE;
90 }
91
92 /***********************************************************************
93  *
94  *           DIALOG_CopyMove
95  */
96
97 static struct
98 {
99   LPCSTR lpszProgramName, lpszFromGroupName;
100   HLOCAL hToGroup;
101 } CopyMove;
102
103 HLOCAL DIALOG_CopyMove(LPCSTR lpszProgramName, LPCSTR lpszFromGroupName,
104                      BOOL bMove)
105 {
106   DLGPROC lpfnDlg = MakeProcInstance(DIALOG_COPY_MOVE_DlgProc, Globals.hInstance);
107   INT ret;
108
109   CopyMove.lpszProgramName   = lpszProgramName;
110   CopyMove.lpszFromGroupName = lpszFromGroupName;
111   CopyMove.hToGroup          = 0;
112
113   ret = DialogBox(Globals.hInstance,
114                   bMove ? STRING_MOVE : STRING_COPY,
115                   Globals.hMainWnd, lpfnDlg);
116   FreeProcInstance(lpfnDlg);
117
118   return((ret == IDOK) ? CopyMove.hToGroup : 0);
119 }
120
121 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
122  *
123  *           DIALOG_COPY_MOVE_DlgProc
124  */
125
126 static BOOL CALLBACK DIALOG_COPY_MOVE_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
127 {
128   HLOCAL hGroup;
129
130   switch (msg)
131     {
132     case WM_INITDIALOG:
133       /* List all group names */
134       for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
135         SendDlgItemMessage(hDlg, PM_TO_GROUP, CB_ADDSTRING, 0,
136                            (LPARAM) GROUP_GroupName(hGroup));
137
138       SetDlgItemText(hDlg, PM_PROGRAM,    (LPSTR)CopyMove.lpszProgramName);
139       SetDlgItemText(hDlg, PM_FROM_GROUP, (LPSTR)CopyMove.lpszFromGroupName);
140       break;
141
142     case WM_COMMAND:
143       switch (wParam)
144         {
145         case IDOK:
146         {
147           /* Get selected group */
148           INT nCurSel    = SendDlgItemMessage(hDlg, PM_TO_GROUP, CB_GETCURSEL, 0, 0);
149           INT nLen       = SendDlgItemMessage(hDlg, PM_TO_GROUP, CB_GETLBTEXTLEN, nCurSel, 0);
150           HLOCAL hBuffer = LocalAlloc(LMEM_FIXED, nLen + 1);
151           LPSTR   buffer = LocalLock(hBuffer);
152
153           SendDlgItemMessage(hDlg, PM_TO_GROUP, CB_GETLBTEXT, nCurSel, (LPARAM)buffer);
154           for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
155             if (!lstrcmp(buffer, GROUP_GroupName(hGroup))) break;
156           LocalFree(hBuffer);
157
158           CopyMove.hToGroup = hGroup;
159           EndDialog(hDlg, IDOK);
160           return TRUE;
161         }
162
163         case IDCANCEL:
164           EndDialog(hDlg, IDCANCEL);
165           return TRUE;
166         }
167     }
168   return FALSE;
169 }
170
171 /***********************************************************************
172  *
173  *           DIALOG_Delete
174  */
175
176 BOOL DIALOG_Delete(UINT ids_text_s, LPCSTR lpszName)
177 {
178   return (IDYES == MAIN_MessageBoxIDS_s(ids_text_s, lpszName, IDS_DELETE,
179                                         MB_YESNO | MB_DEFBUTTON2));
180 }
181
182
183 /***********************************************************************
184  *
185  *           DIALOG_GroupAttributes
186  */
187
188 static struct
189 {
190   LPSTR lpszTitle, lpszGrpFile;
191   INT   nSize;
192 } GroupAttributes;
193
194 BOOL DIALOG_GroupAttributes(LPSTR lpszTitle, LPSTR lpszGrpFile, INT nSize)
195 {
196   DLGPROC lpfnDlg = MakeProcInstance(DIALOG_GROUP_DlgProc, Globals.hInstance);
197   INT ret;
198
199   GroupAttributes.nSize       = nSize;
200   GroupAttributes.lpszTitle   = lpszTitle;
201   GroupAttributes.lpszGrpFile = lpszGrpFile;
202
203   ret = DialogBox(Globals.hInstance,  STRING_GROUP,
204                   Globals.hMainWnd, lpfnDlg);
205   FreeProcInstance(lpfnDlg);
206   return(ret == IDOK);
207 }
208
209 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
210  *
211  *           DIALOG_GROUP_DlgProc
212  */
213
214 static BOOL CALLBACK DIALOG_GROUP_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
215 {
216   switch (msg)
217     {
218     case WM_INITDIALOG:
219       SetDlgItemText(hDlg, PM_DESCRIPTION, GroupAttributes.lpszTitle);
220       SetDlgItemText(hDlg, PM_FILE, GroupAttributes.lpszGrpFile);
221       break;
222
223     case WM_COMMAND:
224       switch (wParam)
225         {
226         case IDOK:
227           GetDlgItemText(hDlg, PM_DESCRIPTION, GroupAttributes.lpszTitle,
228                          GroupAttributes.nSize);
229           GetDlgItemText(hDlg, PM_FILE, GroupAttributes.lpszGrpFile,
230                          GroupAttributes.nSize);
231           EndDialog(hDlg, IDOK);
232           return TRUE;
233
234         case IDCANCEL:
235           EndDialog(hDlg, IDCANCEL);
236           return TRUE;
237         }
238     }
239   return FALSE;
240 }
241
242 /***********************************************************************
243  *
244  *           DIALOG_ProgramAttributes
245  */
246
247 static struct
248 {
249   LPSTR lpszTitle, lpszCmdLine, lpszWorkDir, lpszIconFile, lpszTmpIconFile;
250   INT   nSize;
251   INT   *lpnCmdShow;
252   INT   *lpnHotKey;
253   HWND  hSelGroupWnd;
254   HICON *lphIcon, hTmpIcon;
255   INT   *lpnIconIndex, nTmpIconIndex;
256 } ProgramAttributes;
257
258 BOOL DIALOG_ProgramAttributes(LPSTR lpszTitle, LPSTR lpszCmdLine,
259                               LPSTR lpszWorkDir, LPSTR lpszIconFile,
260                               HICON *lphIcon, INT *lpnIconIndex,
261                               INT *lpnHotKey, INT *lpnCmdShow, INT nSize)
262 {
263   CHAR szTmpIconFile[MAX_PATHNAME_LEN];
264   DLGPROC lpfnDlg = MakeProcInstance(DIALOG_PROGRAM_DlgProc, Globals.hInstance);
265   INT ret;
266
267   ProgramAttributes.nSize = nSize;
268   ProgramAttributes.lpszTitle = lpszTitle;
269   ProgramAttributes.lpszCmdLine = lpszCmdLine;
270   ProgramAttributes.lpszWorkDir = lpszWorkDir;
271   ProgramAttributes.lpszIconFile = lpszIconFile;
272   ProgramAttributes.lpnCmdShow = lpnCmdShow;
273   ProgramAttributes.lpnHotKey = lpnHotKey;
274   ProgramAttributes.lphIcon = lphIcon;
275   ProgramAttributes.lpnIconIndex = lpnIconIndex;
276
277 #if 0
278   ProgramAttributes.hTmpIcon = 0;
279 #else
280   ProgramAttributes.hTmpIcon = *lphIcon;
281 #endif
282   ProgramAttributes.nTmpIconIndex = *lpnIconIndex;
283   ProgramAttributes.lpszTmpIconFile = szTmpIconFile;
284   lstrcpyn(ProgramAttributes.lpszTmpIconFile, lpszIconFile, MAX_PATHNAME_LEN);
285
286   ret = DialogBox(Globals.hInstance,  STRING_PROGRAM,
287                   Globals.hMainWnd, lpfnDlg);
288   FreeProcInstance(lpfnDlg);
289
290   return(ret == IDOK);
291 }
292
293 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
294  *
295  *           DIALOG_PROGRAM_DlgProc
296  */
297
298 static BOOL CALLBACK DIALOG_PROGRAM_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
299 {
300   CHAR buffer[MAX_STRING_LEN];
301   switch (msg)
302     {
303     case WM_INITDIALOG:
304       SetDlgItemText(hDlg, PM_DESCRIPTION, ProgramAttributes.lpszTitle);
305       SetDlgItemText(hDlg, PM_COMMAND_LINE, ProgramAttributes.lpszCmdLine);
306       SetDlgItemText(hDlg, PM_DIRECTORY, ProgramAttributes.lpszWorkDir);
307       if (!*ProgramAttributes.lpnHotKey)
308         {
309           LoadString(Globals.hInstance, IDS_NO_HOT_KEY, buffer, sizeof(buffer));
310           SetDlgItemText(hDlg, PM_HOT_KEY, buffer);
311         }
312
313       CheckDlgButton(hDlg, PM_SYMBOL,
314                      (*ProgramAttributes.lpnCmdShow == SW_SHOWMINIMIZED));
315       SendDlgItemMessage(hDlg, PM_ICON, STM_SETICON,
316                          (WPARAM) ProgramAttributes.hTmpIcon, 0);
317       break;
318
319     case WM_COMMAND:
320       switch (wParam)
321         {
322         case PM_SYMBOL:
323           CheckDlgButton(hDlg, PM_SYMBOL, !IsDlgButtonChecked(hDlg, PM_SYMBOL));
324           return TRUE;
325
326         case PM_BROWSE:
327           {
328             CHAR filename[MAX_PATHNAME_LEN];
329             if (DIALOG_BrowsePrograms(hDlg, filename, sizeof(filename)))
330               SetDlgItemText(hDlg, PM_COMMAND_LINE, filename);
331             return TRUE;
332           }
333
334         case PM_OTHER_SYMBOL:
335           {
336             DIALOG_Symbol(&ProgramAttributes.hTmpIcon,
337                           ProgramAttributes.lpszTmpIconFile,
338                           &ProgramAttributes.nTmpIconIndex,
339                           MAX_PATHNAME_LEN);
340
341             SendDlgItemMessage(hDlg, PM_ICON, STM_SETICON,
342                                (WPARAM) ProgramAttributes.hTmpIcon, 0);
343             return TRUE;
344           }
345
346         case IDOK:
347           GetDlgItemText(hDlg, PM_DESCRIPTION,
348                          ProgramAttributes.lpszTitle,
349                          ProgramAttributes.nSize);
350           GetDlgItemText(hDlg, PM_COMMAND_LINE,
351                          ProgramAttributes.lpszCmdLine,
352                          ProgramAttributes.nSize);
353           GetDlgItemText(hDlg, PM_DIRECTORY,
354                          ProgramAttributes.lpszWorkDir,
355                          ProgramAttributes.nSize);
356
357           if (ProgramAttributes.hTmpIcon)
358             {
359 #if 0
360               if (*ProgramAttributes.lphIcon)
361                 DestroyIcon(*ProgramAttributes.lphIcon);
362 #endif
363               *ProgramAttributes.lphIcon = ProgramAttributes.hTmpIcon;
364               *ProgramAttributes.lpnIconIndex = ProgramAttributes.nTmpIconIndex;
365               lstrcpyn(ProgramAttributes.lpszIconFile,
366                        ProgramAttributes.lpszTmpIconFile,
367                        ProgramAttributes.nSize);
368             }
369
370           *ProgramAttributes.lpnCmdShow =
371             IsDlgButtonChecked(hDlg, PM_SYMBOL) ?
372             SW_SHOWMINIMIZED : SW_SHOWNORMAL;
373           EndDialog(hDlg, IDOK);
374           return TRUE;
375
376         case IDCANCEL:
377           EndDialog(hDlg, IDCANCEL);
378           return TRUE;
379         }
380       return FALSE;
381     }
382   return FALSE;
383 }
384
385 /***********************************************************************
386  *
387  *           DIALOG_Symbol
388  */
389
390 static struct
391 {
392   LPSTR  lpszIconFile;
393   INT    nSize;
394   HICON  *lphIcon;
395   INT    *lpnIconIndex;
396 } Symbol;
397
398 VOID DIALOG_Symbol(HICON *lphIcon, LPSTR lpszIconFile,
399                    INT *lpnIconIndex, INT nSize)
400 {
401   DLGPROC lpfnDlg = MakeProcInstance(DIALOG_SYMBOL_DlgProc, Globals.hInstance);
402
403   Symbol.nSize = nSize;
404   Symbol.lpszIconFile = lpszIconFile;
405   Symbol.lphIcon = lphIcon;
406   Symbol.lpnIconIndex = lpnIconIndex;
407
408   DialogBox(Globals.hInstance, STRING_SYMBOL,
409             Globals.hMainWnd, lpfnDlg);
410   FreeProcInstance(lpfnDlg);
411 }
412
413 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
414  *
415  *           DIALOG_SYMBOL_DlgProc
416  */
417
418 static BOOL CALLBACK DIALOG_SYMBOL_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
419 {
420   switch (msg)
421     {
422     case WM_INITDIALOG:
423       SetDlgItemText(hDlg, PM_ICON_FILE, Symbol.lpszIconFile);
424       SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_SETITEMHEIGHT, 0, (LPARAM) 32);
425       SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_ADDSTRING, 0, (LPARAM)*Symbol.lphIcon);
426       SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_ADDSTRING, 0, (LPARAM)Globals.hDefaultIcon);
427       SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_SETCURSEL, 0, 0);
428       return TRUE;
429
430     case WM_MEASUREITEM:
431       {
432         PMEASUREITEMSTRUCT measure = (PMEASUREITEMSTRUCT) lParam;
433         measure->itemWidth = 32;
434         measure->itemHeight = 32;
435         return TRUE;
436       }
437
438     case WM_DRAWITEM:
439       {
440         PDRAWITEMSTRUCT dis = (PDRAWITEMSTRUCT) lParam;
441         DrawIcon(dis->hDC, dis->rcItem.left, dis->rcItem.top, (HICON)dis->itemData);
442         return TRUE;
443       }
444
445     case WM_COMMAND:
446       switch (wParam)
447         {
448         case PM_BROWSE:
449           {
450             CHAR filename[MAX_PATHNAME_LEN];
451             if (DIALOG_BrowseSymbols(hDlg, filename, sizeof(filename)))
452               SetDlgItemText(hDlg, PM_ICON_FILE, filename);
453             return TRUE;
454           }
455
456         case PM_HELP:
457           MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK);
458           return TRUE;
459
460         case IDOK:
461           {
462             INT nCurSel = SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_GETCURSEL, 0, 0);
463
464             GetDlgItemText(hDlg, PM_ICON_FILE, Symbol.lpszIconFile, Symbol.nSize);
465
466             *Symbol.lphIcon = (HICON)SendDlgItemMessage(hDlg, PM_SYMBOL_LIST,
467                                                         CB_GETITEMDATA,
468                                                         (WPARAM) nCurSel, 0);
469 #if 0
470             *Symbol.lphIcon = CopyIcon(*Symbol.lphIcon);
471 #endif
472
473             EndDialog(hDlg, IDOK);
474             return TRUE;
475           }
476
477         case IDCANCEL:
478           EndDialog(hDlg, IDCANCEL);
479           return TRUE;
480         }
481     }
482   return FALSE;
483 }
484
485 /***********************************************************************
486  *
487  *           DIALOG_Execute
488  */
489
490 VOID DIALOG_Execute()
491 {
492 INT_PTR z;
493         DLGPROC lpfnDlg = MakeProcInstance(DIALOG_EXECUTE_DlgProc, Globals.hInstance);
494         z=DialogBox(Globals.hInstance, STRING_EXECUTE,
495             Globals.hMainWnd, lpfnDlg);
496             FreeProcInstance(lpfnDlg);
497 }
498
499 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
500  *
501  *           DIALOG_EXECUTE_DlgProc
502  */
503
504 static BOOL CALLBACK DIALOG_EXECUTE_DlgProc(HWND hDlg, UINT msg,
505                                       WPARAM wParam, LPARAM lParam)
506 {
507   switch (msg)
508     {
509     case WM_COMMAND:
510       switch (wParam)
511         {
512         case PM_SYMBOL:
513           CheckDlgButton(hDlg, PM_SYMBOL, !IsDlgButtonChecked(hDlg, PM_SYMBOL));
514           return TRUE;
515
516         case PM_BROWSE:
517           {
518             CHAR filename[MAX_PATHNAME_LEN];
519             if (DIALOG_BrowsePrograms(hDlg, filename, sizeof(filename)))
520               SetDlgItemText(hDlg, PM_COMMAND, filename);
521             return TRUE;
522           }
523
524         case PM_HELP:
525           MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK);
526           return TRUE;
527
528         case IDOK:
529           {
530             CHAR cmdline[MAX_PATHNAME_LEN];
531             GetDlgItemText(hDlg, PM_COMMAND, cmdline, sizeof(cmdline));
532
533             WinExec(cmdline, IsDlgButtonChecked(hDlg, PM_SYMBOL) ?
534                     SW_SHOWMINIMIZED : SW_SHOWNORMAL);
535             if (Globals.bMinOnRun) CloseWindow(Globals.hMainWnd);
536
537             EndDialog(hDlg, IDOK);
538             return TRUE;
539           }
540
541         case IDCANCEL:
542           EndDialog(hDlg, IDCANCEL);
543           return TRUE;
544         }
545     }
546   return FALSE;
547 }
548
549 /***********************************************************************
550  *
551  *           DIALOG_Browse
552  */
553
554 static BOOL DIALOG_Browse(HWND hDlg, LPCSTR lpszzFilter,
555                           LPSTR lpstrFile, INT nMaxFile)
556
557 {
558     OPENFILENAME openfilename;
559
560     CHAR szPath[MAX_PATH];
561     CHAR szDir[MAX_PATH];
562     CHAR szDefaultExt[] = "exe";
563
564     ZeroMemory(&openfilename, sizeof(openfilename));
565
566     GetCurrentDirectory(sizeof(szDir), szDir);
567     lstrcpy(szPath,"*.exe");
568
569     /* FIXME is this correct ? */
570     openfilename.lStructSize       = sizeof(openfilename);
571     openfilename.hwndOwner         = Globals.hMainWnd;
572     openfilename.hInstance         = Globals.hInstance;
573     openfilename.lpstrFile         = szPath;
574     openfilename.nMaxFile          = sizeof(szPath);
575     openfilename.lpstrInitialDir   = szDir;
576     openfilename.Flags             = 0;
577     openfilename.lpstrDefExt       = szDefaultExt;
578     openfilename.lpstrCustomFilter = 0;
579     openfilename.nMaxCustFilter    = 0;
580     openfilename.nFilterIndex      = 0;
581     openfilename.lpstrFileTitle    = 0;
582     openfilename.nMaxFileTitle     = 0;
583     openfilename.lpstrInitialDir   = 0;
584     openfilename.lpstrTitle        = 0;
585     openfilename.nFileOffset       = 0;
586     openfilename.nFileExtension    = 0;
587     openfilename.lCustData         = 0;
588     openfilename.lpfnHook          = 0;
589     openfilename.lpTemplateName    = 0;
590
591     return GetOpenFileName(&openfilename);
592     /* FIXME */
593 }
594
595 /***********************************************************************
596  *
597  *           DIALOG_AddFilterItem
598  */
599
600 static VOID DIALOG_AddFilterItem(LPSTR *p, UINT ids, LPCSTR filter)
601 {
602   LoadString(Globals.hInstance, ids, *p, MAX_STRING_LEN);
603   *p += strlen(*p) + 1;
604   lstrcpy(*p, filter);
605   *p += strlen(*p) + 1;
606   **p = '\0';
607 }
608
609 /***********************************************************************
610  *
611  *           DIALOG_BrowsePrograms
612  */
613
614 static BOOL DIALOG_BrowsePrograms(HWND hDlg, LPSTR lpszFile, INT nMaxFile)
615 {
616   CHAR  szzFilter[2 * MAX_STRING_LEN + 100];
617   LPSTR p = szzFilter;
618
619   DIALOG_AddFilterItem(&p, IDS_PROGRAMS,  "*.exe;*.pif;*.com;*.bat");
620   DIALOG_AddFilterItem(&p, IDS_ALL_FILES, "*.*");
621
622   return(DIALOG_Browse(hDlg, szzFilter, lpszFile, nMaxFile));
623 }
624
625 /***********************************************************************
626  *
627  *           DIALOG_BrowseSymbols
628  */
629
630 static BOOL DIALOG_BrowseSymbols(HWND hDlg, LPSTR lpszFile, INT nMaxFile)
631 {
632   CHAR  szzFilter[5 * MAX_STRING_LEN + 100];
633   LPSTR p = szzFilter;
634
635   DIALOG_AddFilterItem(&p, IDS_SYMBOL_FILES,  "*.ico;*.exe;*.dll");
636   DIALOG_AddFilterItem(&p, IDS_PROGRAMS,      "*.exe");
637   DIALOG_AddFilterItem(&p, IDS_LIBRARIES_DLL, "*.dll");
638   DIALOG_AddFilterItem(&p, IDS_SYMBOLS_ICO,   "*.ico");
639   DIALOG_AddFilterItem(&p, IDS_ALL_FILES,     "*.*");
640
641   return(DIALOG_Browse(hDlg, szzFilter, lpszFile, nMaxFile));
642 }
643
644 /* Local Variables:    */
645 /* c-file-style: "GNU" */
646 /* End:                */