kernel32: Correctly parse the input strings for advanced keys.
[wine/multimedia.git] / programs / progman / main.c
blobd76a079034e96fc69275826da6babd833ea3230a
1 /*
2 * Program Manager
4 * Copyright 1996 Ulrich Schmid
5 * Copyright 2002 Sylvain Petreolle
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdio.h>
23 #include <string.h>
25 #define OEMRESOURCE
27 #include "windows.h"
28 #include "progman.h"
30 GLOBALS Globals;
32 static VOID MAIN_CreateGroups(void);
33 static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
34 static ATOM MAIN_RegisterMainWinClass(void);
35 static VOID MAIN_CreateMainWindow(void);
36 static VOID MAIN_CreateMDIWindow(void);
37 static VOID MAIN_AutoStart(void);
39 #define BUFFER_SIZE 1000
41 /***********************************************************************
43 * WinMain
46 int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
48 MSG msg;
50 Globals.lpszIniFile = "progman.ini";
51 Globals.lpszIcoFile = "progman.ico";
53 Globals.hInstance = hInstance;
54 Globals.hGroups = 0;
55 Globals.hActiveGroup = 0;
57 /* Read Options from `progman.ini' */
58 Globals.bAutoArrange =
59 GetPrivateProfileInt("Settings", "AutoArrange", 0, Globals.lpszIniFile);
60 Globals.bMinOnRun =
61 GetPrivateProfileInt("Settings", "MinOnRun", 0, Globals.lpszIniFile);
62 Globals.bSaveSettings =
63 GetPrivateProfileInt("Settings", "SaveSettings", 0, Globals.lpszIniFile);
65 /* Load default icons */
66 Globals.hMainIcon = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
67 Globals.hGroupIcon = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
68 Globals.hDefaultIcon = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
69 if (!Globals.hMainIcon) Globals.hMainIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
70 if (!Globals.hGroupIcon) Globals.hGroupIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
71 if (!Globals.hDefaultIcon) Globals.hDefaultIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
73 /* Register classes */
74 if (!prev)
76 if (!MAIN_RegisterMainWinClass()) return(FALSE);
77 if (!GROUP_RegisterGroupWinClass()) return(FALSE);
78 if (!PROGRAM_RegisterProgramWinClass()) return(FALSE);
81 /* Create main window */
82 MAIN_CreateMainWindow();
83 Globals.hAccel = LoadAccelerators(Globals.hInstance, STRING_ACCEL);
85 /* Setup menu, stringtable and resourcenames */
86 STRING_LoadMenus();
88 MAIN_CreateMDIWindow();
90 /* Initialize groups */
91 MAIN_CreateGroups();
93 /* Start initial applications */
94 MAIN_AutoStart();
96 /* Message loop */
97 while (GetMessage (&msg, 0, 0, 0))
98 if (!TranslateAccelerator(Globals.hMainWnd, Globals.hAccel, &msg))
100 TranslateMessage (&msg);
101 DispatchMessage (&msg);
103 return 0;
106 /***********************************************************************
108 * MAIN_CreateGroups
111 static VOID MAIN_CreateGroups(void)
113 CHAR buffer[BUFFER_SIZE];
114 CHAR szPath[MAX_PATHNAME_LEN];
115 CHAR key[20], *ptr;
117 /* Initialize groups according the `Order' entry of `progman.ini' */
118 GetPrivateProfileString("Settings", "Order", "", buffer, sizeof(buffer), Globals.lpszIniFile);
119 ptr = buffer;
120 while (ptr < buffer + sizeof(buffer))
122 int num, skip, ret;
123 ret = sscanf(ptr, "%d%n", &num, &skip);
124 if (ret == 0)
125 MAIN_MessageBoxIDS_s(IDS_FILE_READ_ERROR_s, Globals.lpszIniFile, IDS_ERROR, MB_OK);
126 if (ret != 1) break;
128 sprintf(key, "Group%d", num);
129 GetPrivateProfileString("Groups", key, "", szPath,
130 sizeof(szPath), Globals.lpszIniFile);
131 if (!szPath[0]) continue;
133 GRPFILE_ReadGroupFile(szPath);
135 ptr += skip;
137 /* FIXME initialize other groups, not enumerated by `Order' */
140 /***********************************************************************
142 * MAIN_AutoStart
145 VOID MAIN_AutoStart(void)
147 CHAR buffer[BUFFER_SIZE];
148 HLOCAL hGroup, hProgram;
150 GetPrivateProfileString("Settings", "AutoStart", "Autostart", buffer,
151 sizeof(buffer), Globals.lpszIniFile);
153 for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
154 if (!lstrcmp(buffer, GROUP_GroupName(hGroup)))
155 for (hProgram = PROGRAM_FirstProgram(hGroup); hProgram;
156 hProgram = PROGRAM_NextProgram(hProgram))
157 PROGRAM_ExecuteProgram(hProgram);
160 /***********************************************************************
162 * MAIN_MainWndProc
165 static LRESULT CALLBACK MAIN_MainWndProc(HWND hWnd, UINT msg,
166 WPARAM wParam, LPARAM lParam)
168 #if 0
169 printf("M %4.4x %4.4x\n", msg, wParam);
170 #endif
171 switch (msg)
173 case WM_INITMENU:
174 CheckMenuItem(Globals.hOptionMenu, PM_AUTO_ARRANGE,
175 MF_BYCOMMAND | (Globals.bAutoArrange ? MF_CHECKED : MF_UNCHECKED));
176 CheckMenuItem(Globals.hOptionMenu, PM_MIN_ON_RUN,
177 MF_BYCOMMAND | (Globals.bMinOnRun ? MF_CHECKED : MF_UNCHECKED));
178 CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
179 MF_BYCOMMAND | (Globals.bSaveSettings ? MF_CHECKED : MF_UNCHECKED));
180 break;
182 case WM_COMMAND:
183 if (wParam < PM_FIRST_CHILD){
184 MAIN_MenuCommand(hWnd, wParam, lParam);
186 break;
188 case WM_DESTROY:
189 PostQuitMessage (0);
190 break;
192 return(DefFrameProc(hWnd, Globals.hMDIWnd, msg, wParam, lParam));
195 /***********************************************************************
197 * MAIN_MenuCommand
200 static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
202 HLOCAL hActiveGroup = GROUP_ActiveGroup();
203 HLOCAL hActiveProgram = PROGRAM_ActiveProgram(hActiveGroup);
204 HWND hActiveGroupWnd = GROUP_GroupWnd(hActiveGroup);
206 switch(wParam)
208 /* Menu File */
209 case PM_NEW:
210 switch (DIALOG_New((hActiveGroupWnd && !IsIconic(hActiveGroupWnd)) ?
211 PM_NEW_PROGRAM : PM_NEW_GROUP))
213 case PM_NEW_PROGRAM:
214 if (hActiveGroup) PROGRAM_NewProgram(hActiveGroup);
215 break;
217 case PM_NEW_GROUP:
218 GROUP_NewGroup();
219 break;
221 break;
223 case PM_OPEN:
224 if (hActiveProgram)
225 PROGRAM_ExecuteProgram(hActiveProgram);
226 else if (hActiveGroupWnd)
227 OpenIcon(hActiveGroupWnd);
228 break;
230 case PM_MOVE:
231 case PM_COPY:
232 if (hActiveProgram)
233 PROGRAM_CopyMoveProgram(hActiveProgram, wParam == PM_MOVE);
234 break;
236 case PM_DELETE:
237 if (hActiveProgram)
239 if (DIALOG_Delete(IDS_DELETE_PROGRAM_s, PROGRAM_ProgramName(hActiveProgram)))
240 PROGRAM_DeleteProgram(hActiveProgram, TRUE);
242 else if (hActiveGroup)
244 if (DIALOG_Delete(IDS_DELETE_GROUP_s, GROUP_GroupName(hActiveGroup)))
245 GROUP_DeleteGroup(hActiveGroup);
247 break;
249 case PM_ATTRIBUTES:
250 if (hActiveProgram)
251 PROGRAM_ModifyProgram(hActiveProgram);
252 else if (hActiveGroup)
253 GROUP_ModifyGroup(hActiveGroup);
254 break;
256 case PM_EXECUTE:
257 DIALOG_Execute();
258 break;
260 case PM_EXIT:
261 PostQuitMessage(0);
262 break;
264 /* Menu Options */
265 case PM_AUTO_ARRANGE:
266 Globals.bAutoArrange = !Globals.bAutoArrange;
267 CheckMenuItem(Globals.hOptionMenu, PM_AUTO_ARRANGE,
268 MF_BYCOMMAND | (Globals.bAutoArrange ?
269 MF_CHECKED : MF_UNCHECKED));
270 WritePrivateProfileString("Settings", "AutoArrange",
271 Globals.bAutoArrange ? "1" : "0",
272 Globals.lpszIniFile);
273 WritePrivateProfileString(NULL,NULL,NULL,Globals.lpszIniFile); /* flush it */
274 break;
276 case PM_MIN_ON_RUN:
277 Globals.bMinOnRun = !Globals.bMinOnRun;
278 CheckMenuItem(Globals.hOptionMenu, PM_MIN_ON_RUN,
279 MF_BYCOMMAND | (Globals.bMinOnRun ?
280 MF_CHECKED : MF_UNCHECKED));
281 WritePrivateProfileString("Settings", "MinOnRun",
282 Globals.bMinOnRun ? "1" : "0",
283 Globals.lpszIniFile);
284 WritePrivateProfileString(NULL,NULL,NULL,Globals.lpszIniFile); /* flush it */
285 break;
287 case PM_SAVE_SETTINGS:
288 Globals.bSaveSettings = !Globals.bSaveSettings;
289 CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
290 MF_BYCOMMAND | (Globals.bSaveSettings ?
291 MF_CHECKED : MF_UNCHECKED));
292 WritePrivateProfileString("Settings", "SaveSettings",
293 Globals.bSaveSettings ? "1" : "0",
294 Globals.lpszIniFile);
295 WritePrivateProfileString(NULL,NULL,NULL,Globals.lpszIniFile); /* flush it */
296 break;
298 /* Menu Windows */
299 case PM_ARRANGE:
301 if (hActiveGroupWnd && !IsIconic(hActiveGroupWnd))
302 ArrangeIconicWindows(hActiveGroupWnd);
303 else
304 SendMessage(Globals.hMDIWnd, WM_MDIICONARRANGE, 0, 0);
305 break;
307 /* Menu Help */
308 case PM_CONTENTS:
309 if (!WinHelp(Globals.hMainWnd, "progman.hlp", HELP_CONTENTS, 0))
310 MAIN_MessageBoxIDS(IDS_WINHELP_ERROR, IDS_ERROR, MB_OK);
311 break;
313 case PM_HELPONHELP:
314 if (!WinHelp(Globals.hMainWnd, "progman.hlp", HELP_HELPONHELP, 0))
315 MAIN_MessageBoxIDS(IDS_WINHELP_ERROR, IDS_ERROR, MB_OK);
316 break;
318 case PM_TUTORIAL:
319 WinExec("wintutor.exe", SW_SHOWNORMAL);
320 break;
322 case PM_ABOUT_WINE:
323 ShellAbout(hWnd, "WINE", "Program Manager", 0);
324 break;
326 default:
327 MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK);
328 break;
332 /***********************************************************************
334 * MAIN_RegisterMainWinClass
337 static ATOM MAIN_RegisterMainWinClass(void)
339 WNDCLASS class;
341 class.style = CS_HREDRAW | CS_VREDRAW;
342 class.lpfnWndProc = MAIN_MainWndProc;
343 class.cbClsExtra = 0;
344 class.cbWndExtra = 0;
345 class.hInstance = Globals.hInstance;
346 class.hIcon = Globals.hMainIcon;
347 class.hCursor = LoadCursor (0, IDC_ARROW);
348 class.hbrBackground = GetStockObject (NULL_BRUSH);
349 class.lpszMenuName = 0;
350 class.lpszClassName = STRING_MAIN_WIN_CLASS_NAME;
352 return RegisterClass(&class);
355 /***********************************************************************
357 * MAIN_CreateMainWindow
360 static VOID MAIN_CreateMainWindow(void)
362 INT left , top, right, bottom, width, height, show;
363 CHAR buffer[100];
365 Globals.hMDIWnd = 0;
366 Globals.hMainMenu = 0;
368 /* Get the geometry of the main window */
369 GetPrivateProfileString("Settings", "Window", "",
370 buffer, sizeof(buffer), Globals.lpszIniFile);
371 if (5 == sscanf(buffer, "%d %d %d %d %d", &left, &top, &right, &bottom, &show))
373 width = right - left;
374 height = bottom - top;
376 else
378 left = top = width = height = CW_USEDEFAULT;
379 show = SW_SHOWNORMAL;
382 /* Create main Window */
383 Globals.hMainWnd =
384 CreateWindow (STRING_MAIN_WIN_CLASS_NAME, "",
385 WS_OVERLAPPEDWINDOW, left, top, width, height,
386 0, 0, Globals.hInstance, 0);
388 ShowWindow (Globals.hMainWnd, show);
389 UpdateWindow (Globals.hMainWnd);
392 /***********************************************************************
394 * MAIN_CreateMDIWindow
397 static VOID MAIN_CreateMDIWindow(void)
399 CLIENTCREATESTRUCT ccs;
400 RECT rect;
402 /* Get the geometry of the MDI window */
403 GetClientRect(Globals.hMainWnd, &rect);
405 ccs.hWindowMenu = Globals.hWindowsMenu;
406 ccs.idFirstChild = PM_FIRST_CHILD;
408 /* Create MDI Window */
409 Globals.hMDIWnd =
410 CreateWindow (STRING_MDI_WIN_CLASS_NAME, "",
411 WS_CHILD, rect.left, rect.top,
412 rect.right - rect.left, rect.bottom - rect.top,
413 Globals.hMainWnd, 0,
414 Globals.hInstance, &ccs);
416 ShowWindow (Globals.hMDIWnd, SW_SHOW);
417 UpdateWindow (Globals.hMDIWnd);
420 /**********************************************************************/
421 /***********************************************************************
423 * MAIN_MessageBoxIDS
425 INT MAIN_MessageBoxIDS(UINT ids_text, UINT ids_title, WORD type)
427 CHAR text[MAX_STRING_LEN];
428 CHAR title[MAX_STRING_LEN];
430 LoadString(Globals.hInstance, ids_text, text, sizeof(text));
431 LoadString(Globals.hInstance, ids_title, title, sizeof(title));
433 return(MessageBox(Globals.hMainWnd, text, title, type));
436 /***********************************************************************
438 * MAIN_MessageBoxIDS_s
440 INT MAIN_MessageBoxIDS_s(UINT ids_text, LPCSTR str, UINT ids_title, WORD type)
442 CHAR text[MAX_STRING_LEN];
443 CHAR title[MAX_STRING_LEN];
444 CHAR newtext[MAX_STRING_LEN + MAX_PATHNAME_LEN];
446 LoadString(Globals.hInstance, ids_text, text, sizeof(text));
447 LoadString(Globals.hInstance, ids_title, title, sizeof(title));
448 wsprintf(newtext, text, str);
450 return(MessageBox(Globals.hMainWnd, newtext, title, type));
453 /***********************************************************************
455 * MAIN_ReplaceString
458 VOID MAIN_ReplaceString(HLOCAL *handle, LPSTR replace)
460 HLOCAL newhandle = LocalAlloc(LMEM_FIXED, strlen(replace) + 1);
461 if (newhandle)
463 LPSTR newstring = LocalLock(newhandle);
464 lstrcpy(newstring, replace);
465 LocalFree(*handle);
466 *handle = newhandle;
468 else MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_OK);
471 /* Local Variables: */
472 /* c-file-style: "GNU" */
473 /* End: */