Author: ashaposhnikov
Date: Tue Jul 18 22:52:51 2017
New Revision: 75373
URL: 
http://svn.reactos.org/svn/reactos?rev=75373&view=rev
Log:
[RAPPS] Refactoring & bugfixes
- Made a bunch of classes for Available apps;
- Removed unnessesary GetBuffer calls;
- Set a bit higher minimum height for RichEdit;
- Added "Single" indicator for the Languages to show that the translation
available is the only one;
- Small style changes.
Modified:
    branches/GSoC_2017/rapps/reactos/base/applications/rapps/available.cpp
    branches/GSoC_2017/rapps/reactos/base/applications/rapps/crichedit.h
    branches/GSoC_2017/rapps/reactos/base/applications/rapps/gui.cpp
    branches/GSoC_2017/rapps/reactos/base/applications/rapps/installed.cpp
    branches/GSoC_2017/rapps/reactos/base/applications/rapps/lang/en-US.rc
    branches/GSoC_2017/rapps/reactos/base/applications/rapps/loaddlg.cpp
    branches/GSoC_2017/rapps/reactos/base/applications/rapps/misc.cpp
    branches/GSoC_2017/rapps/reactos/base/applications/rapps/rapps.h
    branches/GSoC_2017/rapps/reactos/base/applications/rapps/resource.h
    branches/GSoC_2017/rapps/reactos/base/applications/rapps/winmain.cpp
Modified: branches/GSoC_2017/rapps/reactos/base/applications/rapps/available.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2017/rapps/reactos/base/ap…
==============================================================================
--- branches/GSoC_2017/rapps/reactos/base/applications/rapps/available.cpp
[iso-8859-1] (original)
+++ branches/GSoC_2017/rapps/reactos/base/applications/rapps/available.cpp
[iso-8859-1] Tue Jul 18 22:52:51 2017
@@ -2,7 +2,7 @@
  * PROJECT:         ReactOS Applications Manager
  * LICENSE:         GPL - See COPYING in the top level directory
  * FILE:            base/applications/rapps/available.cpp
- * PURPOSE:         Functions for working with available applications
+ * PURPOSE:         Classes for working with available applications
  * PROGRAMMERS:     Dmitry Chapyshev           (dmitry(a)reactos.org)
  *                  Ismael Ferreras Morezuelas (swyterzone+ros(a)gmail.com)
  *                  Alexander Shaposhnikov     (chaez.san(a)gmail.com)
@@ -10,265 +10,212 @@
 #include "rapps.h"
