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 // #define OEMRESOURCE
27 static VOID
MAIN_CreateGroups(void);
28 static VOID
MAIN_MenuCommand(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
29 static ATOM
MAIN_RegisterMainWinClass(void);
30 static VOID
MAIN_CreateMainWindow(void);
31 static VOID
MAIN_CreateMDIWindow(void);
32 static VOID
MAIN_AutoStart(void);
34 #define BUFFER_SIZE 1000
36 /***********************************************************************
41 int WINAPI
WinMain (HINSTANCE hInstance
, HINSTANCE prev
, LPSTR cmdline
, int show
)
45 Globals
.lpszIniFile
= "progman.ini";
47 Globals
.hInstance
= hInstance
;
49 Globals
.hActiveGroup
= 0;
51 /* Read Options from `progman.ini' */
52 Globals
.bAutoArrange
=
53 GetPrivateProfileIntA("Settings", "AutoArrange", 0, Globals
.lpszIniFile
);
55 GetPrivateProfileIntA("Settings", "MinOnRun", 0, Globals
.lpszIniFile
);
56 Globals
.bSaveSettings
=
57 GetPrivateProfileIntA("Settings", "SaveSettings", 0, Globals
.lpszIniFile
);
59 /* Load default icons */
60 Globals
.hMainIcon
= LoadIconW(Globals
.hInstance
, MAKEINTRESOURCEW(IDI_APPICON
));
61 Globals
.hGroupIcon
= Globals
.hMainIcon
; // ExtractIconA(Globals.hInstance, Globals.lpszIcoFile, 0);
62 Globals
.hDefaultIcon
= Globals
.hMainIcon
; // ExtractIconA(Globals.hInstance, Globals.lpszIcoFile, 0);
63 if (!Globals
.hMainIcon
) Globals
.hMainIcon
= LoadIconW(0, (LPWSTR
)DEFAULTICON
);
64 if (!Globals
.hGroupIcon
) Globals
.hGroupIcon
= LoadIconW(0, (LPWSTR
)DEFAULTICON
);
65 if (!Globals
.hDefaultIcon
) Globals
.hDefaultIcon
= LoadIconW(0, (LPWSTR
)DEFAULTICON
);
67 /* Register classes */
70 if (!MAIN_RegisterMainWinClass()) return(FALSE
);
71 if (!GROUP_RegisterGroupWinClass()) return(FALSE
);
72 if (!PROGRAM_RegisterProgramWinClass()) return(FALSE
);
75 /* Create main window */
76 MAIN_CreateMainWindow();
77 Globals
.hAccel
= LoadAcceleratorsW(Globals
.hInstance
, MAKEINTRESOURCEW(IDA_ACCEL
));
79 /* Setup menu, stringtable and resourcenames */
82 MAIN_CreateMDIWindow();
84 /* Initialize groups */
87 /* Start initial applications */
91 while (GetMessageW (&msg
, 0, 0, 0))
92 if (!TranslateAcceleratorW(Globals
.hMainWnd
, Globals
.hAccel
, &msg
))
94 TranslateMessage (&msg
);
95 DispatchMessageW (&msg
);
100 /***********************************************************************
105 static VOID
MAIN_CreateGroups(void)
107 CHAR buffer
[BUFFER_SIZE
];
108 CHAR szPath
[MAX_PATHNAME_LEN
];
111 /* Initialize groups according the `Order' entry of `progman.ini' */
112 GetPrivateProfileStringA("Settings", "Order", "", buffer
, sizeof(buffer
), Globals
.lpszIniFile
);
114 while (ptr
< buffer
+ sizeof(buffer
))
117 ret
= sscanf(ptr
, "%d%n", &num
, &skip
);
119 MAIN_MessageBoxIDS_s(IDS_FILE_READ_ERROR_s
, Globals
.lpszIniFile
, IDS_ERROR
, MB_OK
);
122 sprintf(key
, "Group%d", num
);
123 GetPrivateProfileStringA("Groups", key
, "", szPath
,
124 sizeof(szPath
), Globals
.lpszIniFile
);
125 if (!szPath
[0]) continue;
127 GRPFILE_ReadGroupFile(szPath
);
131 /* FIXME initialize other groups, not enumerated by `Order' */
134 /***********************************************************************
139 VOID
MAIN_AutoStart(void)
141 CHAR buffer
[BUFFER_SIZE
];
142 HLOCAL hGroup
, hProgram
;
144 GetPrivateProfileStringA("Settings", "AutoStart", "Autostart", buffer
,
145 sizeof(buffer
), Globals
.lpszIniFile
);
147 for (hGroup
= GROUP_FirstGroup(); hGroup
; hGroup
= GROUP_NextGroup(hGroup
))
148 if (!lstrcmpA(buffer
, GROUP_GroupName(hGroup
)))
149 for (hProgram
= PROGRAM_FirstProgram(hGroup
); hProgram
;
150 hProgram
= PROGRAM_NextProgram(hProgram
))
151 PROGRAM_ExecuteProgram(hProgram
);
154 /***********************************************************************
159 static LRESULT CALLBACK
MAIN_MainWndProc(HWND hWnd
, UINT msg
,
160 WPARAM wParam
, LPARAM lParam
)
165 CheckMenuItem(Globals
.hOptionMenu
, PM_AUTO_ARRANGE
,
166 MF_BYCOMMAND
| (Globals
.bAutoArrange
? MF_CHECKED
: MF_UNCHECKED
));
167 CheckMenuItem(Globals
.hOptionMenu
, PM_MIN_ON_RUN
,
168 MF_BYCOMMAND
| (Globals
.bMinOnRun
? MF_CHECKED
: MF_UNCHECKED
));
169 CheckMenuItem(Globals
.hOptionMenu
, PM_SAVE_SETTINGS
,
170 MF_BYCOMMAND
| (Globals
.bSaveSettings
? MF_CHECKED
: MF_UNCHECKED
));
174 if (LOWORD(wParam
) < PM_FIRST_CHILD
){
175 MAIN_MenuCommand(hWnd
, LOWORD(wParam
), lParam
);
183 return DefFrameProcW(hWnd
, Globals
.hMDIWnd
, msg
, wParam
, lParam
);
186 /***********************************************************************
191 static VOID
MAIN_MenuCommand(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
193 HLOCAL hActiveGroup
= GROUP_ActiveGroup();
194 HLOCAL hActiveProgram
= PROGRAM_ActiveProgram(hActiveGroup
);
195 HWND hActiveGroupWnd
= GROUP_GroupWnd(hActiveGroup
);
201 switch (DIALOG_New((hActiveGroupWnd
&& !IsIconic(hActiveGroupWnd
)) ?
202 PM_NEW_PROGRAM
: PM_NEW_GROUP
))
205 if (hActiveGroup
) PROGRAM_NewProgram(hActiveGroup
);
216 PROGRAM_ExecuteProgram(hActiveProgram
);
217 else if (hActiveGroupWnd
)
218 OpenIcon(hActiveGroupWnd
);
224 PROGRAM_CopyMoveProgram(hActiveProgram
, wParam
== PM_MOVE
);
230 if (DIALOG_Delete(IDS_DELETE_PROGRAM_s
, PROGRAM_ProgramName(hActiveProgram
)))
231 PROGRAM_DeleteProgram(hActiveProgram
, TRUE
);
233 else if (hActiveGroup
)
235 if (DIALOG_Delete(IDS_DELETE_GROUP_s
, GROUP_GroupName(hActiveGroup
)))
236 GROUP_DeleteGroup(hActiveGroup
);
242 PROGRAM_ModifyProgram(hActiveProgram
);
243 else if (hActiveGroup
)
244 GROUP_ModifyGroup(hActiveGroup
);
256 case PM_AUTO_ARRANGE
:
257 Globals
.bAutoArrange
= !Globals
.bAutoArrange
;
258 CheckMenuItem(Globals
.hOptionMenu
, PM_AUTO_ARRANGE
,
259 MF_BYCOMMAND
| (Globals
.bAutoArrange
?
260 MF_CHECKED
: MF_UNCHECKED
));
261 WritePrivateProfileStringA("Settings", "AutoArrange",
262 Globals
.bAutoArrange
? "1" : "0",
263 Globals
.lpszIniFile
);
264 WritePrivateProfileStringA(NULL
,NULL
,NULL
,Globals
.lpszIniFile
); /* flush it */
268 Globals
.bMinOnRun
= !Globals
.bMinOnRun
;
269 CheckMenuItem(Globals
.hOptionMenu
, PM_MIN_ON_RUN
,
270 MF_BYCOMMAND
| (Globals
.bMinOnRun
?
271 MF_CHECKED
: MF_UNCHECKED
));
272 WritePrivateProfileStringA("Settings", "MinOnRun",
273 Globals
.bMinOnRun
? "1" : "0",
274 Globals
.lpszIniFile
);
275 WritePrivateProfileStringA(NULL
,NULL
,NULL
,Globals
.lpszIniFile
); /* flush it */
278 case PM_SAVE_SETTINGS
:
279 Globals
.bSaveSettings
= !Globals
.bSaveSettings
;
280 CheckMenuItem(Globals
.hOptionMenu
, PM_SAVE_SETTINGS
,
281 MF_BYCOMMAND
| (Globals
.bSaveSettings
?
282 MF_CHECKED
: MF_UNCHECKED
));
283 WritePrivateProfileStringA("Settings", "SaveSettings",
284 Globals
.bSaveSettings
? "1" : "0",
285 Globals
.lpszIniFile
);
286 WritePrivateProfileStringA(NULL
,NULL
,NULL
,Globals
.lpszIniFile
); /* flush it */
291 SendMessageW(Globals
.hMDIWnd
, WM_MDICASCADE
, 0, 0);
294 case PM_SIDE_BY_SIDE
:
295 SendMessageW(Globals
.hMDIWnd
, WM_MDITILE
, MDITILE_VERTICAL
, 0);
300 if (hActiveGroupWnd
&& !IsIconic(hActiveGroupWnd
))
301 ArrangeIconicWindows(hActiveGroupWnd
);
303 SendMessageW(Globals
.hMDIWnd
, WM_MDIICONARRANGE
, 0, 0);
308 if (!WinHelpA(Globals
.hMainWnd
, "progman.hlp", HELP_CONTENTS
, 0))
309 MAIN_MessageBoxIDS(IDS_WINHELP_ERROR
, IDS_ERROR
, MB_OK
);
314 WCHAR szTitle
[MAX_STRING_LEN
];
315 LoadStringW(Globals
.hInstance
, IDS_PROGRAM_MANAGER
, szTitle
, ARRAYSIZE(szTitle
));
316 ShellAboutW(hWnd
, szTitle
, NULL
, NULL
);
321 MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED
, IDS_ERROR
, MB_OK
);
326 /***********************************************************************
328 * MAIN_RegisterMainWinClass
331 static ATOM
MAIN_RegisterMainWinClass(void)
335 class.style
= CS_HREDRAW
| CS_VREDRAW
;
336 class.lpfnWndProc
= MAIN_MainWndProc
;
337 class.cbClsExtra
= 0;
338 class.cbWndExtra
= 0;
339 class.hInstance
= Globals
.hInstance
;
340 class.hIcon
= Globals
.hMainIcon
;
341 class.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
342 class.hbrBackground
= GetStockObject (NULL_BRUSH
);
343 class.lpszMenuName
= 0;
344 class.lpszClassName
= STRING_MAIN_WIN_CLASS_NAME
;
346 return RegisterClassW(&class);
349 /***********************************************************************
351 * MAIN_CreateMainWindow
354 static VOID
MAIN_CreateMainWindow(void)
356 INT left
, top
, right
, bottom
, width
, height
, show
;
360 Globals
.hMainMenu
= 0;
362 /* Get the geometry of the main window */
363 GetPrivateProfileStringA("Settings", "Window", "", buffer
, sizeof(buffer
), Globals
.lpszIniFile
);
364 if (5 == sscanf(buffer
, "%d %d %d %d %d", &left
, &top
, &right
, &bottom
, &show
))
366 width
= right
- left
;
367 height
= bottom
- top
;
371 left
= top
= width
= height
= CW_USEDEFAULT
;
372 show
= SW_SHOWNORMAL
;
375 /* Create main Window */
377 CreateWindowW(STRING_MAIN_WIN_CLASS_NAME
, NULL
,
378 WS_OVERLAPPEDWINDOW
, left
, top
, width
, height
,
379 0, 0, Globals
.hInstance
, 0);
381 ShowWindow (Globals
.hMainWnd
, show
);
382 UpdateWindow (Globals
.hMainWnd
);
385 /***********************************************************************
387 * MAIN_CreateMDIWindow
390 static VOID
MAIN_CreateMDIWindow(void)
392 CLIENTCREATESTRUCT ccs
;
395 /* Get the geometry of the MDI window */
396 GetClientRect(Globals
.hMainWnd
, &rect
);
398 ccs
.hWindowMenu
= Globals
.hWindowsMenu
;
399 ccs
.idFirstChild
= PM_FIRST_CHILD
;
401 /* Create MDI Window */
403 CreateWindowW(STRING_MDI_WIN_CLASS_NAME
, NULL
,
404 WS_CHILD
, rect
.left
, rect
.top
,
405 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
407 Globals
.hInstance
, &ccs
);
409 ShowWindow (Globals
.hMDIWnd
, SW_SHOW
);
410 UpdateWindow (Globals
.hMDIWnd
);
413 /**********************************************************************/
414 /***********************************************************************
418 INT
MAIN_MessageBoxIDS(UINT ids_text
, UINT ids_title
, WORD type
)
420 CHAR text
[MAX_STRING_LEN
];
421 CHAR title
[MAX_STRING_LEN
];
423 LoadStringA(Globals
.hInstance
, ids_text
, text
, sizeof(text
));
424 LoadStringA(Globals
.hInstance
, ids_title
, title
, sizeof(title
));
426 return(MessageBoxA(Globals
.hMainWnd
, text
, title
, type
));
429 /***********************************************************************
431 * MAIN_MessageBoxIDS_s
433 INT
MAIN_MessageBoxIDS_s(UINT ids_text
, LPCSTR str
, UINT ids_title
, WORD type
)
435 CHAR text
[MAX_STRING_LEN
];
436 CHAR title
[MAX_STRING_LEN
];
437 CHAR newtext
[MAX_STRING_LEN
+ MAX_PATHNAME_LEN
];
439 LoadStringA(Globals
.hInstance
, ids_text
, text
, sizeof(text
));
440 LoadStringA(Globals
.hInstance
, ids_title
, title
, sizeof(title
));
441 wsprintfA(newtext
, text
, str
);
443 return(MessageBoxA(Globals
.hMainWnd
, newtext
, title
, type
));
446 /***********************************************************************
451 VOID
MAIN_ReplaceString(HLOCAL
*handle
, LPSTR replace
)
453 HLOCAL newhandle
= LocalAlloc(LMEM_FIXED
, strlen(replace
) + 1);
456 LPSTR newstring
= LocalLock(newhandle
);
457 strcpy(newstring
, replace
);
461 else MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY
, IDS_ERROR
, MB_OK
);