[APPLICATIONS]
[reactos.git] / reactos / base / applications / rapps / winmain.c
index 3e6d636..d722fac 100644 (file)
 
 HWND hMainWnd;
 HINSTANCE hInst;
-HIMAGELIST hImageListView = NULL;
 HIMAGELIST hImageTreeView = NULL;
 INT SelectedEnumType = ENUM_ALL_COMPONENTS;
+SETTINGS_INFO SettingsInfo;
 
 
-CALLBACK
+VOID
+FillDafaultSettings(PSETTINGS_INFO pSettingsInfo)
+{
+    pSettingsInfo->bSaveWndPos = TRUE;
+    pSettingsInfo->bUpdateAtStart = FALSE;
+    pSettingsInfo->bLogEnabled = TRUE;
+    wcscpy(pSettingsInfo->szDownloadDir, L"C:\\Downloads");
+    pSettingsInfo->bDelInstaller = FALSE;
+
+    pSettingsInfo->Maximized = FALSE;
+    pSettingsInfo->Left = 0;
+    pSettingsInfo->Top = 0;
+    pSettingsInfo->Right = 680;
+    pSettingsInfo->Bottom = 450;
+}
+
+static BOOL
+LoadSettings(VOID)
+{
+    HKEY hKey;
+    DWORD dwSize;
+
+    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\ReactOS\\rapps", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+    {
+        dwSize = sizeof(SETTINGS_INFO);
+        if (RegQueryValueExW(hKey, L"Settings", NULL, NULL, (LPBYTE)&SettingsInfo, &dwSize) == ERROR_SUCCESS)
+        {
+            RegCloseKey(hKey);
+            return TRUE;
+        }
+
+        RegCloseKey(hKey);
+    }
+
+    return FALSE;
+}
+
+VOID
+SaveSettings(HWND hwnd)
+{
+    WINDOWPLACEMENT wp;
+    HKEY hKey;
+
+    if (SettingsInfo.bSaveWndPos)
+    {
+        wp.length = sizeof(WINDOWPLACEMENT);
+        GetWindowPlacement(hwnd, &wp);
+
+        SettingsInfo.Left = wp.rcNormalPosition.left;
+        SettingsInfo.Top  = wp.rcNormalPosition.top;
+        SettingsInfo.Right  = wp.rcNormalPosition.right;
+        SettingsInfo.Bottom = wp.rcNormalPosition.bottom;
+        SettingsInfo.Maximized = (IsZoomed(hwnd) || (wp.flags & WPF_RESTORETOMAXIMIZED));
+    }
+
+    if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"Software\\ReactOS\\rapps", 0, NULL,
+        REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
+    {
+        RegSetValueEx(hKey, L"Settings", 0, REG_BINARY, (LPBYTE)&SettingsInfo, sizeof(SETTINGS_INFO));
+        RegCloseKey(hKey);
+    }
+}
+
+VOID
+FreeInstalledAppList(VOID)
+{
+    INT Count = ListView_GetItemCount(hListView) - 1;
+    PINSTALLED_INFO Info;
+
+    while (Count >= 0)
+    {
+        Info = ListViewGetlParam(Count);
+        if (Info)
+        {
+            RegCloseKey(Info->hSubKey);
+            HeapFree(GetProcessHeap(), 0, Info);
+        }
+        Count--;
+    }
+}
+
 BOOL
-EnumInstalledAppProc(INT ItemIndex, LPWSTR lpName, LPWSTR lpKeyName, LPARAM lParam)
+CALLBACK
+EnumInstalledAppProc(INT ItemIndex, LPWSTR lpName, INSTALLED_INFO Info)
 {
+    PINSTALLED_INFO ItemInfo;
     WCHAR szText[MAX_PATH];
     INT Index;
 
-    Index = ListViewAddItem(ItemIndex, 0, lpName, lParam);
+    ItemInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(INSTALLED_INFO));
+    if (!ItemInfo) return FALSE;
+
+    *ItemInfo = Info;
+
+    Index = ListViewAddItem(ItemIndex, 0, lpName, (LPARAM)ItemInfo);
 
     /* Get version info */
-    GetApplicationString((HKEY)lParam, L"DisplayVersion", szText);
+    GetApplicationString((HKEY)ItemInfo->hSubKey, L"DisplayVersion", szText);
     ListView_SetItemText(hListView, Index, 1, szText);
     /* Get comments */