-ATL::CAtlList<PAPPLICATION_INFO> InfoList;
-
-inline VOID
-InsertTextAfterLoaded_RichEdit(UINT uStringID, const ATL::CStringW& szText, DWORD
StringFlags, DWORD TextFlags)
-{
-    ATL::CStringW szLoadedText;
-    if (!szText.IsEmpty() && szLoadedText.LoadStringW(hInst, uStringID))
-    {
-        InsertRichEditText(szLoadedText, StringFlags);
-        InsertRichEditText(szText, TextFlags);
-    }
-}
-
-inline VOID
-InsertLoadedTextNewl_RichEdit(UINT uStringID, DWORD StringFlags)
-{
-    ATL::CStringW szLoadedText;
-    if (szLoadedText.LoadStringW(hInst, uStringID))
-    {
-        InsertRichEditText(L"\n", 0);
-        InsertRichEditText(szLoadedText, StringFlags);
-        InsertRichEditText(L"\n", 0);
-    }
-}
-
-inline BOOL
-GetString(LPCWSTR lpKeyName, ATL::CStringW& ReturnedString, const ATL::CStringW&
cFileName)
-{
-    if (!ParserGetString(lpKeyName, cFileName, ReturnedString))
-    {
-        ReturnedString.Empty();
-        return FALSE;
-    }
-    return TRUE;
-}
-
-//Check both registry keys in 64bit system
-//TODO: check system type beforehand to avoid double checks?
-inline BOOL
-GetInstalledVersionEx(PAPPLICATION_INFO Info, ATL::CStringW* szVersion, REGSAM key)
-{
-    return (!Info->szRegName.IsEmpty()
-            && (GetInstalledVersion_WowUser(szVersion, Info->szRegName, TRUE,
key)
-                || GetInstalledVersion_WowUser(szVersion, Info->szRegName, FALSE,
key)))
-        || (!Info->szName.IsEmpty()
-            && (GetInstalledVersion_WowUser(szVersion, Info->szName, TRUE,
key)
-                || GetInstalledVersion_WowUser(szVersion, Info->szName, FALSE, key)));
-}
-
-inline BOOL
-GetInstalledVersion(PAPPLICATION_INFO Info, ATL::CStringW* szVersion)
-{
-    return  GetInstalledVersionEx(Info, szVersion, KEY_WOW64_32KEY)
-        || GetInstalledVersionEx(Info, szVersion, KEY_WOW64_64KEY);
-}
-
-inline BOOL
-IsAppInstalled(PAPPLICATION_INFO Info)
-{
-    return GetInstalledVersion(Info, NULL);
-}
-
-ATL::CSimpleArray<ATL::CStringW>
-ParserGetAppLanguages(const ATL::CStringW& szFileName)
+ // CAvailableApplicationInfo
+
+CAvailableApplicationInfo::CAvailableApplicationInfo(const ATL::CStringW&
sFileNameParam)
+{
+    LicenseType = LICENSE_TYPE::None;
+    sFileName = sFileNameParam;
+    RetrieveCategory();
+}
+
+VOID CAvailableApplicationInfo::RefreshAppInfo()
+{
+    if (RetrieveGeneralInfo())
+    {
+        RetrieveLicenseType();
+        RetrieveLanguages();
+        RetrieveInstalledStatus();
+        if (m_IsInstalled)
+        {
+            RetrieveInstalledVersion();
+        }
+    }
+}
+
+BOOL CAvailableApplicationInfo::RetrieveGeneralInfo()
+{
+    if (szUrlDownload.IsEmpty())
+    {
+        if (!GetString(L"Name", szName)
+            || !GetString(L"URLDownload", szUrlDownload))
+        {
+            return FALSE;
+        }
+
+        GetString(L"RegName", szRegName);
+        GetString(L"Version", szVersion);
+        GetString(L"License", szLicense);
+        GetString(L"Description", szDesc);
+        GetString(L"Size", szSize);
+        GetString(L"URLSite", szUrlSite);
+        GetString(L"CDPath", szCDPath);
+        GetString(L"Language", szRegName);
+        GetString(L"SHA1", szSHA1);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+VOID CAvailableApplicationInfo::RetrieveInstalledStatus()
+{
+    m_IsInstalled = ::GetInstalledVersion(NULL, szRegName)
+        || ::GetInstalledVersion(NULL, szName);
+}
+
+VOID CAvailableApplicationInfo::RetrieveInstalledVersion()
+{
+    m_HasInstalledVersion = ::GetInstalledVersion(&szInstalledVersion, szRegName)
+        || ::GetInstalledVersion(&szInstalledVersion, szName);
+}
+
+BOOL CAvailableApplicationInfo::RetrieveLanguages()
 {
     const WCHAR cDelimiter = L'|';
     ATL::CStringW szBuffer;
-    if (!ParserGetString(L"Languages", szFileName, szBuffer))
-        return CSimpleArray<ATL::CStringW>();
-
+    // TODO: Get multiline parameter
+    if (!ParserGetString(L"Languages", sFileName, szBuffer))
+        return FALSE;
+
+    // Parse parameter string
     ATL::CStringW szLocale;
-    ATL::CSimpleArray<ATL::CStringW> arrLocalesResult;
     for (INT i = 0; szBuffer[i] != UNICODE_NULL; ++i)
     {
         if (szBuffer[i] != cDelimiter)
         {
             szLocale += szBuffer[i];
-        } else {
-            arrLocalesResult.Add(szLocale);
+        }
+        else
+        {
+            Languages.Add(szLocale);
             szLocale.Empty();
         }
     }
+
     // For the text after delimiter
     if (!szLocale.IsEmpty())
     {
-        arrLocalesResult.Add(szLocale);
-    }
-    return arrLocalesResult;
-}
-
-BOOL
-HasNativeLanguage(PAPPLICATION_INFO Info)
-{
-    if (!Info)
-    {
-        return FALSE;
-    }
+        Languages.Add(szLocale);
+    }
+
+    return TRUE;
+}
+
+VOID CAvailableApplicationInfo::RetrieveLicenseType()
+{
+    INT IntBuffer = ParserGetInt(L"LicenseType", sFileName);
+
+    if (IntBuffer < 0 || IntBuffer > LICENSE_TYPE::Max)
+    {
+        LicenseType = LICENSE_TYPE::None;
+    }
+    else
+    {
+        LicenseType = (LICENSE_TYPE) IntBuffer;
+    }
+}
+
+VOID CAvailableApplicationInfo::RetrieveCategory()
+{
+    Category = ParserGetInt(L"Category", sFileName);
+}
+
+BOOL CAvailableApplicationInfo::HasLanguageInfo() const
+{
+    return m_HasLanguageInfo;
+}
+
+BOOL CAvailableApplicationInfo::HasNativeLanguage() const
+{
+    if (!m_HasLanguageInfo)
+    {
+        return FALSE;
+    }
+
     //TODO: make the actual check
     return TRUE;
 }
-BOOL
-HasEnglishLanguage(PAPPLICATION_INFO Info)
-{
-    if (!Info)
-    {
-        return FALSE;
-    }
+
+BOOL CAvailableApplicationInfo::HasEnglishLanguage() const
+{
+    if (!m_HasLanguageInfo)
+    {
+        return FALSE;
+    }
+
     //TODO: make the actual check
     return TRUE;
 }
-LICENSE_TYPE
-ParserGetLicenseType(const ATL::CStringW& szFileName)
-{
-    INT IntBuffer = ParserGetInt(L"LicenseType", szFileName);
-    if (IntBuffer < 0 || IntBuffer > LICENSE_TYPE::Max)
-    {
-        return LICENSE_TYPE::None;
-    }
-    return (LICENSE_TYPE) IntBuffer;
-}
-
-LIST_ENTRY CachedEntriesHead = {&CachedEntriesHead, &CachedEntriesHead};
-PLIST_ENTRY pCachedEntry = &CachedEntriesHead;
-
-VOID
-InsertVersionInfo_RichEdit(PAPPLICATION_INFO Info)
-{
-    ATL::CStringW szVersion;
-    BOOL bIsInstalled = IsAppInstalled(Info),
-        bHasVersion = GetInstalledVersion(Info, &szVersion);
-
-    if (bIsInstalled)
-    {
-        if (bHasVersion)
-        {
-            if (Info->szVersion.Compare(szVersion) > 0)
-                InsertLoadedTextNewl_RichEdit(IDS_STATUS_UPDATE_AVAILABLE, CFE_ITALIC);
-            else
-                InsertLoadedTextNewl_RichEdit(IDS_STATUS_INSTALLED, CFE_ITALIC);
-
-            InsertTextAfterLoaded_RichEdit(IDS_AINFO_VERSION, szVersion, CFE_BOLD, 0);
-        }
-        else
-        {
-            InsertLoadedTextNewl_RichEdit(IDS_STATUS_INSTALLED, CFE_ITALIC);
-        }
-    }
-    else
-    {
-        InsertLoadedTextNewl_RichEdit(IDS_STATUS_NOTINSTALLED, CFE_ITALIC);
-    }
-
-    InsertTextAfterLoaded_RichEdit(IDS_AINFO_AVAILABLEVERSION, Info->szVersion,
CFE_BOLD, 0);
-}
-
-VOID
-InsertLicenseInfo_RichEdit(PAPPLICATION_INFO Info)
-{
-    ATL::CStringW szLicense;
-    switch (Info->LicenseType)
-    {
-    case LICENSE_TYPE::OpenSource:
-        szLicense.LoadStringW(hInst, IDS_LICENSE_OPENSOURCE);
-        break;
-    case LICENSE_TYPE::Freeware:
-        szLicense.LoadStringW(hInst, IDS_LICENSE_FREEWARE);
-        break;
-    case LICENSE_TYPE::Trial:
-        szLicense.LoadStringW(hInst, IDS_LICENSE_TRIAL);
-        break;
-    default:
-        break;
-    }
-
-    if (szLicense.IsEmpty())
-    {
-        InsertTextAfterLoaded_RichEdit(IDS_AINFO_LICENSE, Info->szLicense, CFE_BOLD,
0);
-    }
-    else
-    {
-        szLicense.Format(L"(%ls)", Info->szLicense);
-        InsertTextAfterLoaded_RichEdit(IDS_AINFO_LICENSE, szLicense, CFE_BOLD, 0);
-    }
-
-}
-
-VOID
-InsertLanguageInfo_RichEdit(PAPPLICATION_INFO Info)
-{
-    const INT nTranslations = Info->Languages.GetSize();
-    ATL::CStringW szLangInfo;
-    ATL::CStringW szLoadedTextAvailability;
-    ATL::CStringW szLoadedAInfoText;
-    szLoadedAInfoText.LoadStringW(IDS_AINFO_LANGUAGES);
-
-    if(HasNativeLanguage(Info))
-    {
-        szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_AVAILABLE_TRANSLATION);
-    }
-    else if (HasEnglishLanguage(Info))
-    {
-        szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_ENGLISH_TRANSLATION);
-    }
-    else
-    {
-        szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_NO_TRANSLATION);
-    }
-
-    if (nTranslations > 1)
-    {
-        szLangInfo.Format(L" (+%d more)", nTranslations - 1);
-    }
-
-    InsertRichEditText(szLoadedAInfoText, CFE_BOLD);
-    InsertRichEditText(szLoadedTextAvailability, NULL);
-    InsertRichEditText(szLangInfo, CFE_ITALIC);
-}
-
-BOOL
-ShowAvailableAppInfo(INT Index)
-{
-    PAPPLICATION_INFO Info = (PAPPLICATION_INFO) ListViewGetlParam(Index);
-    if (!Info) return FALSE;
-
-    NewRichEditText(Info->szName, CFE_BOLD);
-    InsertVersionInfo_RichEdit(Info);
-    InsertLicenseInfo_RichEdit(Info);
-    InsertLanguageInfo_RichEdit(Info);
-
-    InsertTextAfterLoaded_RichEdit(IDS_AINFO_SIZE, Info->szSize, CFE_BOLD, 0);
-    InsertTextAfterLoaded_RichEdit(IDS_AINFO_URLSITE, Info->szUrlSite, CFE_BOLD,
CFE_LINK);
-    InsertTextAfterLoaded_RichEdit(IDS_AINFO_DESCRIPTION, Info->szDesc, CFE_BOLD, 0);
-    InsertTextAfterLoaded_RichEdit(IDS_AINFO_URLDOWNLOAD, Info->szUrlDownload,
CFE_BOLD, CFE_LINK);
-
-    return TRUE;
-}
-
-static BOOL
-DeleteCurrentAppsDB(VOID)
+BOOL CAvailableApplicationInfo::IsInstalled() const
+{
+    return m_IsInstalled;
+}
+
+BOOL CAvailableApplicationInfo::HasInstalledVersion() const
+{
+    return m_HasInstalledVersion;
+}
+
+BOOL CAvailableApplicationInfo::HasUpdate() const
+{
+    return (szInstalledVersion.Compare(szVersion) < 0) ? TRUE : FALSE;
+}
+
+VOID CAvailableApplicationInfo::SetLastWriteTime(FILETIME* ftTime)
+{
+    RtlCopyMemory(&ftCacheStamp, ftTime, sizeof(FILETIME));
+}
+
+inline BOOL CAvailableApplicationInfo::GetString(LPCWSTR lpKeyName, ATL::CStringW&
ReturnedString)
+{
+    if (!ParserGetString(lpKeyName, sFileName, ReturnedString))
+    {
+        ReturnedString.Empty();
+        return FALSE;
+    }
+    return TRUE;
+}
+
+// CAvailableApps
+CAvailableApps::CAvailableApps()
+{
+    //set all paths
+    if (GetStorageDirectory(m_szPath))
+    {
+        m_szAppsPath = m_szPath + L"\\rapps\\";
+        m_szCabPath = m_szPath + L"\\rappmgr.cab";
+        m_szSearchPath = m_szAppsPath + L"*.txt";
+    }
+}
+
+VOID CAvailableApps::FreeCachedEntries()
+{
+    POSITION InfoListPosition = m_InfoList.GetHeadPosition();
+
+    /* loop and deallocate all the cached app infos in the list */
+    while (InfoListPosition)
+    {
+        CAvailableApplicationInfo* Info = m_InfoList.GetAt(InfoListPosition);
+        m_InfoList.RemoveHead();
+        delete Info;
+
+        InfoListPosition = m_InfoList.GetHeadPosition();
+    }
+}
+
+BOOL CAvailableApps::DeleteCurrentAppsDB()
 {
     HANDLE hFind = INVALID_HANDLE_VALUE;
     WIN32_FIND_DATAW FindFileData;
-    ATL::CStringW szCabPath;
-    ATL::CStringW szSearchPath;
-    ATL::CStringW szPath;
     BOOL result = TRUE;
-    if (!GetStorageDirectory(szPath))
-        return FALSE;
-
-    szCabPath = szPath + L"\\rappmgr.cab";
-    result = result && DeleteFileW(szCabPath.GetString());
-
-    szPath += L"\\rapps\\";
-    szSearchPath = szPath + L"*.txt";
-
-    hFind = FindFirstFileW(szSearchPath.GetString(), &FindFileData);
+    if (m_szPath.IsEmpty())
+        return FALSE;
+
+    result = result && DeleteFileW(m_szCabPath.GetString());
+    hFind = FindFirstFileW(m_szSearchPath.GetString(), &FindFileData);
     if (hFind == INVALID_HANDLE_VALUE)
         return result;
@@ -276,7 +223,7 @@
     ATL::CStringW szTmp;
     do
     {
-        szTmp = szPath + FindFileData.cFileName;
+        szTmp = m_szPath + FindFileData.cFileName;
         result = result && DeleteFileW(szTmp.GetString());
     } while (FindNextFileW(hFind, &FindFileData) != 0);
@@ -285,66 +232,44 @@
     return result;
 }
