progman: Load license from resources.
[wine] / programs / progman / main.c
1 /*
2  * Program Manager
3  *
4  * Copyright 1996 Ulrich Schmid
5  * Copyright 2002 Sylvain Petreolle
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include "windows.h"
25 #include "windowsx.h"
26 #include "progman.h"
27
28 GLOBALS Globals;
29
30 static VOID MAIN_CreateGroups(void);
31 static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
32 static ATOM MAIN_RegisterMainWinClass(void);
33 static VOID MAIN_CreateMainWindow(void);
34 static VOID MAIN_CreateMDIWindow(void);
35 static VOID MAIN_AutoStart(void);
36 static VOID WineLicense(HWND Wnd);
37 static VOID WineWarranty(HWND Wnd);
38
39 #define BUFFER_SIZE 1000
40
41 /***********************************************************************
42  *
43  *           WinMain
44  */
45
46 int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
47 {
48   MSG      msg;
49
50   Globals.lpszIniFile         = "progman.ini";
51   Globals.lpszIcoFile         = "progman.ico";
52
53   Globals.hInstance           = hInstance;
54   Globals.hGroups             = 0;
55   Globals.hActiveGroup        = 0;
56
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);
64
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));
72
73   /* Register classes */
74   if (!prev)
75     {
76       if (!MAIN_RegisterMainWinClass()) return(FALSE);
77       if (!GROUP_RegisterGroupWinClass()) return(FALSE);
78       if (!PROGRAM_RegisterProgramWinClass()) return(FALSE);
79     }
80
81   /* Create main window */
82   MAIN_CreateMainWindow();
83   Globals.hAccel = LoadAccelerators(Globals.hInstance, STRING_ACCEL);
84
85   /* Setup menu, stringtable and resourcenames */
86   STRING_LoadMenus();
87
88   MAIN_CreateMDIWindow();
89
90   /* Initialize groups */
91   MAIN_CreateGroups();
92
93   /* Start initial applications */
94   MAIN_AutoStart();
95
96   /* Message loop */
97   while (GetMessage (&msg, 0, 0, 0))
98     if (!TranslateAccelerator(Globals.hMainWnd, Globals.hAccel, &msg))
99       {
100         TranslateMessage (&msg);
101         DispatchMessage (&msg);
102       }
103   return 0;
104 }
105
106 /***********************************************************************
107  *
108  *           MAIN_CreateGroups
109  */
110
111 static VOID MAIN_CreateGroups()
112 {
113   CHAR buffer[BUFFER_SIZE];
114   CHAR szPath[MAX_PATHNAME_LEN];
115   CHAR key[20], *ptr;
116
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))
121     {
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;
127
128       sprintf(key, "Group%d", num);
129       GetPrivateProfileString("Groups", key, "", szPath,
130                               sizeof(szPath), Globals.lpszIniFile);
131       if (!szPath[0]) continue;
132
133       GRPFILE_ReadGroupFile(szPath);
134
135       ptr += skip;
136     }
137   /* FIXME initialize other groups, not enumerated by `Order' */
138 }
139
140 /***********************************************************************
141  *
142  *           MAIN_AutoStart
143  */
144
145 VOID MAIN_AutoStart()
146 {
147   CHAR buffer[BUFFER_SIZE];
148   HLOCAL hGroup, hProgram;
149
150   GetPrivateProfileString("Settings", "AutoStart", "Autostart", buffer,
151                           sizeof(buffer), Globals.lpszIniFile);
152
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);
158 }
159
160 /***********************************************************************
161  *
162  *           MAIN_MainWndProc
163  */
164
165 static LRESULT CALLBACK MAIN_MainWndProc(HWND hWnd, UINT msg,
166                                  WPARAM wParam, LPARAM lParam)
167 {
168 #if 0
169   printf("M %4.4x %4.4x\n", msg, wParam);
170 #endif
171   switch (msg)
172     {
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;
181
182     case WM_COMMAND:
183       if (wParam < PM_FIRST_CHILD){
184         MAIN_MenuCommand(hWnd, wParam, lParam);
185       }
186       break;
187
188     case WM_DESTROY:
189       PostQuitMessage (0);
190       break;
191     }
192   return(DefFrameProc(hWnd, Globals.hMDIWnd, msg, wParam, lParam));
193 }
194
195 /***********************************************************************
196  *
197  *           MAIN_MenuCommand
198  */
199
200 static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
201 {
202   HLOCAL hActiveGroup    = GROUP_ActiveGroup();
203   HLOCAL hActiveProgram  = PROGRAM_ActiveProgram(hActiveGroup);
204   HWND   hActiveGroupWnd = GROUP_GroupWnd(hActiveGroup);
205
206   switch(wParam)
207     {
208       /* Menu File */
209     case PM_NEW:
210       switch (DIALOG_New((hActiveGroupWnd && !IsIconic(hActiveGroupWnd)) ?
211                          PM_NEW_PROGRAM : PM_NEW_GROUP))
212       {
213       case PM_NEW_PROGRAM:
214         if (hActiveGroup) PROGRAM_NewProgram(hActiveGroup);
215         break;
216
217       case PM_NEW_GROUP:
218         GROUP_NewGroup();
219         break;
220       }
221       break;
222
223     case PM_OPEN:
224       if (hActiveProgram)
225         PROGRAM_ExecuteProgram(hActiveProgram);
226       else if (hActiveGroupWnd)
227         OpenIcon(hActiveGroupWnd);
228       break;
229
230     case PM_MOVE:
231     case PM_COPY:
232       if (hActiveProgram)
233         PROGRAM_CopyMoveProgram(hActiveProgram, wParam == PM_MOVE);
234       break;
235
236     case PM_DELETE:
237       if (hActiveProgram)
238         {
239         if (DIALOG_Delete(IDS_DELETE_PROGRAM_s, PROGRAM_ProgramName(hActiveProgram)))
240           PROGRAM_DeleteProgram(hActiveProgram, TRUE);
241         }
242       else if (hActiveGroup)
243         {
244         if (DIALOG_Delete(IDS_DELETE_GROUP_s, GROUP_GroupName(hActiveGroup)))
245           GROUP_DeleteGroup(hActiveGroup);
246         }
247       break;
248
249     case PM_ATTRIBUTES:
250       if (hActiveProgram)
251         PROGRAM_ModifyProgram(hActiveProgram);
252       else if (hActiveGroup)
253         GROUP_ModifyGroup(hActiveGroup);
254       break;
255
256     case PM_EXECUTE:
257       DIALOG_Execute();
258       break;
259
260     case PM_EXIT:
261       PostQuitMessage(0);
262       break;
263
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;
275
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;
286
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;
297
298       /* Menu Windows */
299     case PM_ARRANGE:
300
301       if (hActiveGroupWnd && !IsIconic(hActiveGroupWnd))
302         ArrangeIconicWindows(hActiveGroupWnd);
303       else
304         SendMessage(Globals.hMDIWnd, WM_MDIICONARRANGE, 0, 0);
305       break;
306
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;
312
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;
317
318     case PM_TUTORIAL:
319       WinExec("wintutor.exe", SW_SHOWNORMAL);
320       break;
321
322     case PM_LICENSE:
323       WineLicense(Globals.hMainWnd);
324       break;
325
326     case PM_NO_WARRANTY:
327       WineWarranty(Globals.hMainWnd);
328       break;
329
330     case PM_ABOUT_WINE:
331       ShellAbout(hWnd, "WINE", "Program Manager", 0);
332       break;
333
334     default:
335         MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK);
336       break;
337     }
338 }
339
340 /***********************************************************************
341  *
342  *           MAIN_RegisterMainWinClass
343  */
344
345 static ATOM MAIN_RegisterMainWinClass()
346 {
347   WNDCLASS class;
348
349   class.style         = CS_HREDRAW | CS_VREDRAW;
350   class.lpfnWndProc   = MAIN_MainWndProc;
351   class.cbClsExtra    = 0;
352   class.cbWndExtra    = 0;
353   class.hInstance     = Globals.hInstance;
354   class.hIcon         = Globals.hMainIcon;
355   class.hCursor       = LoadCursor (0, IDC_ARROW);
356   class.hbrBackground = GetStockObject (NULL_BRUSH);
357   class.lpszMenuName  = 0;
358   class.lpszClassName = STRING_MAIN_WIN_CLASS_NAME;
359
360   return RegisterClass(&class);
361 }
362
363 /***********************************************************************
364  *
365  *           MAIN_CreateMainWindow
366  */
367
368 static VOID MAIN_CreateMainWindow()
369 {
370   INT  left , top, right, bottom, width, height, show;
371   CHAR buffer[100];
372
373   Globals.hMDIWnd   = 0;
374   Globals.hMainMenu = 0;
375
376   /* Get the geometry of the main window */
377   GetPrivateProfileString("Settings", "Window", "",
378                           buffer, sizeof(buffer), Globals.lpszIniFile);
379   if (5 == sscanf(buffer, "%d %d %d %d %d", &left, &top, &right, &bottom, &show))
380   {
381     width  = right - left;
382     height = bottom - top;
383   }
384   else
385   {
386     left = top = width = height = CW_USEDEFAULT;
387     show = SW_SHOWNORMAL;
388   }
389
390   /* Create main Window */
391   Globals.hMainWnd =
392     CreateWindow (STRING_MAIN_WIN_CLASS_NAME, "",
393                   WS_OVERLAPPEDWINDOW, left, top, width, height,
394                   0, 0, Globals.hInstance, 0);
395
396   ShowWindow (Globals.hMainWnd, show);
397   UpdateWindow (Globals.hMainWnd);
398 }
399
400 /***********************************************************************
401  *
402  *           MAIN_CreateMDIWindow
403  */
404
405 static VOID MAIN_CreateMDIWindow()
406 {
407   CLIENTCREATESTRUCT ccs;
408   RECT rect;
409
410   /* Get the geometry of the MDI window */
411   GetClientRect(Globals.hMainWnd, &rect);
412
413   ccs.hWindowMenu  = Globals.hWindowsMenu;
414   ccs.idFirstChild = PM_FIRST_CHILD;
415
416   /* Create MDI Window */
417   Globals.hMDIWnd =
418     CreateWindow (STRING_MDI_WIN_CLASS_NAME, "",
419                   WS_CHILD, rect.left, rect.top,
420                   rect.right - rect.left, rect.bottom - rect.top,
421                   Globals.hMainWnd, 0,
422                   Globals.hInstance, &ccs);
423
424   ShowWindow (Globals.hMDIWnd, SW_SHOW);
425   UpdateWindow (Globals.hMDIWnd);
426 }
427
428 /**********************************************************************/
429 /***********************************************************************
430  *
431  *           MAIN_MessageBoxIDS
432  */
433 INT MAIN_MessageBoxIDS(UINT ids_text, UINT ids_title, WORD type)
434 {
435   CHAR text[MAX_STRING_LEN];
436   CHAR title[MAX_STRING_LEN];
437
438   LoadString(Globals.hInstance, ids_text, text, sizeof(text));
439   LoadString(Globals.hInstance, ids_title, title, sizeof(title));
440
441   return(MessageBox(Globals.hMainWnd, text, title, type));
442 }
443
444 /***********************************************************************
445  *
446  *           MAIN_MessageBoxIDS_s
447  */
448 INT MAIN_MessageBoxIDS_s(UINT ids_text, LPCSTR str, UINT ids_title, WORD type)
449 {
450   CHAR text[MAX_STRING_LEN];
451   CHAR title[MAX_STRING_LEN];
452   CHAR newtext[MAX_STRING_LEN + MAX_PATHNAME_LEN];
453
454   LoadString(Globals.hInstance, ids_text, text, sizeof(text));
455   LoadString(Globals.hInstance, ids_title, title, sizeof(title));
456   wsprintf(newtext, text, str);
457
458   return(MessageBox(Globals.hMainWnd, newtext, title, type));
459 }
460
461 /***********************************************************************
462  *
463  *           MAIN_ReplaceString
464  */
465
466 VOID MAIN_ReplaceString(HLOCAL *handle, LPSTR replace)
467 {
468   HLOCAL newhandle = LocalAlloc(LMEM_FIXED, strlen(replace) + 1);
469   if (newhandle)
470     {
471       LPSTR  newstring = LocalLock(newhandle);
472       lstrcpy(newstring, replace);
473       LocalFree(*handle);
474       *handle = newhandle;
475     }
476   else MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_OK);
477 }
478
479 VOID WineLicense(HWND Wnd)
480 {
481   char cap[20], text[1024];
482   LoadString(Globals.hInstance, IDS_LICENSE, text, sizeof text);
483   LoadString(Globals.hInstance, IDS_LICENSE_CAPTION, cap, sizeof cap);
484   MessageBox(Wnd, text, cap, MB_ICONINFORMATION | MB_OK);
485 }
486
487 VOID WineWarranty(HWND Wnd)
488 {
489   char cap[20], text[1024];
490   LoadString(Globals.hInstance, IDS_WARRANTY, text, sizeof text);
491   LoadString(Globals.hInstance, IDS_WARRANTY_CAPTION, cap, sizeof cap);
492   MessageBox(Wnd, text, cap, MB_ICONEXCLAMATION | MB_OK);
493 }
494
495 /* Local Variables:    */
496 /* c-file-style: "GNU" */
497 /* End:                */