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