-BOOL
-UpdateAppsDB(VOID)
-{
-    ATL::CStringW szPath;
-    ATL::CStringW szAppsPath;
-    ATL::CStringW szCabPath;
-
+BOOL CAvailableApps::UpdateAppsDB()
+{
     if (!DeleteCurrentAppsDB())
         return FALSE;
     DownloadApplicationsDB(APPLICATION_DATABASE_URL);
-    if (!GetStorageDirectory(szPath))
-        return FALSE;
-
-    szCabPath = szPath + L"\\rappmgr.cab";
-    szAppsPath = szPath + L"\\rapps\\";
-
-    if (!ExtractFilesFromCab(szCabPath, szAppsPath))
-    {
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-
-BOOL
-EnumAvailableApplications(INT EnumType, AVAILENUMPROC lpEnumProc)
+    if (m_szPath.IsEmpty())
+        return FALSE;
+
+    if (!ExtractFilesFromCab(m_szCabPath, m_szAppsPath))
+    {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+BOOL CAvailableApps::EnumAvailableApplications(INT EnumType, AVAILENUMPROC lpEnumProc)
 {
     HANDLE hFind = INVALID_HANDLE_VALUE;
     WIN32_FIND_DATAW FindFileData;
-    ATL::CStringW szPath;
-    ATL::CStringW szAppsPath;
-    ATL::CStringW szCabPath;
-    PAPPLICATION_INFO Info;
-
-    if (!GetStorageDirectory(szPath))
-        return FALSE;
-
-    szCabPath = szPath + L"\\rappmgr.cab";
-    szPath += L"\\rapps\\";
-    szAppsPath = szPath;
-
-    if (!CreateDirectoryW(szPath.GetString(), NULL) &&
+
+    if (!CreateDirectoryW(m_szPath.GetString(), NULL) &&
         GetLastError() != ERROR_ALREADY_EXISTS)
     {
         return FALSE;
     }
-    szPath += L"*.txt";
-    hFind = FindFirstFileW(szPath.GetString(), &FindFileData);
+    hFind = FindFirstFileW(m_szSearchPath.GetString(), &FindFileData);
     if (hFind == INVALID_HANDLE_VALUE)
     {
-        if (GetFileAttributesW(szCabPath) == INVALID_FILE_ATTRIBUTES)
+        if (GetFileAttributesW(m_szCabPath) == INVALID_FILE_ATTRIBUTES)
             DownloadApplicationsDB(APPLICATION_DATABASE_URL);
-        ExtractFilesFromCab(szCabPath, szAppsPath);
-        hFind = FindFirstFileW(szPath, &FindFileData);
+        ExtractFilesFromCab(m_szCabPath, m_szAppsPath);
+        hFind = FindFirstFileW(m_szSearchPath.GetString(), &FindFileData);
         if (hFind == INVALID_HANDLE_VALUE)
             return FALSE;
@@ -353,22 +278,25 @@
     do
     {
         /* loop for all the cached entries */
-        POSITION CurrentListPosition = InfoList.GetHeadPosition();
+        POSITION CurrentListPosition = m_InfoList.GetHeadPosition();
+        CAvailableApplicationInfo* Info = NULL;
         while (CurrentListPosition != NULL)
         {
             POSITION LastListPosition = CurrentListPosition;
-            Info = InfoList.GetNext(CurrentListPosition);
+            Info = m_InfoList.GetNext(CurrentListPosition);
             /* do we already have this entry in cache? */
-            if (!Info->cFileName.Compare(FindFileData.cFileName))
+            if (Info->sFileName == FindFileData.cFileName)
             {
                 /* is it current enough, or the file has been modified since our last
time here? */
                 if (CompareFileTime(&FindFileData.ftLastWriteTime,
&Info->ftCacheStamp) == 1)
                 {
                     /* recreate our cache, this is the slow path */
-                    InfoList.RemoveAt(LastListPosition);
+                    m_InfoList.RemoveAt(LastListPosition);
+
                     delete Info;
+                    Info = nullptr;
                     break;
                 }
                 else
@@ -380,21 +308,11 @@
         }
         /* create a new entry */
-        Info = new APPLICATION_INFO();
-
-        if (!Info)
-            break;
-
-        Info->Category = ParserGetInt(L"Category", FindFileData.cFileName);
-        Info->LicenseType = ParserGetLicenseType(FindFileData.cFileName);
-        Info->Languages = ParserGetAppLanguages(FindFileData.cFileName);
-
-        /* copy the cache-related fields for the next time */
-        Info->cFileName = FindFileData.cFileName;
-        RtlCopyMemory(&Info->ftCacheStamp, &FindFileData.ftLastWriteTime,
sizeof(FILETIME));
-
-        /* add our cached entry to the cached list */
-        InfoList.AddTail(Info);
+        Info = new CAvailableApplicationInfo(FindFileData.cFileName);
+
+        /* set a timestamp for the next time */
+        Info->SetLastWriteTime(&FindFileData.ftLastWriteTime);
+        m_InfoList.AddTail(Info);
 skip_if_cached:
         if (Info->Category == FALSE)
@@ -403,50 +321,43 @@
         if (EnumType != Info->Category && EnumType != ENUM_ALL_AVAILABLE)
             continue;
-        /* if our cache hit was only partial, we need to parse
-           and lazily fill the rest of fields only when needed */
-
-        if (Info->szUrlDownload.IsEmpty())
-        {
-            if (!GetString(L"Name", Info->szName, FindFileData.cFileName)
-                || !GetString(L"URLDownload", Info->szUrlDownload,
FindFileData.cFileName))
-            {
-                continue;
-            }
-
-            GetString(L"RegName", Info->szRegName, FindFileData.cFileName);
-            GetString(L"Version", Info->szVersion, FindFileData.cFileName);
-            GetString(L"License", Info->szLicense, FindFileData.cFileName);
-            GetString(L"Description", Info->szDesc, FindFileData.cFileName);
-            GetString(L"Size", Info->szSize, FindFileData.cFileName);
-            GetString(L"URLSite", Info->szUrlSite, FindFileData.cFileName);
-            GetString(L"CDPath", Info->szCDPath, FindFileData.cFileName);
-            GetString(L"Language", Info->szRegName, FindFileData.cFileName);
-            GetString(L"SHA1", Info->szSHA1, FindFileData.cFileName);
-        }
-
-        if (!lpEnumProc(Info))
+        Info->RefreshAppInfo();
+
+        if (!lpEnumProc(static_cast<PAPPLICATION_INFO>(Info),
m_szAppsPath.GetString()))
             break;
     } while (FindNextFileW(hFind, &FindFileData) != 0);
     FindClose(hFind);
-
-    return TRUE;
-}
-
-VOID FreeCachedAvailableEntries(VOID)
-{
-    PAPPLICATION_INFO Info;
-    POSITION InfoListPosition = InfoList.GetHeadPosition();
-
-    /* loop and deallocate all the cached app infos in the list */
-    while (InfoListPosition)
-    {
-        Info = InfoList.GetAt(InfoListPosition);
-        InfoList.RemoveHead();
-        InfoListPosition = InfoList.GetHeadPosition();
-
-        delete Info;
-    }
-}
+    return TRUE;
+}
+
+const ATL::CStringW & CAvailableApps::GetFolderPath()
+{
+    return m_szPath;
+}
+
+const ATL::CStringW & CAvailableApps::GetAppPath()
+{
+    return m_szAppsPath;
+}
+
+const ATL::CStringW & CAvailableApps::GetCabPath()
+{
+    return m_szCabPath;
+}
+
+const LPCWSTR CAvailableApps::GetFolderPathString()
+{
+    return m_szPath.GetString();
+}
+
+const LPCWSTR CAvailableApps::GetAppPathString()
+{
+    return m_szPath.GetString();
+}
+
+const LPCWSTR CAvailableApps::GetCabPathString()
+{
+    return m_szPath.GetString();
+}
Modified: branches/GSoC_2017/rapps/reactos/base/applications/rapps/crichedit.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2017/rapps/reactos/base/ap…
==============================================================================
--- branches/GSoC_2017/rapps/reactos/base/applications/rapps/crichedit.h
[iso-8859-1] (original)
+++ branches/GSoC_2017/rapps/reactos/base/applications/rapps/crichedit.h
[iso-8859-1] Tue Jul 18 22:52:51 2017
@@ -83,7 +83,6 @@
     HWND Create(HWND hwndParent)
     {
-        // TODO: FreeLibrary when the window is destroyed
         LoadedLibrary = LoadLibraryW(L"riched20.dll");
         m_hWnd = CreateWindowExW(0,
Modified: branches/GSoC_2017/rapps/reactos/base/applications/rapps/gui.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2017/rapps/reactos/base/ap…
==============================================================================
--- branches/GSoC_2017/rapps/reactos/base/applications/rapps/gui.cpp    [iso-8859-1]
(original)
+++ branches/GSoC_2017/rapps/reactos/base/applications/rapps/gui.cpp    [iso-8859-1] Tue
Jul 18 22:52:51 2017
@@ -23,6 +23,138 @@
 #define SEARCH_TIMER_ID 'SR'
 HWND hListView = NULL;
+
+class CAvailableAppView
+{
+    static inline VOID InsertTextAfterLoaded_RichEdit(UINT uStringID,
+                                                      const ATL::CStringW& szText,
+                                                      DWORD StringFlags,
+                                                      DWORD TextFlags)
+    {
+        ATL::CStringW szLoadedText;
+        if (!szText.IsEmpty() && szLoadedText.LoadStringW(hInst, uStringID))
+        {
+            InsertRichEditText(szLoadedText, StringFlags);
+            InsertRichEditText(szText, TextFlags);
+        }
+    }
+
+    static inline VOID InsertLoadedTextNewl_RichEdit(UINT uStringID,
+                                                     DWORD StringFlags)
+    {
+        ATL::CStringW szLoadedText;
+        if (szLoadedText.LoadStringW(hInst, uStringID))
+        {
+            InsertRichEditText(L"\n", 0);
+            InsertRichEditText(szLoadedText, StringFlags);
+            InsertRichEditText(L"\n", 0);
+        }
+    }
+
+    static VOID InsertVersionInfo_RichEdit(CAvailableApplicationInfo* Info)
+    {
+        if (Info->IsInstalled())
+        {
+            if (Info->HasInstalledVersion())
+            {
+                if (Info->HasUpdate())
+                    InsertLoadedTextNewl_RichEdit(IDS_STATUS_UPDATE_AVAILABLE,
CFE_ITALIC);
+                else
+                    InsertLoadedTextNewl_RichEdit(IDS_STATUS_INSTALLED, CFE_ITALIC);
+
+                InsertTextAfterLoaded_RichEdit(IDS_AINFO_VERSION,
Info->szInstalledVersion, CFE_BOLD, 0);
+            }
+            else
+            {
+                InsertLoadedTextNewl_RichEdit(IDS_STATUS_INSTALLED, CFE_ITALIC);
+            }
+        }
+        else
+        {
+            InsertLoadedTextNewl_RichEdit(IDS_STATUS_NOTINSTALLED, CFE_ITALIC);
+        }
+
+        InsertTextAfterLoaded_RichEdit(IDS_AINFO_AVAILABLEVERSION, Info->szVersion,
CFE_BOLD, 0);
+    }
+
+    static VOID InsertLicenseInfo_RichEdit(CAvailableApplicationInfo* Info)
+    {
+        ATL::CStringW szLicense;
+        switch (Info->LicenseType)
+        {
+        case LICENSE_TYPE::OpenSource:
+            szLicense.LoadStringW(hInst, IDS_LICENSE_OPENSOURCE);
+            break;
+        case LICENSE_TYPE::Freeware:
+            szLicense.LoadStringW(hInst, IDS_LICENSE_FREEWARE);
+            break;
+        case LICENSE_TYPE::Trial:
+            szLicense.LoadStringW(hInst, IDS_LICENSE_TRIAL);
+            break;
+        default:
+            InsertTextAfterLoaded_RichEdit(IDS_AINFO_LICENSE, Info->szLicense,
CFE_BOLD, 0);
+            return;
+        }
+
+        szLicense += L" (" + Info->szLicense + L")";
+        InsertTextAfterLoaded_RichEdit(IDS_AINFO_LICENSE, szLicense, CFE_BOLD, 0);
+    }
+
+    static VOID InsertLanguageInfo_RichEdit(CAvailableApplicationInfo* Info)
+    {
+        const INT nTranslations = Info->Languages.GetSize();
+        ATL::CStringW szLangInfo;
+        ATL::CStringW szLoadedTextAvailability;
+        ATL::CStringW szLoadedAInfoText;
+        szLoadedAInfoText.LoadStringW(IDS_AINFO_LANGUAGES);
+
+        if (Info->HasNativeLanguage())
+        {
+            szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_AVAILABLE_TRANSLATION);
+        }
+        else if (Info->HasEnglishLanguage())
+        {
+            szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_ENGLISH_TRANSLATION);
+        }
+        else
+        {
+            szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_NO_TRANSLATION);
+        }
+
+        if (nTranslations > 1)
+        {
+            szLangInfo.Format(L" (+%d more)", nTranslations - 1);
+        }
+        else
+        {
+            szLangInfo.LoadStringW(IDS_LANGUAGE_SINGLE);
+            szLangInfo = L" (" + szLangInfo + L")";
+        }
+
+        InsertRichEditText(szLoadedAInfoText, CFE_BOLD);
+        InsertRichEditText(szLoadedTextAvailability, NULL);
+        InsertRichEditText(szLangInfo, CFE_ITALIC);
+    }
+
+public:
+    static BOOL ShowAvailableAppInfo(INT Index)
+    {
+        CAvailableApplicationInfo* Info = (CAvailableApplicationInfo*)
ListViewGetlParam(Index);
+        if (!Info) return FALSE;
+
+        NewRichEditText(Info->szName, CFE_BOLD);
+        InsertVersionInfo_RichEdit(Info);
+        InsertLicenseInfo_RichEdit(Info);
+        InsertLanguageInfo_RichEdit(Info);
+
+        InsertTextAfterLoaded_RichEdit(IDS_AINFO_SIZE, Info->szSize, CFE_BOLD, 0);
+        InsertTextAfterLoaded_RichEdit(IDS_AINFO_URLSITE, Info->szUrlSite, CFE_BOLD,
CFE_LINK);
+        InsertTextAfterLoaded_RichEdit(IDS_AINFO_DESCRIPTION, Info->szDesc, CFE_BOLD,
0);
+        InsertTextAfterLoaded_RichEdit(IDS_AINFO_URLDOWNLOAD, Info->szUrlDownload,
CFE_BOLD, CFE_LINK);
+
+        return TRUE;
+    }
+};
 class CMainToolbar :
     public CUiWindow< CToolbar<> >
@@ -222,9 +354,7 @@
     BOOL AddColumn(INT Index, ATL::CStringW& Text, INT Width, INT Format)
     {
-        BOOL result = AddColumn(Index, Text.GetBuffer(), Width, Format);
-
-        return result;
+        return AddColumn(Index, const_cast<LPWSTR>(Text.GetString()), Width,
Format);
     }
     BOOL AddColumn(INT Index, LPWSTR lpText, INT Width, INT Format)
@@ -315,9 +445,7 @@
 public:
     HTREEITEM AddItem(HTREEITEM hParent, ATL::CStringW &Text, INT Image, INT
SelectedImage, LPARAM lParam)
     {
-        HTREEITEM result = CUiWindow<CTreeView>::AddItem(hParent, Text.GetBuffer(),
Image, SelectedImage, lParam);
-        Text.ReleaseBuffer();
-        return result;
+        return CUiWindow<CTreeView>::AddItem(hParent,
const_cast<LPWSTR>(Text.GetString()), Image, SelectedImage, lParam);
     }
     HTREEITEM AddCategory(HTREEITEM hRootItem, UINT TextIndex, UINT IconIndex)
@@ -406,6 +534,8 @@
     BOOL SearchEnabled;
+    CAvailableApps m_AvailableApps;
+
 public:
     CMainWindow() :
         m_ClientPanel(NULL),
@@ -413,7 +543,6 @@
         SearchEnabled(TRUE)
     {
     }
-
 private:
     VOID InitApplicationsList(VOID)
@@ -538,7 +667,7 @@
         m_HSplitter->m_Horizontal = TRUE;
         m_HSplitter->m_Pos = 32768;
         m_HSplitter->m_MinFirst = 300;
-        m_HSplitter->m_MinSecond = 80;
+        m_HSplitter->m_MinSecond = 150;
         m_VSplitter->Second().Append(m_HSplitter);
         return m_HSplitter->Create(m_hWnd) != NULL;
@@ -669,8 +798,6 @@
             SaveSettings(hwnd);
             FreeLogs();
-
-            FreeCachedAvailableEntries();
             if (IS_INSTALLED_ENUM(SelectedEnumType))
                 FreeInstalledAppList();
@@ -839,7 +966,7 @@
                         if (IS_INSTALLED_ENUM(SelectedEnumType))
                             ShowInstalledAppInfo(ItemIndex);
                         if (IS_AVAILABLE_ENUM(SelectedEnumType))
-                            ShowAvailableAppInfo(ItemIndex);
+                            CAvailableAppView::ShowAvailableAppInfo(ItemIndex);
                     }
                 }
             }
@@ -860,7 +987,7 @@
                     if (IS_INSTALLED_ENUM(SelectedEnumType))
                         ShowInstalledAppInfo(-1);
                     if (IS_AVAILABLE_ENUM(SelectedEnumType))
-                        ShowAvailableAppInfo(-1);
+                        CAvailableAppView::ShowAvailableAppInfo(-1);
                 }
             }
             break;
