xref: /reactos/base/shell/progman/program.c (revision 1734f297)
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 }
337