4 * Copyright 1996 Ulrich Schmid
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.
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.
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
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)
34 static LRESULT CALLBACK
PROGRAM_ProgramWndProc(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
38 case WM_NCLBUTTONDOWN
:
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
);
48 case WM_NCLBUTTONDBLCLK
:
50 PROGRAM_ExecuteProgram((HLOCAL
) GetWindowLongPtrW(hWnd
, 0));
60 hdc
= BeginPaint(hWnd
,&ps
);
61 program
= LocalLock((HLOCAL
) GetWindowLongPtrW(hWnd
, 0));
63 DrawIcon(hdc
, 0, 0, program
->hIcon
);
68 return DefWindowProcW(hWnd
, msg
, wParam
, lParam
);
75 /***********************************************************************
80 VOID
PROGRAM_NewProgram(PROGGROUP
* hGroup
)
85 INT nCmdShow
= SW_SHOWNORMAL
;
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
"";
92 if (!DIALOG_ProgramAttributes(szTitle
, szCmdLine
, szWorkDir
, szIconFile
,
93 &hIcon
, &nIconIndex
, &nHotKey
, &nCmdShow
, &bNewVDM
,
100 hIcon
= LoadIconW(NULL
, MAKEINTRESOURCEW(IDI_WINLOGO
));
102 if (!PROGRAM_AddProgram(hGroup
, hIcon
, szTitle
, -1, -1, szCmdLine
, szIconFile
,
103 nIconIndex
, szWorkDir
, nHotKey
, nCmdShow
, bNewVDM
))
108 GRPFILE_WriteGroupFile(hGroup
);
111 /***********************************************************************
113 * PROGRAM_ModifyProgram
116 VOID
PROGRAM_ModifyProgram(PROGRAM
* hProgram
)
119 WCHAR szName
[MAX_PATHNAME_LEN
];
120 WCHAR szWorkDir
[MAX_PATHNAME_LEN
];
121 WCHAR szCmdLine
[MAX_PATHNAME_LEN
];
122 WCHAR szIconFile
[MAX_PATHNAME_LEN
];
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
));
129 if (!DIALOG_ProgramAttributes(szName
, szCmdLine
, szWorkDir
, szIconFile
,
130 &hProgram
->hIcon
, &hProgram
->nIconIndex
,
131 &hProgram
->nHotKey
, &hProgram
->nCmdShow
,
132 &hProgram
->bNewVDM
, MAX_PATHNAME_LEN
))
137 MAIN_ReplaceString(&hProgram
->hName
, szName
);
138 MAIN_ReplaceString(&hProgram
->hCmdLine
, szCmdLine
);
139 MAIN_ReplaceString(&hProgram
->hIconFile
, szIconFile
);
140 MAIN_ReplaceString(&hProgram
->hWorkDir
, szWorkDir
);
142 ZeroMemory(&lvItem
, sizeof(lvItem
));
143 lvItem
.mask
= LVIF_TEXT
;
145 lvItem
.pszText
= szName
;
146 SendMessageW(hProgram
->hGroup
->hListView
, LVM_SETITEMTEXTW
, hProgram
->iItem
, (LPARAM
)&lvItem
);
148 GRPFILE_WriteGroupFile(hProgram
->hGroup
);
151 /***********************************************************************
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
)
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
)
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
);
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
));
191 hGroup
->hActiveProgram
= hProgram
;
194 for (p
= &hGroup
->hPrograms
; *p
; p
= &hPrior
->hNext
)
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
;
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
);
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
));
231 /***********************************************************************
233 * PROGRAM_CopyMoveProgram
236 VOID
PROGRAM_CopyMoveProgram(PROGRAM
* hProgram
, BOOL bMove
)
240 hGroup
= DIALOG_CopyMove(hProgram
, bMove
);
244 /* FIXME: shouldn't be necessary */
245 OpenIcon(hGroup
->hWnd
);
247 if (!PROGRAM_AddProgram(hGroup
,
254 hProgram
->nIconIndex
,
263 GRPFILE_WriteGroupFile(hGroup
);
266 PROGRAM_DeleteProgram(hProgram
, TRUE
);
269 /***********************************************************************
271 * PROGRAM_ExecuteProgram
274 VOID
PROGRAM_ExecuteProgram(PROGRAM
* hProgram
)
276 // TODO: Use a (private?) shell API with which one can use hProgram->bNewVDM
278 ShellExecuteW(NULL
, NULL
, hProgram
->hCmdLine
, NULL
, hProgram
->hWorkDir
, hProgram
->nCmdShow
);
280 if (Globals
.bMinOnRun
)
281 CloseWindow(Globals
.hMainWnd
);
284 /***********************************************************************
286 * PROGRAM_DeleteProgram
289 VOID
PROGRAM_DeleteProgram(PROGRAM
* hProgram
, BOOL bUpdateGrpFile
)
293 group
= hProgram
->hGroup
;
294 if (hProgram
->hGroup
->hActiveProgram
== hProgram
)
295 group
->hActiveProgram
= NULL
;
297 SendMessageA(group
->hListView
, LVM_DELETEITEM
, hProgram
->iItem
, 0);
299 if (hProgram
->hPrior
)
300 hProgram
->hPrior
->hNext
= hProgram
->hNext
;
302 hProgram
->hGroup
->hPrograms
= hProgram
->hNext
;
305 hProgram
->hNext
->hPrior
= hProgram
->hPrior
;
308 GRPFILE_WriteGroupFile(hProgram
->hGroup
);
311 DestroyWindow(program
->hWnd
);
313 DestroyIcon(program
->hIcon
);
317 Free(hProgram
->Tags
);
318 Free(hProgram
->hName
);
319 Free(hProgram
->hCmdLine
);
320 Free(hProgram
->hIconFile
);
321 Free(hProgram
->hWorkDir
);
326 /***********************************************************************
328 * PROGRAM_ActiveProgram
331 PROGRAM
* PROGRAM_ActiveProgram(PROGGROUP
* hGroup
)
333 if (!hGroup
) return NULL
;
334 if (IsIconic(hGroup
->hWnd
)) return NULL
;
335 return hGroup
->hActiveProgram
;