Release 20050419.
[wine.git] / programs / progman / main.c
blob3476bdd369c0218a78c77992295bcb8a04135a2d
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <stdio.h>
23 #include <string.h>
24 #include "windows.h"
25 #include "windowsx.h"
26 #include "license.h"
27 #include "progman.h"
29 GLOBALS Globals;
31 static VOID MAIN_CreateGroups(void);
32 static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
33 static ATOM MAIN_RegisterMainWinClass(void);
34 static VOID MAIN_CreateMainWindow(void);
35 static VOID MAIN_CreateMDIWindow(void);
36 static VOID MAIN_AutoStart(void);
38 #define BUFFER_SIZE 1000
40 /***********************************************************************
42 * WinMain
45 int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
47 MSG msg;
49 Globals.lpszIniFile = "progman.ini";
50 Globals.lpszIcoFile = "progman.ico";
52 Globals.hInstance = hInstance;
53 Globals.hGroups = 0;
54 Globals.hActiveGroup = 0;
56 /* Read Options from `progman.ini' */
57 Globals.bAutoArrange =
58 GetPrivateProfileInt("Settings", "AutoArrange", 0, Globals.lpszIniFile);
59 Globals.bMinOnRun =
60 GetPrivateProfileInt("Settings", "MinOnRun", 0, Globals.lpszIniFile);
61 Globals.bSaveSettings =
62 GetPrivateProfileInt("Settings", "SaveSettings", 0, Globals.lpszIniFile);
64 /* Load default icons */
65 Globals.hMainIcon = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
66 Globals.hGroupIcon = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
67 Globals.hDefaultIcon = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
68 if (!Globals.hMainIcon) Globals.hMainIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
69 if (!Globals.hGroupIcon) Globals.hGroupIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
70 if (!Globals.hDefaultIcon) Globals.hDefaultIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
72 /* Register classes */
73 if (!prev)
75 if (!MAIN_RegisterMainWinClass()) return(FALSE);
76 if (!GROUP_RegisterGroupWinClass()) return(FALSE);
77 if (!PROGRAM_RegisterProgramWinClass()) return(FALSE);
80 /* Create main window */
81 MAIN_CreateMainWindow();
82 Globals.hAccel = LoadAccelerators(Globals.hInstance, STRING_ACCEL);
84 /* Setup menu, stringtable and resourcenames */
85 STRING_LoadMenus();
87 MAIN_CreateMDIWindow();
89 /* Initialize groups */
90 MAIN_CreateGroups();
92 /* Start initial applications */
93 MAIN_AutoStart();
95 /* Message loop */
96 while (GetMessage (&msg, 0, 0, 0))
97 if (!TranslateAccelerator(Globals.hMainWnd, Globals.hAccel, &msg))
99 TranslateMessage (&msg);
100 DispatchMessage (&msg);
102 return 0;
105 /***********************************************************************
107 * MAIN_CreateGroups
110 static VOID MAIN_CreateGroups()
112 CHAR buffer[BUFFER_SIZE];
113 CHAR szPath[MAX_PATHNAME_LEN];
114 CHAR key[20], *ptr;
116 /* Initialize groups according the `Order' entry of `progman.ini' */
117 GetPrivateProfileString("Settings", "Order", "", buffer, sizeof(buffer), Globals.lpszIniFile);
118 ptr = buffer;
119 while (ptr < buffer + sizeof(buffer))
121 int num, skip, ret;
122 ret = sscanf(ptr, "%d%n", &num, &skip);
123 if (ret == 0)
124 MAIN_MessageBoxIDS_s(IDS_FILE_READ_ERROR_s, Globals.lpszIniFile, IDS_ERROR, MB_OK);
125 if (ret != 1) break;
127 sprintf(key, "Group%d", num);
128 GetPrivateProfileString("Groups", key, "", szPath,
129 sizeof(szPath), Globals.lpszIniFile);
130 if (!szPath[0]) continue;
132 GRPFILE_ReadGroupFile(szPath);
134 ptr += skip;
136 /* FIXME initialize other groups, not enumerated by `Order' */
139 /***********************************************************************
141 * MAIN_AutoStart
144 VOID MAIN_AutoStart()
146 CHAR buffer[BUFFER_SIZE];
147 HLOCAL hGroup, hProgram;
149 GetPrivateProfileString("Settings", "AutoStart", "Autostart", buffer,
150 sizeof(buffer), Globals.lpszIniFile);
152 for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
153 if (!lstrcmp(buffer, GROUP_GroupName(hGroup)))
154 for (hProgram = PROGRAM_FirstProgram(hGroup); hProgram;
155 hProgram = PROGRAM_NextProgram(hProgram))
156 PROGRAM_ExecuteProgram(hProgram);
159 /***********************************************************************
161 * MAIN_MainWndProc
164 static LRESULT CALLBACK MAIN_MainWndProc(HWND hWnd, UINT msg,
165 WPARAM wParam, LPARAM lParam)
167 #if 0
168 printf("M %4.4x %4.4x\n", msg, wParam);
169 #endif
170 switch (msg)
172 case WM_INITMENU:
173 CheckMenuItem(Globals.hOptionMenu, PM_AUTO_ARRANGE,
174 MF_BYCOMMAND | (Globals.bAutoArrange ? MF_CHECKED : MF_UNCHECKED));
175 CheckMenuItem(Globals.hOptionMenu, PM_MIN_ON_RUN,
176 MF_BYCOMMAND | (Globals.bMinOnRun ? MF_CHECKED : MF_UNCHECKED));
177 CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
178 MF_BYCOMMAND | (Globals.bSaveSettings ? MF_CHECKED : MF_UNCHECKED));
179 break;
181 case WM_COMMAND:
182 if (wParam < PM_FIRST_CHILD){
183 MAIN_MenuCommand(hWnd, wParam, lParam);
185 break;
187 case WM_DESTROY:
188 PostQuitMessage (0);
189 break;
191 return(DefFrameProc(hWnd, Globals.hMDIWnd, msg, wParam, lParam));
194 /***********************************************************************
196 * MAIN_MenuCommand
199 static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
201 HLOCAL hActiveGroup = GROUP_ActiveGroup();
202 HLOCAL hActiveProgram = PROGRAM_ActiveProgram(hActiveGroup);
203 HWND hActiveGroupWnd = GROUP_GroupWnd(hActiveGroup);
205 switch(wParam)
207 /* Menu File */
208 case PM_NEW:
209 switch (DIALOG_New((hActiveGroupWnd && !IsIconic(hActiveGroupWnd)) ?
210 PM_NEW_PROGRAM : PM_NEW_GROUP))
212 case PM_NEW_PROGRAM:
213 if (hActiveGroup) PROGRAM_NewProgram(hActiveGroup);
214 break;
216 case PM_NEW_GROUP:
217 GROUP_NewGroup();
218 break;
220 break;
222 case PM_OPEN:
223 if (hActiveProgram)
224 PROGRAM_ExecuteProgram(hActiveProgram);
225 else if (hActiveGroupWnd)
226 OpenIcon(hActiveGroupWnd);
227 break;
229 case PM_MOVE:
230 case PM_COPY:
231 if (hActiveProgram)
232 PROGRAM_CopyMoveProgram(hActiveProgram, wParam == PM_MOVE);
233 break;
235 case PM_DELETE:
236 if (hActiveProgram)
238 if (DIALOG_Delete(IDS_DELETE_PROGRAM_s, PROGRAM_ProgramName(hActiveProgram)))
239 PROGRAM_DeleteProgram(hActiveProgram, TRUE);
241 else if (hActiveGroup)
243 if (DIALOG_Delete(IDS_DELETE_GROUP_s, GROUP_GroupName(hActiveGroup)))
244 GROUP_DeleteGroup(hActiveGroup);
246 break;
248 case PM_ATTRIBUTES:
249 if (hActiveProgram)
250 PROGRAM_ModifyProgram(hActiveProgram);
251 else if (hActiveGroup)
252 GROUP_ModifyGroup(hActiveGroup);
253 break;
255 case PM_EXECUTE:
256 DIALOG_Execute();
257 break;
259 case PM_EXIT:
260 PostQuitMessage(0);
261 break;
263 /* Menu Options */
264 case PM_AUTO_ARRANGE:
265 Globals.bAutoArrange = !Globals.bAutoArrange;
266 CheckMenuItem(Globals.hOptionMenu, PM_AUTO_ARRANGE,
267 MF_BYCOMMAND | (Globals.bAutoArrange ?
268 MF_CHECKED : MF_UNCHECKED));
269 WritePrivateProfileString("Settings", "AutoArrange",
270 Globals.bAutoArrange ? "1" : "0",
271 Globals.lpszIniFile);
272 WritePrivateProfileString(NULL,NULL,NULL,Globals.lpszIniFile); /* flush it */
273 break;
275 case PM_MIN_ON_RUN:
276 Globals.bMinOnRun = !Globals.bMinOnRun;
277 CheckMenuItem(Globals.hOptionMenu, PM_MIN_ON_RUN,
278 MF_BYCOMMAND | (Globals.bMinOnRun ?
279 MF_CHECKED : MF_UNCHECKED));
280 WritePrivateProfileString("Settings", "MinOnRun",
281 Globals.bMinOnRun ? "1" : "0",
282 Globals.lpszIniFile);
283 WritePrivateProfileString(NULL,NULL,NULL,Globals.lpszIniFile); /* flush it */
284 break;
286 case PM_SAVE_SETTINGS:
287 Globals.bSaveSettings = !Globals.bSaveSettings;
288 CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
289 MF_BYCOMMAND | (Globals.bSaveSettings ?
290 MF_CHECKED : MF_UNCHECKED));
291 WritePrivateProfileString("Settings", "SaveSettings",
292 Globals.bSaveSettings ? "1" : "0",
293 Globals.lpszIniFile);
294 WritePrivateProfileString(NULL,NULL,NULL,Globals.lpszIniFile); /* flush it */
295 break;
297 /* Menu Windows */
298 case PM_ARRANGE:
300 if (hActiveGroupWnd && !IsIconic(hActiveGroupWnd))
301 ArrangeIconicWindows(hActiveGroupWnd);
302 else
303 SendMessage(Globals.hMDIWnd, WM_MDIICONARRANGE, 0, 0);
304 break;
306 /* Menu Help */
307 case PM_CONTENTS:
308 if (!WinHelp(Globals.hMainWnd, "progman.hlp", HELP_CONTENTS, 0))
309 MAIN_MessageBoxIDS(IDS_WINHELP_ERROR, IDS_ERROR, MB_OK);
310 break;
312 case PM_HELPONHELP:
313 if (!WinHelp(Globals.hMainWnd, "progman.hlp", HELP_HELPONHELP, 0))
314 MAIN_MessageBoxIDS(IDS_WINHELP_ERROR, IDS_ERROR, MB_OK);
315 break;
317 case PM_TUTORIAL:
318 WinExec("wintutor.exe", SW_SHOWNORMAL);
319 break;
321 case PM_LICENSE:
322 WineLicense(Globals.hMainWnd);
323 break;
325 case PM_NO_WARRANTY:
326 WineWarranty(Globals.hMainWnd);
327 break;
329 case PM_ABOUT_WINE:
330 ShellAbout(hWnd, "WINE", "Program Manager", 0);
331 break;
333 default:
334 MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK);
335 break;
339 /***********************************************************************
341 * MAIN_RegisterMainWinClass
344 static ATOM MAIN_RegisterMainWinClass()
346 WNDCLASS class;
348 class.style = CS_HREDRAW | CS_VREDRAW;
349 class.lpfnWndProc = MAIN_MainWndProc;
350 class.cbClsExtra = 0;
351 class.cbWndExtra = 0;
352 class.hInstance = Globals.hInstance;
353 class.hIcon = Globals.hMainIcon;
354 class.hCursor = LoadCursor (0, IDC_ARROW);
355 class.hbrBackground = GetStockObject (NULL_BRUSH);
356 class.lpszMenuName = 0;
357 class.lpszClassName = STRING_MAIN_WIN_CLASS_NAME;
359 return RegisterClass(&class);
362 /***********************************************************************
364 * MAIN_CreateMainWindow
367 static VOID MAIN_CreateMainWindow()
369 INT left , top, right, bottom, width, height, show;
370 CHAR buffer[100];
372 Globals.hMDIWnd = 0;
373 Globals.hMainMenu = 0;
375 /* Get the geometry of the main window */
376 GetPrivateProfileString("Settings", "Window", "",
377 buffer, sizeof(buffer), Globals.lpszIniFile);
378 if (5 == sscanf(buffer, "%d %d %d %d %d", &left, &top, &right, &bottom, &show))
380 width = right - left;
381 height = bottom - top;
383 else
385 left = top = width = height = CW_USEDEFAULT;
386 show = SW_SHOWNORMAL;
389 /* Create main Window */
390 Globals.hMainWnd =
391 CreateWindow (STRING_MAIN_WIN_CLASS_NAME, "",
392 WS_OVERLAPPEDWINDOW, left, top, width, height,
393 0, 0, Globals.hInstance, 0);
395 ShowWindow (Globals.hMainWnd, show);
396 UpdateWindow (Globals.hMainWnd);
399 /***********************************************************************
401 * MAIN_CreateMDIWindow
404 static VOID MAIN_CreateMDIWindow()
406 CLIENTCREATESTRUCT ccs;
407 RECT rect;
409 /* Get the geometry of the MDI window */
410 GetClientRect(Globals.hMainWnd, &rect);
412 ccs.hWindowMenu = Globals.hWindowsMenu;
413 ccs.idFirstChild = PM_FIRST_CHILD;
415 /* Create MDI Window */
416 Globals.hMDIWnd =
417 CreateWindow (STRING_MDI_WIN_CLASS_NAME, "",
418 WS_CHILD, rect.left, rect.top,
419 rect.right - rect.left, rect.bottom - rect.top,
420 Globals.hMainWnd, 0,
421 Globals.hInstance, &ccs);
423 ShowWindow (Globals.hMDIWnd, SW_SHOW);
424 UpdateWindow (Globals.hMDIWnd);
427 /**********************************************************************/
428 /***********************************************************************
430 * MAIN_MessageBoxIDS
432 INT MAIN_MessageBoxIDS(UINT ids_text, UINT ids_title, WORD type)
434 CHAR text[MAX_STRING_LEN];
435 CHAR title[MAX_STRING_LEN];
437 LoadString(Globals.hInstance, ids_text, text, sizeof(text));
438 LoadString(Globals.hInstance, ids_title, title, sizeof(title));
440 return(MessageBox(Globals.hMainWnd, text, title, type));
443 /***********************************************************************
445 * MAIN_MessageBoxIDS_s
447 INT MAIN_MessageBoxIDS_s(UINT ids_text, LPCSTR str, UINT ids_title, WORD type)
449 CHAR text[MAX_STRING_LEN];
450 CHAR title[MAX_STRING_LEN];
451 CHAR newtext[MAX_STRING_LEN + MAX_PATHNAME_LEN];
453 LoadString(Globals.hInstance, ids_text, text, sizeof(text));
454 LoadString(Globals.hInstance, ids_title, title, sizeof(title));
455 wsprintf(newtext, text, str);
457 return(MessageBox(Globals.hMainWnd, newtext, title, type));
460 /***********************************************************************
462 * MAIN_ReplaceString
465 VOID MAIN_ReplaceString(HLOCAL *handle, LPSTR replace)
467 HLOCAL newhandle = LocalAlloc(LMEM_FIXED, strlen(replace) + 1);
468 if (newhandle)
470 LPSTR newstring = LocalLock(newhandle);
471 lstrcpy(newstring, replace);
472 LocalFree(*handle);
473 *handle = newhandle;
475 else MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_OK);
478 /* Local Variables: */
479 /* c-file-style: "GNU" */
480 /* End: */