14c1fb7c29d1bc1713fe6e96b24609387aac74a2
[reactos.git] / reactos / base / shell / 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23 #include "progman.h"
24
25 /***********************************************************************
26 *
27 * DIALOG_Browse
28 */
29
30 static BOOL DIALOG_Browse(HWND hDlg, LPCSTR lpszzFilter,
31 LPSTR lpstrFile, INT nMaxFile)
32
33 {
34 OPENFILENAMEA openfilename;
35
36 CHAR szDir[MAX_PATH];
37 CHAR szDefaultExt[] = "exe";
38
39 ZeroMemory(&openfilename, sizeof(openfilename));
40
41 GetCurrentDirectoryA(sizeof(szDir), szDir);
42
43 openfilename.lStructSize = sizeof(openfilename);
44 openfilename.hwndOwner = Globals.hMainWnd;
45 openfilename.hInstance = Globals.hInstance;
46 openfilename.lpstrFilter = lpszzFilter;
47 openfilename.lpstrFile = lpstrFile;
48 openfilename.nMaxFile = nMaxFile;
49 openfilename.lpstrInitialDir = szDir;
50 openfilename.Flags = 0;
51 openfilename.lpstrDefExt = szDefaultExt;
52 openfilename.lpstrCustomFilter = 0;
53 openfilename.nMaxCustFilter = 0;
54 openfilename.nFilterIndex = 0;
55 openfilename.lpstrFileTitle = 0;
56 openfilename.nMaxFileTitle = 0;
57 openfilename.lpstrInitialDir = 0;
58 openfilename.lpstrTitle = 0;
59 openfilename.nFileOffset = 0;
60 openfilename.nFileExtension = 0;
61 openfilename.lCustData = 0;
62 openfilename.lpfnHook = 0;
63 openfilename.lpTemplateName = 0;
64
65 return GetOpenFileNameA(&openfilename);
66 }
67
68 /***********************************************************************
69 *
70 * DIALOG_AddFilterItem
71 */
72
73 static VOID DIALOG_AddFilterItem(LPSTR *p, UINT ids, LPCSTR filter)
74 {
75 LoadStringA(Globals.hInstance, ids, *p, MAX_STRING_LEN);
76 *p += strlen(*p) + 1;
77 lstrcpyA(*p, filter);
78 *p += strlen(*p) + 1;
79 **p = '\0';
80 }
81
82 /***********************************************************************
83 *
84 * DIALOG_BrowsePrograms
85 */
86
87 static BOOL DIALOG_BrowsePrograms(HWND hDlg, LPSTR lpszFile, INT nMaxFile)
88 {
89 CHAR szzFilter[2 * MAX_STRING_LEN + 100];
90 LPSTR p = szzFilter;
91
92 DIALOG_AddFilterItem(&p, IDS_PROGRAMS, "*.exe;*.pif;*.com;*.bat");
93 DIALOG_AddFilterItem(&p, IDS_ALL_FILES, "*.*");
94
95 return(DIALOG_Browse(hDlg, szzFilter, lpszFile, nMaxFile));
96 }
97
98 /***********************************************************************
99 *
100 * DIALOG_BrowseSymbols
101 */
102
103 static BOOL DIALOG_BrowseSymbols(HWND hDlg, LPSTR lpszFile, INT nMaxFile)
104 {
105 CHAR szzFilter[5 * MAX_STRING_LEN + 100];
106 LPSTR p = szzFilter;
107
108 DIALOG_AddFilterItem(&p, IDS_SYMBOL_FILES, "*.ico;*.exe;*.dll");
109 DIALOG_AddFilterItem(&p, IDS_PROGRAMS, "*.exe");
110 DIALOG_AddFilterItem(&p, IDS_LIBRARIES_DLL, "*.dll");
111 DIALOG_AddFilterItem(&p, IDS_SYMBOLS_ICO, "*.ico");
112 DIALOG_AddFilterItem(&p, IDS_ALL_FILES, "*.*");
113
114 return(DIALOG_Browse(hDlg, szzFilter, lpszFile, nMaxFile));
115 }
116
117 static struct
118 {
119 INT nDefault;
120 } New;
121
122 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
123 *
124 * DIALOG_NEW_DlgProc
125 */
126 static INT_PTR CALLBACK DIALOG_NEW_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
127 {
128 switch (msg)
129 {
130 case WM_INITDIALOG:
131 CheckRadioButton(hDlg, PM_NEW_GROUP, PM_NEW_PROGRAM, New.nDefault);
132 break;
133
134 case WM_COMMAND:
135 switch (wParam)
136 {
137 case PM_NEW_GROUP:
138 case PM_NEW_PROGRAM:
139 CheckRadioButton(hDlg, PM_NEW_GROUP, PM_NEW_PROGRAM, wParam);
140 return TRUE;
141
142 case IDOK:
143 EndDialog(hDlg, IsDlgButtonChecked(hDlg, PM_NEW_GROUP) ?
144 PM_NEW_GROUP : PM_NEW_PROGRAM);
145 return TRUE;
146
147 case IDCANCEL:
148 EndDialog(hDlg, IDCANCEL);
149 return TRUE;
150 }
151 }
152 return FALSE;
153 }
154
155 /***********************************************************************
156 *
157 * DIALOG_New
158 */
159 INT DIALOG_New(INT nDefault)
160 {
161 New.nDefault = nDefault;
162 return DialogBoxW(Globals.hInstance, MAKEINTRESOURCEW(IDD_NEW), Globals.hMainWnd, DIALOG_NEW_DlgProc);
163 }
164
165
166 static struct
167 {
168 LPCSTR lpszProgramName, lpszFromGroupName;
169 HLOCAL hToGroup;
170 } CopyMove;
171
172 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
173 *
174 * DIALOG_COPY_MOVE_DlgProc
175 */
176 static INT_PTR CALLBACK DIALOG_COPY_MOVE_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
177 {
178 HLOCAL hGroup;
179
180 switch (msg)
181 {
182 case WM_INITDIALOG:
183 /* List all group names */
184 for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
185 SendDlgItemMessageA(hDlg, PM_TO_GROUP, CB_ADDSTRING, 0, (LPARAM)GROUP_GroupName(hGroup));
186
187 SetDlgItemTextA(hDlg, PM_PROGRAM, CopyMove.lpszProgramName);
188 SetDlgItemTextA(hDlg, PM_FROM_GROUP, CopyMove.lpszFromGroupName);
189 break;
190
191 case WM_COMMAND:
192 switch (wParam)
193 {
194 case IDOK:
195 {
196 /* Get selected group */
197 INT nCurSel = SendDlgItemMessageW(hDlg, PM_TO_GROUP, CB_GETCURSEL, 0, 0);
198 INT nLen = SendDlgItemMessageW(hDlg, PM_TO_GROUP, CB_GETLBTEXTLEN, nCurSel, 0);
199 HLOCAL hBuffer = LocalAlloc(LMEM_FIXED, nLen + 1);
200 LPSTR buffer = LocalLock(hBuffer);
201
202 SendDlgItemMessageA(hDlg, PM_TO_GROUP, CB_GETLBTEXT, nCurSel, (LPARAM)buffer);
203 for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
204 if (!lstrcmpA(buffer, GROUP_GroupName(hGroup))) break;
205 LocalFree(hBuffer);
206
207 CopyMove.hToGroup = hGroup;
208 EndDialog(hDlg, IDOK);
209 return TRUE;
210 }
211
212 case IDCANCEL:
213 EndDialog(hDlg, IDCANCEL);
214 return TRUE;
215 }
216 }
217 return FALSE;
218 }
219
220 /***********************************************************************
221 *
222 * DIALOG_CopyMove
223 */
224 HLOCAL DIALOG_CopyMove(LPCSTR lpszProgramName, LPCSTR lpszFromGroupName,
225 BOOL bMove)
226 {
227 INT ret;
228
229 CopyMove.lpszProgramName = lpszProgramName;
230 CopyMove.lpszFromGroupName = lpszFromGroupName;
231 CopyMove.hToGroup = 0;
232
233 ret = DialogBoxW(Globals.hInstance,
234 bMove ? MAKEINTRESOURCEW(IDD_MOVE) : MAKEINTRESOURCEW(IDD_COPY),
235 Globals.hMainWnd, DIALOG_COPY_MOVE_DlgProc);
236 return((ret == IDOK) ? CopyMove.hToGroup : 0);
237 }
238
239 /***********************************************************************
240 *
241 * DIALOG_Delete
242 */
243
244 BOOL DIALOG_Delete(UINT ids_text_s, LPCSTR lpszName)
245 {
246 return (IDYES == MAIN_MessageBoxIDS_s(ids_text_s, lpszName, IDS_DELETE,
247 MB_YESNO | MB_DEFBUTTON2));
248 }
249
250
251 static struct
252 {
253 LPSTR lpszTitle, lpszGrpFile;
254 INT nSize;
255 } GroupAttributes;
256
257 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
258 *
259 * DIALOG_GROUP_DlgProc
260 */
261 static INT_PTR CALLBACK DIALOG_GROUP_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
262 {
263 switch (msg)
264 {
265 case WM_INITDIALOG:
266 SetDlgItemTextA(hDlg, PM_DESCRIPTION, GroupAttributes.lpszTitle);
267 SetDlgItemTextA(hDlg, PM_FILE, GroupAttributes.lpszGrpFile);
268 break;
269
270 case WM_COMMAND:
271 switch (wParam)
272 {
273 case IDOK:
274 GetDlgItemTextA(hDlg, PM_DESCRIPTION, GroupAttributes.lpszTitle, GroupAttributes.nSize);
275 GetDlgItemTextA(hDlg, PM_FILE, GroupAttributes.lpszGrpFile, GroupAttributes.nSize);
276 EndDialog(hDlg, IDOK);
277 return TRUE;
278
279 case IDCANCEL:
280 EndDialog(hDlg, IDCANCEL);
281 return TRUE;
282 }
283 }
284 return FALSE;
285 }
286
287 /***********************************************************************
288 *
289 * DIALOG_GroupAttributes
290 */
291 BOOL DIALOG_GroupAttributes(LPSTR lpszTitle, LPSTR lpszGrpFile, INT nSize)
292 {
293 INT ret;
294
295 GroupAttributes.nSize = nSize;
296 GroupAttributes.lpszTitle = lpszTitle;
297 GroupAttributes.lpszGrpFile = lpszGrpFile;
298
299 ret = DialogBoxW(Globals.hInstance, MAKEINTRESOURCEW(IDD_GROUP), Globals.hMainWnd, DIALOG_GROUP_DlgProc);
300 return(ret == IDOK);
301 }
302
303
304 static struct
305 {
306 LPSTR lpszIconFile;
307 INT nSize;
308 HICON *lphIcon;
309 INT *lpnIconIndex;
310 } Symbol;
311
312 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
313 *
314 * DIALOG_SYMBOL_DlgProc
315 */
316 static INT_PTR CALLBACK DIALOG_SYMBOL_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
317 {
318 switch (msg)
319 {
320 case WM_INITDIALOG:
321 SetDlgItemTextA(hDlg, PM_ICON_FILE, Symbol.lpszIconFile);
322 SendDlgItemMessageA(hDlg, PM_SYMBOL_LIST, CB_SETITEMHEIGHT, 0, (LPARAM) 32);
323 SendDlgItemMessageA(hDlg, PM_SYMBOL_LIST, CB_ADDSTRING, 0, (LPARAM)*Symbol.lphIcon);
324 SendDlgItemMessageA(hDlg, PM_SYMBOL_LIST, CB_ADDSTRING, 0, (LPARAM)Globals.hDefaultIcon);
325 SendDlgItemMessageA(hDlg, PM_SYMBOL_LIST, CB_SETCURSEL, 0, 0);
326 return TRUE;
327
328 case WM_MEASUREITEM:
329 {
330 PMEASUREITEMSTRUCT measure = (PMEASUREITEMSTRUCT) lParam;
331 measure->itemWidth = 32;
332 measure->itemHeight = 32;
333 return TRUE;
334 }
335
336 case WM_DRAWITEM:
337 {
338 PDRAWITEMSTRUCT dis = (PDRAWITEMSTRUCT) lParam;
339 DrawIcon(dis->hDC, dis->rcItem.left, dis->rcItem.top, (HICON)dis->itemData);
340 return TRUE;
341 }
342
343 case WM_COMMAND:
344 switch (wParam)
345 {
346 case PM_BROWSE:
347 {
348 CHAR filename[MAX_PATHNAME_LEN];
349 filename[0] = 0;
350 if (DIALOG_BrowseSymbols(hDlg, filename, sizeof(filename)))
351 SetDlgItemTextA(hDlg, PM_ICON_FILE, filename);
352 return TRUE;
353 }
354
355 case PM_HELP:
356 MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK);
357 return TRUE;
358
359 case IDOK:
360 {
361 INT nCurSel = SendDlgItemMessageA(hDlg, PM_SYMBOL_LIST, CB_GETCURSEL, 0, 0);
362
363 GetDlgItemTextA(hDlg, PM_ICON_FILE, Symbol.lpszIconFile, Symbol.nSize);
364
365 *Symbol.lphIcon = (HICON)SendDlgItemMessageA(hDlg, PM_SYMBOL_LIST,
366 CB_GETITEMDATA,
367 (WPARAM) nCurSel, 0);
368 #if 0
369 *Symbol.lphIcon = CopyIcon(*Symbol.lphIcon);
370 #endif
371
372 EndDialog(hDlg, IDOK);
373 return TRUE;
374 }
375
376 case IDCANCEL:
377 EndDialog(hDlg, IDCANCEL);
378 return TRUE;
379 }
380 }
381 return FALSE;
382 }
383
384 /***********************************************************************
385 *
386 * DIALOG_Symbol
387 */
388 static VOID DIALOG_Symbol(HICON *lphIcon, LPSTR lpszIconFile,
389 INT *lpnIconIndex, INT nSize)
390 {
391 Symbol.nSize = nSize;
392 Symbol.lpszIconFile = lpszIconFile;
393 Symbol.lphIcon = lphIcon;
394 Symbol.lpnIconIndex = lpnIconIndex;
395
396 DialogBoxW(Globals.hInstance, MAKEINTRESOURCEW(IDD_SYMBOL), Globals.hMainWnd, DIALOG_SYMBOL_DlgProc);
397 }
398
399
400 static struct
401 {
402 LPSTR lpszTitle, lpszCmdLine, lpszWorkDir, lpszIconFile, lpszTmpIconFile;
403 INT nSize;
404 INT *lpnCmdShow;
405 INT *lpnHotKey;
406 HWND hSelGroupWnd;
407 HICON *lphIcon, hTmpIcon;
408 INT *lpnIconIndex, nTmpIconIndex;
409 } ProgramAttributes;
410
411 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
412 *
413 * DIALOG_PROGRAM_DlgProc
414 */
415 static INT_PTR CALLBACK DIALOG_PROGRAM_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
416 {
417 CHAR buffer[MAX_STRING_LEN];
418 switch (msg)
419 {
420 case WM_INITDIALOG:
421 SetDlgItemTextA(hDlg, PM_DESCRIPTION, ProgramAttributes.lpszTitle);
422 SetDlgItemTextA(hDlg, PM_COMMAND_LINE, ProgramAttributes.lpszCmdLine);
423 SetDlgItemTextA(hDlg, PM_DIRECTORY, ProgramAttributes.lpszWorkDir);
424 if (!*ProgramAttributes.lpnHotKey)
425 {
426 LoadStringA(Globals.hInstance, IDS_NO_HOT_KEY, buffer, sizeof(buffer));
427 SetDlgItemTextA(hDlg, PM_HOT_KEY, buffer);
428 }
429
430 CheckDlgButton(hDlg, PM_SYMBOL,
431 (*ProgramAttributes.lpnCmdShow == SW_SHOWMINIMIZED));
432 SendDlgItemMessageA(hDlg, PM_ICON, STM_SETICON, (WPARAM)ProgramAttributes.hTmpIcon, 0);
433 break;
434
435 case WM_COMMAND:
436 switch (wParam)
437 {
438 case PM_SYMBOL:
439 CheckDlgButton(hDlg, PM_SYMBOL, !IsDlgButtonChecked(hDlg, PM_SYMBOL));
440 return TRUE;
441
442 case PM_BROWSE:
443 {
444 CHAR filename[MAX_PATHNAME_LEN];
445 filename[0] = 0;
446 if (DIALOG_BrowsePrograms(hDlg, filename, sizeof(filename)))
447 SetDlgItemTextA(hDlg, PM_COMMAND_LINE, filename);
448 return TRUE;
449 }
450
451 case PM_OTHER_SYMBOL:
452 {
453 DIALOG_Symbol(&ProgramAttributes.hTmpIcon,
454 ProgramAttributes.lpszTmpIconFile,
455 &ProgramAttributes.nTmpIconIndex,
456 MAX_PATHNAME_LEN);
457
458 SendDlgItemMessageA(hDlg, PM_ICON, STM_SETICON, (WPARAM)ProgramAttributes.hTmpIcon, 0);
459 return TRUE;
460 }
461
462 case IDOK:
463 GetDlgItemTextA(hDlg, PM_DESCRIPTION,
464 ProgramAttributes.lpszTitle,
465 ProgramAttributes.nSize);
466 GetDlgItemTextA(hDlg, PM_COMMAND_LINE,
467 ProgramAttributes.lpszCmdLine,
468 ProgramAttributes.nSize);
469 GetDlgItemTextA(hDlg, PM_DIRECTORY,
470 ProgramAttributes.lpszWorkDir,
471 ProgramAttributes.nSize);
472
473 if (ProgramAttributes.hTmpIcon)
474 {
475 #if 0
476 if (*ProgramAttributes.lphIcon)
477 DestroyIcon(*ProgramAttributes.lphIcon);
478 #endif
479 *ProgramAttributes.lphIcon = ProgramAttributes.hTmpIcon;
480 *ProgramAttributes.lpnIconIndex = ProgramAttributes.nTmpIconIndex;
481 lstrcpynA(ProgramAttributes.lpszIconFile,
482 ProgramAttributes.lpszTmpIconFile,
483 ProgramAttributes.nSize);
484 }
485
486 *ProgramAttributes.lpnCmdShow =
487 IsDlgButtonChecked(hDlg, PM_SYMBOL) ?
488 SW_SHOWMINIMIZED : SW_SHOWNORMAL;
489 EndDialog(hDlg, IDOK);
490 return TRUE;
491
492 case IDCANCEL:
493 EndDialog(hDlg, IDCANCEL);
494 return TRUE;
495 }
496 return FALSE;
497 }
498 return FALSE;
499 }
500
501 /***********************************************************************
502 *
503 * DIALOG_ProgramAttributes
504 */
505 BOOL DIALOG_ProgramAttributes(LPSTR lpszTitle, LPSTR lpszCmdLine,
506 LPSTR lpszWorkDir, LPSTR lpszIconFile,
507 HICON *lphIcon, INT *lpnIconIndex,
508 INT *lpnHotKey, INT *lpnCmdShow, INT nSize)
509 {
510 CHAR szTmpIconFile[MAX_PATHNAME_LEN];
511 INT ret;
512
513 ProgramAttributes.nSize = nSize;
514 ProgramAttributes.lpszTitle = lpszTitle;
515 ProgramAttributes.lpszCmdLine = lpszCmdLine;
516 ProgramAttributes.lpszWorkDir = lpszWorkDir;
517 ProgramAttributes.lpszIconFile = lpszIconFile;
518 ProgramAttributes.lpnCmdShow = lpnCmdShow;
519 ProgramAttributes.lpnHotKey = lpnHotKey;
520 ProgramAttributes.lphIcon = lphIcon;
521 ProgramAttributes.lpnIconIndex = lpnIconIndex;
522
523 #if 0
524 ProgramAttributes.hTmpIcon = 0;
525 #else
526 ProgramAttributes.hTmpIcon = *lphIcon;
527 #endif
528 ProgramAttributes.nTmpIconIndex = *lpnIconIndex;
529 ProgramAttributes.lpszTmpIconFile = szTmpIconFile;
530 lstrcpynA(ProgramAttributes.lpszTmpIconFile, lpszIconFile, MAX_PATHNAME_LEN);
531
532 ret = DialogBoxW(Globals.hInstance, MAKEINTRESOURCEW(IDD_PROGRAM), Globals.hMainWnd, DIALOG_PROGRAM_DlgProc);
533 return(ret == IDOK);
534 }
535
536
537 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
538 *
539 * DIALOG_EXECUTE_DlgProc
540 */
541 static INT_PTR CALLBACK DIALOG_EXECUTE_DlgProc(HWND hDlg, UINT msg,
542 WPARAM wParam, LPARAM lParam)
543 {
544 switch (msg)
545 {
546 case WM_COMMAND:
547 switch (wParam)
548 {
549 case PM_SYMBOL:
550 CheckDlgButton(hDlg, PM_SYMBOL, !IsDlgButtonChecked(hDlg, PM_SYMBOL));
551 return TRUE;
552
553 case PM_BROWSE:
554 {
555 CHAR filename[MAX_PATHNAME_LEN];
556 filename[0] = 0;
557 if (DIALOG_BrowsePrograms(hDlg, filename, sizeof(filename)))
558 SetDlgItemTextA(hDlg, PM_COMMAND, filename);
559 return TRUE;
560 }
561
562 case PM_HELP:
563 MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK);
564 return TRUE;
565
566 case IDOK:
567 {
568 CHAR cmdline[MAX_PATHNAME_LEN];
569 GetDlgItemTextA(hDlg, PM_COMMAND, cmdline, sizeof(cmdline));
570
571 WinExec(cmdline, IsDlgButtonChecked(hDlg, PM_SYMBOL) ?
572 SW_SHOWMINIMIZED : SW_SHOWNORMAL);
573 if (Globals.bMinOnRun) CloseWindow(Globals.hMainWnd);
574
575 EndDialog(hDlg, IDOK);
576 return TRUE;
577 }
578
579 case IDCANCEL:
580 EndDialog(hDlg, IDCANCEL);
581 return TRUE;
582 }
583 }
584 return FALSE;
585 }
586
587 /***********************************************************************
588 *
589 * DIALOG_Execute
590 */
591
592 VOID DIALOG_Execute(void)
593 {
594 DialogBoxW(Globals.hInstance, MAKEINTRESOURCEW(IDD_EXECUTE), Globals.hMainWnd, DIALOG_EXECUTE_DlgProc);
595 }