user32: Specify cursor hotspots separately for each size.
[wine.git] / programs / progman / dialog.c
blob2e816211c7ab8c3c4f0878f87c10d6d85a970ad0
1 /*
2 * Program Manager
4 * Copyright 1996 Ulrich Schmid
5 * Copyright 2002 Sylvain Petreolle
6 * Copyright 2002 Andriy Palamarchuk
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.
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.
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
23 #define WIN32_LEAN_AND_MEAN
25 #include "windows.h"
26 #include "commdlg.h"
27 #include "progman.h"
30 /***********************************************************************
32 * DIALOG_Browse
35 static BOOL DIALOG_Browse(HWND hDlg, LPCSTR lpszzFilter,
36 LPSTR lpstrFile, INT nMaxFile)
39 OPENFILENAMEA openfilename;
41 CHAR szDir[MAX_PATH];
42 CHAR szDefaultExt[] = "exe";
44 ZeroMemory(&openfilename, sizeof(openfilename));
46 GetCurrentDirectoryA(sizeof(szDir), szDir);
48 openfilename.lStructSize = sizeof(openfilename);
49 openfilename.hwndOwner = Globals.hMainWnd;
50 openfilename.hInstance = Globals.hInstance;
51 openfilename.lpstrFilter = lpszzFilter;
52 openfilename.lpstrFile = lpstrFile;
53 openfilename.nMaxFile = nMaxFile;
54 openfilename.lpstrInitialDir = szDir;
55 openfilename.Flags = 0;
56 openfilename.lpstrDefExt = szDefaultExt;
57 openfilename.lpstrCustomFilter = 0;
58 openfilename.nMaxCustFilter = 0;
59 openfilename.nFilterIndex = 0;
60 openfilename.lpstrFileTitle = 0;
61 openfilename.nMaxFileTitle = 0;
62 openfilename.lpstrInitialDir = 0;
63 openfilename.lpstrTitle = 0;
64 openfilename.nFileOffset = 0;
65 openfilename.nFileExtension = 0;
66 openfilename.lCustData = 0;
67 openfilename.lpfnHook = 0;
68 openfilename.lpTemplateName = 0;
70 return GetOpenFileNameA(&openfilename);
73 /***********************************************************************
75 * DIALOG_AddFilterItem
78 static VOID DIALOG_AddFilterItem(LPSTR *p, UINT ids, LPCSTR filter)
80 LoadStringA(Globals.hInstance, ids, *p, MAX_STRING_LEN);
81 *p += strlen(*p) + 1;
82 lstrcpyA(*p, filter);
83 *p += strlen(*p) + 1;
84 **p = '\0';
87 /***********************************************************************
89 * DIALOG_BrowsePrograms
92 static BOOL DIALOG_BrowsePrograms(HWND hDlg, LPSTR lpszFile, INT nMaxFile)
94 CHAR szzFilter[2 * MAX_STRING_LEN + 100];
95 LPSTR p = szzFilter;
97 DIALOG_AddFilterItem(&p, IDS_PROGRAMS, "*.exe;*.pif;*.com;*.bat");
98 DIALOG_AddFilterItem(&p, IDS_ALL_FILES, "*.*");
100 return(DIALOG_Browse(hDlg, szzFilter, lpszFile, nMaxFile));
103 /***********************************************************************
105 * DIALOG_BrowseSymbols
108 static BOOL DIALOG_BrowseSymbols(HWND hDlg, LPSTR lpszFile, INT nMaxFile)
110 CHAR szzFilter[5 * MAX_STRING_LEN + 100];
111 LPSTR p = szzFilter;
113 DIALOG_AddFilterItem(&p, IDS_SYMBOL_FILES, "*.ico;*.exe;*.dll");
114 DIALOG_AddFilterItem(&p, IDS_PROGRAMS, "*.exe");
115 DIALOG_AddFilterItem(&p, IDS_LIBRARIES_DLL, "*.dll");
116 DIALOG_AddFilterItem(&p, IDS_SYMBOLS_ICO, "*.ico");
117 DIALOG_AddFilterItem(&p, IDS_ALL_FILES, "*.*");
119 return(DIALOG_Browse(hDlg, szzFilter, lpszFile, nMaxFile));
122 static struct
124 INT nDefault;
125 } New;
127 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
129 * DIALOG_NEW_DlgProc
131 static INT_PTR CALLBACK DIALOG_NEW_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
133 switch (msg)
135 case WM_INITDIALOG:
136 CheckRadioButton(hDlg, PM_NEW_GROUP, PM_NEW_PROGRAM, New.nDefault);
137 break;
139 case WM_COMMAND:
140 switch (wParam)
142 case PM_NEW_GROUP:
143 case PM_NEW_PROGRAM:
144 CheckRadioButton(hDlg, PM_NEW_GROUP, PM_NEW_PROGRAM, wParam);
145 return TRUE;
147 case IDOK:
148 EndDialog(hDlg, IsDlgButtonChecked(hDlg, PM_NEW_GROUP) ?
149 PM_NEW_GROUP : PM_NEW_PROGRAM);
150 return TRUE;
152 case IDCANCEL:
153 EndDialog(hDlg, IDCANCEL);
154 return TRUE;
157 return FALSE;
160 /***********************************************************************
162 * DIALOG_New
164 INT DIALOG_New(INT nDefault)
166 New.nDefault = nDefault;
167 return DialogBoxW(Globals.hInstance, MAKEINTRESOURCEW(IDD_NEW), Globals.hMainWnd, DIALOG_NEW_DlgProc);
171 static struct
173 LPCSTR lpszProgramName, lpszFromGroupName;
174 HLOCAL hToGroup;
175 } CopyMove;
177 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
179 * DIALOG_COPY_MOVE_DlgProc
181 static INT_PTR CALLBACK DIALOG_COPY_MOVE_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
183 HLOCAL hGroup;
185 switch (msg)
187 case WM_INITDIALOG:
188 /* List all group names */
189 for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
190 SendDlgItemMessageA(hDlg, PM_TO_GROUP, CB_ADDSTRING, 0, (LPARAM)GROUP_GroupName(hGroup));
192 SetDlgItemTextA(hDlg, PM_PROGRAM, CopyMove.lpszProgramName);
193 SetDlgItemTextA(hDlg, PM_FROM_GROUP, CopyMove.lpszFromGroupName);
194 break;
196 case WM_COMMAND:
197 switch (wParam)
199 case IDOK:
201 /* Get selected group */
202 INT nCurSel = SendDlgItemMessageW(hDlg, PM_TO_GROUP, CB_GETCURSEL, 0, 0);
203 INT nLen = SendDlgItemMessageW(hDlg, PM_TO_GROUP, CB_GETLBTEXTLEN, nCurSel, 0);
204 HLOCAL hBuffer = LocalAlloc(LMEM_FIXED, nLen + 1);
205 LPSTR buffer = LocalLock(hBuffer);
207 SendDlgItemMessageA(hDlg, PM_TO_GROUP, CB_GETLBTEXT, nCurSel, (LPARAM)buffer);
208 for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
209 if (!lstrcmpA(buffer, GROUP_GroupName(hGroup))) break;
210 LocalFree(hBuffer);
212 CopyMove.hToGroup = hGroup;
213 EndDialog(hDlg, IDOK);
214 return TRUE;
217 case IDCANCEL:
218 EndDialog(hDlg, IDCANCEL);
219 return TRUE;
222 return FALSE;
225 /***********************************************************************
227 * DIALOG_CopyMove
229 HLOCAL DIALOG_CopyMove(LPCSTR lpszProgramName, LPCSTR lpszFromGroupName,
230 BOOL bMove)
232 INT ret;
234 CopyMove.lpszProgramName = lpszProgramName;
235 CopyMove.lpszFromGroupName = lpszFromGroupName;
236 CopyMove.hToGroup = 0;
238 ret = DialogBoxW(Globals.hInstance,
239 bMove ? MAKEINTRESOURCEW(IDD_MOVE) : MAKEINTRESOURCEW(IDD_COPY),
240 Globals.hMainWnd, DIALOG_COPY_MOVE_DlgProc);
241 return((ret == IDOK) ? CopyMove.hToGroup : 0);
244 /***********************************************************************
246 * DIALOG_Delete
249 BOOL DIALOG_Delete(UINT ids_text_s, LPCSTR lpszName)
251 return (IDYES == MAIN_MessageBoxIDS_s(ids_text_s, lpszName, IDS_DELETE,
252 MB_YESNO | MB_DEFBUTTON2));
256 static struct
258 LPSTR lpszTitle, lpszGrpFile;
259 INT nSize;
260 } GroupAttributes;
262 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
264 * DIALOG_GROUP_DlgProc
266 static INT_PTR CALLBACK DIALOG_GROUP_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
268 switch (msg)
270 case WM_INITDIALOG:
271 SetDlgItemTextA(hDlg, PM_DESCRIPTION, GroupAttributes.lpszTitle);
272 SetDlgItemTextA(hDlg, PM_FILE, GroupAttributes.lpszGrpFile);
273 break;
275 case WM_COMMAND:
276 switch (wParam)
278 case IDOK:
279 GetDlgItemTextA(hDlg, PM_DESCRIPTION, GroupAttributes.lpszTitle, GroupAttributes.nSize);
280 GetDlgItemTextA(hDlg, PM_FILE, GroupAttributes.lpszGrpFile, GroupAttributes.nSize);
281 EndDialog(hDlg, IDOK);
282 return TRUE;
284 case IDCANCEL:
285 EndDialog(hDlg, IDCANCEL);
286 return TRUE;
289 return FALSE;
292 /***********************************************************************
294 * DIALOG_GroupAttributes
296 BOOL DIALOG_GroupAttributes(LPSTR lpszTitle, LPSTR lpszGrpFile, INT nSize)
298 INT ret;
300 GroupAttributes.nSize = nSize;
301 GroupAttributes.lpszTitle = lpszTitle;
302 GroupAttributes.lpszGrpFile = lpszGrpFile;
304 ret = DialogBoxW(Globals.hInstance, MAKEINTRESOURCEW(IDD_GROUP), Globals.hMainWnd, DIALOG_GROUP_DlgProc);
305 return(ret == IDOK);
309 static struct
311 LPSTR lpszIconFile;
312 INT nSize;
313 HICON *lphIcon;
314 INT *lpnIconIndex;
315 } Symbol;
317 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
319 * DIALOG_SYMBOL_DlgProc
321 static INT_PTR CALLBACK DIALOG_SYMBOL_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
323 switch (msg)
325 case WM_INITDIALOG:
326 SetDlgItemTextA(hDlg, PM_ICON_FILE, Symbol.lpszIconFile);
327 SendDlgItemMessageA(hDlg, PM_SYMBOL_LIST, CB_SETITEMHEIGHT, 0, (LPARAM) 32);
328 SendDlgItemMessageA(hDlg, PM_SYMBOL_LIST, CB_ADDSTRING, 0, (LPARAM)*Symbol.lphIcon);
329 SendDlgItemMessageA(hDlg, PM_SYMBOL_LIST, CB_ADDSTRING, 0, (LPARAM)Globals.hDefaultIcon);
330 SendDlgItemMessageA(hDlg, PM_SYMBOL_LIST, CB_SETCURSEL, 0, 0);
331 return TRUE;
333 case WM_MEASUREITEM:
335 PMEASUREITEMSTRUCT measure = (PMEASUREITEMSTRUCT) lParam;
336 measure->itemWidth = 32;
337 measure->itemHeight = 32;
338 return TRUE;
341 case WM_DRAWITEM:
343 PDRAWITEMSTRUCT dis = (PDRAWITEMSTRUCT) lParam;
344 DrawIcon(dis->hDC, dis->rcItem.left, dis->rcItem.top, (HICON)dis->itemData);
345 return TRUE;
348 case WM_COMMAND:
349 switch (wParam)
351 case PM_BROWSE:
353 CHAR filename[MAX_PATHNAME_LEN];
354 filename[0] = 0;
355 if (DIALOG_BrowseSymbols(hDlg, filename, sizeof(filename)))
356 SetDlgItemTextA(hDlg, PM_ICON_FILE, filename);
357 return TRUE;
360 case PM_HELP:
361 MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK);
362 return TRUE;
364 case IDOK:
366 INT nCurSel = SendDlgItemMessageA(hDlg, PM_SYMBOL_LIST, CB_GETCURSEL, 0, 0);
368 GetDlgItemTextA(hDlg, PM_ICON_FILE, Symbol.lpszIconFile, Symbol.nSize);
370 *Symbol.lphIcon = (HICON)SendDlgItemMessageA(hDlg, PM_SYMBOL_LIST,
371 CB_GETITEMDATA,
372 (WPARAM) nCurSel, 0);
373 #if 0
374 *Symbol.lphIcon = CopyIcon(*Symbol.lphIcon);
375 #endif
377 EndDialog(hDlg, IDOK);
378 return TRUE;
381 case IDCANCEL:
382 EndDialog(hDlg, IDCANCEL);
383 return TRUE;
386 return FALSE;
389 /***********************************************************************
391 * DIALOG_Symbol
393 static VOID DIALOG_Symbol(HICON *lphIcon, LPSTR lpszIconFile,
394 INT *lpnIconIndex, INT nSize)
396 Symbol.nSize = nSize;
397 Symbol.lpszIconFile = lpszIconFile;
398 Symbol.lphIcon = lphIcon;
399 Symbol.lpnIconIndex = lpnIconIndex;
401 DialogBoxW(Globals.hInstance, MAKEINTRESOURCEW(IDD_SYMBOL), Globals.hMainWnd, DIALOG_SYMBOL_DlgProc);
405 static struct
407 LPSTR lpszTitle, lpszCmdLine, lpszWorkDir, lpszIconFile, lpszTmpIconFile;
408 INT nSize;
409 INT *lpnCmdShow;
410 INT *lpnHotKey;
411 HWND hSelGroupWnd;
412 HICON *lphIcon, hTmpIcon;
413 INT *lpnIconIndex, nTmpIconIndex;
414 } ProgramAttributes;
416 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
418 * DIALOG_PROGRAM_DlgProc
420 static INT_PTR CALLBACK DIALOG_PROGRAM_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
422 CHAR buffer[MAX_STRING_LEN];
423 switch (msg)
425 case WM_INITDIALOG:
426 SetDlgItemTextA(hDlg, PM_DESCRIPTION, ProgramAttributes.lpszTitle);
427 SetDlgItemTextA(hDlg, PM_COMMAND_LINE, ProgramAttributes.lpszCmdLine);
428 SetDlgItemTextA(hDlg, PM_DIRECTORY, ProgramAttributes.lpszWorkDir);
429 if (!*ProgramAttributes.lpnHotKey)
431 LoadStringA(Globals.hInstance, IDS_NO_HOT_KEY, buffer, sizeof(buffer));
432 SetDlgItemTextA(hDlg, PM_HOT_KEY, buffer);
435 CheckDlgButton(hDlg, PM_SYMBOL,
436 (*ProgramAttributes.lpnCmdShow == SW_SHOWMINIMIZED));
437 SendDlgItemMessageA(hDlg, PM_ICON, STM_SETICON, (WPARAM)ProgramAttributes.hTmpIcon, 0);
438 break;
440 case WM_COMMAND:
441 switch (wParam)
443 case PM_SYMBOL:
444 CheckDlgButton(hDlg, PM_SYMBOL, !IsDlgButtonChecked(hDlg, PM_SYMBOL));
445 return TRUE;
447 case PM_BROWSE:
449 CHAR filename[MAX_PATHNAME_LEN];
450 filename[0] = 0;
451 if (DIALOG_BrowsePrograms(hDlg, filename, sizeof(filename)))
452 SetDlgItemTextA(hDlg, PM_COMMAND_LINE, filename);
453 return TRUE;
456 case PM_OTHER_SYMBOL:
458 DIALOG_Symbol(&ProgramAttributes.hTmpIcon,
459 ProgramAttributes.lpszTmpIconFile,
460 &ProgramAttributes.nTmpIconIndex,
461 MAX_PATHNAME_LEN);
463 SendDlgItemMessageA(hDlg, PM_ICON, STM_SETICON, (WPARAM)ProgramAttributes.hTmpIcon, 0);
464 return TRUE;
467 case IDOK:
468 GetDlgItemTextA(hDlg, PM_DESCRIPTION,
469 ProgramAttributes.lpszTitle,
470 ProgramAttributes.nSize);
471 GetDlgItemTextA(hDlg, PM_COMMAND_LINE,
472 ProgramAttributes.lpszCmdLine,
473 ProgramAttributes.nSize);
474 GetDlgItemTextA(hDlg, PM_DIRECTORY,
475 ProgramAttributes.lpszWorkDir,
476 ProgramAttributes.nSize);
478 if (ProgramAttributes.hTmpIcon)
480 #if 0
481 if (*ProgramAttributes.lphIcon)
482 DestroyIcon(*ProgramAttributes.lphIcon);
483 #endif
484 *ProgramAttributes.lphIcon = ProgramAttributes.hTmpIcon;
485 *ProgramAttributes.lpnIconIndex = ProgramAttributes.nTmpIconIndex;
486 lstrcpynA(ProgramAttributes.lpszIconFile,
487 ProgramAttributes.lpszTmpIconFile,
488 ProgramAttributes.nSize);
491 *ProgramAttributes.lpnCmdShow =
492 IsDlgButtonChecked(hDlg, PM_SYMBOL) ?
493 SW_SHOWMINIMIZED : SW_SHOWNORMAL;
494 EndDialog(hDlg, IDOK);
495 return TRUE;
497 case IDCANCEL:
498 EndDialog(hDlg, IDCANCEL);
499 return TRUE;
501 return FALSE;
503 return FALSE;
506 /***********************************************************************
508 * DIALOG_ProgramAttributes
510 BOOL DIALOG_ProgramAttributes(LPSTR lpszTitle, LPSTR lpszCmdLine,
511 LPSTR lpszWorkDir, LPSTR lpszIconFile,
512 HICON *lphIcon, INT *lpnIconIndex,
513 INT *lpnHotKey, INT *lpnCmdShow, INT nSize)
515 CHAR szTmpIconFile[MAX_PATHNAME_LEN];
516 INT ret;
518 ProgramAttributes.nSize = nSize;
519 ProgramAttributes.lpszTitle = lpszTitle;
520 ProgramAttributes.lpszCmdLine = lpszCmdLine;
521 ProgramAttributes.lpszWorkDir = lpszWorkDir;
522 ProgramAttributes.lpszIconFile = lpszIconFile;
523 ProgramAttributes.lpnCmdShow = lpnCmdShow;
524 ProgramAttributes.lpnHotKey = lpnHotKey;
525 ProgramAttributes.lphIcon = lphIcon;
526 ProgramAttributes.lpnIconIndex = lpnIconIndex;
528 #if 0
529 ProgramAttributes.hTmpIcon = 0;
530 #else
531 ProgramAttributes.hTmpIcon = *lphIcon;
532 #endif
533 ProgramAttributes.nTmpIconIndex = *lpnIconIndex;
534 ProgramAttributes.lpszTmpIconFile = szTmpIconFile;
535 lstrcpynA(ProgramAttributes.lpszTmpIconFile, lpszIconFile, MAX_PATHNAME_LEN);
537 ret = DialogBoxW(Globals.hInstance, MAKEINTRESOURCEW(IDD_PROGRAM), Globals.hMainWnd, DIALOG_PROGRAM_DlgProc);
538 return(ret == IDOK);
542 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
544 * DIALOG_EXECUTE_DlgProc
546 static INT_PTR CALLBACK DIALOG_EXECUTE_DlgProc(HWND hDlg, UINT msg,
547 WPARAM wParam, LPARAM lParam)
549 switch (msg)
551 case WM_COMMAND:
552 switch (wParam)
554 case PM_SYMBOL:
555 CheckDlgButton(hDlg, PM_SYMBOL, !IsDlgButtonChecked(hDlg, PM_SYMBOL));
556 return TRUE;
558 case PM_BROWSE:
560 CHAR filename[MAX_PATHNAME_LEN];
561 filename[0] = 0;
562 if (DIALOG_BrowsePrograms(hDlg, filename, sizeof(filename)))
563 SetDlgItemTextA(hDlg, PM_COMMAND, filename);
564 return TRUE;
567 case PM_HELP:
568 MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK);
569 return TRUE;
571 case IDOK:
573 CHAR cmdline[MAX_PATHNAME_LEN];
574 GetDlgItemTextA(hDlg, PM_COMMAND, cmdline, sizeof(cmdline));
576 WinExec(cmdline, IsDlgButtonChecked(hDlg, PM_SYMBOL) ?
577 SW_SHOWMINIMIZED : SW_SHOWNORMAL);
578 if (Globals.bMinOnRun) CloseWindow(Globals.hMainWnd);
580 EndDialog(hDlg, IDOK);
581 return TRUE;
584 case IDCANCEL:
585 EndDialog(hDlg, IDCANCEL);
586 return TRUE;
589 return FALSE;
592 /***********************************************************************
594 * DIALOG_Execute
597 VOID DIALOG_Execute(void)
599 DialogBoxW(Globals.hInstance, MAKEINTRESOURCEW(IDD_EXECUTE), Globals.hMainWnd, DIALOG_EXECUTE_DlgProc);