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