[PROGMAN] Properly import from Wine Staging 1.9.4. This fixes PCH usage, marks ReactO...
[reactos.git] / reactos / base / shell / progman / group.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 * GROUP_GroupWndProc
26 */
27
28 static LRESULT CALLBACK GROUP_GroupWndProc(HWND hWnd, UINT msg,
29 WPARAM wParam, LPARAM lParam)
30 {
31 switch (msg)
32 {
33 case WM_SYSCOMMAND:
34 if (wParam == SC_CLOSE) wParam = SC_MINIMIZE;
35 break;
36
37 case WM_CHILDACTIVATE:
38 case WM_NCLBUTTONDOWN:
39 Globals.hActiveGroup = (HLOCAL)GetWindowLongPtrW(hWnd, 0);
40 EnableMenuItem(Globals.hFileMenu, PM_MOVE , MF_GRAYED);
41 EnableMenuItem(Globals.hFileMenu, PM_COPY , MF_GRAYED);
42 break;
43 }
44 return DefMDIChildProcW(hWnd, msg, wParam, lParam);
45 }
46
47 /***********************************************************************
48 *
49 * GROUP_RegisterGroupWinClass
50 */
51
52 ATOM GROUP_RegisterGroupWinClass(void)
53 {
54 WNDCLASSW class;
55
56 class.style = CS_HREDRAW | CS_VREDRAW;
57 class.lpfnWndProc = GROUP_GroupWndProc;
58 class.cbClsExtra = 0;
59 class.cbWndExtra = sizeof(LONG_PTR);
60 class.hInstance = Globals.hInstance;
61 class.hIcon = LoadIconW (0, (LPWSTR)IDI_WINLOGO);
62 class.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW);
63 class.hbrBackground = GetStockObject (WHITE_BRUSH);
64 class.lpszMenuName = 0;
65 class.lpszClassName = STRING_GROUP_WIN_CLASS_NAME;
66
67 return RegisterClassW(&class);
68 }
69
70 /***********************************************************************
71 *
72 * GROUP_NewGroup
73 */
74
75 VOID GROUP_NewGroup(void)
76 {
77 CHAR szName[MAX_PATHNAME_LEN] = "";
78 CHAR szFile[MAX_PATHNAME_LEN] = "";
79 OFSTRUCT dummy;
80
81 if (!DIALOG_GroupAttributes(szName, szFile, MAX_PATHNAME_LEN)) return;
82
83 if (OpenFile(szFile, &dummy, OF_EXIST) == HFILE_ERROR)
84 {
85 /* File doesn't exist */
86 HLOCAL hGroup =
87 GROUP_AddGroup(szName, szFile, SW_SHOWNORMAL,
88 DEF_GROUP_WIN_XPOS, DEF_GROUP_WIN_YPOS,
89 DEF_GROUP_WIN_WIDTH, DEF_GROUP_WIN_HEIGHT, 0, 0,
90 FALSE, FALSE, FALSE);
91 if (!hGroup) return;
92 GRPFILE_WriteGroupFile(hGroup);
93 }
94 else /* File exist */
95 GRPFILE_ReadGroupFile(szFile);
96
97 /* FIXME Update progman.ini */
98 }
99
100 /***********************************************************************
101 *
102 * GROUP_AddGroup
103 */
104
105 HLOCAL GROUP_AddGroup(LPCSTR lpszName, LPCSTR lpszGrpFile, INT nCmdShow,
106 INT x, INT y, INT width, INT height,
107 INT iconx, INT icony,
108 BOOL bFileNameModified, BOOL bOverwriteFileOk,
109 /* FIXME shouldn't be necessary */
110 BOOL bSuppressShowWindow)
111 {
112 PROGGROUP *group, *prior;
113 MDICREATESTRUCTW cs;
114 INT seqnum;
115 HLOCAL hPrior, *p;
116 HLOCAL hGroup = LocalAlloc(LMEM_FIXED, sizeof(PROGGROUP));
117 HLOCAL hName = LocalAlloc(LMEM_FIXED, 1 + strlen(lpszName));
118 HLOCAL hGrpFile = LocalAlloc(LMEM_FIXED, 1 + strlen(lpszGrpFile));
119 if (!hGroup || !hName || !hGrpFile)
120 {
121 MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_OK);
122 if (hGroup) LocalFree(hGroup);
123 if (hName) LocalFree(hName);
124 if (hGrpFile) LocalFree(hGrpFile);
125 return(0);
126 }
127 memcpy(LocalLock(hName), lpszName, 1 + strlen(lpszName));
128 memcpy(LocalLock(hGrpFile), lpszGrpFile, 1 + strlen(lpszGrpFile));
129
130 Globals.hActiveGroup = hGroup;
131
132 seqnum = 1;
133 hPrior = 0;
134 p = &Globals.hGroups;
135 while (*p)
136 {
137 hPrior = *p;
138 prior = LocalLock(hPrior);
139 p = &prior->hNext;
140 if (prior->seqnum >= seqnum)
141 seqnum = prior->seqnum + 1;
142 }
143 *p = hGroup;
144
145 group = LocalLock(hGroup);
146 group->hPrior = hPrior;
147 group->hNext = 0;
148 group->hName = hName;
149 group->hGrpFile = hGrpFile;
150 group->bFileNameModified = bFileNameModified;
151 group->bOverwriteFileOk = bOverwriteFileOk;
152 group->seqnum = seqnum;
153 group->nCmdShow = nCmdShow;
154 group->x = x;
155 group->y = y;
156 group->width = width;
157 group->height = height;
158 group->iconx = iconx;
159 group->icony = icony;
160 group->hPrograms = 0;
161 group->hActiveProgram = 0;
162
163 cs.szClass = STRING_GROUP_WIN_CLASS_NAME;
164 cs.szTitle = NULL;
165 cs.hOwner = 0;
166 cs.x = x;
167 cs.y = y;
168 cs.cx = width;
169 cs.cy = height;
170 cs.style = 0;
171 cs.lParam = 0;
172
173 #ifdef __REACTOS__
174 group->hWnd = (HWND)SendMessageW(Globals.hMDIWnd, WM_MDICREATE, 0, (LPARAM)&cs);
175 #else
176 group->hWnd = (HWND)SendMessageA(Globals.hMDIWnd, WM_MDICREATE, 0, (LPARAM)&cs);
177 #endif
178 SetWindowTextA( group->hWnd, lpszName );
179 SetWindowLongPtrW(group->hWnd, 0, (LONG_PTR) hGroup);
180
181 #if 1
182 if (!bSuppressShowWindow) /* FIXME shouldn't be necessary */
183 #endif
184 {
185 ShowWindow (group->hWnd, nCmdShow);
186 UpdateWindow (group->hWnd);
187 }
188
189 return(hGroup);
190 }
191
192 /***********************************************************************
193 *
194 * GROUP_ModifyGroup
195 */
196
197 VOID GROUP_ModifyGroup(HLOCAL hGroup)
198 {
199 PROGGROUP *group = LocalLock(hGroup);
200 CHAR szName[MAX_PATHNAME_LEN];
201 CHAR szFile[MAX_PATHNAME_LEN];
202 lstrcpynA(szName, LocalLock(group->hName), MAX_PATHNAME_LEN);
203 lstrcpynA(szFile, LocalLock(group->hGrpFile), MAX_PATHNAME_LEN);
204
205 if (!DIALOG_GroupAttributes(szName, szFile, MAX_PATHNAME_LEN)) return;
206
207 if (strcmp(szFile, LocalLock(group->hGrpFile)))
208 group->bOverwriteFileOk = FALSE;
209
210 MAIN_ReplaceString(&group->hName, szName);
211 MAIN_ReplaceString(&group->hGrpFile, szFile);
212
213 GRPFILE_WriteGroupFile(hGroup);
214
215 /* FIXME Delete old GrpFile if GrpFile changed */
216
217 /* FIXME Update progman.ini */
218
219 SetWindowTextA(group->hWnd, szName);
220 }
221
222 /***********************************************************************
223 *
224 * GROUP_ShowGroupWindow
225 */
226
227 /* FIXME shouldn't be necessary */
228 VOID GROUP_ShowGroupWindow(HLOCAL hGroup)
229 {
230 PROGGROUP *group = LocalLock(hGroup);
231 ShowWindow (group->hWnd, group->nCmdShow);
232 UpdateWindow (group->hWnd);
233 }
234
235 /***********************************************************************
236 *
237 * GROUP_DeleteGroup
238 */
239
240 VOID GROUP_DeleteGroup(HLOCAL hGroup)
241 {
242 PROGGROUP *group = LocalLock(hGroup);
243
244 Globals.hActiveGroup = 0;
245
246 if (group->hPrior)
247 ((PROGGROUP*)LocalLock(group->hPrior))->hNext = group->hNext;
248 else Globals.hGroups = group->hNext;
249
250 if (group->hNext)
251 ((PROGGROUP*)LocalLock(group->hNext))->hPrior = group->hPrior;
252
253 while (group->hPrograms)
254 PROGRAM_DeleteProgram(group->hPrograms, FALSE);
255
256 /* FIXME Update progman.ini */
257
258 SendMessageW(Globals.hMDIWnd, WM_MDIDESTROY, (WPARAM)group->hWnd, 0);
259
260 LocalFree(group->hName);
261 LocalFree(group->hGrpFile);
262 LocalFree(hGroup);
263 }
264
265 /***********************************************************************
266 *
267 * GROUP_FirstGroup
268 */
269
270 HLOCAL GROUP_FirstGroup(void)
271 {
272 return(Globals.hGroups);
273 }
274
275 /***********************************************************************
276 *
277 * GROUP_NextGroup
278 */
279
280 HLOCAL GROUP_NextGroup(HLOCAL hGroup)
281 {
282 PROGGROUP *group;
283 if (!hGroup) return(0);
284 group = LocalLock(hGroup);
285 return(group->hNext);
286 }
287
288 /***********************************************************************
289 *
290 * GROUP_ActiveGroup
291 */
292
293 HLOCAL GROUP_ActiveGroup(void)
294 {
295 return(Globals.hActiveGroup);
296 }
297
298 /***********************************************************************
299 *
300 * GROUP_GroupWnd
301 */
302
303 HWND GROUP_GroupWnd(HLOCAL hGroup)
304 {
305 PROGGROUP *group;
306 if (!hGroup) return(0);
307 group = LocalLock(hGroup);
308 return(group->hWnd);
309 }
310
311 /***********************************************************************
312 *
313 * GROUP_GroupName
314 */
315
316 LPCSTR GROUP_GroupName(HLOCAL hGroup)
317 {
318 PROGGROUP *group;
319 if (!hGroup) return(0);
320 group = LocalLock(hGroup);
321 return(LocalLock(group->hName));
322 }