@@ -1094,7 +1221,7 @@
             break;
         case ID_RESETDB:
-            UpdateAppsDB();
+            m_AvailableApps.UpdateAppsDB();
             UpdateApplicationsList(-1);
             break;
@@ -1158,21 +1285,20 @@
         /* Get version info */
         GetApplicationString(ItemInfo->hSubKey, L"DisplayVersion", szText);
-        ListView_SetItemText(hListView, Index, 1, szText.GetBuffer());
-        szText.ReleaseBuffer();
+        ListView_SetItemText(hListView, Index, 1,
const_cast<LPWSTR>(szText.GetString()));
         /* Get comments */
         GetApplicationString(ItemInfo->hSubKey, L"Comments", szText);
-        ListView_SetItemText(hListView, Index, 2, szText.GetBuffer());
-        szText.ReleaseBuffer();
+        ListView_SetItemText(hListView, Index, 2,
const_cast<LPWSTR>(szText.GetString()));
+
         return TRUE;
     }
-    static BOOL CALLBACK s_EnumAvailableAppProc(PAPPLICATION_INFO Info)
+    static BOOL CALLBACK s_EnumAvailableAppProc(PAPPLICATION_INFO Info, LPCWSTR
szFolderPath)
     {
         INT Index;
         HICON hIcon = NULL;
-        ATL::CStringW szIconPath;
+
         HIMAGELIST hImageListView = ListView_GetImageList(hListView, LVSIL_SMALL);
         if (!SearchPatternMatch(Info->szName, szSearchPattern) &&
@@ -1181,34 +1307,31 @@
             return TRUE;
         }
-        if (GetStorageDirectory(szIconPath))
-        {
-            /* Load icon from file */
-            szIconPath += L"\\rapps\\icons\\" + Info->szName +
L".ico";
-            hIcon = (HICON) LoadImageW(NULL,
-                                       szIconPath.GetString(),
-                                       IMAGE_ICON,
-                                       LISTVIEW_ICON_SIZE,
-                                       LISTVIEW_ICON_SIZE,
-                                       LR_LOADFROMFILE);
-        }
-
-        if (!hIcon)
+        /* Load icon from file */
+        ATL::CStringW szIconPath;
+        szIconPath.Format(L"%lsicons\\%ls.ico", szFolderPath, Info->szName);
+        hIcon = (HICON) LoadImageW(NULL,
+                                   szIconPath.GetString(),
+                                   IMAGE_ICON,
+                                   LISTVIEW_ICON_SIZE,
+                                   LISTVIEW_ICON_SIZE,
+                                   LR_LOADFROMFILE);
+
+        if (!hIcon || GetLastError() != ERROR_SUCCESS)
         {
             /* Load default icon */
             hIcon = (HICON) LoadIconW(hInst, MAKEINTRESOURCEW(IDI_MAIN));
         }
+
         Index = ImageList_AddIcon(hImageListView, hIcon);
         DestroyIcon(hIcon);
         Index = ListViewAddItem(Info->Category, Index, Info->szName, (LPARAM)
Info);
-        hImageListView = ListView_SetImageList(hListView, hImageListView, LVSIL_SMALL);
-
-        ListView_SetItemText(hListView, Index, 1, Info->szVersion.GetBuffer());
-        Info->szVersion.ReleaseBuffer();
-
-        ListView_SetItemText(hListView, Index, 2, Info->szDesc.GetBuffer());
-        Info->szDesc.ReleaseBuffer();
+        ListView_SetImageList(hListView, hImageListView, LVSIL_SMALL);
+
+        ListView_SetItemText(hListView, Index, 1,
const_cast<LPWSTR>(Info->szVersion.GetString()));
+        ListView_SetItemText(hListView, Index, 2,
const_cast<LPWSTR>(Info->szDesc.GetString()));
+
         return TRUE;
     }
