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