Add .keep guard files in order to restore lost but empty directories we had with...
[reactos.git] / base / applications / rapps / winmain.c
index f7b3dbd..92c9bfa 100644 (file)
@@ -3,7 +3,8 @@
  * LICENSE:         GPL - See COPYING in the top level directory
  * FILE:            base/applications/rapps/winmain.c
  * PURPOSE:         Main program
- * PROGRAMMERS:     Dmitry Chapyshev (dmitry@reactos.org)
+ * PROGRAMMERS:     Dmitry Chapyshev           (dmitry@reactos.org)
+ *                  Ismael Ferreras Morezuelas (swyterzone+ros@gmail.com)
  */
 
 #include "rapps.h"
@@ -42,10 +43,14 @@ FillDefaultSettings(PSETTINGS_INFO pSettingsInfo)
     pSettingsInfo->bDelInstaller = FALSE;
 
     pSettingsInfo->Maximized = FALSE;
-    pSettingsInfo->Left = 0;
-    pSettingsInfo->Top = 0;
-    pSettingsInfo->Right = 680;
-    pSettingsInfo->Bottom = 450;
+    pSettingsInfo->Left = CW_USEDEFAULT;
+    pSettingsInfo->Top = CW_USEDEFAULT;
+    pSettingsInfo->Width = 680;
+    pSettingsInfo->Height = 450;
+
+    pSettingsInfo->Proxy = 0;
+    StringCbCopyW(pSettingsInfo->szProxyServer, sizeof(pSettingsInfo->szProxyServer), L"");
+    StringCbCopyW(pSettingsInfo->szNoProxyFor,  sizeof(pSettingsInfo->szNoProxyFor),  L"");
 }
 
 static BOOL
@@ -56,7 +61,7 @@ LoadSettings(VOID)
 
     if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\ReactOS\\rapps", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
     {
-        dwSize = sizeof(SETTINGS_INFO);
+        dwSize = sizeof(SettingsInfo);
         if (RegQueryValueExW(hKey, L"Settings", NULL, NULL, (LPBYTE)&SettingsInfo, &dwSize) == ERROR_SUCCESS)
         {
             RegCloseKey(hKey);
@@ -77,20 +82,20 @@ SaveSettings(HWND hwnd)
 
     if (SettingsInfo.bSaveWndPos)
     {
-        wp.length = sizeof(WINDOWPLACEMENT);
+        wp.length = sizeof(wp);
         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));
+        SettingsInfo.Width  = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
+        SettingsInfo.Height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
+        SettingsInfo.Maximized = (wp.showCmd == SW_MAXIMIZE || (wp.showCmd == SW_SHOWMINIMIZED && (wp.flags & WPF_RESTORETOMAXIMIZED)));
     }
 
     if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\ReactOS\\rapps", 0, NULL,
         REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
     {
-        RegSetValueExW(hKey, L"Settings", 0, REG_BINARY, (LPBYTE)&SettingsInfo, sizeof(SETTINGS_INFO));
+        RegSetValueExW(hKey, L"Settings", 0, REG_BINARY, (LPBYTE)&SettingsInfo, sizeof(SettingsInfo));
         RegCloseKey(hKey);
     }
 }
@@ -122,10 +127,17 @@ EnumInstalledAppProc(INT ItemIndex, LPWSTR lpName, PINSTALLED_INFO Info)
     INT Index;
 
     if (!SearchPatternMatch(lpName, szSearchPattern))
+    {
+        RegCloseKey(Info->hSubKey);
         return TRUE;
+    }
 
     ItemInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(INSTALLED_INFO));
-    if (!ItemInfo) return FALSE;
+    if (!ItemInfo)
+    {
+        RegCloseKey(Info->hSubKey);
+        return FALSE;
+    }
 
     RtlCopyMemory(ItemInfo, Info, sizeof(INSTALLED_INFO));
 
@@ -134,6 +146,7 @@ EnumInstalledAppProc(INT ItemIndex, LPWSTR lpName, PINSTALLED_INFO Info)
     /* Get version info */
     GetApplicationString(ItemInfo->hSubKey, L"DisplayVersion", szText);
     ListView_SetItemText(hListView, Index, 1, szText);
+
     /* Get comments */
     GetApplicationString(ItemInfo->hSubKey, L"Comments", szText);
     ListView_SetItemText(hListView, Index, 2, szText);