@@ -1216,7 +1339,7 @@
     VOID UpdateApplicationsList(INT EnumType)
     {
         ATL::CStringW szBuffer1, szBuffer2;
-        HIMAGELIST hImageListView = NULL;
+        HIMAGELIST hImageListView;
         m_ListView->SendMessageW(WM_SETREDRAW, FALSE, 0);
@@ -1226,20 +1349,23 @@
             FreeInstalledAppList();
         (VOID) ListView_DeleteAllItems(hListView);
+
         /* Create new ImageList */
         hImageListView = ImageList_Create(LISTVIEW_ICON_SIZE,
                                           LISTVIEW_ICON_SIZE,
                                           GetSystemColorDepth() | ILC_MASK,
                                           0, 1);
-        hImageListView = ListView_SetImageList(hListView, hImageListView, LVSIL_SMALL);
-
-        if (hImageListView)
-            ImageList_Destroy(hImageListView);
+        HIMAGELIST hImageListBuf = ListView_SetImageList(hListView, hImageListView,
LVSIL_SMALL);
+        if (hImageListBuf)
+        {
+            ImageList_Destroy(hImageListBuf);
+        }
+
         if (IS_AVAILABLE_ENUM(EnumType))
         {
             /* Enum available applications */
-            EnumAvailableApplications(EnumType, s_EnumAvailableAppProc);
+            m_AvailableApps.EnumAvailableApplications(EnumType, s_EnumAvailableAppProc);
         }
         SelectedEnumType = EnumType;
@@ -1263,18 +1389,18 @@
         DWORD csStyle = CS_VREDRAW | CS_HREDRAW;
         static ATL::CWndClassInfo wc =
         {
-            {
-                sizeof(WNDCLASSEX),
-                csStyle,
+            {
+                sizeof(WNDCLASSEX),
+                csStyle,
                 StartWindowProc,
-                0,
-                0,
+                0,
+                0,
                 NULL,
                 LoadIconW(_AtlBaseModule.GetModuleInstance(),
MAKEINTRESOURCEW(IDI_MAIN)),
                 LoadCursorW(NULL, IDC_ARROW),
-                (HBRUSH) (COLOR_BTNFACE + 1),
+                (HBRUSH) (COLOR_BTNFACE + 1),
                 MAKEINTRESOURCEW(IDR_MAINMENU),
-                L"RAppsWnd",
+                L"RAppsWnd",
                 NULL
             },
             NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
@@ -1313,7 +1439,14 @@
     {
         return m_RichEdit;
     }
+
+    CAvailableApps * GetAvailableApps()
+    {
+        return &m_AvailableApps;
+    }
 };
+
+// File interface
 CMainWindow * g_MainWindow;
@@ -1360,9 +1493,7 @@
 INT ListViewAddItem(INT ItemIndex, INT IconIndex, ATL::CStringW & Name, LPARAM
lParam)
 {
-    INT result = ListViewAddItem(ItemIndex, IconIndex, Name.GetBuffer(), lParam);
-    Name.ReleaseBuffer();
-    return result;
+    return ListViewAddItem(ItemIndex, IconIndex,
const_cast<LPWSTR>(Name.GetString()), lParam);
 }
 VOID NewRichEditText(const ATL::CStringW& szText, DWORD flags)
@@ -1375,3 +1506,7 @@
     InsertRichEditText(szText.GetString(), flags);
 }
+CAvailableApps* GetAvailableApps()
+{
+    return g_MainWindow->GetAvailableApps();
+}
Modified: branches/GSoC_2017/rapps/reactos/base/applications/rapps/installed.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2017/rapps/reactos/base/ap…
==============================================================================
--- branches/GSoC_2017/rapps/reactos/base/applications/rapps/installed.cpp
[iso-8859-1] (original)
+++ branches/GSoC_2017/rapps/reactos/base/applications/rapps/installed.cpp
[iso-8859-1] Tue Jul 18 22:52:51 2017
@@ -37,7 +37,10 @@
 }
 BOOL