-    GetApplicationString((HKEY)lParam, L"Comments", szText);
+    GetApplicationString((HKEY)ItemInfo->hSubKey, L"Comments", szText);
     ListView_SetItemText(hListView, Index, 2, szText);
 
     return TRUE;
@@ -49,14 +136,18 @@ FreeAvailableAppList(VOID)
     }
 }
 
-CALLBACK
 BOOL
+CALLBACK
 EnumAvailableAppProc(APPLICATION_INFO Info)
 {
     PAPPLICATION_INFO ItemInfo;
     INT Index;
 
-    if (!IsInstalledApplication(Info.szRegName))
+    /* Only add a ListView entry if...
+         - no RegName was supplied (so we cannot determine whether the application is installed or not) or
+         - a RegName was supplied and the application is not installed
+    */
+    if (!*Info.szRegName || (!IsInstalledApplication(Info.szRegName, FALSE) && !IsInstalledApplication(Info.szRegName, TRUE)))
     {
         ItemInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(APPLICATION_INFO));
         if (!ItemInfo) return FALSE;
@@ -76,8 +167,8 @@ UpdateApplicationsList(INT EnumType)
 {
     WCHAR szBuffer1[MAX_STR_LEN], szBuffer2[MAX_STR_LEN];
     HICON hIcon;
+    HIMAGELIST hImageListView;
 
-    if (hImageListView) ImageList_Destroy(hImageListView);
     (VOID) ListView_DeleteAllItems(hListView);
 
     /* Create image list */
@@ -98,22 +189,29 @@ UpdateApplicationsList(INT EnumType)
 
     if (EnumType == -1) EnumType = SelectedEnumType;
 
+    if (IS_INSTALLED_ENUM(SelectedEnumType))
+        FreeInstalledAppList();
+    else if (IS_AVAILABLE_ENUM(SelectedEnumType))
+        FreeAvailableAppList();
+
     if (IS_INSTALLED_ENUM(EnumType))
     {
         /* Enum installed applications and updates */
-        EnumInstalledApplications(EnumType, EnumInstalledAppProc);
+        EnumInstalledApplications(EnumType, TRUE, EnumInstalledAppProc);
+        EnumInstalledApplications(EnumType, FALSE, EnumInstalledAppProc);
     }
     else if (IS_AVAILABLE_ENUM(EnumType))
     {
-        if (IS_AVAILABLE_ENUM(SelectedEnumType))
-            FreeAvailableAppList();
-
         /* Enum availabled applications */
         EnumAvailableApplications(EnumType, EnumAvailableAppProc);
     }
 
     /* Set image list for ListView */
-    (VOID) ListView_SetImageList(hListView, hImageListView, LVSIL_SMALL);
+    hImageListView = ListView_SetImageList(hListView, hImageListView, LVSIL_SMALL);
+
+    /* Destroy old image list */
+    if (hImageListView)
+               ImageList_Destroy(hImageListView);
 
     SelectedEnumType = EnumType;
 
@@ -207,6 +305,15 @@ InitCategoriesList(VOID)
 BOOL
 InitControls(HWND hwnd)
 {
+    if (SettingsInfo.bSaveWndPos)
+    {
+        MoveWindow(hwnd, SettingsInfo.Left, SettingsInfo.Top,
+                   SettingsInfo.Right - SettingsInfo.Left,
+                   SettingsInfo.Bottom - SettingsInfo.Top, TRUE);
+
+        if (SettingsInfo.Maximized) ShowWindow(hwnd, SW_MAXIMIZE);
+    }
+
     if (CreateStatusBar(hwnd) &&
         CreateToolBar(hwnd) &&
         CreateListView(hwnd) &&
@@ -308,6 +415,10 @@ MainWndOnCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
                 UpdateApplicationsList(-1);
             break;
 
+        case ID_REGREMOVE:
+            RemoveAppFromRegistry(-1);
+            break;
+
         case ID_REFRESH:
             UpdateApplicationsList(-1);
             break;
@@ -328,7 +439,7 @@ MainWndOnSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
     HDWP hdwp = BeginDeferWindowPos(5);
     INT SearchBarWidth = GetWindowWidth(hSearchBar);
     INT RichPos = GetWindowHeight(hRichEdit);
-    INT NewPos = GetClientWindowHeight(hMainWnd) - (RichPos + SPLIT_WIDTH + GetWindowHeight(hStatusBar));
+    INT NewPos = HIWORD(lParam) - (RichPos + SPLIT_WIDTH + GetWindowHeight(hStatusBar));
     INT VSplitterPos;
 
     /* Size status bar */
@@ -368,7 +479,7 @@ MainWndOnSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
     while (NewPos < SPLIT_WIDTH + GetWindowHeight(hToolBar))
     {
         RichPos--;
-        NewPos = GetClientWindowHeight(hMainWnd) - (RichPos +
+        NewPos = HIWORD(lParam) - (RichPos +
                  SPLIT_WIDTH + GetWindowHeight(hStatusBar));
     }
     SetHSplitterPos(NewPos);
@@ -389,7 +500,7 @@ MainWndOnSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
                    0,
                    VSplitterPos + SPLIT_WIDTH,
                    GetHSplitterPos() + SPLIT_WIDTH,
-                   GetClientWindowWidth(hMainWnd) - (VSplitterPos + SPLIT_WIDTH),
+                   LOWORD(lParam) - (VSplitterPos + SPLIT_WIDTH),
                    RichPos,
                    SWP_NOZORDER|SWP_NOACTIVATE);
 
@@ -399,7 +510,7 @@ MainWndOnSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
                    0,
                    VSplitterPos + SPLIT_WIDTH,
                    GetHSplitterPos(),
-                   GetClientWindowWidth(hMainWnd) - (VSplitterPos + SPLIT_WIDTH),
+                   LOWORD(lParam) - (VSplitterPos + SPLIT_WIDTH),
                    SPLIT_WIDTH,
                    SWP_NOZORDER|SWP_NOACTIVATE);
 
@@ -414,6 +525,9 @@ MainWindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
         case WM_CREATE:
             if (!InitControls(hwnd))
                 PostMessage(hwnd, WM_CLOSE, 0, 0);
+
+            if (SettingsInfo.bUpdateAtStart)
+                UpdateAppsDB();
             break;
 
         case WM_COMMAND:
@@ -603,12 +717,28 @@ MainWindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
             return TRUE;
         }
 
+        case WM_SYSCOLORCHANGE:
+        {
+            /* Forward WM_SYSCOLORCHANGE to common controls */
+            SendMessage(hListView, WM_SYSCOLORCHANGE, 0, 0);
+            SendMessage(hTreeView, WM_SYSCOLORCHANGE, 0, 0);
+            SendMessage(hToolBar, WM_SYSCOLORCHANGE, 0, 0);
+        }
+        break;
+
         case WM_DESTROY:
         {
+            ShowWindow(hwnd, SW_HIDE);
+            SaveSettings(hwnd);
+
+            FreeLogs();
+
             if (IS_AVAILABLE_ENUM(SelectedEnumType))
                 FreeAvailableAppList();
-            if (hImageListView) ImageList_Destroy(hImageListView);
+            if (IS_INSTALLED_ENUM(SelectedEnumType))
+                FreeInstalledAppList();
             if (hImageTreeView) ImageList_Destroy(hImageTreeView);
+
             PostQuitMessage(0);
             return 0;
         }
@@ -624,9 +754,19 @@ wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nSh
     WNDCLASSEXW WndClass = {0};
     WCHAR szWindowClass[] = L"ROSAPPMGR";
     WCHAR szWindowName[MAX_STR_LEN];
+    WCHAR szErrorText[MAX_STR_LEN];
     HANDLE hMutex = NULL;
     MSG Msg;
 
+    hInst = hInstance;
+
+    if (!IsUserAnAdmin())
+    {
+        LoadStringW(hInst, IDS_USER_NOT_ADMIN, szErrorText, sizeof(szErrorText) / sizeof(WCHAR));
+        MessageBox(0, szErrorText, NULL, MB_OK | MB_ICONWARNING);
+        return 1;
+    }
+
     hMutex = CreateMutexW(NULL, FALSE, szWindowClass);
     if ((!hMutex) || (GetLastError() == ERROR_ALREADY_EXISTS))
     {
@@ -639,7 +779,12 @@ wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nSh
         return 1;
     }
 
-    hInst = hInstance;
+    if (!LoadSettings())
+    {
+        FillDafaultSettings(&SettingsInfo);
+    }
+
+    InitLogs();
 
     InitCommonControls();