5fa47d6ecf21e7b4fa9e523a61d577578de62ff2
[reactos.git] / reactos / base / applications / rapps / winmain.cpp
1 /*
2 * PROJECT: ReactOS Applications Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/rapps/winmain.cpp
5 * PURPOSE: Main program
6 * PROGRAMMERS: Dmitry Chapyshev (dmitry@reactos.org)
7 * Ismael Ferreras Morezuelas (swyterzone+ros@gmail.com)
8 * Alexander Shaposhnikov (chaez.san@gmail.com)
9 */
10 #include "defines.h"
11
12 #include "rapps.h"
13
14 #include <atlbase.h>
15 #include <atlcom.h>
16 #include <shellapi.h>
17
18 HWND hMainWnd;
19 HINSTANCE hInst;
20 INT SelectedEnumType = ENUM_ALL_COMPONENTS;
21 SETTINGS_INFO SettingsInfo;
22
23 ATL::CStringW szSearchPattern;
24
25 class CRAppsModule : public CComModule
26 {
27 public:
28 };
29
30 BEGIN_OBJECT_MAP(ObjectMap)
31 END_OBJECT_MAP()
32
33 CRAppsModule gModule;
34 CAtlWinModule gWinModule;
35
36 //void *operator new (size_t, void *buf)
37 //{
38 // return buf;
39 //}
40
41 static VOID InitializeAtlModule(HINSTANCE hInstance, BOOL bInitialize)
42 {
43 if (bInitialize)
44 {
45 gModule.Init(ObjectMap, hInstance, NULL);
46 }
47 else
48 {
49 gModule.Term();
50 }
51 }
52
53 VOID FillDefaultSettings(PSETTINGS_INFO pSettingsInfo)
54 {
55 ATL::CStringW szDownloadDir;
56
57 pSettingsInfo->bSaveWndPos = TRUE;
58 pSettingsInfo->bUpdateAtStart = FALSE;
59 pSettingsInfo->bLogEnabled = TRUE;
60
61 if (FAILED(SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, szDownloadDir.GetBuffer(MAX_PATH))))
62 {
63 szDownloadDir.ReleaseBuffer();
64 if (!szDownloadDir.GetEnvironmentVariableW(L"SystemDrive"))
65 {
66 szDownloadDir = L"C:";
67 }
68 }
69 else
70 {
71 szDownloadDir.ReleaseBuffer();
72 }
73
74 szDownloadDir += L"\\RAPPS Downloads";
75 ATL::CStringW::CopyChars(pSettingsInfo->szDownloadDir,
76 _countof(pSettingsInfo->szDownloadDir),
77 szDownloadDir.GetString(),
78 szDownloadDir.GetLength() + 1);
79
80 pSettingsInfo->bDelInstaller = FALSE;
81 pSettingsInfo->Maximized = FALSE;
82 pSettingsInfo->Left = CW_USEDEFAULT;
83 pSettingsInfo->Top = CW_USEDEFAULT;
84 pSettingsInfo->Width = 680;
85 pSettingsInfo->Height = 450;
86 pSettingsInfo->Proxy = 0;
87
88 pSettingsInfo->szProxyServer[0] = UNICODE_NULL;
89 pSettingsInfo->szNoProxyFor[0] = UNICODE_NULL;
90 }
91
92 static BOOL LoadSettings()
93 {
94 ATL::CRegKey RegKey;
95 DWORD dwSize;
96 BOOL bResult = FALSE;
97 if (RegKey.Open(HKEY_CURRENT_USER, L"Software\\ReactOS\\rapps", KEY_READ) == ERROR_SUCCESS)
98 {
99 dwSize = sizeof(SettingsInfo);
100 bResult = (RegKey.QueryBinaryValue(L"Settings", (PVOID) &SettingsInfo, &dwSize) == ERROR_SUCCESS);
101
102 RegKey.Close();
103 }
104
105 return bResult;
106 }
107
108 VOID SaveSettings(HWND hwnd)
109 {
110 WINDOWPLACEMENT wp;
111 ATL::CRegKey RegKey;
112
113 if (SettingsInfo.bSaveWndPos)
114 {
115 wp.length = sizeof(wp);
116 GetWindowPlacement(hwnd, &wp);
117
118 SettingsInfo.Left = wp.rcNormalPosition.left;
119 SettingsInfo.Top = wp.rcNormalPosition.top;
120 SettingsInfo.Width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
121 SettingsInfo.Height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
122 SettingsInfo.Maximized = (wp.showCmd == SW_MAXIMIZE
123 || (wp.showCmd == SW_SHOWMINIMIZED
124 && (wp.flags & WPF_RESTORETOMAXIMIZED)));
125 }
126
127 if (RegKey.Create(HKEY_CURRENT_USER, L"Software\\ReactOS\\rapps", NULL,
128 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, NULL) == ERROR_SUCCESS)
129 {
130 RegKey.SetBinaryValue(L"Settings", (const PVOID) &SettingsInfo, sizeof(SettingsInfo));
131 RegKey.Close();
132 }
133 }
134
135
136 #define CMD_KEY_SETUP L"/SETUP"
137
138 // return TRUE if the SETUP key was valid
139 BOOL CmdParser(LPWSTR lpCmdLine)
140 {
141 INT argc;
142 LPWSTR* argv = CommandLineToArgvW(lpCmdLine, &argc);
143 CAvailableApps apps;
144 PAPPLICATION_INFO appInfo;
145 ATL::CString szName;
146
147 if (!argv || argc < 2 || StrCmpW(argv[0], CMD_KEY_SETUP))
148 {
149 return FALSE;
150 }
151
152 apps.EnumAvailableApplications(ENUM_ALL_AVAILABLE, NULL);
153 appInfo = apps.FindInfo(argv[1]);
154 if (appInfo)
155 {
156 CDownloadManager::DownloadApplication(appInfo, TRUE);
157 return TRUE;
158 }
159
160 return FALSE;
161 }
162
163 INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
164 {
165 LPCWSTR szWindowClass = L"ROSAPPMGR";
166 HANDLE hMutex = NULL;
167 HACCEL KeyBrd = NULL;
168 MSG Msg;
169
170 InitializeAtlModule(hInstance, TRUE);
171
172 if (GetUserDefaultUILanguage() == MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT))
173 {
174 SetProcessDefaultLayout(LAYOUT_RTL);
175 }
176
177 hInst = hInstance;
178
179 hMutex = CreateMutexW(NULL, FALSE, szWindowClass);
180 if ((!hMutex) || (GetLastError() == ERROR_ALREADY_EXISTS))
181 {
182 /* If already started, it is found its window */
183 HWND hWindow = FindWindowW(szWindowClass, NULL);
184
185 /* Activate window */
186 ShowWindow(hWindow, SW_SHOWNORMAL);
187 SetForegroundWindow(hWindow);
188 return 1;
189 }
190
191 if (!LoadSettings())
192 {
193 FillDefaultSettings(&SettingsInfo);
194 }
195
196 InitLogs();
197
198 InitCommonControls();
199
200 //skip window creation if there were some keys
201 if (!CmdParser(lpCmdLine))
202 {
203 hMainWnd = CreateMainWindow();
204 if (hMainWnd)
205 {
206 /* Maximize it if we must */
207 ShowWindow(hMainWnd, (SettingsInfo.bSaveWndPos && SettingsInfo.Maximized ? SW_MAXIMIZE : nShowCmd));
208 UpdateWindow(hMainWnd);
209
210 //TODO: get around the ugliness
211 if (SettingsInfo.bUpdateAtStart)
212 GetAvailableApps()->UpdateAppsDB();
213
214 /* Load the menu hotkeys */
215 KeyBrd = LoadAcceleratorsW(NULL, MAKEINTRESOURCEW(HOTKEYS));
216
217 /* Message Loop */
218 while (GetMessageW(&Msg, NULL, 0, 0))
219 {
220 if (!TranslateAcceleratorW(hMainWnd, KeyBrd, &Msg))
221 {
222 TranslateMessage(&Msg);
223 DispatchMessageW(&Msg);
224 }
225 }
226 }
227 }
228
229 if (hMutex)
230 CloseHandle(hMutex);
231
232 InitializeAtlModule(hInstance, FALSE);
233
234 return 0;
235 }