-GetInstalledVersion_WowUser(_Out_opt_ ATL::CStringW* szVersionResult, _In_z_ const
ATL::CStringW& RegName, _In_ BOOL IsUserKey, _In_ REGSAM keyWow)
+GetInstalledVersion_WowUser(_Out_opt_ ATL::CStringW* szVersionResult,
+                            _In_z_ const ATL::CStringW& RegName,
+                            _In_ BOOL IsUserKey,
+                            _In_ REGSAM keyWow)
 {
     HKEY hKey;
     BOOL bHasSucceded = FALSE;
@@ -48,7 +51,7 @@
                       szPath.GetString(), 0, keyWow | KEY_READ,
                       &hKey) == ERROR_SUCCESS)
     {
-        if (szVersionResult)
+        if (szVersionResult != NULL)
         {
             DWORD dwSize = MAX_PATH * sizeof(WCHAR);
             DWORD dwType = REG_SZ;
@@ -80,6 +83,14 @@
     return bHasSucceded;
 }
+BOOL GetInstalledVersion(ATL::CStringW* pszVersion, const ATL::CStringW& szRegName)
+{
+    return (!szRegName.IsEmpty()
+            && (::GetInstalledVersion_WowUser(pszVersion, szRegName, TRUE,
KEY_WOW64_32KEY)
+                || ::GetInstalledVersion_WowUser(pszVersion, szRegName, FALSE,
KEY_WOW64_32KEY)
+                || ::GetInstalledVersion_WowUser(pszVersion, szRegName, TRUE,
KEY_WOW64_64KEY)
+                || ::GetInstalledVersion_WowUser(pszVersion, szRegName, FALSE,
KEY_WOW64_64KEY)));
+}
 BOOL
 UninstallApplication(INT Index, BOOL bModify)
Modified: branches/GSoC_2017/rapps/reactos/base/applications/rapps/lang/en-US.rc
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2017/rapps/reactos/base/ap…
==============================================================================
--- branches/GSoC_2017/rapps/reactos/base/applications/rapps/lang/en-US.rc
[iso-8859-1] (original)
+++ branches/GSoC_2017/rapps/reactos/base/applications/rapps/lang/en-US.rc
[iso-8859-1] Tue Jul 18 22:52:51 2017
@@ -232,4 +232,5 @@
     IDS_LANGUAGE_NO_TRANSLATION "In your language"
     IDS_LANGUAGE_NOT_AVAILABLE "No translations"
     IDS_LANGUAGE_ENGLISH_TRANSLATION "In English"
-END
+    IDS_LANGUAGE_SINGLE "Single language"
+END
Modified: branches/GSoC_2017/rapps/reactos/base/applications/rapps/loaddlg.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2017/rapps/reactos/base/ap…
==============================================================================
--- branches/GSoC_2017/rapps/reactos/base/applications/rapps/loaddlg.cpp
[iso-8859-1] (original)
+++ branches/GSoC_2017/rapps/reactos/base/applications/rapps/loaddlg.cpp
[iso-8859-1] Tue Jul 18 22:52:51 2017
@@ -111,8 +111,7 @@
                                   uiPercentage,
                                   szProgress,
                                   szProgressMax);
