main.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  20. */
  21. #include <stdio.h>
  22. #include <string.h>
  23. #define OEMRESOURCE
  24. #include "windows.h"
  25. #include "shellapi.h"
  26. #include "progman.h"
  27. GLOBALS Globals;
  28. static VOID MAIN_CreateGroups(void);
  29. static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
  30. static ATOM MAIN_RegisterMainWinClass(void);
  31. static VOID MAIN_CreateMainWindow(void);
  32. static VOID MAIN_CreateMDIWindow(void);
  33. static VOID MAIN_AutoStart(void);
  34. #define BUFFER_SIZE 1000
  35. /***********************************************************************
  36. *
  37. * WinMain
  38. */
  39. int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
  40. {
  41. MSG msg;
  42. Globals.lpszIniFile = "progman.ini";
  43. Globals.lpszIcoFile = "progman.ico";
  44. Globals.hInstance = hInstance;
  45. Globals.hGroups = 0;
  46. Globals.hActiveGroup = 0;
  47. /* Read Options from `progman.ini' */
  48. Globals.bAutoArrange =
  49. GetPrivateProfileIntA("Settings", "AutoArrange", 0, Globals.lpszIniFile);
  50. Globals.bMinOnRun =
  51. GetPrivateProfileIntA("Settings", "MinOnRun", 0, Globals.lpszIniFile);
  52. Globals.bSaveSettings =
  53. GetPrivateProfileIntA("Settings", "SaveSettings", 0, Globals.lpszIniFile);
  54. /* Load default icons */
  55. Globals.hMainIcon = ExtractIconA(Globals.hInstance, Globals.lpszIcoFile, 0);
  56. Globals.hGroupIcon = ExtractIconA(Globals.hInstance, Globals.lpszIcoFile, 0);
  57. Globals.hDefaultIcon = ExtractIconA(Globals.hInstance, Globals.lpszIcoFile, 0);
  58. if (!Globals.hMainIcon) Globals.hMainIcon = LoadIconW(0, (LPWSTR)DEFAULTICON);
  59. if (!Globals.hGroupIcon) Globals.hGroupIcon = LoadIconW(0, (LPWSTR)DEFAULTICON);
  60. if (!Globals.hDefaultIcon) Globals.hDefaultIcon = LoadIconW(0, (LPWSTR)DEFAULTICON);
  61. /* Register classes */
  62. if (!prev)
  63. {
  64. if (!MAIN_RegisterMainWinClass()) return(FALSE);
  65. if (!GROUP_RegisterGroupWinClass()) return(FALSE);
  66. if (!PROGRAM_RegisterProgramWinClass()) return(FALSE);
  67. }
  68. /* Create main window */
  69. MAIN_CreateMainWindow();
  70. Globals.hAccel = LoadAcceleratorsW(Globals.hInstance, MAKEINTRESOURCEW(IDA_ACCEL));
  71. /* Setup menu, stringtable and resourcenames */
  72. STRING_LoadMenus();
  73. MAIN_CreateMDIWindow();
  74. /* Initialize groups */
  75. MAIN_CreateGroups();
  76. /* Start initial applications */
  77. MAIN_AutoStart();
  78. /* Message loop */
  79. while (GetMessageW (&msg, 0, 0, 0))
  80. if (!TranslateAcceleratorW(Globals.hMainWnd, Globals.hAccel, &msg))
  81. {
  82. TranslateMessage (&msg);
  83. DispatchMessageW (&msg);
  84. }
  85. return 0;
  86. }
  87. /***********************************************************************
  88. *
  89. * MAIN_CreateGroups
  90. */
  91. static VOID MAIN_CreateGroups(void)
  92. {
  93. CHAR buffer[BUFFER_SIZE];
  94. CHAR szPath[MAX_PATHNAME_LEN];
  95. CHAR key[20], *ptr;
  96. /* Initialize groups according the `Order' entry of `progman.ini' */
  97. GetPrivateProfileStringA("Settings", "Order", "", buffer, sizeof(buffer), Globals.lpszIniFile);
  98. ptr = buffer;
  99. while (ptr < buffer + sizeof(buffer))
  100. {
  101. int num, skip, ret;
  102. ret = sscanf(ptr, "%d%n", &num, &skip);
  103. if (ret == 0)
  104. MAIN_MessageBoxIDS_s(IDS_FILE_READ_ERROR_s, Globals.lpszIniFile, IDS_ERROR, MB_OK);
  105. if (ret != 1) break;
  106. sprintf(key, "Group%d", num);
  107. GetPrivateProfileStringA("Groups", key, "", szPath,
  108. sizeof(szPath), Globals.lpszIniFile);
  109. if (!szPath[0]) continue;
  110. GRPFILE_ReadGroupFile(szPath);
  111. ptr += skip;
  112. }
  113. /* FIXME initialize other groups, not enumerated by `Order' */
  114. }
  115. /***********************************************************************
  116. *
  117. * MAIN_AutoStart
  118. */
  119. VOID MAIN_AutoStart(void)
  120. {
  121. CHAR buffer[BUFFER_SIZE];
  122. HLOCAL hGroup, hProgram;
  123. GetPrivateProfileStringA("Settings", "AutoStart", "Autostart", buffer,
  124. sizeof(buffer), Globals.lpszIniFile);
  125. for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
  126. if (!lstrcmpA(buffer, GROUP_GroupName(hGroup)))
  127. for (hProgram = PROGRAM_FirstProgram(hGroup); hProgram;
  128. hProgram = PROGRAM_NextProgram(hProgram))
  129. PROGRAM_ExecuteProgram(hProgram);
  130. }
  131. /***********************************************************************
  132. *
  133. * MAIN_MainWndProc
  134. */
  135. static LRESULT CALLBACK MAIN_MainWndProc(HWND hWnd, UINT msg,
  136. WPARAM wParam, LPARAM lParam)
  137. {
  138. switch (msg)
  139. {
  140. case WM_INITMENU:
  141. CheckMenuItem(Globals.hOptionMenu, PM_AUTO_ARRANGE,
  142. MF_BYCOMMAND | (Globals.bAutoArrange ? MF_CHECKED : MF_UNCHECKED));
  143. CheckMenuItem(Globals.hOptionMenu, PM_MIN_ON_RUN,
  144. MF_BYCOMMAND | (Globals.bMinOnRun ? MF_CHECKED : MF_UNCHECKED));
  145. CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
  146. MF_BYCOMMAND | (Globals.bSaveSettings ? MF_CHECKED : MF_UNCHECKED));
  147. break;
  148. case WM_COMMAND:
  149. if (LOWORD(wParam) < PM_FIRST_CHILD){
  150. MAIN_MenuCommand(hWnd, LOWORD(wParam), lParam);
  151. }
  152. break;
  153. case WM_DESTROY:
  154. PostQuitMessage (0);
  155. break;
  156. }
  157. return DefFrameProcW(hWnd, Globals.hMDIWnd, msg, wParam, lParam);
  158. }
  159. /***********************************************************************
  160. *
  161. * MAIN_MenuCommand
  162. */
  163. static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
  164. {
  165. HLOCAL hActiveGroup = GROUP_ActiveGroup();
  166. HLOCAL hActiveProgram = PROGRAM_ActiveProgram(hActiveGroup);
  167. HWND hActiveGroupWnd = GROUP_GroupWnd(hActiveGroup);
  168. switch(wParam)
  169. {
  170. /* Menu File */
  171. case PM_NEW:
  172. switch (DIALOG_New((hActiveGroupWnd && !IsIconic(hActiveGroupWnd)) ?
  173. PM_NEW_PROGRAM : PM_NEW_GROUP))
  174. {
  175. case PM_NEW_PROGRAM:
  176. if (hActiveGroup) PROGRAM_NewProgram(hActiveGroup);
  177. break;
  178. case PM_NEW_GROUP:
  179. GROUP_NewGroup();
  180. break;
  181. }
  182. break;
  183. case PM_OPEN:
  184. if (hActiveProgram)
  185. PROGRAM_ExecuteProgram(hActiveProgram);
  186. else if (hActiveGroupWnd)
  187. OpenIcon(hActiveGroupWnd);
  188. break;
  189. case PM_MOVE:
  190. case PM_COPY:
  191. if (hActiveProgram)
  192. PROGRAM_CopyMoveProgram(hActiveProgram, wParam == PM_MOVE);
  193. break;
  194. case PM_DELETE:
  195. if (hActiveProgram)
  196. {
  197. if (DIALOG_Delete(IDS_DELETE_PROGRAM_s, PROGRAM_ProgramName(hActiveProgram)))
  198. PROGRAM_DeleteProgram(hActiveProgram, TRUE);
  199. }
  200. else if (hActiveGroup)
  201. {
  202. if (DIALOG_Delete(IDS_DELETE_GROUP_s, GROUP_GroupName(hActiveGroup)))
  203. GROUP_DeleteGroup(hActiveGroup);
  204. }
  205. break;
  206. case PM_ATTRIBUTES:
  207. if (hActiveProgram)
  208. PROGRAM_ModifyProgram(hActiveProgram);
  209. else if (hActiveGroup)
  210. GROUP_ModifyGroup(hActiveGroup);
  211. break;
  212. case PM_EXECUTE:
  213. DIALOG_Execute();
  214. break;
  215. case PM_EXIT:
  216. PostQuitMessage(0);
  217. break;
  218. /* Menu Options */
  219. case PM_AUTO_ARRANGE:
  220. Globals.bAutoArrange = !Globals.bAutoArrange;
  221. CheckMenuItem(Globals.hOptionMenu, PM_AUTO_ARRANGE,
  222. MF_BYCOMMAND | (Globals.bAutoArrange ?
  223. MF_CHECKED : MF_UNCHECKED));
  224. WritePrivateProfileStringA("Settings", "AutoArrange",
  225. Globals.bAutoArrange ? "1" : "0",
  226. Globals.lpszIniFile);
  227. WritePrivateProfileStringA(NULL,NULL,NULL,Globals.lpszIniFile); /* flush it */
  228. break;
  229. case PM_MIN_ON_RUN:
  230. Globals.bMinOnRun = !Globals.bMinOnRun;
  231. CheckMenuItem(Globals.hOptionMenu, PM_MIN_ON_RUN,
  232. MF_BYCOMMAND | (Globals.bMinOnRun ?
  233. MF_CHECKED : MF_UNCHECKED));
  234. WritePrivateProfileStringA("Settings", "MinOnRun",
  235. Globals.bMinOnRun ? "1" : "0",
  236. Globals.lpszIniFile);
  237. WritePrivateProfileStringA(NULL,NULL,NULL,Globals.lpszIniFile); /* flush it */
  238. break;
  239. case PM_SAVE_SETTINGS:
  240. Globals.bSaveSettings = !Globals.bSaveSettings;
  241. CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
  242. MF_BYCOMMAND | (Globals.bSaveSettings ?
  243. MF_CHECKED : MF_UNCHECKED));
  244. WritePrivateProfileStringA("Settings", "SaveSettings",
  245. Globals.bSaveSettings ? "1" : "0",
  246. Globals.lpszIniFile);
  247. WritePrivateProfileStringA(NULL,NULL,NULL,Globals.lpszIniFile); /* flush it */
  248. break;
  249. /* Menu Windows */
  250. case PM_OVERLAP:
  251. SendMessageW(Globals.hMDIWnd, WM_MDICASCADE, 0, 0);
  252. break;
  253. case PM_SIDE_BY_SIDE:
  254. SendMessageW(Globals.hMDIWnd, WM_MDITILE, MDITILE_VERTICAL, 0);
  255. break;
  256. case PM_ARRANGE:
  257. if (hActiveGroupWnd && !IsIconic(hActiveGroupWnd))
  258. ArrangeIconicWindows(hActiveGroupWnd);
  259. else
  260. SendMessageW(Globals.hMDIWnd, WM_MDIICONARRANGE, 0, 0);
  261. break;
  262. /* Menu Help */
  263. case PM_CONTENTS:
  264. if (!WinHelpA(Globals.hMainWnd, "progman.hlp", HELP_CONTENTS, 0))
  265. MAIN_MessageBoxIDS(IDS_WINHELP_ERROR, IDS_ERROR, MB_OK);
  266. break;
  267. case PM_ABOUT_WINE:
  268. ShellAboutA(hWnd, "WINE", "Program Manager", 0);
  269. break;
  270. default:
  271. MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK);
  272. break;
  273. }
  274. }
  275. /***********************************************************************
  276. *
  277. * MAIN_RegisterMainWinClass
  278. */
  279. static ATOM MAIN_RegisterMainWinClass(void)
  280. {
  281. WNDCLASSW class;
  282. class.style = CS_HREDRAW | CS_VREDRAW;
  283. class.lpfnWndProc = MAIN_MainWndProc;
  284. class.cbClsExtra = 0;
  285. class.cbWndExtra = 0;
  286. class.hInstance = Globals.hInstance;
  287. class.hIcon = Globals.hMainIcon;
  288. class.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW);
  289. class.hbrBackground = GetStockObject (NULL_BRUSH);
  290. class.lpszMenuName = 0;
  291. class.lpszClassName = STRING_MAIN_WIN_CLASS_NAME;
  292. return RegisterClassW(&class);
  293. }
  294. /***********************************************************************
  295. *
  296. * MAIN_CreateMainWindow
  297. */
  298. static VOID MAIN_CreateMainWindow(void)
  299. {
  300. INT left , top, right, bottom, width, height, show;
  301. CHAR buffer[100];
  302. Globals.hMDIWnd = 0;
  303. Globals.hMainMenu = 0;
  304. /* Get the geometry of the main window */
  305. GetPrivateProfileStringA("Settings", "Window", "", buffer, sizeof(buffer), Globals.lpszIniFile);
  306. if (5 == sscanf(buffer, "%d %d %d %d %d", &left, &top, &right, &bottom, &show))
  307. {
  308. width = right - left;
  309. height = bottom - top;
  310. }
  311. else
  312. {
  313. left = top = width = height = CW_USEDEFAULT;
  314. show = SW_SHOWNORMAL;
  315. }
  316. /* Create main Window */
  317. Globals.hMainWnd =
  318. CreateWindowW(STRING_MAIN_WIN_CLASS_NAME, NULL,
  319. WS_OVERLAPPEDWINDOW, left, top, width, height,
  320. 0, 0, Globals.hInstance, 0);
  321. ShowWindow (Globals.hMainWnd, show);
  322. UpdateWindow (Globals.hMainWnd);
  323. }
  324. /***********************************************************************
  325. *
  326. * MAIN_CreateMDIWindow
  327. */
  328. static VOID MAIN_CreateMDIWindow(void)
  329. {
  330. CLIENTCREATESTRUCT ccs;
  331. RECT rect;
  332. /* Get the geometry of the MDI window */
  333. GetClientRect(Globals.hMainWnd, &rect);
  334. ccs.hWindowMenu = Globals.hWindowsMenu;
  335. ccs.idFirstChild = PM_FIRST_CHILD;
  336. /* Create MDI Window */
  337. Globals.hMDIWnd =
  338. CreateWindowW(STRING_MDI_WIN_CLASS_NAME, NULL,
  339. WS_CHILD, rect.left, rect.top,
  340. rect.right - rect.left, rect.bottom - rect.top,
  341. Globals.hMainWnd, 0,
  342. Globals.hInstance, &ccs);
  343. ShowWindow (Globals.hMDIWnd, SW_SHOW);
  344. UpdateWindow (Globals.hMDIWnd);
  345. }
  346. /**********************************************************************/
  347. /***********************************************************************
  348. *
  349. * MAIN_MessageBoxIDS
  350. */
  351. INT MAIN_MessageBoxIDS(UINT ids_text, UINT ids_title, WORD type)
  352. {
  353. CHAR text[MAX_STRING_LEN];
  354. CHAR title[MAX_STRING_LEN];
  355. LoadStringA(Globals.hInstance, ids_text, text, sizeof(text));
  356. LoadStringA(Globals.hInstance, ids_title, title, sizeof(title));
  357. return(MessageBoxA(Globals.hMainWnd, text, title, type));
  358. }
  359. /***********************************************************************
  360. *
  361. * MAIN_MessageBoxIDS_s
  362. */
  363. INT MAIN_MessageBoxIDS_s(UINT ids_text, LPCSTR str, UINT ids_title, WORD type)
  364. {
  365. CHAR text[MAX_STRING_LEN];
  366. CHAR title[MAX_STRING_LEN];
  367. CHAR newtext[MAX_STRING_LEN + MAX_PATHNAME_LEN];
  368. LoadStringA(Globals.hInstance, ids_text, text, sizeof(text));
  369. LoadStringA(Globals.hInstance, ids_title, title, sizeof(title));
  370. wsprintfA(newtext, text, str);
  371. return(MessageBoxA(Globals.hMainWnd, newtext, title, type));
  372. }
  373. /***********************************************************************
  374. *
  375. * MAIN_ReplaceString
  376. */
  377. VOID MAIN_ReplaceString(HLOCAL *handle, LPSTR replace)
  378. {
  379. HLOCAL newhandle = LocalAlloc(LMEM_FIXED, strlen(replace) + 1);
  380. if (newhandle)
  381. {
  382. LPSTR newstring = LocalLock(newhandle);
  383. strcpy(newstring, replace);
  384. LocalFree(*handle);
  385. *handle = newhandle;
  386. }
  387. else MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_OK);
  388. }