[PROGMAN] Properly import from Wine Staging 1.9.4. This fixes PCH usage, marks ReactO...
[reactos.git] / reactos / 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 #include "progman.h"
22
23 /***********************************************************************
24 *
25 * PROGRAM_ProgramWndProc
26 */
27
28 static LRESULT CALLBACK PROGRAM_ProgramWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
29 {
30 switch (msg)
31 {
32 case WM_NCLBUTTONDOWN:
33 {
34 HLOCAL hProgram = (HLOCAL) GetWindowLongPtrW(hWnd, 0);
35 PROGRAM *program = LocalLock(hProgram);
36 PROGGROUP *group = LocalLock(program->hGroup);
37 group->hActiveProgram = hProgram;
38 EnableMenuItem(Globals.hFileMenu, PM_MOVE , MF_ENABLED);
39 EnableMenuItem(Globals.hFileMenu, PM_COPY , MF_ENABLED);
40 break;
41 }
42 case WM_NCLBUTTONDBLCLK:
43 {
44 PROGRAM_ExecuteProgram((HLOCAL) GetWindowLongPtrW(hWnd, 0));
45 return(0);
46 }
47
48 case WM_PAINTICON:
49 case WM_NCPAINT:
50 {
51 PROGRAM *program;
52 PAINTSTRUCT ps;
53 HDC hdc;
54 hdc = BeginPaint(hWnd,&ps);
55 program = LocalLock((HLOCAL) GetWindowLongPtrW(hWnd, 0));
56 if (program->hIcon)
57 DrawIcon(hdc, 0, 0, program->hIcon);
58 EndPaint(hWnd,&ps);
59 break;
60 }
61 }
62 return DefWindowProcW(hWnd, msg, wParam, lParam);
63 }
64
65 /***********************************************************************
66 *
67 * PROGRAM_RegisterProgramWinClass
68 */
69
70 ATOM PROGRAM_RegisterProgramWinClass(void)
71 {
72 WNDCLASSW class;
73
74 class.style = CS_HREDRAW | CS_VREDRAW;
75 class.lpfnWndProc = PROGRAM_ProgramWndProc;
76 class.cbClsExtra = 0;
77 class.cbWndExtra = sizeof(LONG_PTR);
78 class.hInstance = Globals.hInstance;
79 class.hIcon = 0;
80 class.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW);
81 class.hbrBackground = GetStockObject (WHITE_BRUSH);
82 class.lpszMenuName = 0;
83 class.lpszClassName = STRING_PROGRAM_WIN_CLASS_NAME;
84
85 return RegisterClassW(&class);
86 }
87
88 /***********************************************************************
89 *
90 * PROGRAM_NewProgram
91 */
92
93 VOID PROGRAM_NewProgram(HLOCAL hGroup)
94 {
95 INT nCmdShow = SW_SHOWNORMAL;
96 INT nHotKey = 0;
97 INT nIconIndex = 0;
98 CHAR szName[MAX_PATHNAME_LEN] = "";
99 CHAR szCmdLine[MAX_PATHNAME_LEN] = "";
100 CHAR szIconFile[MAX_PATHNAME_LEN] = "";
101 CHAR szWorkDir[MAX_PATHNAME_LEN] = "";
102 HICON hIcon = 0;
103
104 if (!DIALOG_ProgramAttributes(szName, szCmdLine, szWorkDir, szIconFile,
105 &hIcon, &nIconIndex, &nHotKey,
106 &nCmdShow, MAX_PATHNAME_LEN))
107 return;
108
109 if (!hIcon) hIcon = LoadIconW(0, (LPWSTR)IDI_WINLOGO);
110
111
112 if (!PROGRAM_AddProgram(hGroup, hIcon, szName, 0, 0, szCmdLine, szIconFile,
113 nIconIndex, szWorkDir, nHotKey, nCmdShow))
114 return;
115
116 GRPFILE_WriteGroupFile(hGroup);
117 }
118
119 /***********************************************************************
120 *
121 * PROGRAM_ModifyProgram
122 */
123
124 VOID PROGRAM_ModifyProgram(HLOCAL hProgram)
125 {
126 PROGRAM *program = LocalLock(hProgram);
127 CHAR szName[MAX_PATHNAME_LEN];
128 CHAR szCmdLine[MAX_PATHNAME_LEN];
129 CHAR szIconFile[MAX_PATHNAME_LEN];
130 CHAR szWorkDir[MAX_PATHNAME_LEN];
131
132 lstrcpynA(szName, LocalLock(program->hName), MAX_PATHNAME_LEN);
133 lstrcpynA(szCmdLine, LocalLock(program->hCmdLine), MAX_PATHNAME_LEN);
134 lstrcpynA(szIconFile, LocalLock(program->hIconFile), MAX_PATHNAME_LEN);
135 lstrcpynA(szWorkDir, LocalLock(program->hWorkDir), MAX_PATHNAME_LEN);
136
137 if (!DIALOG_ProgramAttributes(szName, szCmdLine, szWorkDir, szIconFile,
138 &program->hIcon, &program->nIconIndex,
139 &program->nHotKey, &program->nCmdShow,
140 MAX_PATHNAME_LEN))
141 return;
142
143 MAIN_ReplaceString(&program->hName, szName);
144 MAIN_ReplaceString(&program->hCmdLine, szCmdLine);
145 MAIN_ReplaceString(&program->hIconFile, szIconFile);
146 MAIN_ReplaceString(&program->hWorkDir, szWorkDir);
147
148 SetWindowTextA(program->hWnd, szName);
149 UpdateWindow(program->hWnd);
150
151 GRPFILE_WriteGroupFile(program->hGroup);
152
153 return;
154 }
155
156 /***********************************************************************
157 *
158 * PROGRAM_AddProgram
159 */
160
161 HLOCAL PROGRAM_AddProgram(HLOCAL hGroup, HICON hIcon, LPCSTR lpszName,
162 INT x, INT y, LPCSTR lpszCmdLine,
163 LPCSTR lpszIconFile, INT nIconIndex,
164 LPCSTR lpszWorkDir, INT nHotKey, INT nCmdShow)
165 {
166 PROGGROUP *group = LocalLock(hGroup);
167 PROGRAM *program;
168 HLOCAL hPrior, *p;
169 HLOCAL hProgram = LocalAlloc(LMEM_FIXED, sizeof(PROGRAM));
170 HLOCAL hName = LocalAlloc(LMEM_FIXED, 1 + strlen(lpszName));
171 HLOCAL hCmdLine = LocalAlloc(LMEM_FIXED, 1 + strlen(lpszCmdLine));
172 HLOCAL hIconFile = LocalAlloc(LMEM_FIXED, 1 + strlen(lpszIconFile));
173 HLOCAL hWorkDir = LocalAlloc(LMEM_FIXED, 1 + strlen(lpszWorkDir));
174 if (!hProgram || !hName || !hCmdLine || !hIconFile || !hWorkDir)
175 {
176 MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_OK);
177 if (hProgram) LocalFree(hProgram);
178 if (hName) LocalFree(hName);
179 if (hCmdLine) LocalFree(hCmdLine);
180 if (hIconFile) LocalFree(hIconFile);
181 if (hWorkDir) LocalFree(hWorkDir);
182 return(0);
183 }
184 memcpy(LocalLock(hName), lpszName, 1 + strlen(lpszName));
185 memcpy(LocalLock(hCmdLine), lpszCmdLine, 1 + strlen(lpszCmdLine));
186 memcpy(LocalLock(hIconFile), lpszIconFile, 1 + strlen(lpszIconFile));
187 memcpy(LocalLock(hWorkDir), lpszWorkDir, 1 + strlen(lpszWorkDir));
188
189 group->hActiveProgram = hProgram;
190
191 hPrior = 0;
192 p = &group->hPrograms;
193 while (*p)
194 {
195 hPrior = *p;
196 p = &((PROGRAM*)LocalLock(hPrior))->hNext;
197 }
198 *p = hProgram;
199
200 program = LocalLock(hProgram);
201 program->hGroup = hGroup;
202 program->hPrior = hPrior;
203 program->hNext = 0;
204 program->hName = hName;
205 program->hCmdLine = hCmdLine;
206 program->hIconFile = hIconFile;
207 program->nIconIndex = nIconIndex;
208 program->hWorkDir = hWorkDir;
209 program->hIcon = hIcon;
210 program->nCmdShow = nCmdShow;
211 program->nHotKey = nHotKey;
212
213 program->hWnd =
214 CreateWindowW(STRING_PROGRAM_WIN_CLASS_NAME, NULL,
215 WS_CHILD | WS_CAPTION,
216 x, y, CW_USEDEFAULT, CW_USEDEFAULT,
217 group->hWnd, 0, Globals.hInstance, 0);
218
219 SetWindowTextA(program->hWnd, lpszName);
220 SetWindowLongPtrW(program->hWnd, 0, (LONG_PTR) hProgram);
221
222 ShowWindow (program->hWnd, SW_SHOWMINIMIZED);
223 SetWindowPos (program->hWnd, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE);
224 UpdateWindow (program->hWnd);
225
226 return hProgram;
227 }
228
229 /***********************************************************************
230 *
231 * PROGRAM_CopyMoveProgram
232 */
233
234 VOID PROGRAM_CopyMoveProgram(HLOCAL hProgram, BOOL bMove)
235 {
236 PROGRAM *program = LocalLock(hProgram);
237 PROGGROUP *fromgroup = LocalLock(program->hGroup);
238 HLOCAL hGroup = DIALOG_CopyMove(LocalLock(program->hName),
239 LocalLock(fromgroup->hName), bMove);
240 if (!hGroup) return;
241
242 /* FIXME shouldn't be necessary */
243 OpenIcon(((PROGGROUP*)LocalLock(hGroup))->hWnd);
244
245 if (!PROGRAM_AddProgram(hGroup,
246 #if 0
247 CopyIcon(program->hIcon),
248 #else
249 program->hIcon,
250 #endif
251 LocalLock(program->hName),
252 program->x, program->y,
253 LocalLock(program->hCmdLine),
254 LocalLock(program->hIconFile),
255 program->nIconIndex,
256 LocalLock(program->hWorkDir),
257 program->nHotKey, program->nCmdShow)) return;
258 GRPFILE_WriteGroupFile(hGroup);
259
260 if (bMove) PROGRAM_DeleteProgram(hProgram, TRUE);
261 }
262
263 /***********************************************************************
264 *
265 * PROGRAM_ExecuteProgram
266 */
267
268 VOID PROGRAM_ExecuteProgram(HLOCAL hProgram)
269 {
270 PROGRAM *program = LocalLock(hProgram);
271 LPSTR lpszCmdLine = LocalLock(program->hCmdLine);
272
273 /* FIXME set working directory from program->hWorkDir */
274
275 WinExec(lpszCmdLine, program->nCmdShow);
276 if (Globals.bMinOnRun) CloseWindow(Globals.hMainWnd);
277 }
278
279 /***********************************************************************
280 *
281 * PROGRAM_DeleteProgram
282 */
283
284 VOID PROGRAM_DeleteProgram(HLOCAL hProgram, BOOL bUpdateGrpFile)
285 {
286 PROGRAM *program = LocalLock(hProgram);
287 PROGGROUP *group = LocalLock(program->hGroup);
288
289 group->hActiveProgram = 0;
290
291 if (program->hPrior)
292 ((PROGRAM*)LocalLock(program->hPrior))->hNext = program->hNext;
293 else
294 ((PROGGROUP*)LocalLock(program->hGroup))->hPrograms = program->hNext;
295
296 if (program->hNext)
297 ((PROGRAM*)LocalLock(program->hNext))->hPrior = program->hPrior;
298
299 if (bUpdateGrpFile)
300 GRPFILE_WriteGroupFile(program->hGroup);
301
302 DestroyWindow(program->hWnd);
303 #if 0
304 if (program->hIcon)
305 DestroyIcon(program->hIcon);
306 #endif
307 LocalFree(program->hName);
308 LocalFree(program->hCmdLine);
309 LocalFree(program->hIconFile);
310 LocalFree(program->hWorkDir);
311 LocalFree(hProgram);
312 }
313
314 /***********************************************************************
315 *
316 * PROGRAM_FirstProgram
317 */
318
319 HLOCAL PROGRAM_FirstProgram(HLOCAL hGroup)
320 {
321 PROGGROUP *group;
322 if (!hGroup) return(0);
323 group = LocalLock(hGroup);
324 return(group->hPrograms);
325 }
326
327 /***********************************************************************
328 *
329 * PROGRAM_NextProgram
330 */
331
332 HLOCAL PROGRAM_NextProgram(HLOCAL hProgram)
333 {
334 PROGRAM *program;
335 if (!hProgram) return(0);
336 program = LocalLock(hProgram);
337 return(program->hNext);
338 }
339
340 /***********************************************************************
341 *
342 * PROGRAM_ActiveProgram
343 */
344
345 HLOCAL PROGRAM_ActiveProgram(HLOCAL hGroup)
346 {
347 PROGGROUP *group;
348 if (!hGroup) return(0);
349 group = LocalLock(hGroup);
350 if (IsIconic(group->hWnd)) return(0);
351
352 return(group->hActiveProgram);
353 }
354
355 /***********************************************************************
356 *
357 * PROGRAM_ProgramName
358 */
359
360 LPCSTR PROGRAM_ProgramName(HLOCAL hProgram)
361 {
362 PROGRAM *program;
363 if (!hProgram) return(0);
364 program = LocalLock(hProgram);
365 return(LocalLock(program->hName));
366 }