[DCOMLAUNCH] Add a DcomLaunch service stub
[reactos.git] / base / shell / progman / program.c
1 /*
2 * Program Manager
3 *
4 * Copyright 1996 Ulrich Schmid
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 /*
22 * PROJECT: ReactOS Program Manager
23 * COPYRIGHT: GPL - See COPYING in the top level directory
24 * FILE: base/shell/progman/program.c
25 * PURPOSE: Program items helper functions
26 * PROGRAMMERS: Ulrich Schmid
27 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
28 */
29
30 #include "progman.h"
31
32 #if 0
33
34 static LRESULT CALLBACK PROGRAM_ProgramWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
35 {
36 switch (msg)
37 {
38 case WM_NCLBUTTONDOWN:
39 {
40 HLOCAL hProgram = (HLOCAL) GetWindowLongPtrW(hWnd, 0);
41 PROGRAM *program = LocalLock(hProgram);
42 PROGGROUP *group = LocalLock(program->hGroup);
43 group->hActiveProgram = hProgram;
44 EnableMenuItem(Globals.hFileMenu, PM_MOVE , MF_ENABLED);
45 EnableMenuItem(Globals.hFileMenu, PM_COPY , MF_ENABLED);
46 break;
47 }
48 case WM_NCLBUTTONDBLCLK:
49 {
50 PROGRAM_ExecuteProgram((HLOCAL) GetWindowLongPtrW(hWnd, 0));
51 return(0);
52 }
53
54 case WM_PAINTICON:
55 case WM_NCPAINT:
56 {
57 PROGRAM *program;
58 PAINTSTRUCT ps;
59 HDC hdc;
60 hdc = BeginPaint(hWnd,&ps);
61 program = LocalLock((HLOCAL) GetWindowLongPtrW(hWnd, 0));
62 if (program->hIcon)
63 DrawIcon(hdc, 0, 0, program->hIcon);
64 EndPaint(hWnd,&ps);
65 break;
66 }
67 }
68 return DefWindowProcW(hWnd, msg, wParam, lParam);
69 }
70
71 #endif
72
73
74
75 /***********************************************************************
76 *
77 * PROGRAM_NewProgram
78 */
79
80 VOID PROGRAM_NewProgram(PROGGROUP* hGroup)
81 {
82 HICON hIcon = NULL;
83 INT nIconIndex = 0;
84 INT nHotKey = 0;
85 INT nCmdShow = SW_SHOWNORMAL;
86 BOOL bNewVDM = FALSE;
87 WCHAR szTitle[MAX_PATHNAME_LEN] = L"";
88 WCHAR szCmdLine[MAX_PATHNAME_LEN] = L"";
89 WCHAR szIconFile[MAX_PATHNAME_LEN] = L"";
90 WCHAR szWorkDir[MAX_PATHNAME_LEN] = L"";
91
92 if (!DIALOG_ProgramAttributes(szTitle, szCmdLine, szWorkDir, szIconFile,
93 &hIcon, &nIconIndex, &nHotKey, &nCmdShow, &bNewVDM,
94 MAX_PATHNAME_LEN))
95 {
96 return;
97 }
98
99 if (!hIcon)
100 hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(IDI_WINLOGO));
101
102 if (!PROGRAM_AddProgram(hGroup, hIcon, szTitle, -1, -1, szCmdLine, szIconFile,
103 nIconIndex, szWorkDir, nHotKey, nCmdShow, bNewVDM))
104 {
105 return;
106 }
107
108 GRPFILE_WriteGroupFile(hGroup);
109 }
110
111 /***********************************************************************
112 *
113 * PROGRAM_ModifyProgram
114 */
115
116 VOID PROGRAM_ModifyProgram(PROGRAM* hProgram)
117 {
118 LVITEMW lvItem;
119 WCHAR szName[MAX_PATHNAME_LEN];
120 WCHAR szWorkDir[MAX_PATHNAME_LEN];
121 WCHAR szCmdLine[MAX_PATHNAME_LEN];
122 WCHAR szIconFile[MAX_PATHNAME_LEN];
123
124 lstrcpynW(szName , hProgram->hName , ARRAYSIZE(szName));
125 lstrcpynW(szCmdLine , hProgram->hCmdLine , ARRAYSIZE(szCmdLine));
126 lstrcpynW(szIconFile, hProgram->hIconFile, ARRAYSIZE(szIconFile));
127 lstrcpynW(szWorkDir , hProgram->hWorkDir , ARRAYSIZE(szWorkDir));
128
129 if (!DIALOG_ProgramAttributes(szName, szCmdLine, szWorkDir, szIconFile,
130 &hProgram->hIcon, &hProgram->nIconIndex,
131 &hProgram->nHotKey, &hProgram->nCmdShow,
132 &hProgram->bNewVDM, MAX_PATHNAME_LEN))
133 {
134 return;
135 }
136
137 MAIN_ReplaceString(&hProgram->hName , szName);
138 MAIN_ReplaceString(&hProgram->hCmdLine , szCmdLine);
139 MAIN_ReplaceString(&hProgram->hIconFile, szIconFile);
140 MAIN_ReplaceString(&hProgram->hWorkDir , szWorkDir);
141
142 ZeroMemory(&lvItem, sizeof(lvItem));
143 lvItem.mask = LVIF_TEXT;
144 lvItem.iSubItem = 0;
145 lvItem.pszText = szName;
146 SendMessageW(hProgram->hGroup->hListView, LVM_SETITEMTEXTW, hProgram->iItem, (LPARAM)&lvItem);
147
148 GRPFILE_WriteGroupFile(hProgram->hGroup);
149 }
150
151 /***********************************************************************
152 *
153 * PROGRAM_AddProgram
154 */
155
156 PROGRAM*
157 PROGRAM_AddProgram(PROGGROUP* hGroup, HICON hIcon, LPCWSTR lpszName,
158 INT x, INT y, LPCWSTR lpszCmdLine, LPCWSTR lpszIconFile, INT nIconIndex,
159 LPCWSTR lpszWorkDir, INT nHotKey, INT nCmdShow, BOOL bNewVDM)
160 {
161 PROGRAM* hProgram;
162 PROGRAM* hPrior;
163 PROGRAM** p;
164 LPWSTR hCmdLine;
165 LPWSTR hIconFile;
166 LPWSTR hName;
167 LPWSTR hWorkDir;
168 LVITEMW lvItem;
169 INT iItem;
170
171 hProgram = Alloc(HEAP_ZERO_MEMORY, sizeof(*hProgram));
172 hName = Alloc(HEAP_ZERO_MEMORY, (wcslen(lpszName) + 1) * sizeof(WCHAR));
173 hCmdLine = Alloc(HEAP_ZERO_MEMORY, (wcslen(lpszCmdLine) + 1) * sizeof(WCHAR));
174 hIconFile = Alloc(HEAP_ZERO_MEMORY, (wcslen(lpszIconFile) + 1) * sizeof(WCHAR));
175 hWorkDir = Alloc(HEAP_ZERO_MEMORY, (wcslen(lpszWorkDir) + 1) * sizeof(WCHAR));
176 if (!hProgram || !hName || !hCmdLine || !hIconFile || !hWorkDir)
177 {
178 MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_OK);
179 if (hProgram) Free(hProgram);
180 if (hName) Free(hName);
181 if (hCmdLine) Free(hCmdLine);
182 if (hIconFile) Free(hIconFile);
183 if (hWorkDir) Free(hWorkDir);
184 return NULL;
185 }
186 memcpy(hName , lpszName , (wcslen(lpszName) + 1) * sizeof(WCHAR));
187 memcpy(hCmdLine , lpszCmdLine , (wcslen(lpszCmdLine) + 1) * sizeof(WCHAR));
188 memcpy(hIconFile, lpszIconFile, (wcslen(lpszIconFile) + 1) * sizeof(WCHAR));
189 memcpy(hWorkDir , lpszWorkDir , (wcslen(lpszWorkDir) + 1) * sizeof(WCHAR));
190
191 hGroup->hActiveProgram = hProgram;
192
193 hPrior = NULL;
194 for (p = &hGroup->hPrograms; *p; p = &hPrior->hNext)
195 hPrior = *p;
196 *p = hProgram;
197
198 hProgram->hGroup = hGroup;
199 hProgram->hPrior = hPrior;
200 hProgram->hNext = NULL;
201 hProgram->hName = hName;
202 hProgram->hCmdLine = hCmdLine;
203 hProgram->hIconFile = hIconFile;
204 hProgram->nIconIndex = nIconIndex;
205 hProgram->hWorkDir = hWorkDir;
206 hProgram->hIcon = hIcon;
207 hProgram->nCmdShow = nCmdShow;
208 hProgram->nHotKey = nHotKey;
209 hProgram->bNewVDM = bNewVDM;
210 hProgram->TagsSize = 0;
211 hProgram->Tags = NULL;
212
213 ZeroMemory(&lvItem, sizeof(lvItem));
214 lvItem.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT;
215 lvItem.pszText = (LPWSTR)lpszName;
216 lvItem.lParam = (LPARAM)hProgram;
217 lvItem.iImage = ImageList_ReplaceIcon(hGroup->hListLarge, -1, hIcon);
218 DestroyIcon(hIcon);
219
220 lvItem.iItem = SendMessageA(hGroup->hListView, LVM_GETITEMCOUNT, 0, 0);
221 iItem = SendMessageW(hGroup->hListView, LVM_INSERTITEMW, 0, (LPARAM)&lvItem);
222 hProgram->iItem = iItem;
223 if (x != -1 && y != -1)
224 SendMessageA(hGroup->hListView, LVM_SETITEMPOSITION, lvItem.iItem, MAKELPARAM(x, y));
225
226 return hProgram;
227 }
228
229
230
231 /***********************************************************************
232 *
233 * PROGRAM_CopyMoveProgram
234 */
235
236 VOID PROGRAM_CopyMoveProgram(PROGRAM* hProgram, BOOL bMove)
237 {
238 PROGGROUP* hGroup;
239
240 hGroup = DIALOG_CopyMove(hProgram, bMove);
241 if (!hGroup)
242 return;
243
244 /* FIXME: shouldn't be necessary */
245 OpenIcon(hGroup->hWnd);
246
247 if (!PROGRAM_AddProgram(hGroup,
248 hProgram->hIcon,
249 hProgram->hName,
250 hProgram->x,
251 hProgram->y,
252 hProgram->hCmdLine,
253 hProgram->hIconFile,
254 hProgram->nIconIndex,
255 hProgram->hWorkDir,
256 hProgram->nHotKey,
257 hProgram->nCmdShow,
258 hProgram->bNewVDM))
259 {
260 return;
261 }
262
263 GRPFILE_WriteGroupFile(hGroup);
264
265 if (bMove)
266 PROGRAM_DeleteProgram(hProgram, TRUE);
267 }
268
269 /***********************************************************************
270 *
271 * PROGRAM_ExecuteProgram
272 */
273
274 VOID PROGRAM_ExecuteProgram(PROGRAM* hProgram)
275 {
276 // TODO: Use a (private?) shell API with which one can use hProgram->bNewVDM
277
278 ShellExecuteW(NULL, NULL, hProgram->hCmdLine, NULL, hProgram->hWorkDir, hProgram->nCmdShow);
279
280 if (Globals.bMinOnRun)
281 CloseWindow(Globals.hMainWnd);
282 }
283
284 /***********************************************************************
285 *
286 * PROGRAM_DeleteProgram
287 */
288
289 VOID PROGRAM_DeleteProgram(PROGRAM* hProgram, BOOL bUpdateGrpFile)
290 {
291 PROGGROUP* group;
292
293 group = hProgram->hGroup;
294 if (hProgram->hGroup->hActiveProgram == hProgram)
295 group->hActiveProgram = NULL;
296
297 SendMessageA(group->hListView, LVM_DELETEITEM, hProgram->iItem, 0);
298
299 if (hProgram->hPrior)
300 hProgram->hPrior->hNext = hProgram->hNext;
301 else
302 hProgram->hGroup->hPrograms = hProgram->hNext;
303
304 if (hProgram->hNext)
305 hProgram->hNext->hPrior = hProgram->hPrior;
306
307 if (bUpdateGrpFile)
308 GRPFILE_WriteGroupFile(hProgram->hGroup);
309
310 #if 0
311 DestroyWindow(program->hWnd);
312 if (program->hIcon)
313 DestroyIcon(program->hIcon);
314 #endif
315
316 if (hProgram->Tags)
317 Free(hProgram->Tags);
318 Free(hProgram->hName);
319 Free(hProgram->hCmdLine);
320 Free(hProgram->hIconFile);
321 Free(hProgram->hWorkDir);
322 Free(hProgram);
323 }
324
325
326 /***********************************************************************
327 *
328 * PROGRAM_ActiveProgram
329 */
330
331 PROGRAM* PROGRAM_ActiveProgram(PROGGROUP* hGroup)
332 {
333 if (!hGroup) return NULL;
334 if (IsIconic(hGroup->hWnd)) return NULL;
335 return hGroup->hActiveProgram;
336 }