@@ -141,26 +154,10 @@ EnumInstalledAppProc(INT ItemIndex, LPWSTR lpName, PINSTALLED_INFO Info)
     return TRUE;
 }
 
-VOID
-FreeAvailableAppList(VOID)
-{
-    INT Count = ListView_GetItemCount(hListView) - 1;
-    PVOID Info;
-
-    while (Count >= 0)
-    {
-        Info = ListViewGetlParam(Count);
-        if (Info)
-            HeapFree(GetProcessHeap(), 0, Info);
-        Count--;
-    }
-}
-
 BOOL
 CALLBACK
 EnumAvailableAppProc(PAPPLICATION_INFO Info)
 {
-    PAPPLICATION_INFO ItemInfo;
     INT Index;
 
     if (!SearchPatternMatch(Info->szName, szSearchPattern) &&
@@ -171,16 +168,12 @@ EnumAvailableAppProc(PAPPLICATION_INFO Info)
 
     /* 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
+         -  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;
+        Index = ListViewAddItem(Info->Category, 0, Info->szName, (LPARAM)Info);
 
-        RtlCopyMemory(ItemInfo, Info, sizeof(APPLICATION_INFO));
-
-        Index = ListViewAddItem(Info->Category, 0, Info->szName, (LPARAM)ItemInfo);
         ListView_SetItemText(hListView, Index, 1, Info->szVersion);
         ListView_SetItemText(hListView, Index, 2, Info->szDesc);
     }
@@ -195,6 +188,13 @@ UpdateApplicationsList(INT EnumType)
     HICON hIcon;
     HIMAGELIST hImageListView;
 
+    SendMessage(hListView, WM_SETREDRAW, FALSE, 0);
+
+    if (EnumType == -1) EnumType = SelectedEnumType;
+
+    if (IS_INSTALLED_ENUM(SelectedEnumType))
+        FreeInstalledAppList();
+
     (VOID) ListView_DeleteAllItems(hListView);
 
     /* Create image list */
@@ -213,13 +213,6 @@ UpdateApplicationsList(INT EnumType)
     ImageList_AddIcon(hImageListView, hIcon);
     DestroyIcon(hIcon);
 
-    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 */
@@ -228,7 +221,7 @@ UpdateApplicationsList(INT EnumType)
     }
     else if (IS_AVAILABLE_ENUM(EnumType))
     {
-        /* Enum availabled applications */
+        /* Enum available applications */
         EnumAvailableApplications(EnumType, EnumAvailableAppProc);
     }
 
@@ -241,13 +234,19 @@ UpdateApplicationsList(INT EnumType)
 
     SelectedEnumType = EnumType;
 
-    LoadStringW(hInst, IDS_APPS_COUNT, szBuffer2, sizeof(szBuffer2) / sizeof(WCHAR));
+    LoadStringW(hInst, IDS_APPS_COUNT, szBuffer2, _countof(szBuffer2));
     StringCbPrintfW(szBuffer1, sizeof(szBuffer1),
                     szBuffer2,
                     ListView_GetItemCount(hListView));
     SetStatusBarText(szBuffer1);
 
     SetWelcomeText();
+
+    /* set automatic column width for program names if the list is not empty */
+    if (ListView_GetItemCount(hListView) > 0)
+        ListView_SetColumnWidth(hListView, 0, LVSCW_AUTOSIZE);
+
+    SendMessage(hListView, WM_SETREDRAW, TRUE, 0);
 }
 
 VOID
@@ -256,13 +255,13 @@ InitApplicationsList(VOID)
     WCHAR szText[MAX_STR_LEN];
 
     /* Add columns to ListView */
-    LoadStringW(hInst, IDS_APP_NAME, szText, sizeof(szText) / sizeof(WCHAR));
+    LoadStringW(hInst, IDS_APP_NAME, szText, _countof(szText));
     ListViewAddColumn(0, szText, 200, LVCFMT_LEFT);
 
-    LoadStringW(hInst, IDS_APP_INST_VERSION, szText, sizeof(szText) / sizeof(WCHAR));
+    LoadStringW(hInst, IDS_APP_INST_VERSION, szText, _countof(szText));
     ListViewAddColumn(1, szText, 90, LVCFMT_RIGHT);
 