-            SendMessageW(Item, WM_SETTEXT, 0, (LPARAM) m_ProgressText.GetBuffer());
-            m_ProgressText.ReleaseBuffer();
+            SendMessageW(Item, WM_SETTEXT, 0, (LPARAM) m_ProgressText.GetString());
         }
         Item = GetDlgItem(m_hDialog, IDC_DOWNLOAD_STATUS);
@@ -134,8 +133,7 @@
             }
             /* paste it into our dialog and don't do it again in this instance */
-            SendMessageW(Item, WM_SETTEXT, 0, (LPARAM) buf.GetBuffer());
-            buf.ReleaseBuffer();
+            SendMessageW(Item, WM_SETTEXT, 0, (LPARAM) buf.GetString());
             m_UrlHasBeenCopied = TRUE;
         }
@@ -436,8 +434,7 @@
             goto end;
         SetWindowText(Dlg, szMsgText.GetString());
-        SendMessageW(GetDlgItem(Dlg, IDC_DOWNLOAD_STATUS), WM_SETTEXT, 0, (LPARAM)
Path.GetBuffer());
-        Path.ReleaseBuffer();
+        SendMessageW(GetDlgItem(Dlg, IDC_DOWNLOAD_STATUS), WM_SETTEXT, 0, (LPARAM)
Path.GetString());
         /* this may take a while, depending on the file size */
         if (!VerifyInteg(AppInfo->szSHA1, Path.GetString()))
