Release 960805
[wine] / programs / progman / main.c
1 /*
2  * Program Manager
3  *
4  * Copyright 1996 Ulrich Schmid <uschmid@mail.hh.provi.de>
5  */
6
7 #include <stdio.h>
8 #include <windows.h>
9 #include "license.h"
10 #include "progman.h"
11 #ifdef WINELIB
12 #include <resource.h>
13 #include <options.h>
14 #include <shell.h>
15 void LIBWINE_Register_accel();
16 void LIBWINE_Register_De();
17 void LIBWINE_Register_En();
18 void LIBWINE_Register_Fi();
19 void LIBWINE_Register_Fr();
20 #endif
21
22 GLOBALS Globals;
23
24 static VOID MAIN_CreateGroups(void);
25 static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
26 static ATOM MAIN_RegisterMainWinClass(void);
27 static VOID MAIN_CreateMainWindow(void);
28 static VOID MAIN_CreateMDIWindow(void);
29 static VOID MAIN_AutoStart(void);
30
31 #define BUFFER_SIZE 1000
32
33 /***********************************************************************
34  *
35  *           WinMain
36  */
37
38 int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show)
39 {
40   MSG      msg;
41
42 #if defined(WINELIB) && !defined(HAVE_WINE_CONSTRUCTOR)
43   /* Register resources */
44   LIBWINE_Register_accel();
45   LIBWINE_Register_De();
46   LIBWINE_Register_En();
47   LIBWINE_Register_Fi();
48   LIBWINE_Register_Fr();
49 #endif
50
51 #ifndef WINELIB
52   Globals.lpszIniFile         = "progman.ini";
53   Globals.lpszIcoFile         = "progman.ico";
54 #else /* Configuration in `wine.ini' */
55   {
56     CHAR buffer[MAX_PATHNAME_LEN], *p;
57
58     /* Redirect `progman.ini' */
59     PROFILE_GetWineIniString("progman", "progman.ini", "progman.ini", 
60                              buffer, sizeof(buffer));
61     Globals.lpszIniFile = p = LocalLock(LocalAlloc(LMEM_FIXED, lstrlen(buffer)));
62     hmemcpy(p, buffer, 1 + lstrlen(buffer));
63
64     /* Redirect `progman.ico' */
65     PROFILE_GetWineIniString("progman", "progman.ico", "progman.ico", 
66                              buffer, sizeof(buffer));
67     Globals.lpszIcoFile = p = LocalLock(LocalAlloc(LMEM_FIXED, lstrlen(buffer)));
68     hmemcpy(p, buffer, 1 + lstrlen(buffer));
69   }
70 #endif
71
72   /* Select Language */
73 #ifdef WINELIB
74   Globals.lpszLanguage = langNames[Options.language];
75 #else
76   Globals.lpszLanguage = "En";
77 #endif
78
79   Globals.hInstance           = hInstance;
80   Globals.hGroups             = 0;
81   Globals.hActiveGroup        = 0;
82
83   /* Read Options from `progman.ini' */
84   Globals.bAutoArrange =
85     GetPrivateProfileInt("Settings", "AutoArrange", 0, Globals.lpszIniFile);
86   Globals.bMinOnRun =
87     GetPrivateProfileInt("Settings", "MinOnRun", 0, Globals.lpszIniFile);
88   Globals.bSaveSettings =
89     GetPrivateProfileInt("Settings", "SaveSettings", 0, Globals.lpszIniFile);
90
91   /* Load default icons */
92   Globals.hMainIcon    = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
93   Globals.hGroupIcon   = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
94   Globals.hDefaultIcon = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
95   if (!Globals.hMainIcon)    Globals.hMainIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
96   if (!Globals.hGroupIcon)   Globals.hGroupIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
97   if (!Globals.hDefaultIcon) Globals.hDefaultIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
98
99   /* Register classes */
100   if (!prev)
101     {
102       if (!MAIN_RegisterMainWinClass()) return(FALSE);
103       if (!GROUP_RegisterGroupWinClass()) return(FALSE);
104       if (!PROGRAM_RegisterProgramWinClass()) return(FALSE);
105     }
106
107   /* Create main window */
108   MAIN_CreateMainWindow();
109   Globals.hAccel = LoadAccelerators(Globals.hInstance, STRING_ACCEL);
110
111   /* Setup menu, stringtable and resourcenames */
112   STRING_SelectLanguageByName(Globals.lpszLanguage);
113
114   MAIN_CreateMDIWindow();
115
116   /* Initialize groups */
117   MAIN_CreateGroups();
118
119   /* Start initial applications */
120   MAIN_AutoStart();
121
122   /* Message loop */
123   while (GetMessage (&msg, 0, 0, 0))
124     if (!TranslateAccelerator(Globals.hMainWnd, Globals.hAccel, &msg))
125       {
126         TranslateMessage (&msg);
127         DispatchMessage (&msg);
128       }
129   return 0;
130 }
131
132 /***********************************************************************
133  *
134  *           MAIN_CreateGroups
135  */
136
137 static VOID MAIN_CreateGroups()
138 {
139   CHAR buffer[BUFFER_SIZE];
140   CHAR szPath[MAX_PATHNAME_LEN];
141   CHAR key[20], *ptr;
142
143   /* Initialize groups according the `Order' entry of `progman.ini' */
144   GetPrivateProfileString("Settings", "Order", "", buffer, sizeof(buffer), Globals.lpszIniFile);
145   ptr = buffer;
146   while (ptr < buffer + sizeof(buffer))
147     {
148       int num, skip, ret;
149       ret = sscanf(ptr, "%d%n", &num, &skip);
150       if (ret == 0)
151         MAIN_MessageBoxIDS_s(IDS_FILE_READ_ERROR_s, Globals.lpszIniFile, IDS_ERROR, MB_OK);
152       if (ret != 1) break;
153
154       sprintf(key, "Group%d", num);
155       GetPrivateProfileString("Groups", key, "", szPath,
156                               sizeof(szPath), Globals.lpszIniFile);
157       if (!szPath[0]) continue;
158
159       GRPFILE_ReadGroupFile(szPath);
160
161       ptr += skip;
162     }
163   /* FIXME initialize other groups, not enumerated by `Order' */
164 }
165
166 /***********************************************************************
167  *
168  *           MAIN_AutoStart
169  */
170
171 VOID MAIN_AutoStart()
172 {
173   CHAR buffer[BUFFER_SIZE];
174   HLOCAL hGroup, hProgram;
175
176   GetPrivateProfileString("Settings", "AutoStart", "Autostart", buffer,
177                           sizeof(buffer), Globals.lpszIniFile);
178
179   for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
180     if (!lstrcmp(buffer, GROUP_GroupName(hGroup)))
181       for (hProgram = PROGRAM_FirstProgram(hGroup); hProgram;
182            hProgram = PROGRAM_NextProgram(hProgram))
183         PROGRAM_ExecuteProgram(hProgram);
184 }
185
186 /***********************************************************************
187  *
188  *           MAIN_MainWndProc
189  */
190
191 static LRESULT MAIN_MainWndProc (HWND hWnd, UINT msg,
192                                  WPARAM wParam, LPARAM lParam)
193 {
194 #if 0
195   printf("M %4.4x %4.4x\n", msg, wParam);
196 #endif
197   switch (msg)
198     {
199     case WM_INITMENU:
200       CheckMenuItem(Globals.hOptionMenu, PM_AUTO_ARRANGE,
201                     MF_BYCOMMAND | (Globals.bAutoArrange ? MF_CHECKED : MF_UNCHECKED));
202       CheckMenuItem(Globals.hOptionMenu, PM_MIN_ON_RUN,
203                     MF_BYCOMMAND | (Globals.bMinOnRun ? MF_CHECKED : MF_UNCHECKED));
204       CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
205                     MF_BYCOMMAND | (Globals.bSaveSettings ? MF_CHECKED : MF_UNCHECKED));
206       break;
207
208     case WM_COMMAND:
209       if (wParam < PM_FIRST_CHILD)
210         MAIN_MenuCommand(hWnd, wParam, lParam);
211       break;
212
213     case WM_DESTROY:
214       PostQuitMessage (0);
215       break;
216     }
217   return(DefFrameProc(hWnd, Globals.hMDIWnd, msg, wParam, lParam));
218 }
219
220 /***********************************************************************
221  *
222  *           MAIN_MenuCommand
223  */
224
225 static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
226 {
227   HLOCAL hActiveGroup    = GROUP_ActiveGroup();
228   HLOCAL hActiveProgram  = PROGRAM_ActiveProgram(hActiveGroup);
229   HWND   hActiveGroupWnd = GROUP_GroupWnd(hActiveGroup);
230
231   switch(wParam)
232     {
233       /* Menu File */
234     case PM_NEW:
235       switch (DIALOG_New((hActiveGroupWnd && !IsIconic(hActiveGroupWnd)) ?
236                          PM_NEW_PROGRAM : PM_NEW_GROUP))
237       {
238       case PM_NEW_PROGRAM:
239         if (hActiveGroup) PROGRAM_NewProgram(hActiveGroup);
240         break;
241
242       case PM_NEW_GROUP:
243         GROUP_NewGroup();
244         break;
245       }
246       break;
247
248     case PM_OPEN:
249       if (hActiveProgram)
250         PROGRAM_ExecuteProgram(hActiveProgram);
251       else if (hActiveGroupWnd)
252         OpenIcon(hActiveGroupWnd);
253       break;
254
255     case PM_MOVE:
256     case PM_COPY:
257       if (hActiveProgram)
258         PROGRAM_CopyMoveProgram(hActiveProgram, wParam == PM_MOVE);
259       break;
260
261     case PM_DELETE:
262       if (hActiveProgram)
263         {
264         if (DIALOG_Delete(IDS_DELETE_PROGRAM_s, PROGRAM_ProgramName(hActiveProgram)))
265           PROGRAM_DeleteProgram(hActiveProgram, TRUE);
266         }
267       else if (hActiveGroup)
268         {
269         if (DIALOG_Delete(IDS_DELETE_GROUP_s, GROUP_GroupName(hActiveGroup)))
270           GROUP_DeleteGroup(hActiveGroup);
271         }
272       break;
273
274     case PM_ATTRIBUTES:
275       if (hActiveProgram)
276         PROGRAM_ModifyProgram(hActiveProgram);
277       else if (hActiveGroup)
278         GROUP_ModifyGroup(hActiveGroup);
279       break;
280
281     case PM_EXECUTE:
282       DIALOG_Execute();
283       break;
284
285     case PM_EXIT:
286       PostQuitMessage(0);
287       break;
288
289       /* Menu Options */
290     case PM_AUTO_ARRANGE:
291       Globals.bAutoArrange = !Globals.bAutoArrange;
292       CheckMenuItem(Globals.hOptionMenu, PM_AUTO_ARRANGE,
293                     MF_BYCOMMAND | (Globals.bAutoArrange ?
294                                     MF_CHECKED : MF_UNCHECKED));
295       WritePrivateProfileString("Settings", "AutoArrange",
296                                 Globals.bAutoArrange ? "1" : "0",
297                                 Globals.lpszIniFile);
298       WriteOutProfiles();
299       break;
300
301     case PM_MIN_ON_RUN:
302       Globals.bMinOnRun = !Globals.bMinOnRun;
303       CheckMenuItem(Globals.hOptionMenu, PM_MIN_ON_RUN,
304                     MF_BYCOMMAND | (Globals.bMinOnRun ?
305                                     MF_CHECKED : MF_UNCHECKED));
306       WritePrivateProfileString("Settings", "MinOnRun",
307                                 Globals.bMinOnRun ? "1" : "0",
308                                 Globals.lpszIniFile);
309       WriteOutProfiles();
310       break;
311
312     case PM_SAVE_SETTINGS:
313       Globals.bSaveSettings = !Globals.bSaveSettings;
314       CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
315                     MF_BYCOMMAND | (Globals.bSaveSettings ?
316                                     MF_CHECKED : MF_UNCHECKED));
317       WritePrivateProfileString("Settings", "SaveSettings",
318                                 Globals.bSaveSettings ? "1" : "0",
319                                 Globals.lpszIniFile);
320       WriteOutProfiles();
321       break;
322
323       /* Menu Windows */
324     case PM_ARRANGE:
325       if (hActiveGroupWnd && !IsIconic(hActiveGroupWnd))
326         ArrangeIconicWindows(hActiveGroupWnd);
327       else
328         SendMessage(Globals.hMDIWnd, WM_MDIICONARRANGE, 0, 0);
329       break;
330
331       /* Menu Help */
332     case PM_CONTENTS:
333       if (!WinHelp(Globals.hMainWnd, "progman.hlp", HELP_INDEX, 0))
334         MAIN_MessageBoxIDS(IDS_WINHELP_ERROR, IDS_ERROR, MB_OK);
335       break;
336
337     case PM_HELPONHELP:
338       if (!WinHelp(Globals.hMainWnd, "progman.hlp", HELP_HELPONHELP, 0))
339         MAIN_MessageBoxIDS(IDS_WINHELP_ERROR, IDS_ERROR, MB_OK);
340       break;
341
342     case PM_TUTORIAL:
343       WinExec("wintutor.exe", SW_SHOWNORMAL);
344       break;
345
346     case PM_LICENSE:
347       WineLicense(Globals.hMainWnd, Globals.lpszLanguage);
348       break;
349
350     case PM_NO_WARRANTY:
351       WineWarranty(Globals.hMainWnd, Globals.lpszLanguage);
352       break;
353
354 #ifdef WINELIB
355     case PM_ABOUT_WINE:
356       {
357         extern const char people[];
358         ShellAbout(hWnd, "WINE", people, 0);
359       }
360       break;
361 #endif
362
363     default:
364       if (wParam >= PM_FIRST_LANGUAGE && wParam <= PM_LAST_LANGUAGE)
365         STRING_SelectLanguageByNumber(wParam - PM_FIRST_LANGUAGE);
366       else
367         MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK);
368       break;
369     }
370 }
371
372 /***********************************************************************
373  *
374  *           MAIN_RegisterMainWinClass
375  */
376
377 static ATOM MAIN_RegisterMainWinClass()
378 {
379   WNDCLASS class;
380
381   class.style         = CS_HREDRAW | CS_VREDRAW;
382   class.lpfnWndProc   = MAIN_MainWndProc;
383   class.cbClsExtra    = 0;
384   class.cbWndExtra    = 0;
385   class.hInstance     = Globals.hInstance;
386   class.hIcon         = Globals.hMainIcon;
387   class.hCursor       = LoadCursor (0, IDC_ARROW);
388   class.hbrBackground = GetStockObject (NULL_BRUSH);
389   class.lpszMenuName  = 0;
390   class.lpszClassName = STRING_MAIN_WIN_CLASS_NAME;
391
392   return RegisterClass(&class);
393 }
394
395 /***********************************************************************
396  *
397  *           MAIN_CreateMainWindow
398  */
399
400 static VOID MAIN_CreateMainWindow()
401 {
402   INT  left , top, right, bottom, width, height, show;
403   CHAR buffer[100];
404
405   Globals.hMDIWnd   = 0;
406   Globals.hMainMenu = 0;
407
408   /* Get the geometry of the main window */
409   GetPrivateProfileString("Settings", "Window", "",
410                           buffer, sizeof(buffer), Globals.lpszIniFile);
411   if (5 == sscanf(buffer, "%d %d %d %d %d", &left, &top, &right, &bottom, &show))
412   {
413     width  = right - left;
414     height = bottom - top;
415   }
416   else
417   {
418     left = top = width = height = CW_USEDEFAULT;
419     show = SW_SHOWNORMAL;
420   }
421
422   /* Create main Window */
423   Globals.hMainWnd =
424     CreateWindow (STRING_MAIN_WIN_CLASS_NAME, "",
425                   WS_OVERLAPPEDWINDOW, left, top, width, height,
426                   0, 0, Globals.hInstance, 0);
427
428   ShowWindow (Globals.hMainWnd, show);
429   UpdateWindow (Globals.hMainWnd);
430 }
431
432 /***********************************************************************
433  *
434  *           MAIN_CreateMDIWindow
435  */
436
437 static VOID MAIN_CreateMDIWindow()
438 {
439   CLIENTCREATESTRUCT ccs;
440   RECT rect;
441
442   /* Get the geometry of the MDI window */
443   GetClientRect(Globals.hMainWnd, &rect);
444
445   ccs.hWindowMenu  = Globals.hWindowsMenu;
446   ccs.idFirstChild = PM_FIRST_CHILD;
447
448   /* Create MDI Window */
449   Globals.hMDIWnd =
450     CreateWindow (STRING_MDI_WIN_CLASS_NAME, "",
451                   WS_CHILD, rect.left, rect.top,
452                   rect.right - rect.left, rect.bottom - rect.top,
453                   Globals.hMainWnd, 0,
454                   Globals.hInstance, &ccs);
455
456   ShowWindow (Globals.hMDIWnd, SW_SHOW);
457   UpdateWindow (Globals.hMDIWnd);
458 }
459
460 /**********************************************************************/
461 /***********************************************************************
462  *
463  *           MAIN_MessageBoxIDS
464  */
465 INT MAIN_MessageBoxIDS(UINT ids_text, UINT ids_title, WORD type)
466 {
467   CHAR text[MAX_STRING_LEN];
468   CHAR title[MAX_STRING_LEN];
469
470   LoadString(Globals.hInstance, ids_text, text, sizeof(text));
471   LoadString(Globals.hInstance, ids_title, title, sizeof(title));
472
473   return(MessageBox(Globals.hMainWnd, text, title, type));
474 }
475
476 /***********************************************************************
477  *
478  *           MAIN_MessageBoxIDS_s
479  */
480 INT MAIN_MessageBoxIDS_s(UINT ids_text, LPCSTR str, UINT ids_title, WORD type)
481 {
482   CHAR text[MAX_STRING_LEN];
483   CHAR title[MAX_STRING_LEN];
484   CHAR newtext[MAX_STRING_LEN + MAX_PATHNAME_LEN];
485
486   LoadString(Globals.hInstance, ids_text, text, sizeof(text));
487   LoadString(Globals.hInstance, ids_title, title, sizeof(title));
488   wsprintf(newtext, text, str);
489
490   return(MessageBox(Globals.hMainWnd, newtext, title, type));
491 }
492
493 /***********************************************************************
494  *
495  *           MAIN_ReplaceString
496  */
497
498 VOID MAIN_ReplaceString(HLOCAL *handle, LPSTR replace)
499 {
500   HLOCAL newhandle = LocalAlloc(LMEM_FIXED, strlen(replace) + 1);
501   if (newhandle)
502     {
503       LPSTR  newstring = LocalLock(newhandle);
504       lstrcpy(newstring, replace);
505       LocalFree(*handle);
506       *handle = newhandle;
507     }
508   else MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_OK);
509 }
510
511 /* Local Variables:    */
512 /* c-file-style: "GNU" */
513 /* End:                */