-    LoadStringW(hInst, IDS_APP_DESCRIPTION, szText, sizeof(szText) / sizeof(WCHAR));
+    LoadStringW(hInst, IDS_APP_DESCRIPTION, szText, _countof(szText));
     ListViewAddColumn(3, szText, 250, LVCFMT_LEFT);
 
     UpdateApplicationsList(ENUM_ALL_COMPONENTS);
@@ -285,7 +284,7 @@ AddCategory(HTREEITEM hRootItem, UINT TextIndex, UINT IconIndex)
     Index = ImageList_AddIcon(hImageTreeView, hIcon);
     DestroyIcon(hIcon);
 
-    LoadStringW(hInst, TextIndex, szText, sizeof(szText) / sizeof(TCHAR));
+    LoadStringW(hInst, TextIndex, szText, _countof(szText));
 
     return TreeViewAddItem(hRootItem, szText, Index, Index, TextIndex);
 }
@@ -333,20 +332,12 @@ 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) &&
-        CreateTreeView(hwnd) &&
-        CreateRichEdit(hwnd) &&
+        CreateToolBar(hwnd)   &&
+        CreateListView(hwnd)  &&
+        CreateTreeView(hwnd)  &&
+        CreateRichEdit(hwnd)  &&
         CreateVSplitBar(hwnd) &&
         CreateHSplitBar(hwnd))
     {
@@ -356,7 +347,7 @@ InitControls(HWND hwnd)
 
         InitCategoriesList();
 
-        LoadStringW(hInst, IDS_APPS_COUNT, szBuffer2, sizeof(szBuffer2) / sizeof(WCHAR));
+        LoadStringW(hInst, IDS_APPS_COUNT, szBuffer2, _countof(szBuffer2));
         StringCbPrintfW(szBuffer1, sizeof(szBuffer1),
                         szBuffer2,
                         ListView_GetItemCount(hListView));
@@ -389,7 +380,7 @@ MainWndOnCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
             {
                 WCHAR szWndText[MAX_STR_LEN];
 
-                LoadStringW(hInst, IDS_SEARCH_TEXT, szBuf, sizeof(szBuf) / sizeof(WCHAR));
+                LoadStringW(hInst, IDS_SEARCH_TEXT, szBuf, _countof(szBuf));
                 GetWindowTextW(hSearchBar, szWndText, MAX_STR_LEN);
                 if (wcscmp(szBuf, szWndText) == 0)
                 {
@@ -404,7 +395,7 @@ MainWndOnCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
                 GetWindowTextW(hSearchBar, szBuf, MAX_STR_LEN);
                 if (wcslen(szBuf) < 1)
                 {
-                    LoadStringW(hInst, IDS_SEARCH_TEXT, szBuf, sizeof(szBuf) / sizeof(WCHAR));
+                    LoadStringW(hInst, IDS_SEARCH_TEXT, szBuf, _countof(szBuf));
                     SearchEnabled = FALSE;
                     SetWindowTextW(hSearchBar, szBuf);
                 }
@@ -421,7 +412,7 @@ MainWndOnCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
                     break;
                 }
 
-                LoadStringW(hInst, IDS_SEARCH_TEXT, szBuf, sizeof(szBuf) / sizeof(WCHAR));
+                LoadStringW(hInst, IDS_SEARCH_TEXT, szBuf, _countof(szBuf));
                 GetWindowTextW(hSearchBar, szWndText, MAX_STR_LEN);
                 if (wcscmp(szBuf, szWndText) != 0)
                 {
@@ -526,64 +517,73 @@ MainWndOnSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
      */
 
     /* Size vertical splitter bar */
-    DeferWindowPos(hdwp,
-                   hVSplitter,
-                   0,
-                   (VSplitterPos = GetWindowWidth(hTreeView)),
-                   GetWindowHeight(hToolBar),
-                   SPLIT_WIDTH,
-                   HIWORD(lParam) - GetWindowHeight(hToolBar) - GetWindowHeight(hStatusBar),
-                   SWP_NOZORDER|SWP_NOACTIVATE);
+    if (hdwp)
+        hdwp = DeferWindowPos(hdwp,
+                              hVSplitter,
+                              0,
+                              (VSplitterPos = GetWindowWidth(hTreeView)),
+                              GetWindowHeight(hToolBar),
+                              SPLIT_WIDTH,
+                              HIWORD(lParam) - GetWindowHeight(hToolBar) - GetWindowHeight(hStatusBar),
+                              SWP_NOZORDER|SWP_NOACTIVATE);
 
     /* Size TreeView */
-    DeferWindowPos(hdwp,
-                   hTreeView,
-                   0,
-                   0,
-                   GetWindowHeight(hToolBar),
-                   VSplitterPos,
-                   HIWORD(lParam) - GetWindowHeight(hToolBar) - GetWindowHeight(hStatusBar),
-                   SWP_NOZORDER|SWP_NOACTIVATE);
-
-    while (NewPos < SPLIT_WIDTH + GetWindowHeight(hToolBar))
+    if (hdwp)
+        hdwp = DeferWindowPos(hdwp,
+                              hTreeView,
+                              0,
+                              0,
+                              GetWindowHeight(hToolBar),
+                              VSplitterPos,
+                              HIWORD(lParam) - GetWindowHeight(hToolBar) - GetWindowHeight(hStatusBar),
+                              SWP_NOZORDER|SWP_NOACTIVATE);
+
+    if(wParam != SIZE_MINIMIZED)
     {
-        RichPos--;
-        NewPos = HIWORD(lParam) - (RichPos +
-                 SPLIT_WIDTH + GetWindowHeight(hStatusBar));
+        while (NewPos < SPLIT_WIDTH + GetWindowHeight(hToolBar))
+        {
+            RichPos--;
+            NewPos = HIWORD(lParam) - (RichPos +
+                     SPLIT_WIDTH + GetWindowHeight(hStatusBar));
+        }
     }
     SetHSplitterPos(NewPos);
 
     /* Size ListView */
-    DeferWindowPos(hdwp,
-                   hListView,
-                   0,
-                   VSplitterPos + SPLIT_WIDTH,
-                   GetWindowHeight(hToolBar),
-                   LOWORD(lParam) - (VSplitterPos + SPLIT_WIDTH),
-                   GetHSplitterPos() - GetWindowHeight(hToolBar),
-                   SWP_NOZORDER|SWP_NOACTIVATE);
+    if (hdwp)
+        hdwp = DeferWindowPos(hdwp,
+                              hListView,
+                              0,
+                              VSplitterPos + SPLIT_WIDTH,
+                              GetWindowHeight(hToolBar),
+                              LOWORD(lParam) - (VSplitterPos + SPLIT_WIDTH),
+                              GetHSplitterPos() - GetWindowHeight(hToolBar),
+                              SWP_NOZORDER|SWP_NOACTIVATE);
 
     /* Size RichEdit */
-    DeferWindowPos(hdwp,
-                   hRichEdit,
-                   0,
-                   VSplitterPos + SPLIT_WIDTH,
-                   GetHSplitterPos() + SPLIT_WIDTH,
-                   LOWORD(lParam) - (VSplitterPos + SPLIT_WIDTH),
-                   RichPos,
-                   SWP_NOZORDER|SWP_NOACTIVATE);
+    if (hdwp)
+        hdwp = DeferWindowPos(hdwp,
+                              hRichEdit,
+                              0,
+                              VSplitterPos + SPLIT_WIDTH,
+                              GetHSplitterPos() + SPLIT_WIDTH,
+                              LOWORD(lParam) - (VSplitterPos + SPLIT_WIDTH),
+                              RichPos,
+                              SWP_NOZORDER|SWP_NOACTIVATE);
 
     /* Size horizontal splitter bar */
-    DeferWindowPos(hdwp,
-                   hHSplitter,
-                   0,
-                   VSplitterPos + SPLIT_WIDTH,
-                   GetHSplitterPos(),
-                   LOWORD(lParam) - (VSplitterPos + SPLIT_WIDTH),
-                   SPLIT_WIDTH,
-                   SWP_NOZORDER|SWP_NOACTIVATE);
-
-    EndDeferWindowPos(hdwp);
+    if (hdwp)
+        hdwp = DeferWindowPos(hdwp,
+                              hHSplitter,
+                              0,
+                              VSplitterPos + SPLIT_WIDTH,
+                              GetHSplitterPos(),
+                              LOWORD(lParam) - (VSplitterPos + SPLIT_WIDTH),
+                              SPLIT_WIDTH,
+                              SWP_NOZORDER|SWP_NOACTIVATE);
+
+    if (hdwp)
+        EndDeferWindowPos(hdwp);
 }
 
 BOOL IsSelectedNodeInstalled(void)
@@ -608,12 +608,12 @@ BOOL IsSelectedNodeInstalled(void)
 LRESULT CALLBACK
 MainWindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
 {
+
     switch (Msg)
     {
         case WM_CREATE:
             if (!InitControls(hwnd))
                 PostMessage(hwnd, WM_CLOSE, 0, 0);
-
             break;
 
         case WM_COMMAND:
@@ -802,7 +802,8 @@ MainWindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
                 {
                     if (data->hwndFrom == hListView && ((LPNMLISTVIEW)lParam)->iItem != -1)
                     {
-                        SendMessage(hwnd, WM_COMMAND, ID_INSTALL, 0);   //Won't do anything if the program is already installed
+                        /* this won't do anything if the program is already installed */
+                        SendMessage(hwnd, WM_COMMAND, ID_INSTALL, 0);
                     }
                 }
                 break;
@@ -881,11 +882,13 @@ MainWindowProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
 
             FreeLogs();
 
-            if (IS_AVAILABLE_ENUM(SelectedEnumType))
-                FreeAvailableAppList();
+            FreeCachedAvailableEntries();
+
             if (IS_INSTALLED_ENUM(SelectedEnumType))
                 FreeInstalledAppList();
-            if (hImageTreeView) ImageList_Destroy(hImageTreeView);
+
+            if (hImageTreeView)
+                ImageList_Destroy(hImageTreeView);
 
             PostQuitMessage(0);
             return 0;
@@ -903,6 +906,7 @@ wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nSh
     WCHAR szWindowClass[] = L"ROSAPPMGR";
     WCHAR szWindowName[MAX_STR_LEN];
     HANDLE hMutex = NULL;
+    HACCEL KeyBrd;
     MSG Msg;
 
     switch (GetUserDefaultUILanguage())
@@ -939,7 +943,7 @@ wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nSh
     InitCommonControls();
 
     /* Create the window */
-    WndClass.cbSize        = sizeof(WNDCLASSEXW);
+    WndClass.cbSize        = sizeof(WndClass);
     WndClass.lpszClassName = szWindowClass;
     WndClass.lpfnWndProc   = MainWindowProc;
     WndClass.hInstance     = hInstance;
@@ -950,16 +954,16 @@ wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nSh
 
     if (RegisterClassExW(&WndClass) == (ATOM)0) goto Exit;
 
-    LoadStringW(hInst, IDS_APPTITLE, szWindowName, sizeof(szWindowName) / sizeof(WCHAR));
+    LoadStringW(hInst, IDS_APPTITLE, szWindowName, _countof(szWindowName));
 
     hMainWnd = CreateWindowExW(WS_EX_WINDOWEDGE,
                                szWindowClass,
                                szWindowName,
                                WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
-                               CW_USEDEFAULT,
-                               CW_USEDEFAULT,
-                               680,
-                               450,
+                               (SettingsInfo.bSaveWndPos ? SettingsInfo.Left   : CW_USEDEFAULT),
+                               (SettingsInfo.bSaveWndPos ? SettingsInfo.Top    : CW_USEDEFAULT),
+                               (SettingsInfo.bSaveWndPos ? SettingsInfo.Width  : 680),
+                               (SettingsInfo.bSaveWndPos ? SettingsInfo.Height : 450),
                                NULL,
                                NULL,
                                hInstance,
@@ -967,22 +971,29 @@ wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nSh
 
     if (!hMainWnd) goto Exit;
 
-    /* Show it */
-    ShowWindow(hMainWnd, nShowCmd);
+    /* Maximize it if we must */
+    ShowWindow(hMainWnd, (SettingsInfo.bSaveWndPos && SettingsInfo.Maximized ? SW_MAXIMIZE : nShowCmd));
     UpdateWindow(hMainWnd);
 
     if (SettingsInfo.bUpdateAtStart)
         UpdateAppsDB();
 
+    /* Load the menu hotkeys */
+    KeyBrd = LoadAccelerators(NULL, MAKEINTRESOURCE(HOTKEYS));
+
     /* Message Loop */
     while (GetMessage(&Msg, NULL, 0, 0))
     {
-        TranslateMessage(&Msg);
-        DispatchMessage(&Msg);
+        if (!TranslateAccelerator(hMainWnd, KeyBrd, &Msg))
+        {
+            TranslateMessage(&Msg);
+            DispatchMessage(&Msg);
+        }
     }
 
 Exit:
-    if (hMutex) CloseHandle(hMutex);
+    if (hMutex)
+        CloseHandle(hMutex);
 
     return 0;
 }