Modified: branches/GSoC_2017/rapps/reactos/base/applications/rapps/misc.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2017/rapps/reactos/base/ap…
==============================================================================
--- branches/GSoC_2017/rapps/reactos/base/applications/rapps/misc.cpp   [iso-8859-1]
(original)
+++ branches/GSoC_2017/rapps/reactos/base/applications/rapps/misc.cpp   [iso-8859-1] Tue
Jul 18 22:52:51 2017
@@ -193,8 +193,7 @@
 BOOL
 StartProcess(ATL::CStringW &Path, BOOL Wait)
 {
-    BOOL result = StartProcess(Path.GetBuffer(), Wait);
-    Path.ReleaseBuffer();
+    BOOL result = StartProcess(const_cast<LPWSTR>(Path.GetString()), Wait);
     return result;
 }
Modified: branches/GSoC_2017/rapps/reactos/base/applications/rapps/rapps.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2017/rapps/reactos/base/ap…
==============================================================================
--- branches/GSoC_2017/rapps/reactos/base/applications/rapps/rapps.h    [iso-8859-1]
(original)
+++ branches/GSoC_2017/rapps/reactos/base/applications/rapps/rapps.h    [iso-8859-1] Tue
Jul 18 22:52:51 2017
@@ -104,7 +104,7 @@
     ATL::CSimpleArray<ATL::CStringW> Languages;
     /* caching mechanism related entries */
-    ATL::CStringW cFileName;
+    ATL::CStringW sFileName;
     FILETIME ftCacheStamp;
     /* optional integrity checks (SHA-1 digests are 160 bit = 40 characters in hex string
form) */
@@ -143,11 +143,66 @@
 } SETTINGS_INFO, *PSETTINGS_INFO;
 /* available.cpp */
-typedef BOOL (CALLBACK *AVAILENUMPROC)(PAPPLICATION_INFO Info);
-BOOL EnumAvailableApplications(INT EnumType, AVAILENUMPROC lpEnumProc);
-BOOL ShowAvailableAppInfo(INT Index);
-BOOL UpdateAppsDB(VOID);
-VOID FreeCachedAvailableEntries(VOID);
+typedef BOOL (CALLBACK *AVAILENUMPROC)(PAPPLICATION_INFO Info, LPCWSTR szFolderPath);
+struct CAvailableApplicationInfo : public APPLICATION_INFO
+{
+    ATL::CStringW szInstalledVersion;
+
+    CAvailableApplicationInfo(const ATL::CStringW& sFileNameParam);
+
+    // Load all info from the file
+    VOID RefreshAppInfo();
+
+
+
+    BOOL HasLanguageInfo() const;
+    BOOL HasNativeLanguage() const;
+    BOOL HasEnglishLanguage() const;
+    BOOL IsInstalled() const;
+    BOOL HasInstalledVersion() const;
+    BOOL HasUpdate() const;
+
+    // Set a timestamp
+    VOID SetLastWriteTime(FILETIME* ftTime);
+
+private:
+    BOOL m_IsInstalled = FALSE;
+    BOOL m_HasLanguageInfo = FALSE;
+    BOOL m_HasInstalledVersion = FALSE;
+
+    inline BOOL GetString(LPCWSTR lpKeyName,
+                          ATL::CStringW& ReturnedString);
+
+    // Lazily load general info from the file
+    BOOL RetrieveGeneralInfo();
+    VOID RetrieveInstalledStatus();
+    VOID RetrieveInstalledVersion();
+    BOOL RetrieveLanguages();
+    VOID RetrieveLicenseType();
+    VOID RetrieveCategory();
+};
+
+class CAvailableApps
+{
+    ATL::CAtlList<CAvailableApplicationInfo*> m_InfoList;
+    ATL::CStringW m_szPath;
+    ATL::CStringW m_szCabPath;
+    ATL::CStringW m_szAppsPath;
+    ATL::CStringW m_szSearchPath;
+
+public:
+    CAvailableApps();
+    VOID FreeCachedEntries();
+    BOOL DeleteCurrentAppsDB();
+    BOOL UpdateAppsDB();
+    BOOL EnumAvailableApplications(INT EnumType, AVAILENUMPROC lpEnumProc);
+    const ATL::CStringW& GetFolderPath();
+    const ATL::CStringW& GetAppPath();
+    const ATL::CStringW& GetCabPath();
+    const LPCWSTR GetFolderPathString();
+    const LPCWSTR GetAppPathString();
+    const LPCWSTR GetCabPathString();
+};
 /* installdlg.cpp */
 BOOL InstallApplication(INT Index);
@@ -162,7 +217,7 @@
 BOOL UninstallApplication(INT Index, BOOL bModify);
 VOID RemoveAppFromRegistry(INT Index);
-BOOL GetInstalledVersion_WowUser(ATL::CStringW* szVersionResult, const ATL::CStringW&
RegName, BOOL IsUserKey, REGSAM keyWow);
+BOOL GetInstalledVersion(ATL::CStringW* pszVersion, const ATL::CStringW& szRegName);
 /* winmain.cpp */
 extern HWND hMainWnd;
@@ -211,6 +266,7 @@
 INT ListViewAddItem(INT ItemIndex, INT IconIndex, ATL::CStringW & Name, LPARAM
lParam);
 VOID NewRichEditText(const ATL::CStringW& szText, DWORD flags);
 VOID InsertRichEditText(const ATL::CStringW& szText, DWORD flags);
+CAvailableApps * GetAvailableApps();
 extern HWND hListView;
 extern ATL::CStringW szSearchPattern;
Modified: branches/GSoC_2017/rapps/reactos/base/applications/rapps/resource.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2017/rapps/reactos/base/ap…
==============================================================================
--- branches/GSoC_2017/rapps/reactos/base/applications/rapps/resource.h [iso-8859-1]
(original)
+++ branches/GSoC_2017/rapps/reactos/base/applications/rapps/resource.h [iso-8859-1] Tue
Jul 18 22:52:51 2017
@@ -183,6 +183,7 @@
 #define IDS_LANGUAGE_NO_TRANSLATION             911
 #define IDS_LANGUAGE_NOT_AVAILABLE              912
 #define IDS_LANGUAGE_ENGLISH_TRANSLATION        913
+#define IDS_LANGUAGE_SINGLE                     914
 /* Accelerators */
 #define HOTKEYS                  715
Modified: branches/GSoC_2017/rapps/reactos/base/applications/rapps/winmain.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2017/rapps/reactos/base/ap…
==============================================================================
--- branches/GSoC_2017/rapps/reactos/base/applications/rapps/winmain.cpp
[iso-8859-1] (original)
+++ branches/GSoC_2017/rapps/reactos/base/applications/rapps/winmain.cpp
[iso-8859-1] Tue Jul 18 22:52:51 2017
@@ -183,8 +183,9 @@
     ShowWindow(hMainWnd, (SettingsInfo.bSaveWndPos && SettingsInfo.Maximized ?
SW_MAXIMIZE : nShowCmd));
     UpdateWindow(hMainWnd);
+    //TODO: get around the ugliness
     if (SettingsInfo.bUpdateAtStart)
-        UpdateAppsDB();
+        GetAvailableApps()->UpdateAppsDB();
     /* Load the menu hotkeys */
     KeyBrd = LoadAccelerators(NULL, MAKEINTRESOURCE(HOTKEYS));