ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
September 2020
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
25 participants
382 discussions
Start a n
N
ew thread
[reactos] 16/19: [RAPPS] Display package name in UI too
by 赫杨
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=997650d42454ce48d376f…
commit 997650d42454ce48d376f1a9dd390cf354e532f8 Author: 赫杨 <1160386205(a)qq.com> AuthorDate: Wed Aug 19 21:44:50 2020 +0800 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Sep 6 17:10:17 2020 +0200 [RAPPS] Display package name in UI too --- base/applications/rapps/appview.cpp | 1 + base/applications/rapps/include/resource.h | 1 + base/applications/rapps/lang/bg-BG.rc | 1 + base/applications/rapps/lang/cs-CZ.rc | 1 + base/applications/rapps/lang/de-DE.rc | 1 + base/applications/rapps/lang/en-US.rc | 1 + base/applications/rapps/lang/es-ES.rc | 1 + base/applications/rapps/lang/et-EE.rc | 1 + base/applications/rapps/lang/fr-FR.rc | 1 + base/applications/rapps/lang/he-IL.rc | 1 + base/applications/rapps/lang/id-ID.rc | 1 + base/applications/rapps/lang/it-IT.rc | 1 + base/applications/rapps/lang/ja-JP.rc | 1 + base/applications/rapps/lang/no-NO.rc | 1 + base/applications/rapps/lang/pl-PL.rc | 1 + base/applications/rapps/lang/pt-BR.rc | 1 + base/applications/rapps/lang/pt-PT.rc | 1 + base/applications/rapps/lang/ro-RO.rc | 1 + base/applications/rapps/lang/ru-RU.rc | 1 + base/applications/rapps/lang/sk-SK.rc | 1 + base/applications/rapps/lang/sq-AL.rc | 1 + base/applications/rapps/lang/sv-SE.rc | 1 + base/applications/rapps/lang/tr-TR.rc | 1 + base/applications/rapps/lang/uk-UA.rc | 1 + base/applications/rapps/lang/zh-CN.rc | 1 + base/applications/rapps/lang/zh-TW.rc | 1 + 26 files changed, 26 insertions(+) diff --git a/base/applications/rapps/appview.cpp b/base/applications/rapps/appview.cpp index dff7c0eca85..58584fa3b72 100644 --- a/base/applications/rapps/appview.cpp +++ b/base/applications/rapps/appview.cpp @@ -372,6 +372,7 @@ BOOL CAppRichEdit::ShowAvailableAppInfo(CAvailableApplicationInfo *Info) LoadAndInsertText(IDS_AINFO_URLSITE, Info->m_szUrlSite, CFE_BOLD, CFE_LINK); LoadAndInsertText(IDS_AINFO_DESCRIPTION, Info->m_szDesc, CFE_BOLD, 0); LoadAndInsertText(IDS_AINFO_URLDOWNLOAD, Info->m_szUrlDownload, CFE_BOLD, CFE_LINK); + LoadAndInsertText(IDS_AINFO_PACKAGE_NAME, Info->m_szPkgName, CFE_BOLD, 0); return TRUE; } diff --git a/base/applications/rapps/include/resource.h b/base/applications/rapps/include/resource.h index 104d925c039..6ea0ca1a321 100644 --- a/base/applications/rapps/include/resource.h +++ b/base/applications/rapps/include/resource.h @@ -169,6 +169,7 @@ #define IDS_AINFO_KILOBYTE_EXT 358 #define IDS_AINFO_MEGABYTE_EXT 359 #define IDS_AINFO_GIGABYTE_EXT 360 +#define IDS_AINFO_PACKAGE_NAME 361 /* Names of categories */ diff --git a/base/applications/rapps/lang/bg-BG.rc b/base/applications/rapps/lang/bg-BG.rc index 31f208d38e8..4ac81b14652 100644 --- a/base/applications/rapps/lang/bg-BG.rc +++ b/base/applications/rapps/lang/bg-BG.rc @@ -145,6 +145,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nНиз за премахване: " IDS_INFO_MODIFYPATH "\nПът за изменения: " IDS_INFO_INSTALLDATE "\nДата на слагане: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/cs-CZ.rc b/base/applications/rapps/lang/cs-CZ.rc index ce0a04c31e0..965c5b31380 100644 --- a/base/applications/rapps/lang/cs-CZ.rc +++ b/base/applications/rapps/lang/cs-CZ.rc @@ -146,6 +146,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nOdinstalační řetězec: " IDS_INFO_MODIFYPATH "\nCesta úpravy: " IDS_INFO_INSTALLDATE "\nDatum instalace: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/de-DE.rc b/base/applications/rapps/lang/de-DE.rc index 66fe742cf72..8bd0a0bc36a 100644 --- a/base/applications/rapps/lang/de-DE.rc +++ b/base/applications/rapps/lang/de-DE.rc @@ -141,6 +141,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nDeinstallationsstring: " IDS_INFO_MODIFYPATH "\nÄnderungspfad: " IDS_INFO_INSTALLDATE "\nInstallationsdatum: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/en-US.rc b/base/applications/rapps/lang/en-US.rc index 193d54b5177..869868fd255 100644 --- a/base/applications/rapps/lang/en-US.rc +++ b/base/applications/rapps/lang/en-US.rc @@ -141,6 +141,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nUninstall String: " IDS_INFO_MODIFYPATH "\nModify Path: " IDS_INFO_INSTALLDATE "\nInstall Date: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/es-ES.rc b/base/applications/rapps/lang/es-ES.rc index c8be3fe5433..c9f224c17c3 100644 --- a/base/applications/rapps/lang/es-ES.rc +++ b/base/applications/rapps/lang/es-ES.rc @@ -144,6 +144,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nComando de desinstalación: " IDS_INFO_MODIFYPATH "\nRuta de modificación: " IDS_INFO_INSTALLDATE "\nFecha de instalación: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/et-EE.rc b/base/applications/rapps/lang/et-EE.rc index 7149aa767ae..95f2f57a6f9 100644 --- a/base/applications/rapps/lang/et-EE.rc +++ b/base/applications/rapps/lang/et-EE.rc @@ -149,6 +149,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nDesinstalli string: " IDS_INFO_MODIFYPATH "\nMuutmise tee: " IDS_INFO_INSTALLDATE "\nInstalli kuupäev: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/fr-FR.rc b/base/applications/rapps/lang/fr-FR.rc index 97def999b65..22077326c2e 100644 --- a/base/applications/rapps/lang/fr-FR.rc +++ b/base/applications/rapps/lang/fr-FR.rc @@ -141,6 +141,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nCommande de désinstallation : " IDS_INFO_MODIFYPATH "\nModifier le chemin d'accès : " IDS_INFO_INSTALLDATE "\nDate d'installation : " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/he-IL.rc b/base/applications/rapps/lang/he-IL.rc index 24eb6f51217..79a272acb1c 100644 --- a/base/applications/rapps/lang/he-IL.rc +++ b/base/applications/rapps/lang/he-IL.rc @@ -147,6 +147,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nמחרוזת הסרה: " IDS_INFO_MODIFYPATH "\nנתיב שינוי: " IDS_INFO_INSTALLDATE "\nתאריך התקנה: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/id-ID.rc b/base/applications/rapps/lang/id-ID.rc index b7c47d1d123..0a65bcc1605 100644 --- a/base/applications/rapps/lang/id-ID.rc +++ b/base/applications/rapps/lang/id-ID.rc @@ -141,6 +141,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nString Pembongkaran: " IDS_INFO_MODIFYPATH "\nJalur Pengubahan: " IDS_INFO_INSTALLDATE "\nTanggal Pemasangan: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/it-IT.rc b/base/applications/rapps/lang/it-IT.rc index 2a19053a8d1..6321268e6b1 100644 --- a/base/applications/rapps/lang/it-IT.rc +++ b/base/applications/rapps/lang/it-IT.rc @@ -141,6 +141,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nStringa di disinstallazione: " IDS_INFO_MODIFYPATH "\nModifica percorso: " IDS_INFO_INSTALLDATE "\nData installazione: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/ja-JP.rc b/base/applications/rapps/lang/ja-JP.rc index d47201d5967..384eec172de 100644 --- a/base/applications/rapps/lang/ja-JP.rc +++ b/base/applications/rapps/lang/ja-JP.rc @@ -141,6 +141,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nアンインストールに使用する文字列: " IDS_INFO_MODIFYPATH "\n変更に使用するパス: " IDS_INFO_INSTALLDATE "\nインストールした日付: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/no-NO.rc b/base/applications/rapps/lang/no-NO.rc index b217f736b7c..8ce8f1915b3 100644 --- a/base/applications/rapps/lang/no-NO.rc +++ b/base/applications/rapps/lang/no-NO.rc @@ -141,6 +141,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nAvinstallering plassering: " IDS_INFO_MODIFYPATH "\nEndret mappe: " IDS_INFO_INSTALLDATE "\nInstallert dato: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/pl-PL.rc b/base/applications/rapps/lang/pl-PL.rc index eebaeef6213..ca5b2615153 100644 --- a/base/applications/rapps/lang/pl-PL.rc +++ b/base/applications/rapps/lang/pl-PL.rc @@ -149,6 +149,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nKomenda deinstalacji: " IDS_INFO_MODIFYPATH "\nModyfikacja ścieżki instalacji: " IDS_INFO_INSTALLDATE "\nData instalacji: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/pt-BR.rc b/base/applications/rapps/lang/pt-BR.rc index abbcbb037fc..f60e57c4557 100644 --- a/base/applications/rapps/lang/pt-BR.rc +++ b/base/applications/rapps/lang/pt-BR.rc @@ -143,6 +143,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nDesinstalar String: " IDS_INFO_MODIFYPATH "\nModificar Caminho: " IDS_INFO_INSTALLDATE "\nData de Instalação: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/pt-PT.rc b/base/applications/rapps/lang/pt-PT.rc index d26f79dea27..31d968a260a 100644 --- a/base/applications/rapps/lang/pt-PT.rc +++ b/base/applications/rapps/lang/pt-PT.rc @@ -143,6 +143,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nDesinstalar String: " IDS_INFO_MODIFYPATH "\nModificar Caminho: " IDS_INFO_INSTALLDATE "\nData de Instalação: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/ro-RO.rc b/base/applications/rapps/lang/ro-RO.rc index 7b24c8a508b..7e28b9e41d1 100644 --- a/base/applications/rapps/lang/ro-RO.rc +++ b/base/applications/rapps/lang/ro-RO.rc @@ -150,6 +150,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nComanda pentru dezinstalare: " IDS_INFO_MODIFYPATH "\nComanda pentru modificare: " IDS_INFO_INSTALLDATE "\nData de instalare: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/ru-RU.rc b/base/applications/rapps/lang/ru-RU.rc index bb524f5e54e..1ff0dd8651b 100644 --- a/base/applications/rapps/lang/ru-RU.rc +++ b/base/applications/rapps/lang/ru-RU.rc @@ -141,6 +141,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nСтрока для удаления: " IDS_INFO_MODIFYPATH "\nСтрока для изменения: " IDS_INFO_INSTALLDATE "\nДата установки: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/sk-SK.rc b/base/applications/rapps/lang/sk-SK.rc index 935f2165af5..293028d37d6 100644 --- a/base/applications/rapps/lang/sk-SK.rc +++ b/base/applications/rapps/lang/sk-SK.rc @@ -146,6 +146,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nUninstall String: " IDS_INFO_MODIFYPATH "\nModify Path: " IDS_INFO_INSTALLDATE "\nDátum inštalácie: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/sq-AL.rc b/base/applications/rapps/lang/sq-AL.rc index dafe2625a7c..51be3ed3eca 100644 --- a/base/applications/rapps/lang/sq-AL.rc +++ b/base/applications/rapps/lang/sq-AL.rc @@ -145,6 +145,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nUninstall String: " IDS_INFO_MODIFYPATH "\nModifiko Rrugen: " IDS_INFO_INSTALLDATE "\nData Instalimit: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/sv-SE.rc b/base/applications/rapps/lang/sv-SE.rc index bdc851b0017..d4715ed0b35 100644 --- a/base/applications/rapps/lang/sv-SE.rc +++ b/base/applications/rapps/lang/sv-SE.rc @@ -148,6 +148,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nAvinstallationssträng: " IDS_INFO_MODIFYPATH "\nÄndra sökväg: " IDS_INFO_INSTALLDATE "\nInstallationsdatum: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/tr-TR.rc b/base/applications/rapps/lang/tr-TR.rc index 03da9216286..a612fc9b503 100644 --- a/base/applications/rapps/lang/tr-TR.rc +++ b/base/applications/rapps/lang/tr-TR.rc @@ -143,6 +143,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nKaldırma Sözcesi: " IDS_INFO_MODIFYPATH "\nDeğiştirme Yolu: " IDS_INFO_INSTALLDATE "\nKurulum Zamanı: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/uk-UA.rc b/base/applications/rapps/lang/uk-UA.rc index 9c2372b7892..29067f4871f 100644 --- a/base/applications/rapps/lang/uk-UA.rc +++ b/base/applications/rapps/lang/uk-UA.rc @@ -149,6 +149,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\nВидалити рядок: " IDS_INFO_MODIFYPATH "\nЗмінити шлях: " IDS_INFO_INSTALLDATE "\nВстановити дату: " + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE diff --git a/base/applications/rapps/lang/zh-CN.rc b/base/applications/rapps/lang/zh-CN.rc index 308ac4cbda0..25a12c4fb1f 100644 --- a/base/applications/rapps/lang/zh-CN.rc +++ b/base/applications/rapps/lang/zh-CN.rc @@ -144,6 +144,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\n卸载字符串: " IDS_INFO_MODIFYPATH "\n修改路径: " IDS_INFO_INSTALLDATE "\n安装日期: " + IDS_AINFO_PACKAGE_NAME "\n包名称: " END STRINGTABLE diff --git a/base/applications/rapps/lang/zh-TW.rc b/base/applications/rapps/lang/zh-TW.rc index 8118d880df6..49f7dfb2c9f 100644 --- a/base/applications/rapps/lang/zh-TW.rc +++ b/base/applications/rapps/lang/zh-TW.rc @@ -143,6 +143,7 @@ BEGIN IDS_INFO_UNINSTALLSTR "\n解除安裝字元串:" IDS_INFO_MODIFYPATH "\n修改路徑:" IDS_INFO_INSTALLDATE "\n安裝日期:" + IDS_AINFO_PACKAGE_NAME "\nPackage Name: " END STRINGTABLE
4 years, 3 months
1
0
0
0
[reactos] 15/19: [RAPPS] now /INSTALL option use PkgName instead of software name
by 赫杨
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a4ac3c84b2141802d0428…
commit a4ac3c84b2141802d0428daa7c90bb12ef3d90de Author: 赫杨 <1160386205(a)qq.com> AuthorDate: Mon Aug 17 03:04:45 2020 +0800 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Sep 6 17:10:17 2020 +0200 [RAPPS] now /INSTALL option use PkgName instead of software name currently, PkgName is the name of ini file in DB (without suffix) --- base/applications/rapps/available.cpp | 10 +++++----- base/applications/rapps/include/available.h | 4 ++-- base/applications/rapps/unattended.cpp | 13 ++++++------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/base/applications/rapps/available.cpp b/base/applications/rapps/available.cpp index 88a1bf9a8b9..897251321f6 100644 --- a/base/applications/rapps/available.cpp +++ b/base/applications/rapps/available.cpp @@ -530,7 +530,7 @@ int CAvailableApps::GetSelectedCount() return m_SelectedList.GetCount(); } -CAvailableApplicationInfo* CAvailableApps::FindInfo(const ATL::CStringW& szAppName) const +CAvailableApplicationInfo* CAvailableApps::FindAppByPkgName(const ATL::CStringW& szPkgName) const { if (m_InfoList.IsEmpty()) { @@ -543,7 +543,7 @@ CAvailableApplicationInfo* CAvailableApps::FindInfo(const ATL::CStringW& szAppNa while (CurrentListPosition != NULL) { info = m_InfoList.GetNext(CurrentListPosition); - if (info->m_szName.CompareNoCase(szAppName) == 0) + if (info->m_szPkgName.CompareNoCase(szPkgName) == 0) { return info; } @@ -551,12 +551,12 @@ CAvailableApplicationInfo* CAvailableApps::FindInfo(const ATL::CStringW& szAppNa return NULL; } -ATL::CSimpleArray<CAvailableApplicationInfo> CAvailableApps::FindInfoList(const ATL::CSimpleArray<ATL::CStringW> &arrAppsNames) const +ATL::CSimpleArray<CAvailableApplicationInfo> CAvailableApps::FindAppsByPkgNameList(const ATL::CSimpleArray<ATL::CStringW> &PkgNameList) const { ATL::CSimpleArray<CAvailableApplicationInfo> result; - for (INT i = 0; i < arrAppsNames.GetSize(); ++i) + for (INT i = 0; i < PkgNameList.GetSize(); ++i) { - CAvailableApplicationInfo* Info = FindInfo(arrAppsNames[i]); + CAvailableApplicationInfo* Info = FindAppByPkgName(PkgNameList[i]); if (Info) { result.Add(*Info); diff --git a/base/applications/rapps/include/available.h b/base/applications/rapps/include/available.h index 8000c3b11fc..51e32c05230 100644 --- a/base/applications/rapps/include/available.h +++ b/base/applications/rapps/include/available.h @@ -125,8 +125,8 @@ public: VOID RemoveAllSelected(); int GetSelectedCount(); - CAvailableApplicationInfo* FindInfo(const ATL::CStringW& szAppName) const; - ATL::CSimpleArray<CAvailableApplicationInfo> FindInfoList(const ATL::CSimpleArray<ATL::CStringW> &arrAppsNames) const; + CAvailableApplicationInfo* FindAppByPkgName(const ATL::CStringW& szPkgName) const; + ATL::CSimpleArray<CAvailableApplicationInfo> FindAppsByPkgNameList(const ATL::CSimpleArray<ATL::CStringW> &arrAppsNames) const; //ATL::CSimpleArray<CAvailableApplicationInfo> GetSelected() const; const ATL::CStringW& GetFolderPath() const; diff --git a/base/applications/rapps/unattended.cpp b/base/applications/rapps/unattended.cpp index 540795be8d4..b37610c4149 100644 --- a/base/applications/rapps/unattended.cpp +++ b/base/applications/rapps/unattended.cpp @@ -22,13 +22,12 @@ BOOL UseCmdParameters(LPWSTR lpCmdLine) return FALSE; } - // TODO: use DB filenames as names because they're shorter - ATL::CSimpleArray<ATL::CStringW> arrNames; + ATL::CSimpleArray<ATL::CStringW> PkgNameList; if (!StrCmpIW(argv[1], CMD_KEY_INSTALL)) { for (INT i = 2; i < argc; ++i) { - arrNames.Add(argv[i]); + PkgNameList.Add(argv[i]); } } else @@ -43,12 +42,12 @@ BOOL UseCmdParameters(LPWSTR lpCmdLine) INFCONTEXT Context; if (SetupFindFirstLineW(InfHandle, L"RAPPS", L"Install", &Context)) { - WCHAR szName[MAX_PATH]; + WCHAR szPkgName[MAX_PATH]; do { - if (SetupGetStringFieldW(&Context, 1, szName, _countof(szName), NULL)) + if (SetupGetStringFieldW(&Context, 1, szPkgName, _countof(szPkgName), NULL)) { - arrNames.Add(szName); + PkgNameList.Add(szPkgName); } } while (SetupFindNextLine(&Context, &Context)); } @@ -63,7 +62,7 @@ BOOL UseCmdParameters(LPWSTR lpCmdLine) apps.UpdateAppsDB(); apps.Enum(ENUM_ALL_AVAILABLE, NULL, NULL); - ATL::CSimpleArray<CAvailableApplicationInfo> arrAppInfo = apps.FindInfoList(arrNames); + ATL::CSimpleArray<CAvailableApplicationInfo> arrAppInfo = apps.FindAppsByPkgNameList(PkgNameList); if (arrAppInfo.GetSize() > 0) { DownloadListOfApplications(arrAppInfo, TRUE);
4 years, 3 months
1
0
0
0
[reactos] 14/19: [RAPPS] add m_szPkgName for AvailableApps
by 赫杨
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=da8810ab889727d7863c6…
commit da8810ab889727d7863c60e9e0bb4d72e0ca58ef Author: 赫杨 <1160386205(a)qq.com> AuthorDate: Mon Aug 17 02:46:37 2020 +0800 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Sep 6 17:10:17 2020 +0200 [RAPPS] add m_szPkgName for AvailableApps --- base/applications/rapps/available.cpp | 7 +++++++ base/applications/rapps/include/available.h | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/base/applications/rapps/available.cpp b/base/applications/rapps/available.cpp index 155840be11b..88a1bf9a8b9 100644 --- a/base/applications/rapps/available.cpp +++ b/base/applications/rapps/available.cpp @@ -38,6 +38,13 @@ VOID CAvailableApplicationInfo::RetrieveGeneralInfo(AvailableStrings& AvlbString { m_Parser = new CConfigParser(m_sFileName); + // TODO: I temporarily use the file name (without suffix) as package name. + // It should be better to put this in a field of ini file. + // consider write a converter to do this and write a github action for rapps-db to ensure package_name is unique. + m_szPkgName = m_sFileName; + PathRemoveExtensionW(m_szPkgName.GetBuffer(MAX_PATH)); + m_szPkgName.ReleaseBuffer(); + m_Parser->GetInt(L"Category", m_Category); if (!GetString(L"Name", m_szName) diff --git a/base/applications/rapps/include/available.h b/base/applications/rapps/include/available.h index 2ee8136cc91..8000c3b11fc 100644 --- a/base/applications/rapps/include/available.h +++ b/base/applications/rapps/include/available.h @@ -43,7 +43,7 @@ public: INT m_Category; //BOOL m_IsSelected; LicenseType m_LicenseType; - ATL::CStringW m_szName; + ATL::CStringW m_szName; // software's display name. ATL::CStringW m_szRegName; ATL::CStringW m_szVersion; ATL::CStringW m_szLicense; @@ -54,6 +54,7 @@ public: ATL::CSimpleArray<LCID> m_LanguageLCIDs; ATL::CSimpleArray<ATL::CStringW> m_szScrnshotLocation; ATL::CStringW m_szIconLocation; + ATL::CStringW m_szPkgName; // software's package name. ULONG m_SizeBytes;
4 years, 3 months
1
0
0
0
[reactos] 13/19: [RAPPS] reduce the chance assert failed
by 赫杨
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c5e111427c7945c9f687f…
commit c5e111427c7945c9f687f32d975c1eb694777cc1 Author: 赫杨 <1160386205(a)qq.com> AuthorDate: Sun Aug 16 03:38:28 2020 +0800 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Sep 6 17:10:16 2020 +0200 [RAPPS] reduce the chance assert failed --- base/applications/rapps/loaddlg.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/base/applications/rapps/loaddlg.cpp b/base/applications/rapps/loaddlg.cpp index dce708347bf..505e48643d7 100644 --- a/base/applications/rapps/loaddlg.cpp +++ b/base/applications/rapps/loaddlg.cpp @@ -149,6 +149,7 @@ public: UINT uiPercentage = ((ULONGLONG) ulProgress * 100) / ulProgressMax; /* send the current progress to the progress bar */ + if (!IsWindow()) return; SendMessage(PBM_SETPOS, uiPercentage, 0); /* format total download size */ @@ -163,6 +164,7 @@ public: else { /* send the current progress to the progress bar */ + if (!IsWindow()) return; SendMessage(PBM_SETPOS, 0, 0); /* total size is not known, display only current size */ @@ -170,6 +172,7 @@ public: } /* and finally display it */ + if (!IsWindow()) return; SendMessage(WM_SETTEXT, 0, (LPARAM) ProgressText.GetString()); } @@ -492,8 +495,10 @@ VOID CDownloadManager::UpdateProgress( { HWND Item; + if (!IsWindow(hDlg)) return; ProgressBar.SetProgress(ulProgress, ulProgressMax); + if (!IsWindow(hDlg)) return; Item = GetDlgItem(hDlg, IDC_DOWNLOAD_STATUS); if (Item && szStatusText && wcslen(szStatusText) > 0 && UrlHasBeenCopied == FALSE) { @@ -580,6 +585,7 @@ unsigned int WINAPI CDownloadManager::ThreadFunc(LPVOID param) for (iAppId = 0; iAppId < InfoArray.GetSize(); ++iAppId) { // Reset progress bar + if (!IsWindow(hDlg)) break; Item = GetDlgItem(hDlg, IDC_DOWNLOAD_PROGRESS); if (Item) { @@ -616,7 +622,7 @@ unsigned int WINAPI CDownloadManager::ThreadFunc(LPVOID param) break; } - + if (!IsWindow(hDlg)) goto end; SetWindowTextW(hDlg, szNewCaption.GetString()); // build the path for the download @@ -671,6 +677,7 @@ unsigned int WINAPI CDownloadManager::ThreadFunc(LPVOID param) } // Add the download URL + if (!IsWindow(hDlg)) goto end; SetDlgItemTextW(hDlg, IDC_DOWNLOAD_STATUS, InfoArray[iAppId].szUrl.GetString()); DownloadsListView.SetDownloadStatus(iAppId, DLSTATUS_DOWNLOADING); @@ -832,6 +839,7 @@ unsigned int WINAPI CDownloadManager::ThreadFunc(LPVOID param) } dwCurrentBytesRead += dwBytesRead; + if (!IsWindow(hDlg)) goto end; UpdateProgress(hDlg, dwCurrentBytesRead, dwContentLen, 0, InfoArray[iAppId].szUrl.GetString()); } while (dwBytesRead && !bCancelled); @@ -850,6 +858,7 @@ unsigned int WINAPI CDownloadManager::ThreadFunc(LPVOID param) ProgressBar.SetMarquee(FALSE); dwContentLen = dwCurrentBytesRead; + if (!IsWindow(hDlg)) goto end; UpdateProgress(hDlg, dwCurrentBytesRead, dwContentLen, 0, InfoArray[iAppId].szUrl.GetString()); } @@ -866,6 +875,7 @@ unsigned int WINAPI CDownloadManager::ThreadFunc(LPVOID param) goto end; } + if (!IsWindow(hDlg)) goto end; SetWindowTextW(hDlg, szMsgText.GetString()); SendMessageW(GetDlgItem(hDlg, IDC_DOWNLOAD_STATUS), WM_SETTEXT, 0, (LPARAM) Path.GetString()); @@ -878,6 +888,7 @@ unsigned int WINAPI CDownloadManager::ThreadFunc(LPVOID param) goto end; } + if (!IsWindow(hDlg)) goto end; MessageBoxW(hDlg, szMsgText.GetString(), NULL, MB_OK | MB_ICONERROR); goto end; } @@ -902,6 +913,7 @@ run: //reflect installation progress in the titlebar //TODO: make a separate string with a placeholder to include app name? ATL::CStringW szMsgText = LoadStatusString(DLSTATUS_INSTALLING); + if (!IsWindow(hDlg)) goto end; SetWindowTextW(hDlg, szMsgText.GetString()); DownloadsListView.SetDownloadStatus(iAppId, DLSTATUS_INSTALLING); @@ -929,10 +941,12 @@ end: DeleteFileW(Path.GetString()); } + if (!IsWindow(hDlg)) return 0; DownloadsListView.SetDownloadStatus(iAppId, DLSTATUS_FINISHED); } delete static_cast<DownloadParam*>(param); + if (!IsWindow(hDlg)) return 0; SendMessageW(hDlg, WM_CLOSE, 0, 0); return 0; }
4 years, 3 months
1
0
0
0
[reactos] 12/19: [RAPPS] some renaming
by 赫杨
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4c524ee3d56d44177d3bf…
commit 4c524ee3d56d44177d3bfe29c541d2c6a9435331 Author: 赫杨 <1160386205(a)qq.com> AuthorDate: Wed Aug 5 17:22:07 2020 +0800 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Sep 6 17:10:16 2020 +0200 [RAPPS] some renaming --- base/applications/rapps/loaddlg.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/base/applications/rapps/loaddlg.cpp b/base/applications/rapps/loaddlg.cpp index 0d75c29c4cc..dce708347bf 100644 --- a/base/applications/rapps/loaddlg.cpp +++ b/base/applications/rapps/loaddlg.cpp @@ -357,7 +357,7 @@ inline VOID MessageBox_LoadString(HWND hMainWnd, INT StringID) // Download dialog (loaddlg.cpp) class CDownloadManager { - static ATL::CSimpleArray<DownloadInfo> AppsToInstallList; + static ATL::CSimpleArray<DownloadInfo> AppsDownloadList; static CDowloadingAppsListView DownloadsListView; static CDownloaderProgress ProgressBar; static BOOL bCancelled; @@ -373,7 +373,7 @@ public: // CDownloadManager -ATL::CSimpleArray<DownloadInfo> CDownloadManager::AppsToInstallList; +ATL::CSimpleArray<DownloadInfo> CDownloadManager::AppsDownloadList; CDowloadingAppsListView CDownloadManager::DownloadsListView; CDownloaderProgress CDownloadManager::ProgressBar; BOOL CDownloadManager::bCancelled = FALSE; @@ -381,13 +381,13 @@ BOOL CDownloadManager::bModal = FALSE; VOID CDownloadManager::Add(DownloadInfo info) { - AppsToInstallList.Add(info); + AppsDownloadList.Add(info); } VOID CDownloadManager::Download(const DownloadInfo &DLInfo, BOOL bIsModal) { - AppsToInstallList.RemoveAll(); - AppsToInstallList.Add(DLInfo); + AppsDownloadList.RemoveAll(); + AppsDownloadList.Add(DLInfo); LaunchDownloadDialog(bIsModal); } @@ -430,7 +430,7 @@ INT_PTR CALLBACK CDownloadManager::DownloadDlgProc(HWND Dlg, UINT uMsg, WPARAM w { return FALSE; } - DownloadsListView.LoadList(AppsToInstallList); + DownloadsListView.LoadList(AppsDownloadList); // Get a dlg string for later use GetWindowTextW(Dlg, szCaption, _countof(szCaption)); @@ -443,7 +443,7 @@ INT_PTR CALLBACK CDownloadManager::DownloadDlgProc(HWND Dlg, UINT uMsg, WPARAM w ShowWindow(Dlg, SW_SHOW); // Start download process - DownloadParam *param = new DownloadParam(Dlg, AppsToInstallList, szCaption); + DownloadParam *param = new DownloadParam(Dlg, AppsDownloadList, szCaption); unsigned int ThreadId; HANDLE Thread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, (void *) param, 0, &ThreadId); @@ -453,7 +453,7 @@ INT_PTR CALLBACK CDownloadManager::DownloadDlgProc(HWND Dlg, UINT uMsg, WPARAM w } CloseHandle(Thread); - AppsToInstallList.RemoveAll(); + AppsDownloadList.RemoveAll(); return TRUE; }
4 years, 3 months
1
0
0
0
[reactos] 11/19: [RAPPS] fix the bug that Toolbar is not working
by 赫杨
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d29fba7f7aca41091fb61…
commit d29fba7f7aca41091fb61f21afbb529c8406bcbd Author: 赫杨 <1160386205(a)qq.com> AuthorDate: Mon Aug 3 21:54:01 2020 +0800 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Sep 6 17:10:16 2020 +0200 [RAPPS] fix the bug that Toolbar is not working --- base/applications/rapps/appview.cpp | 64 +++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/base/applications/rapps/appview.cpp b/base/applications/rapps/appview.cpp index 77da1851a38..dff7c0eca85 100644 --- a/base/applications/rapps/appview.cpp +++ b/base/applications/rapps/appview.cpp @@ -1784,6 +1784,7 @@ VOID CApplicationView::OnCommand(WPARAM wParam, LPARAM lParam) break; } + return; } else if ((HWND)lParam == m_ComboBox->GetWindow()) { @@ -1801,42 +1802,51 @@ VOID CApplicationView::OnCommand(WPARAM wParam, LPARAM lParam) } break; } + + return; + } + else if ((HWND)lParam == m_Toolbar->GetWindow()) + { + // the message is sent from Toolbar. fall down to continue process + } + else + { + return; } } - else - { - WORD wCommand = LOWORD(wParam); - switch (wCommand) - { - case ID_INSTALL: - m_MainWindow->InstallApplication((CAvailableApplicationInfo *)GetFocusedItemData()); - break; + // the LOWORD of wParam contains a Menu or Control ID + WORD wCommand = LOWORD(wParam); - case ID_TOOLBAR_INSTALL: - m_MainWindow->SendMessageW(WM_COMMAND, ID_INSTALL, 0); - break; + switch (wCommand) + { + case ID_INSTALL: + m_MainWindow->InstallApplication((CAvailableApplicationInfo *)GetFocusedItemData()); + break; - case ID_UNINSTALL: - m_MainWindow->SendMessageW(WM_COMMAND, ID_UNINSTALL, 0); - break; + case ID_TOOLBAR_INSTALL: + m_MainWindow->SendMessageW(WM_COMMAND, ID_INSTALL, 0); + break; - case ID_MODIFY: - m_MainWindow->SendMessageW(WM_COMMAND, ID_MODIFY, 0); - break; + case ID_UNINSTALL: + m_MainWindow->SendMessageW(WM_COMMAND, ID_UNINSTALL, 0); + break; - case ID_REGREMOVE: - m_MainWindow->SendMessageW(WM_COMMAND, ID_REGREMOVE, 0); - break; + case ID_MODIFY: + m_MainWindow->SendMessageW(WM_COMMAND, ID_MODIFY, 0); + break; - case ID_REFRESH: - m_MainWindow->SendMessageW(WM_COMMAND, ID_REFRESH, 0); - break; + case ID_REGREMOVE: + m_MainWindow->SendMessageW(WM_COMMAND, ID_REGREMOVE, 0); + break; - case ID_RESETDB: - m_MainWindow->SendMessageW(WM_COMMAND, ID_RESETDB, 0); - break; - } + case ID_REFRESH: + m_MainWindow->SendMessageW(WM_COMMAND, ID_REFRESH, 0); + break; + + case ID_RESETDB: + m_MainWindow->SendMessageW(WM_COMMAND, ID_RESETDB, 0); + break; } }
4 years, 3 months
1
0
0
0
[reactos] 10/19: [RAPPS] update some file-header
by 赫杨
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=36870a02f713e82eb21db…
commit 36870a02f713e82eb21db7787bc9b98752eb8e15 Author: 赫杨 <1160386205(a)qq.com> AuthorDate: Sat Aug 1 03:57:35 2020 +0800 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Sep 6 17:10:16 2020 +0200 [RAPPS] update some file-header update some header to newer format, update purpose and add my name to those file I've modified --- base/applications/rapps/available.cpp | 4 ++-- base/applications/rapps/cabinet.cpp | 11 +++++------ base/applications/rapps/gui.cpp | 4 ++-- base/applications/rapps/installed.cpp | 6 +++--- base/applications/rapps/integrity.cpp | 3 +-- base/applications/rapps/loaddlg.cpp | 3 +-- base/applications/rapps/misc.cpp | 3 +-- base/applications/rapps/settingsdlg.cpp | 3 +-- base/applications/rapps/unattended.cpp | 11 +++++------ base/applications/rapps/winmain.cpp | 3 +-- 10 files changed, 22 insertions(+), 29 deletions(-) diff --git a/base/applications/rapps/available.cpp b/base/applications/rapps/available.cpp index 62d4585d3a5..155840be11b 100644 --- a/base/applications/rapps/available.cpp +++ b/base/applications/rapps/available.cpp @@ -1,11 +1,11 @@ /* * PROJECT: ReactOS Applications Manager - * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) - * FILE: base/applications/rapps/available.cpp + * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later
) * PURPOSE: Classes for working with available applications * COPYRIGHT: Copyright 2009 Dmitry Chapyshev (dmitry(a)reactos.org) * Copyright 2015 Ismael Ferreras Morezuelas (swyterzone+ros(a)gmail.com) * Copyright 2017 Alexander Shaposhnikov (sanchaez(a)reactos.org) + * Copyright 2020 He Yang (1160386205(a)qq.com) */ #include "rapps.h" diff --git a/base/applications/rapps/cabinet.cpp b/base/applications/rapps/cabinet.cpp index 11b301ed9cc..e10d64f84c5 100644 --- a/base/applications/rapps/cabinet.cpp +++ b/base/applications/rapps/cabinet.cpp @@ -1,10 +1,9 @@ /* -* PROJECT: ReactOS Applications Manager -* LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) -* FILE: base/applications/rapps/cabinet.cpp -* PURPOSE: Cabinet extraction using FDI API -* COPYRIGHT: Copyright 2018 Alexander Shaposhnikov (sanchaez(a)reactos.org) -*/ + * PROJECT: ReactOS Applications Manager + * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later
) + * PURPOSE: Cabinet extraction using FDI API + * COPYRIGHT: Copyright 2018 Alexander Shaposhnikov (sanchaez(a)reactos.org) + */ #include "rapps.h" #include <fdi.h> diff --git a/base/applications/rapps/gui.cpp b/base/applications/rapps/gui.cpp index 9c47b8841eb..7732d18e501 100644 --- a/base/applications/rapps/gui.cpp +++ b/base/applications/rapps/gui.cpp @@ -1,10 +1,10 @@ /* * PROJECT: ReactOS Applications Manager - * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) - * FILE: base/applications/rapps/gui.cpp + * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later
) * PURPOSE: GUI classes for RAPPS * COPYRIGHT: Copyright 2015 David Quintana (gigaherz(a)gmail.com) * Copyright 2017 Alexander Shaposhnikov (sanchaez(a)reactos.org) + * Copyright 2020 He Yang (1160386205(a)qq.com) */ #include "rapps.h" diff --git a/base/applications/rapps/installed.cpp b/base/applications/rapps/installed.cpp index 0cfb6bc9ddd..955ba012130 100644 --- a/base/applications/rapps/installed.cpp +++ b/base/applications/rapps/installed.cpp @@ -1,10 +1,10 @@ /* * PROJECT: ReactOS Applications Manager - * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) - * FILE: base/applications/rapps/installed.cpp - * PURPOSE: Functions for working with installed applications + * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later
) + * PURPOSE: Classes for working with installed applications * COPYRIGHT: Copyright 2009 Dmitry Chapyshev (dmitry(a)reactos.org) * Copyright 2017 Alexander Shaposhnikov (sanchaez(a)reactos.org) + * Copyright 2020 He Yang (1160386205(a)qq.com) */ #include "rapps.h" diff --git a/base/applications/rapps/integrity.cpp b/base/applications/rapps/integrity.cpp index 10e022c90d2..493a27d69c8 100644 --- a/base/applications/rapps/integrity.cpp +++ b/base/applications/rapps/integrity.cpp @@ -1,7 +1,6 @@ /* * PROJECT: ReactOS Applications Manager - * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) - * FILE: base/applications/rapps/integrity.cpp + * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later
) * PURPOSE: Various integrity check mechanisms * COPYRIGHT: Copyright Ismael Ferreras Morezuelas (swyterzone+ros(a)gmail.com) * Copyright Mark Jansen diff --git a/base/applications/rapps/loaddlg.cpp b/base/applications/rapps/loaddlg.cpp index 60f999967cb..0d75c29c4cc 100644 --- a/base/applications/rapps/loaddlg.cpp +++ b/base/applications/rapps/loaddlg.cpp @@ -1,7 +1,6 @@ /* * PROJECT: ReactOS Applications Manager - * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) - * FILE: base/applications/rapps/loaddlg.cpp + * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later
) * PURPOSE: Displaying a download dialog * COPYRIGHT: Copyright 2001 John R. Sheets (for CodeWeavers) * Copyright 2004 Mike McCormack (for CodeWeavers) diff --git a/base/applications/rapps/misc.cpp b/base/applications/rapps/misc.cpp index be6f68e156d..086adfcfb68 100644 --- a/base/applications/rapps/misc.cpp +++ b/base/applications/rapps/misc.cpp @@ -1,7 +1,6 @@ /* * PROJECT: ReactOS Applications Manager - * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) - * FILE: base/applications/rapps/misc.cpp + * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later
) * PURPOSE: Misc functions * COPYRIGHT: Copyright 2009 Dmitry Chapyshev (dmitry(a)reactos.org) * Copyright 2015 Ismael Ferreras Morezuelas (swyterzone+ros(a)gmail.com) diff --git a/base/applications/rapps/settingsdlg.cpp b/base/applications/rapps/settingsdlg.cpp index 744a07e7a4e..8943c1ac98e 100644 --- a/base/applications/rapps/settingsdlg.cpp +++ b/base/applications/rapps/settingsdlg.cpp @@ -1,7 +1,6 @@ /* * PROJECT: ReactOS Applications Manager - * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) - * FILE: base/applications/rapps/settingsdlg.cpp + * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later
) * PURPOSE: Settings Dialog * COPYRIGHT: Copyright 2009 Dmitry Chapyshev (dmitry(a)reactos.org) * Copyright 2017 Alexander Shaposhnikov (sanchaez(a)reactos.org) diff --git a/base/applications/rapps/unattended.cpp b/base/applications/rapps/unattended.cpp index d5428cae410..540795be8d4 100644 --- a/base/applications/rapps/unattended.cpp +++ b/base/applications/rapps/unattended.cpp @@ -1,10 +1,9 @@ /* -* PROJECT: ReactOS Applications Manager -* LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) -* FILE: base/applications/rapps/unattended.cpp -* PURPOSE: Functions to parse command-line flags and process them -* COPYRIGHT: Copyright 2017 Alexander Shaposhnikov (sanchaez(a)reactos.org) -*/ + * PROJECT: ReactOS Applications Manager + * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later
) + * PURPOSE: Functions to parse command-line flags and process them + * COPYRIGHT: Copyright 2017 Alexander Shaposhnikov (sanchaez(a)reactos.org) + */ #include "rapps.h" #include "unattended.h" diff --git a/base/applications/rapps/winmain.cpp b/base/applications/rapps/winmain.cpp index ad14c9fd80b..2f462459113 100644 --- a/base/applications/rapps/winmain.cpp +++ b/base/applications/rapps/winmain.cpp @@ -1,7 +1,6 @@ /* * PROJECT: ReactOS Applications Manager - * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) - * FILE: base/applications/rapps/winmain.cpp + * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later
) * PURPOSE: Main program * COPYRIGHT: Copyright 2009 Dmitry Chapyshev (dmitry(a)reactos.org) * Copyright 2015 Ismael Ferreras Morezuelas (swyterzone+ros(a)gmail.com)
4 years, 3 months
1
0
0
0
[reactos] 07/19: [RAPPS] listview refactor (#2970)
by He Yang
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=10c0ff7416d6e8066c170…
commit 10c0ff7416d6e8066c170bb3abdfb22303c472ed Author: He Yang <1160386205(a)qq.com> AuthorDate: Tue Jul 21 22:13:39 2020 +0800 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Sep 6 17:09:20 2020 +0200 [RAPPS] listview refactor (#2970) This makes it easier to maintain the listview, and better separates the application list and listview. * [RAPPS] fix memory leak when cleanup. some renaming are also done * [RAPPS] move the code adding apps info inside class CAppsListView * [RAPPS] add table view, create listview and AppInfoDisplay inside it * [RAPPS] rename INSTALLED_INFO as CInstalledApplicationInfo now it corresponds with CAvailableApplicationInfo * [RAPPS] add CInstalledApps * [RAPPS] optimize the speed when refreshing listview * [RAPPS] correctly handle Enum for InstalledApps * [RAPPS] make check all working properly (this also fixes some bugs) the old version has some bugs when check all items after switching tags in tree-view * [RAPPS] add handling for wow64 * [RAPPS] use an inline function to replace INSERT_TEXT macro * [RAPPS] fix the bug that StatusBar won't update when switching tags * [RAPPS] now TableView always reset bIsAscending in SetDisplayMode * [RAPPS] rename TableView to ApplicationView * [RAPPS] now bIsAscending would be reset when switching column in listview --- base/applications/rapps/available.cpp | 169 ++-- base/applications/rapps/gui.cpp | 1335 ++++++++++++++++----------- base/applications/rapps/include/available.h | 16 +- base/applications/rapps/include/installed.h | 46 +- base/applications/rapps/include/misc.h | 2 + base/applications/rapps/include/rosui.h | 5 +- base/applications/rapps/installed.cpp | 306 ++++-- base/applications/rapps/misc.cpp | 33 + 8 files changed, 1203 insertions(+), 709 deletions(-) diff --git a/base/applications/rapps/available.cpp b/base/applications/rapps/available.cpp index 8af6c78a8b9..62d4585d3a5 100644 --- a/base/applications/rapps/available.cpp +++ b/base/applications/rapps/available.cpp @@ -19,7 +19,7 @@ // CAvailableApplicationInfo CAvailableApplicationInfo::CAvailableApplicationInfo(const ATL::CStringW& sFileNameParam, AvailableStrings& AvlbStrings) - : m_IsSelected(FALSE), m_LicenseType(LICENSE_NONE), m_SizeBytes(0), m_sFileName(sFileNameParam), + : m_LicenseType(LICENSE_NONE), m_SizeBytes(0), m_sFileName(sFileNameParam), m_IsInstalled(FALSE), m_HasLanguageInfo(FALSE), m_HasInstalledVersion(FALSE) { RetrieveGeneralInfo(AvlbStrings); @@ -400,71 +400,127 @@ BOOL CAvailableApps::ForceUpdateAppsDB() BOOL CAvailableApps::Enum(INT EnumType, AVAILENUMPROC lpEnumProc, PVOID param) { + if (EnumType == ENUM_CAT_SELECTED) + { + CAvailableApplicationInfo *EnumAvlbInfo = NULL; - HANDLE hFind = INVALID_HANDLE_VALUE; - WIN32_FIND_DATAW FindFileData; - - hFind = FindFirstFileW(m_Strings.szSearchPath.GetString(), &FindFileData); + // enum all object in m_SelectedList and invoke callback + for(POSITION CurrentPosition = m_SelectedList.GetHeadPosition(); + CurrentPosition && (EnumAvlbInfo = m_SelectedList.GetAt(CurrentPosition)); + m_SelectedList.GetNext(CurrentPosition)) + { + EnumAvlbInfo->RefreshAppInfo(m_Strings); - if (hFind == INVALID_HANDLE_VALUE) - { - //no db yet - return FALSE; + if (lpEnumProc) + lpEnumProc(EnumAvlbInfo, TRUE, param); + } + return TRUE; } - - do + else { - // loop for all the cached entries - POSITION CurrentListPosition = m_InfoList.GetHeadPosition(); - CAvailableApplicationInfo* Info = NULL; + HANDLE hFind = INVALID_HANDLE_VALUE; + WIN32_FIND_DATAW FindFileData; + + hFind = FindFirstFileW(m_Strings.szSearchPath.GetString(), &FindFileData); + + if (hFind == INVALID_HANDLE_VALUE) + { + //no db yet + return FALSE; + } - while (CurrentListPosition != NULL) + do { - POSITION LastListPosition = CurrentListPosition; - Info = m_InfoList.GetNext(CurrentListPosition); + // loop for all the cached entries + POSITION CurrentListPosition = m_InfoList.GetHeadPosition(); + CAvailableApplicationInfo *Info = NULL; - // do we already have this entry in cache? - if (Info->m_sFileName == FindFileData.cFileName) + while (CurrentListPosition != NULL) { - // is it current enough, or the file has been modified since our last time here? - if (CompareFileTime(&FindFileData.ftLastWriteTime, &Info->m_ftCacheStamp) == 1) - { - // recreate our cache, this is the slow path - m_InfoList.RemoveAt(LastListPosition); + POSITION LastListPosition = CurrentListPosition; + Info = m_InfoList.GetNext(CurrentListPosition); - delete Info; - Info = NULL; - break; + // do we already have this entry in cache? + if (Info->m_sFileName == FindFileData.cFileName) + { + // is it current enough, or the file has been modified since our last time here? + if (CompareFileTime(&FindFileData.ftLastWriteTime, &Info->m_ftCacheStamp) == 1) + { + // recreate our cache, this is the slow path + m_InfoList.RemoveAt(LastListPosition); + + // also remove this in selected list (if exist) + RemoveSelected(Info); + + delete Info; + Info = NULL; + break; + } + else + { + // speedy path, compare directly, we already have the data + goto skip_if_cached; + } } - else + } + + // create a new entry + Info = new CAvailableApplicationInfo(FindFileData.cFileName, m_Strings); + + // set a timestamp for the next time + Info->SetLastWriteTime(&FindFileData.ftLastWriteTime); + m_InfoList.AddTail(Info); + + skip_if_cached: + if (EnumType == Info->m_Category + || EnumType == ENUM_ALL_AVAILABLE) + { + Info->RefreshAppInfo(m_Strings); + + if (lpEnumProc) { - // speedy path, compare directly, we already have the data - goto skip_if_cached; + if (m_SelectedList.Find(Info)) + { + lpEnumProc(Info, TRUE, param); + } + else + { + lpEnumProc(Info, FALSE, param); + } } } - } + } while (FindNextFileW(hFind, &FindFileData)); - // create a new entry - Info = new CAvailableApplicationInfo(FindFileData.cFileName, m_Strings); + FindClose(hFind); + return TRUE; + } +} - // set a timestamp for the next time - Info->SetLastWriteTime(&FindFileData.ftLastWriteTime); - m_InfoList.AddTail(Info); +BOOL CAvailableApps::AddSelected(CAvailableApplicationInfo *AvlbInfo) +{ + return m_SelectedList.AddTail(AvlbInfo) != 0; +} -skip_if_cached: - if (EnumType == Info->m_Category - || EnumType == ENUM_ALL_AVAILABLE - || (EnumType == ENUM_CAT_SELECTED && Info->m_IsSelected)) - { - Info->RefreshAppInfo(m_Strings); +BOOL CAvailableApps::RemoveSelected(CAvailableApplicationInfo *AvlbInfo) +{ + POSITION Position = m_SelectedList.Find(AvlbInfo); + if (Position) + { + m_SelectedList.RemoveAt(Position); + return TRUE; + } + return FALSE; +} - if (lpEnumProc) - lpEnumProc(Info, m_Strings.szAppsPath.GetString(), param); - } - } while (FindNextFileW(hFind, &FindFileData) != 0); +VOID CAvailableApps::RemoveAllSelected() +{ + m_SelectedList.RemoveAll(); + return; +} - FindClose(hFind); - return TRUE; +int CAvailableApps::GetSelectedCount() +{ + return m_SelectedList.GetCount(); } CAvailableApplicationInfo* CAvailableApps::FindInfo(const ATL::CStringW& szAppName) const @@ -502,23 +558,6 @@ ATL::CSimpleArray<CAvailableApplicationInfo> CAvailableApps::FindInfoList(const return result; } -ATL::CSimpleArray<CAvailableApplicationInfo> CAvailableApps::GetSelected() const -{ - ATL::CSimpleArray<CAvailableApplicationInfo> result; - POSITION CurrentListPosition = m_InfoList.GetHeadPosition(); - CAvailableApplicationInfo* Info; - - while (CurrentListPosition != NULL) - { - Info = m_InfoList.GetNext(CurrentListPosition); - if (Info->m_IsSelected) - { - result.Add(*Info); - } - } - return result; -} - const ATL::CStringW& CAvailableApps::GetFolderPath() const { return m_Strings.szPath; diff --git a/base/applications/rapps/gui.cpp b/base/applications/rapps/gui.cpp index b0599074a47..e3aeccc579f 100644 --- a/base/applications/rapps/gui.cpp +++ b/base/applications/rapps/gui.cpp @@ -65,6 +65,21 @@ enum SCRNSHOT_STATUS #define PI 3.1415927 +// retrieve the value using a mask +#define STATEIMAGETOINDEX(x) (((x) & LVIS_STATEIMAGEMASK) >> 12) + +// for listview with extend style LVS_EX_CHECKBOXES, State image 1 is the unchecked box, and state image 2 is the checked box. +// see this:
https://docs.microsoft.com/en-us/windows/win32/controls/extended-list-view-…
+#define STATEIMAGE_UNCHECKED 1 +#define STATEIMAGE_CHECKED 2 + +enum APPLICATION_VIEW_MODE +{ + ApplicationViewEmpty, + ApplicationViewAvailableApps, + ApplicationViewInstalledApps +}; + typedef struct __ScrnshotDownloadParam { LONGLONG ID; @@ -73,6 +88,8 @@ typedef struct __ScrnshotDownloadParam ATL::CStringW DownloadFileName; } ScrnshotDownloadParam; +class CMainWindow; + INT GetSystemColorDepth() { DEVMODEW pDevMode; @@ -250,41 +267,37 @@ public: return TRUE; } - BOOL ShowInstalledAppInfo(PINSTALLED_INFO Info) + inline VOID InsertTextWithString(UINT StringID, DWORD StringFlags, const ATL::CStringW& Text, DWORD TextFlags) { - ATL::CStringW szText; - ATL::CStringW szInfo; + if (!Text.IsEmpty()) + { + LoadAndInsertText(StringID, Text, StringFlags, TextFlags); + } + } - if (!Info || !Info->hSubKey) - return FALSE; + BOOL ShowInstalledAppInfo(CInstalledApplicationInfo * Info) + { + if (!Info) return FALSE; - Info->GetApplicationString(L"DisplayName", szText); - SetText(szText, CFE_BOLD); + SetText(Info->szDisplayName, CFE_BOLD); InsertText(L"\n", 0); -#define GET_INFO(a, b, c, d) \ - if (Info->GetApplicationString(a, szInfo)) \ - { \ - LoadAndInsertText(b, szInfo, c, d); \ - } - - GET_INFO(L"DisplayVersion", IDS_INFO_VERSION, CFE_BOLD, 0); - GET_INFO(L"Publisher", IDS_INFO_PUBLISHER, CFE_BOLD, 0); - GET_INFO(L"RegOwner", IDS_INFO_REGOWNER, CFE_BOLD, 0); - GET_INFO(L"ProductID", IDS_INFO_PRODUCTID, CFE_BOLD, 0); - GET_INFO(L"HelpLink", IDS_INFO_HELPLINK, CFE_BOLD, CFM_LINK); - GET_INFO(L"HelpTelephone", IDS_INFO_HELPPHONE, CFE_BOLD, 0); - GET_INFO(L"Readme", IDS_INFO_README, CFE_BOLD, 0); - GET_INFO(L"Contact", IDS_INFO_CONTACT, CFE_BOLD, 0); - GET_INFO(L"URLUpdateInfo", IDS_INFO_UPDATEINFO, CFE_BOLD, CFM_LINK); - GET_INFO(L"URLInfoAbout", IDS_INFO_INFOABOUT, CFE_BOLD, CFM_LINK); - GET_INFO(L"Comments", IDS_INFO_COMMENTS, CFE_BOLD, 0); - GET_INFO(L"InstallDate", IDS_INFO_INSTALLDATE, CFE_BOLD, 0); - GET_INFO(L"InstallLocation", IDS_INFO_INSTLOCATION, CFE_BOLD, 0); - GET_INFO(L"InstallSource", IDS_INFO_INSTALLSRC, CFE_BOLD, 0); - GET_INFO(L"UninstallString", IDS_INFO_UNINSTALLSTR, CFE_BOLD, 0); - GET_INFO(L"InstallSource", IDS_INFO_INSTALLSRC, CFE_BOLD, 0); - GET_INFO(L"ModifyPath", IDS_INFO_MODIFYPATH, CFE_BOLD, 0); + InsertTextWithString(IDS_INFO_VERSION, CFE_BOLD, Info->szDisplayVersion, 0); + InsertTextWithString(IDS_INFO_PUBLISHER, CFE_BOLD, Info->szPublisher, 0); + InsertTextWithString(IDS_INFO_REGOWNER, CFE_BOLD, Info->szRegOwner, 0); + InsertTextWithString(IDS_INFO_PRODUCTID, CFE_BOLD, Info->szProductID, 0); + InsertTextWithString(IDS_INFO_HELPLINK, CFE_BOLD, Info->szHelpLink, CFM_LINK); + InsertTextWithString(IDS_INFO_HELPPHONE, CFE_BOLD, Info->szHelpTelephone, 0); + InsertTextWithString(IDS_INFO_README, CFE_BOLD, Info->szReadme, 0); + InsertTextWithString(IDS_INFO_CONTACT, CFE_BOLD, Info->szContact, 0); + InsertTextWithString(IDS_INFO_UPDATEINFO, CFE_BOLD, Info->szURLUpdateInfo, CFM_LINK); + InsertTextWithString(IDS_INFO_INFOABOUT, CFE_BOLD, Info->szURLInfoAbout, CFM_LINK); + InsertTextWithString(IDS_INFO_COMMENTS, CFE_BOLD, Info->szComments, 0); + InsertTextWithString(IDS_INFO_INSTALLDATE, CFE_BOLD, Info->szInstallDate, 0); + InsertTextWithString(IDS_INFO_INSTLOCATION, CFE_BOLD, Info->szInstallLocation, 0); + InsertTextWithString(IDS_INFO_INSTALLSRC, CFE_BOLD, Info->szInstallSource, 0); + InsertTextWithString(IDS_INFO_UNINSTALLSTR, CFE_BOLD, Info->szUninstallString, 0); + InsertTextWithString(IDS_INFO_MODIFYPATH, CFE_BOLD, Info->szModifyPath, 0); return TRUE; } @@ -908,8 +921,8 @@ private: public: - CAppRichEdit * RichEdit; - CAppScrnshotPreview * ScrnshotPrev; + CAppRichEdit * RichEdit = NULL; + CAppScrnshotPreview * ScrnshotPrev = NULL; static ATL::CWndClassInfo& GetWndClassInfo() { @@ -957,7 +970,7 @@ public: return RichEdit->ShowAvailableAppInfo(Info); } - BOOL ShowInstalledAppInfo(PINSTALLED_INFO Info) + BOOL ShowInstalledAppInfo(CInstalledApplicationInfo * Info) { ScrnshotPrev->DisplayEmpty(); ResizeChildren(); @@ -993,6 +1006,11 @@ public: } } + ~CAppInfoDisplay() + { + delete RichEdit; + delete ScrnshotPrev; + } }; class CMainToolbar : @@ -1177,16 +1195,19 @@ class CAppsListView : INT iSubItem; }; - BOOL bHasAllChecked; - BOOL bIsAscending; + BOOL bIsAscending = TRUE; BOOL bHasCheckboxes; + INT ItemCount = 0; + INT CheckedItemCount = 0; + INT ColumnCount = 0; + INT nLastHeaderID; + APPLICATION_VIEW_MODE ApplicationViewMode = ApplicationViewEmpty; + public: CAppsListView() : - bHasAllChecked(FALSE), - bIsAscending(TRUE), bHasCheckboxes(FALSE), nLastHeaderID(-1) { @@ -1221,6 +1242,7 @@ public: /* If the sorting column changed, remove the sorting style from the old column */ if ((nLastHeaderID != -1) && (nLastHeaderID != nHeaderID)) { + bIsAscending = TRUE; // also reset sorting method to ascending hColumn.mask = HDI_FORMAT; Header_GetItem(hHeader, nLastHeaderID, &hColumn); hColumn.fmt &= ~(HDF_SORTUP | HDF_SORTDOWN); @@ -1249,7 +1271,7 @@ public: return AddColumn(Index, const_cast<LPWSTR>(Text.GetString()), Width, Format); } - BOOL AddColumn(INT Index, LPWSTR lpText, INT Width, INT Format) + int AddColumn(INT Index, LPWSTR lpText, INT Width, INT Format) { LVCOLUMNW Column; @@ -1261,7 +1283,13 @@ public: Column.cx = Width; Column.fmt = Format; - return (InsertColumn(Index, &Column) == -1) ? FALSE : TRUE; + return SendMessage(LVM_INSERTCOLUMN, Index, (LPARAM)(&Column)); + } + + void DeleteColumn(INT Index) + { + SendMessage(LVM_DELETECOLUMN, Index, 0); + return; } INT AddItem(INT ItemIndex, INT IconIndex, LPCWSTR lpText, LPARAM lParam) @@ -1270,15 +1298,25 @@ public: ZeroMemory(&Item, sizeof(Item)); - Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; + Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; Item.pszText = const_cast<LPWSTR>(lpText); Item.lParam = lParam; Item.iItem = ItemIndex; Item.iImage = IconIndex; + if (IconIndex >= 0) + { + Item.iImage = IconIndex; + Item.mask |= LVIF_IMAGE; + } return InsertItem(&Item); } + HIMAGELIST GetImageList(int iImageList) + { + return (HIMAGELIST)SendMessage(LVM_GETIMAGELIST, iImageList, 0); + } + static INT CALLBACK s_CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { SortContext * ctx = ((SortContext*) lParamSort); @@ -1319,6 +1357,12 @@ public: SetCheckboxesVisible(FALSE); } + HIMAGELIST hImageListView = ImageList_Create(LISTVIEW_ICON_SIZE, + LISTVIEW_ICON_SIZE, + GetSystemColorDepth() | ILC_MASK, + 0, 1); + SetImageList(hImageListView, LVSIL_SMALL); + return hwnd; } @@ -1332,219 +1376,656 @@ public: if (bHasCheckboxes) { SetItemState(item, INDEXTOSTATEIMAGEMASK((fCheck) ? 2 : 1), LVIS_STATEIMAGEMASK); - SetSelected(item, fCheck); } } - VOID SetSelected(INT item, BOOL value) + VOID CheckAll() { - if (item < 0) + if (bHasCheckboxes) { - for (INT i = 0; i >= 0; i = GetNextItem(i, LVNI_ALL)) + if (CheckedItemCount == ItemCount) { - CAvailableApplicationInfo* pAppInfo = (CAvailableApplicationInfo*) GetItemData(i); - if (pAppInfo) - { - pAppInfo->m_IsSelected = value; - } + // clear all + SetCheckState(-1, FALSE); } - } - else - { - CAvailableApplicationInfo* pAppInfo = (CAvailableApplicationInfo*) GetItemData(item); - if (pAppInfo) + else { - pAppInfo->m_IsSelected = value; + // check all + SetCheckState(-1, TRUE); } } } - - VOID CheckAll() + + PVOID GetFocusedItemData() { - if (bHasCheckboxes) + INT item = GetSelectionMark(); + if (item == -1) { - bHasAllChecked = !bHasAllChecked; - SetCheckState(-1, bHasAllChecked); + return (PVOID)0; } + return (PVOID)GetItemData(item); } - ATL::CSimpleArray<CAvailableApplicationInfo> GetCheckedItems() + BOOL SetDisplayMode(APPLICATION_VIEW_MODE Mode) { - if (!bHasCheckboxes) + if (!DeleteAllItems()) return FALSE; + ApplicationViewMode = Mode; + + bIsAscending = TRUE; + + ItemCount = 0; + CheckedItemCount = 0; + + // delete old columns + while (ColumnCount) { - return ATL::CSimpleArray<CAvailableApplicationInfo>(); + DeleteColumn(--ColumnCount); } - ATL::CSimpleArray<CAvailableApplicationInfo> list; - for (INT i = 0; i >= 0; i = GetNextItem(i, LVNI_ALL)) + ImageList_RemoveAll(GetImageList(LVSIL_SMALL)); + + // add new columns + ATL::CStringW szText; + switch (Mode) { - if (GetCheckState(i) != FALSE) - { - CAvailableApplicationInfo* pAppInfo = (CAvailableApplicationInfo*) GetItemData(i); - list.Add(*pAppInfo); - } + case ApplicationViewInstalledApps: + + /* Add columns to ListView */ + szText.LoadStringW(IDS_APP_NAME); + AddColumn(ColumnCount++, szText, 250, LVCFMT_LEFT); + + szText.LoadStringW(IDS_APP_INST_VERSION); + AddColumn(ColumnCount++, szText, 90, LVCFMT_RIGHT); + + szText.LoadStringW(IDS_APP_DESCRIPTION); + AddColumn(ColumnCount++, szText, 300, LVCFMT_LEFT); + + // disable checkboxes + SetCheckboxesVisible(FALSE); + break; + + case ApplicationViewAvailableApps: + + /* Add columns to ListView */ + szText.LoadStringW(IDS_APP_NAME); + AddColumn(ColumnCount++, szText, 250, LVCFMT_LEFT); + + szText.LoadStringW(IDS_APP_INST_VERSION); + AddColumn(ColumnCount++, szText, 90, LVCFMT_RIGHT); + + szText.LoadStringW(IDS_APP_DESCRIPTION); + AddColumn(ColumnCount++, szText, 300, LVCFMT_LEFT); + + // enable checkboxes + SetCheckboxesVisible(TRUE); + break; + + case ApplicationViewEmpty: + default: + break; } - return list; + + + return TRUE; } - CAvailableApplicationInfo* GetSelectedData() + BOOL AddInstalledApplication(CInstalledApplicationInfo *InstAppInfo, LPVOID CallbackParam) { - INT item = GetSelectionMark(); - return (CAvailableApplicationInfo*) GetItemData(item); - } -}; + if (ApplicationViewMode != ApplicationViewInstalledApps) + { + return FALSE; + } -class CSideTreeView : - public CUiWindow<CTreeView> -{ - HIMAGELIST hImageTreeView; + HICON hIcon = (HICON)LoadIconW(hInst, MAKEINTRESOURCEW(IDI_MAIN)); + HIMAGELIST hImageList = GetImageList(LVSIL_SMALL); + int IconIndex = ImageList_AddIcon(hImageList, hIcon); + DestroyIcon(hIcon); -public: - CSideTreeView() : - CUiWindow(), - hImageTreeView(ImageList_Create(TREEVIEW_ICON_SIZE, TREEVIEW_ICON_SIZE, - GetSystemColorDepth() | ILC_MASK, - 0, 1)) - { - } + int Index = AddItem(ItemCount, IconIndex, InstAppInfo->szDisplayName, (LPARAM)CallbackParam); + SetItemText(Index, 1, InstAppInfo->szDisplayVersion.IsEmpty() ? L"---" : InstAppInfo->szDisplayVersion); + SetItemText(Index, 2, InstAppInfo->szComments.IsEmpty() ? L"---" : InstAppInfo->szComments); - HTREEITEM AddItem(HTREEITEM hParent, ATL::CStringW &Text, INT Image, INT SelectedImage, LPARAM lParam) - { - return CUiWindow<CTreeView>::AddItem(hParent, const_cast<LPWSTR>(Text.GetString()), Image, SelectedImage, lParam); + ItemCount++; + return TRUE; } - HTREEITEM AddCategory(HTREEITEM hRootItem, UINT TextIndex, UINT IconIndex) + BOOL AddAvailableApplication(CAvailableApplicationInfo *AvlbAppInfo, BOOL InitCheckState, LPVOID CallbackParam) { - ATL::CStringW szText; - INT Index; - HICON hIcon; + if (ApplicationViewMode != ApplicationViewAvailableApps) + { + return FALSE; + } - hIcon = (HICON) LoadImageW(hInst, - MAKEINTRESOURCE(IconIndex), - IMAGE_ICON, - TREEVIEW_ICON_SIZE, - TREEVIEW_ICON_SIZE, - LR_CREATEDIBSECTION); - if (hIcon) + /* Load icon from file */ + HICON hIcon = NULL; + ATL::CStringW szIconPath; + if (AvlbAppInfo->RetrieveIcon(szIconPath)) { - Index = ImageList_AddIcon(hImageTreeView, hIcon); - DestroyIcon(hIcon); + hIcon = (HICON)LoadImageW(NULL, + szIconPath.GetString(), + IMAGE_ICON, + LISTVIEW_ICON_SIZE, + LISTVIEW_ICON_SIZE, + LR_LOADFROMFILE); } - szText.LoadStringW(TextIndex); - return AddItem(hRootItem, szText, Index, Index, TextIndex); - } + if (!hIcon || GetLastError() != ERROR_SUCCESS) + { + /* Load default icon */ + hIcon = (HICON)LoadIconW(hInst, MAKEINTRESOURCEW(IDI_MAIN)); + } - HIMAGELIST SetImageList() - { - return CUiWindow<CTreeView>::SetImageList(hImageTreeView, TVSIL_NORMAL); - } + HIMAGELIST hImageList = GetImageList(LVSIL_SMALL); - VOID DestroyImageList() - { - if (hImageTreeView) - ImageList_Destroy(hImageTreeView); - } + int IconIndex = ImageList_AddIcon(hImageList, hIcon); + DestroyIcon(hIcon); - ~CSideTreeView() - { - DestroyImageList(); - } -}; + int Index = AddItem(ItemCount, IconIndex, AvlbAppInfo->m_szName, (LPARAM)CallbackParam); -class CSearchBar : - public CWindow -{ -public: - const INT m_Width; - const INT m_Height; + if (InitCheckState) + { + SetCheckState(Index, TRUE); + } - CSearchBar() : m_Width(200), m_Height(22) - { - } + SetItemText(Index, 1, AvlbAppInfo->m_szVersion); + SetItemText(Index, 2, AvlbAppInfo->m_szDesc); - VOID SetText(LPCWSTR lpszText) - { - SendMessageW(SB_SETTEXT, SBT_NOBORDERS, (LPARAM) lpszText); + ItemCount++; + return TRUE; } - HWND Create(HWND hwndParent) + // this function is called when parent window receiving an notification about checkstate changing + VOID ItemCheckStateNotify(int iItem, BOOL bCheck) { - ATL::CStringW szBuf; - m_hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"Edit", NULL, - WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOHSCROLL, - 0, 0, m_Width, m_Height, - hwndParent, (HMENU) NULL, - hInst, 0); - - SendMessageW(WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0); - szBuf.LoadStringW(IDS_SEARCH_TEXT); - SetWindowTextW(szBuf); - return m_hWnd; + if (bCheck) + { + CheckedItemCount++; + } + else + { + CheckedItemCount--; + } } - }; -class CMainWindow : - public CWindowImpl<CMainWindow, CWindow, CFrameWinTraits> +class CApplicationView : + public CUiWindow<CWindowImpl<CApplicationView>> { - CUiPanel* m_ClientPanel; - CUiSplitPanel* m_VSplitter; - CUiSplitPanel* m_HSplitter; +private: + CUiPanel *m_Panel = NULL; - CMainToolbar* m_Toolbar; - CAppsListView* m_ListView; + CAppsListView *m_ListView = NULL; + CAppInfoDisplay *m_AppsInfo = NULL; + CUiSplitPanel *m_HSplitter = NULL; + CMainWindow *m_MainWindow = NULL; + APPLICATION_VIEW_MODE ApplicationViewMode = ApplicationViewEmpty; - CSideTreeView* m_TreeView; - CUiWindow<CStatusBar>* m_StatusBar; - CAppInfoDisplay* m_AppInfo; + BOOL ProcessWindowMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT& theResult, DWORD dwMapId) + { + theResult = 0; + switch (message) + { + case WM_CREATE: + { + BOOL bSuccess = TRUE; + m_Panel = new CUiPanel(); + m_Panel->m_VerticalAlignment = UiAlign_Stretch; + m_Panel->m_HorizontalAlignment = UiAlign_Stretch; - CUiWindow<CSearchBar>* m_SearchBar; - CAvailableApps m_AvailableApps; + bSuccess &= CreateHSplitter(); + bSuccess &= CreateListView(); + bSuccess &= CreateAppInfoDisplay(); - INT nSelectedApps; + if (!bSuccess) + { + return -1; // creation failure + } + } + break; + case WM_NOTIFY: + { + LPNMHDR pNotifyHeader = (LPNMHDR)lParam; + if (pNotifyHeader->hwndFrom == m_ListView->GetWindow()) + { + switch (pNotifyHeader->code) + { + case LVN_ITEMCHANGED: + { + LPNMLISTVIEW pnic = (LPNMLISTVIEW)lParam; - BOOL bSearchEnabled; - BOOL bUpdating; + /* Check if this is a valid item + * (technically, it can be also an unselect) */ + INT ItemIndex = pnic->iItem; + if (ItemIndex == -1 || + ItemIndex >= ListView_GetItemCount(pnic->hdr.hwndFrom)) + { + break; + } - ATL::CStringW szSearchPattern; - INT SelectedEnumType; + /* Check if the focus has been moved to another item */ + if ((pnic->uChanged & LVIF_STATE) && + (pnic->uNewState & LVIS_FOCUSED) && + !(pnic->uOldState & LVIS_FOCUSED)) + { + ItemGetFocus((LPVOID)pnic->lParam); + } -public: - CMainWindow() : - m_ClientPanel(NULL), - bSearchEnabled(FALSE), - SelectedEnumType(ENUM_ALL_INSTALLED) - { - } + /* Check if the item is checked/unchecked */ + if (pnic->uChanged & LVIF_STATE) + { + int iOldState = STATEIMAGETOINDEX(pnic->uOldState); + int iNewState = STATEIMAGETOINDEX(pnic->uNewState); + + if (iOldState == STATEIMAGE_UNCHECKED && iNewState == STATEIMAGE_CHECKED) + { + // this item is just checked + m_ListView->ItemCheckStateNotify(pnic->iItem, TRUE); + ItemCheckStateChanged(TRUE, (LPVOID)pnic->lParam); + } + else if (iOldState == STATEIMAGE_CHECKED && iNewState == STATEIMAGE_UNCHECKED) + { + // this item is just unchecked + m_ListView->ItemCheckStateNotify(pnic->iItem, FALSE); + ItemCheckStateChanged(FALSE, (LPVOID)pnic->lParam); + } + } + } + break; -private: - VOID InitApplicationsList() - { - ATL::CStringW szText; + case LVN_COLUMNCLICK: + { + LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam; + + m_ListView->ColumnClick(pnmv); + } + break; - /* Add columns to ListView */ - szText.LoadStringW(IDS_APP_NAME); - m_ListView->AddColumn(0, szText, 250, LVCFMT_LEFT); + case NM_DBLCLK: + { + if (((LPNMLISTVIEW)lParam)->iItem != -1) + { + /* this won't do anything if the program is already installed */ + + // TODO: the same problem I've mentioned in NM_RCLICK + // I think if user double-click this app, then this app should be installed, not those checked apps. + if (ApplicationViewMode == ApplicationViewAvailableApps) + { + SendMessageW(GetParent(), WM_COMMAND, ID_INSTALL, 0); + } + } + } + break; - szText.LoadStringW(IDS_APP_INST_VERSION); - m_ListView->AddColumn(1, szText, 90, LVCFMT_RIGHT); + case NM_RCLICK: + { + if (((LPNMLISTVIEW)lParam)->iItem != -1) + { + // TODO: currently the menu will send WM_COMMAND directly to MainWindow. + // possibly it should be handled by this application-view first + // and then forward to mainwindow. + + // TODO: I think if user right-click on one item, and select "Install" + // that means the user want install "this" application + // but if some apps are checked, this will lead to those checked apps to be installed. + // this should be improved. + ShowPopupMenu(m_ListView->m_hWnd, 0, ID_INSTALL); + } + } + break; + } + } + } + break; - szText.LoadStringW(IDS_APP_DESCRIPTION); - m_ListView->AddColumn(3, szText, 300, LVCFMT_LEFT); + case WM_SYSCOLORCHANGE: + { + /* Forward WM_SYSCOLORCHANGE to common controls */ + m_ListView->SendMessageW(WM_SYSCOLORCHANGE, wParam, lParam); + m_ListView->SendMessageW(EM_SETBKGNDCOLOR, 0, GetSysColor(COLOR_BTNFACE)); + } + break; - // Unnesesary since the list updates on every TreeView selection - // UpdateApplicationsList(ENUM_ALL_COMPONENTS); + case WM_SIZE: + { + OnSize(hwnd, wParam, lParam); + break; + } + } + return FALSE; } - VOID InitCategoriesList() + BOOL CreateHSplitter() { - HTREEITEM hRootItemInstalled, hRootItemAvailable; - - hRootItemInstalled = m_TreeView->AddCategory(TVI_ROOT, IDS_INSTALLED, IDI_CATEGORY); - m_TreeView->AddCategory(hRootItemInstalled, IDS_APPLICATIONS, IDI_APPS); - m_TreeView->AddCategory(hRootItemInstalled, IDS_UPDATES, IDI_APPUPD); - + m_HSplitter = new CUiSplitPanel(); + m_HSplitter->m_VerticalAlignment = UiAlign_Stretch; + m_HSplitter->m_HorizontalAlignment = UiAlign_Stretch; + m_HSplitter->m_DynamicFirst = TRUE; + m_HSplitter->m_Horizontal = TRUE; + m_HSplitter->m_Pos = INT_MAX; //set INT_MAX to use lowest possible position (m_MinSecond) + m_HSplitter->m_MinFirst = 10; + m_HSplitter->m_MinSecond = 140; + m_Panel->Children().Append(m_HSplitter); + + return m_HSplitter->Create(m_hWnd) != NULL; + } + + BOOL CreateListView() + { + m_ListView = new CAppsListView(); + m_ListView->m_VerticalAlignment = UiAlign_Stretch; + m_ListView->m_HorizontalAlignment = UiAlign_Stretch; + m_HSplitter->First().Append(m_ListView); + + return m_ListView->Create(m_hWnd) != NULL; + } + + BOOL CreateAppInfoDisplay() + { + m_AppsInfo = new CAppInfoDisplay(); + m_AppsInfo->m_VerticalAlignment = UiAlign_Stretch; + m_AppsInfo->m_HorizontalAlignment = UiAlign_Stretch; + m_HSplitter->Second().Append(m_AppsInfo); + + return m_AppsInfo->Create(m_hWnd) != NULL; + } + + VOID OnSize(HWND hwnd, WPARAM wParam, LPARAM lParam) + { + if (wParam == SIZE_MINIMIZED) + return; + + RECT r = { 0, 0, LOWORD(lParam), HIWORD(lParam) }; + HDWP hdwp = NULL; + INT count = m_Panel->CountSizableChildren(); + + hdwp = BeginDeferWindowPos(count); + if (hdwp) + { + hdwp = m_Panel->OnParentSize(r, hdwp); + if (hdwp) + { + EndDeferWindowPos(hdwp); + } + } + } + +public: + + CApplicationView(CMainWindow *MainWindow) + : m_MainWindow(MainWindow) + { + } + + ~CApplicationView() + { + delete m_ListView; + delete m_AppsInfo; + delete m_HSplitter; + } + + static ATL::CWndClassInfo& GetWndClassInfo() + { + DWORD csStyle = CS_VREDRAW | CS_HREDRAW; + static ATL::CWndClassInfo wc = + { + { + sizeof(WNDCLASSEX), + csStyle, + StartWindowProc, + 0, + 0, + NULL, + NULL, + NULL, + (HBRUSH)(COLOR_BTNFACE + 1), + NULL, + L"RAppsApplicationView", + NULL + }, + NULL, NULL, IDC_ARROW, TRUE, 0, _T("") + }; + return wc; + } + + HWND Create(HWND hwndParent) + { + RECT r = { 0,0,0,0 }; + + return CWindowImpl::Create(hwndParent, r, L"", WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); + } + + BOOL SetDisplayMode(APPLICATION_VIEW_MODE Mode) + { + if (!m_ListView->SetDisplayMode(Mode)) + { + return FALSE; + } + ApplicationViewMode = Mode; + m_AppsInfo->SetWelcomeText(); + + HMENU lvwMenu = ::GetMenu(m_ListView->m_hWnd); + switch (Mode) + { + case ApplicationViewEmpty: + default: + EnableMenuItem(lvwMenu, ID_REGREMOVE, MF_GRAYED); + EnableMenuItem(lvwMenu, ID_INSTALL, MF_GRAYED); + EnableMenuItem(lvwMenu, ID_UNINSTALL, MF_GRAYED); + EnableMenuItem(lvwMenu, ID_MODIFY, MF_GRAYED); + break; + + case ApplicationViewInstalledApps: + EnableMenuItem(lvwMenu, ID_REGREMOVE, MF_ENABLED); + EnableMenuItem(lvwMenu, ID_INSTALL, MF_GRAYED); + EnableMenuItem(lvwMenu, ID_UNINSTALL, MF_ENABLED); + EnableMenuItem(lvwMenu, ID_MODIFY, MF_ENABLED); + break; + + case ApplicationViewAvailableApps: + EnableMenuItem(lvwMenu, ID_REGREMOVE, MF_GRAYED); + EnableMenuItem(lvwMenu, ID_INSTALL, MF_ENABLED); + EnableMenuItem(lvwMenu, ID_UNINSTALL, MF_GRAYED); + EnableMenuItem(lvwMenu, ID_MODIFY, MF_GRAYED); + break; + } + return TRUE; + } + + BOOL AddInstalledApplication(CInstalledApplicationInfo * InstAppInfo, LPVOID param) + { + if (ApplicationViewMode != ApplicationViewInstalledApps) + { + return FALSE; + } + return m_ListView->AddInstalledApplication(InstAppInfo, param); + } + + BOOL AddAvailableApplication(CAvailableApplicationInfo * AvlbAppInfo, BOOL InitCheckState, LPVOID param) + { + if (ApplicationViewMode != ApplicationViewAvailableApps) + { + return FALSE; + } + return m_ListView->AddAvailableApplication(AvlbAppInfo, InitCheckState, param); + } + + void CheckAll() + { + m_ListView->CheckAll(); + return; + } + + PVOID GetFocusedItemData() + { + return m_ListView->GetFocusedItemData(); + } + + int GetItemCount() + { + return m_ListView->GetItemCount(); + } + + // this function is called when a item of listview get focus. + // CallbackParam is the param passed to listview when adding the item (the one getting focus now). + BOOL ItemGetFocus(LPVOID CallbackParam) + { + switch (ApplicationViewMode) + { + case ApplicationViewInstalledApps: + return m_AppsInfo->ShowInstalledAppInfo((CInstalledApplicationInfo *)CallbackParam); + + case ApplicationViewAvailableApps: + return m_AppsInfo->ShowAvailableAppInfo((CAvailableApplicationInfo *)CallbackParam); + + case ApplicationViewEmpty: + default: + m_AppsInfo->SetWelcomeText(); + return FALSE; + } + } + + // this function is called when a item of listview is checked/unchecked + // CallbackParam is the param passed to listview when adding the item (the one getting focus now). + BOOL ItemCheckStateChanged(BOOL bChecked, LPVOID CallbackParam); + +}; + +class CSideTreeView : + public CUiWindow<CTreeView> +{ + HIMAGELIST hImageTreeView; + +public: + CSideTreeView() : + CUiWindow(), + hImageTreeView(ImageList_Create(TREEVIEW_ICON_SIZE, TREEVIEW_ICON_SIZE, + GetSystemColorDepth() | ILC_MASK, + 0, 1)) + { + } + + HTREEITEM AddItem(HTREEITEM hParent, ATL::CStringW &Text, INT Image, INT SelectedImage, LPARAM lParam) + { + return CUiWindow<CTreeView>::AddItem(hParent, const_cast<LPWSTR>(Text.GetString()), Image, SelectedImage, lParam); + } + + HTREEITEM AddCategory(HTREEITEM hRootItem, UINT TextIndex, UINT IconIndex) + { + ATL::CStringW szText; + INT Index; + HICON hIcon; + + hIcon = (HICON) LoadImageW(hInst, + MAKEINTRESOURCE(IconIndex), + IMAGE_ICON, + TREEVIEW_ICON_SIZE, + TREEVIEW_ICON_SIZE, + LR_CREATEDIBSECTION); + if (hIcon) + { + Index = ImageList_AddIcon(hImageTreeView, hIcon); + DestroyIcon(hIcon); + } + + szText.LoadStringW(TextIndex); + return AddItem(hRootItem, szText, Index, Index, TextIndex); + } + + HIMAGELIST SetImageList() + { + return CUiWindow<CTreeView>::SetImageList(hImageTreeView, TVSIL_NORMAL); + } + + VOID DestroyImageList() + { + if (hImageTreeView) + ImageList_Destroy(hImageTreeView); + } + + ~CSideTreeView() + { + DestroyImageList(); + } +}; + +class CSearchBar : + public CWindow +{ +public: + const INT m_Width; + const INT m_Height; + + CSearchBar() : m_Width(200), m_Height(22) + { + } + + VOID SetText(LPCWSTR lpszText) + { + SendMessageW(SB_SETTEXT, SBT_NOBORDERS, (LPARAM) lpszText); + } + + HWND Create(HWND hwndParent) + { + ATL::CStringW szBuf; + m_hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"Edit", NULL, + WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOHSCROLL, + 0, 0, m_Width, m_Height, + hwndParent, (HMENU) NULL, + hInst, 0); + + SendMessageW(WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0); + szBuf.LoadStringW(IDS_SEARCH_TEXT); + SetWindowTextW(szBuf); + return m_hWnd; + } + +}; + +class CMainWindow : + public CWindowImpl<CMainWindow, CWindow, CFrameWinTraits> +{ + CUiPanel* m_ClientPanel = NULL; + CUiSplitPanel* m_VSplitter = NULL; + + CMainToolbar* m_Toolbar = NULL; + + CSideTreeView* m_TreeView = NULL; + CUiWindow<CStatusBar>* m_StatusBar = NULL; + + CApplicationView* m_ApplicationView = NULL; + + CUiWindow<CSearchBar>* m_SearchBar = NULL; + CAvailableApps m_AvailableApps; + CInstalledApps m_InstalledApps; + + BOOL bSearchEnabled; + BOOL bUpdating = FALSE; + + ATL::CStringW szSearchPattern; + INT SelectedEnumType; + +public: + CMainWindow() : + m_ClientPanel(NULL), + bSearchEnabled(FALSE), + SelectedEnumType(ENUM_ALL_INSTALLED) + { + } + + ~CMainWindow() + { + LayoutCleanup(); + } +private: + + VOID InitCategoriesList() + { + HTREEITEM hRootItemInstalled, hRootItemAvailable; + + hRootItemInstalled = m_TreeView->AddCategory(TVI_ROOT, IDS_INSTALLED, IDI_CATEGORY); + m_TreeView->AddCategory(hRootItemInstalled, IDS_APPLICATIONS, IDI_APPS); + m_TreeView->AddCategory(hRootItemInstalled, IDS_UPDATES, IDI_APPUPD); + m_TreeView->AddCategory(TVI_ROOT, IDS_SELECTEDFORINST, IDI_SELECTEDFORINST); hRootItemAvailable = m_TreeView->AddCategory(TVI_ROOT, IDS_AVAILABLEFORINST, IDI_CATEGORY); @@ -1601,24 +2082,14 @@ private: return m_TreeView->Create(m_hWnd) != NULL; } - BOOL CreateListView() + BOOL CreateApplicationView() { - m_ListView = new CAppsListView(); - m_ListView->m_VerticalAlignment = UiAlign_Stretch; - m_ListView->m_HorizontalAlignment = UiAlign_Stretch; - m_HSplitter->First().Append(m_ListView); + m_ApplicationView = new CApplicationView(this); // pass this to ApplicationView for callback purpose + m_ApplicationView->m_VerticalAlignment = UiAlign_Stretch; + m_ApplicationView->m_HorizontalAlignment = UiAlign_Stretch; + m_VSplitter->Second().Append(m_ApplicationView); - return m_ListView->Create(m_hWnd) != NULL; - } - - BOOL CreateRichEdit() - { - m_AppInfo = new CAppInfoDisplay(); - m_AppInfo->m_VerticalAlignment = UiAlign_Stretch; - m_AppInfo->m_HorizontalAlignment = UiAlign_Stretch; - m_HSplitter->Second().Append(m_AppInfo); - - return m_AppInfo->Create(m_hWnd) != NULL; + return m_ApplicationView->Create(m_hWnd) != NULL; } BOOL CreateVSplitter() @@ -1636,21 +2107,6 @@ private: return m_VSplitter->Create(m_hWnd) != NULL; } - BOOL CreateHSplitter() - { - m_HSplitter = new CUiSplitPanel(); - m_HSplitter->m_VerticalAlignment = UiAlign_Stretch; - m_HSplitter->m_HorizontalAlignment = UiAlign_Stretch; - m_HSplitter->m_DynamicFirst = TRUE; - m_HSplitter->m_Horizontal = TRUE; - m_HSplitter->m_Pos = INT_MAX; //set INT_MAX to use lowest possible position (m_MinSecond) - m_HSplitter->m_MinFirst = 10; - m_HSplitter->m_MinSecond = 140; - m_VSplitter->Second().Append(m_HSplitter); - - return m_HSplitter->Create(m_hWnd) != NULL; - } - BOOL CreateSearchBar() { m_SearchBar = new CUiWindow<CSearchBar>(); @@ -1678,12 +2134,8 @@ private: b = b && CreateVSplitter(); // Inside V Splitter - b = b && CreateHSplitter(); b = b && CreateTreeView(); - - // Inside H Splitter - b = b && CreateListView(); - b = b && CreateRichEdit(); + b = b && CreateApplicationView(); if (b) { @@ -1707,15 +2159,23 @@ private: return b; } + VOID LayoutCleanup() + { + delete m_TreeView; + delete m_ApplicationView; + delete m_VSplitter; + delete m_SearchBar; + delete m_Toolbar; + delete m_StatusBar; + return; + } + BOOL InitControls() { if (CreateLayout()) { - - InitApplicationsList(); InitCategoriesList(); - nSelectedApps = 0; UpdateStatusBarText(); return TRUE; @@ -1724,28 +2184,6 @@ private: return FALSE; } - VOID ShowAppInfo(INT Index) - { - if (IsInstalledEnum(SelectedEnumType)) - { - if (Index == -1) - Index = m_ListView->GetSelectionMark(); - - PINSTALLED_INFO Info = (PINSTALLED_INFO) m_ListView->GetItemData(Index); - - m_AppInfo->ShowInstalledAppInfo(Info); - } - else if (IsAvailableEnum(SelectedEnumType)) - { - if (Index == -1) - return; - - CAvailableApplicationInfo* Info = (CAvailableApplicationInfo*) m_ListView->GetItemData(Index); - - m_AppInfo->ShowAvailableAppInfo(Info); - } - } - VOID OnSize(HWND hwnd, WPARAM wParam, LPARAM lParam) { if (wParam == SIZE_MINIMIZED) @@ -1782,7 +2220,6 @@ private: { EndDeferWindowPos(hdwp); } - } // TODO: Sub-layouts for children of children @@ -1796,64 +2233,47 @@ private: EndDeferWindowPos(hdwp); } } - } - VOID RemoveSelectedAppFromRegistry() + BOOL RemoveSelectedAppFromRegistry() { - PINSTALLED_INFO Info; - WCHAR szFullName[MAX_PATH] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"; - ATL::CStringW szMsgText, szMsgTitle; - INT ItemIndex = m_ListView->GetNextItem(-1, LVNI_FOCUSED); - if (!IsInstalledEnum(SelectedEnumType)) - return; + return FALSE; - Info = reinterpret_cast<PINSTALLED_INFO>(m_ListView->GetItemData(ItemIndex)); - if (!Info || !Info->hSubKey || (ItemIndex == -1)) - return; + ATL::CStringW szMsgText, szMsgTitle; if (!szMsgText.LoadStringW(IDS_APP_REG_REMOVE) || !szMsgTitle.LoadStringW(IDS_INFORMATION)) - return; + return FALSE; if (MessageBoxW(szMsgText, szMsgTitle, MB_YESNO | MB_ICONQUESTION) == IDYES) { - ATL::CStringW::CopyChars(szFullName, - MAX_PATH, - Info->szKeyName.GetString(), - MAX_PATH - wcslen(szFullName)); - - if (RegDeleteKeyW(Info->hRootKey, szFullName) == ERROR_SUCCESS) + CInstalledApplicationInfo *InstalledApp = (CInstalledApplicationInfo *)m_ApplicationView->GetFocusedItemData(); + LSTATUS Result = InstalledApp->RemoveFromRegistry(); + if (Result != ERROR_SUCCESS) { - m_ListView->DeleteItem(ItemIndex); - return; + // TODO: popup a messagebox telling user it fails somehow + return FALSE; } - if (!szMsgText.LoadStringW(IDS_UNABLE_TO_REMOVE)) - return; - - MessageBoxW(szMsgText.GetString(), NULL, MB_OK | MB_ICONERROR); + // as it's already removed form registry, this will also remove it from the list + UpdateApplicationsList(-1); + return TRUE; } + + return FALSE; } BOOL UninstallSelectedApp(BOOL bModify) { - WCHAR szAppName[MAX_STR_LEN]; - if (!IsInstalledEnum(SelectedEnumType)) return FALSE; - INT ItemIndex = m_ListView->GetNextItem(-1, LVNI_FOCUSED); - if (ItemIndex == -1) - return FALSE; - - m_ListView->GetItemText(ItemIndex, 0, szAppName, _countof(szAppName)); - WriteLogMessage(EVENTLOG_SUCCESS, MSG_SUCCESS_REMOVE, szAppName); + CInstalledApplicationInfo *InstalledApp = (CInstalledApplicationInfo *)m_ApplicationView->GetFocusedItemData(); - PINSTALLED_INFO ItemInfo = (PINSTALLED_INFO)m_ListView->GetItemData(ItemIndex); - return UninstallApplication(ItemInfo, bModify); + return InstalledApp->UninstallApplication(bModify); } + BOOL ProcessWindowMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT& theResult, DWORD dwMapId) { theResult = 0; @@ -1871,9 +2291,7 @@ private: FreeLogs(); m_AvailableApps.FreeCachedEntries(); - - if (IsInstalledEnum(SelectedEnumType)) - FreeInstalledAppList(); + m_InstalledApps.FreeCachedEntries(); delete m_ClientPanel; @@ -1984,7 +2402,6 @@ private: } HMENU mainMenu = ::GetMenu(hwnd); - HMENU lvwMenu = ::GetMenu(m_ListView->m_hWnd); /* Disable/enable items based on treeview selection */ if (IsSelectedNodeInstalled()) @@ -1994,11 +2411,6 @@ private: EnableMenuItem(mainMenu, ID_UNINSTALL, MF_ENABLED); EnableMenuItem(mainMenu, ID_MODIFY, MF_ENABLED); - EnableMenuItem(lvwMenu, ID_REGREMOVE, MF_ENABLED); - EnableMenuItem(lvwMenu, ID_INSTALL, MF_GRAYED); - EnableMenuItem(lvwMenu, ID_UNINSTALL, MF_ENABLED); - EnableMenuItem(lvwMenu, ID_MODIFY, MF_ENABLED); - m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_REGREMOVE, TRUE); m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_INSTALL, FALSE); m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_UNINSTALL, TRUE); @@ -2011,11 +2423,6 @@ private: EnableMenuItem(mainMenu, ID_UNINSTALL, MF_GRAYED); EnableMenuItem(mainMenu, ID_MODIFY, MF_GRAYED); - EnableMenuItem(lvwMenu, ID_REGREMOVE, MF_GRAYED); - EnableMenuItem(lvwMenu, ID_INSTALL, MF_ENABLED); - EnableMenuItem(lvwMenu, ID_UNINSTALL, MF_GRAYED); - EnableMenuItem(lvwMenu, ID_MODIFY, MF_GRAYED); - m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_REGREMOVE, FALSE); m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_INSTALL, TRUE); m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_UNINSTALL, FALSE); @@ -2024,91 +2431,6 @@ private: } break; - case LVN_ITEMCHANGED: - { - LPNMLISTVIEW pnic = (LPNMLISTVIEW) lParam; - - if (pnic->hdr.hwndFrom == m_ListView->m_hWnd) - { - /* Check if this is a valid item - * (technically, it can be also an unselect) */ - INT ItemIndex = pnic->iItem; - if (ItemIndex == -1 || - ItemIndex >= ListView_GetItemCount(pnic->hdr.hwndFrom)) - { - break; - } - - /* Check if the focus has been moved to another item */ - if ((pnic->uChanged & LVIF_STATE) && - (pnic->uNewState & LVIS_FOCUSED) && - !(pnic->uOldState & LVIS_FOCUSED)) - { - ShowAppInfo(ItemIndex); - } - /* Check if the item is checked */ - if ((pnic->uNewState & LVIS_STATEIMAGEMASK) && !bUpdating) - { - BOOL checked = m_ListView->GetCheckState(pnic->iItem); - /* FIXME: HAX! - - preventing decremention below zero as a safeguard for ReactOS - In ReactOS this action is triggered whenever user changes *selection*, but should be only when *checkbox* state toggled - Maybe LVIS_STATEIMAGEMASK is set incorrectly - */ - nSelectedApps += - (checked) - ? 1 - : ((nSelectedApps > 0) - ? -1 - : 0); - - /* Update item's selection status */ - m_ListView->SetSelected(pnic->iItem, checked); - - UpdateStatusBarText(); - } - } - } - break; - - case LVN_COLUMNCLICK: - { - LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam; - - m_ListView->ColumnClick(pnmv); - } - break; - - case NM_CLICK: - { - if (data->hwndFrom == m_ListView->m_hWnd && ((LPNMLISTVIEW) lParam)->iItem != -1) - { - ShowAppInfo(-1); - } - } - break; - - case NM_DBLCLK: - { - if (data->hwndFrom == m_ListView->m_hWnd && ((LPNMLISTVIEW) lParam)->iItem != -1) - { - /* this won't do anything if the program is already installed */ - SendMessageW(hwnd, WM_COMMAND, ID_INSTALL, 0); - } - } - break; - - case NM_RCLICK: - { - if (data->hwndFrom == m_ListView->m_hWnd && ((LPNMLISTVIEW) lParam)->iItem != -1) - { - ShowPopupMenu(m_ListView->m_hWnd, 0, ID_INSTALL); - } - } - break; - - - case TTN_GETDISPINFO: m_Toolbar->OnGetDispInfo((LPTOOLTIPTEXT) lParam); break; @@ -2136,10 +2458,9 @@ private: case WM_SYSCOLORCHANGE: { /* Forward WM_SYSCOLORCHANGE to common controls */ - m_ListView->SendMessageW(WM_SYSCOLORCHANGE, 0, 0); - m_TreeView->SendMessageW(WM_SYSCOLORCHANGE, 0, 0); + m_ApplicationView->SendMessageW(WM_SYSCOLORCHANGE, wParam, lParam); + m_TreeView->SendMessageW(WM_SYSCOLORCHANGE, wParam, lParam); m_Toolbar->SendMessageW(WM_SYSCOLORCHANGE, 0, 0); - m_ListView->SendMessageW(EM_SETBKGNDCOLOR, 0, GetSysColor(COLOR_BTNFACE)); } break; @@ -2272,17 +2593,36 @@ private: case ID_INSTALL: if (IsAvailableEnum(SelectedEnumType)) { - if (nSelectedApps > 0) + ATL::CSimpleArray<CAvailableApplicationInfo> AppsList; + + // enum all selected apps + m_AvailableApps.Enum(ENUM_CAT_SELECTED, s_EnumSelectedAppForDownloadProc, (PVOID)&AppsList); + + if (AppsList.GetSize()) { - DownloadListOfApplications(m_AvailableApps.GetSelected(), FALSE); - UpdateApplicationsList(-1); - m_ListView->SetSelected(-1, FALSE); + if (DownloadListOfApplications(AppsList, FALSE)) + { + m_AvailableApps.RemoveAllSelected(); + UpdateApplicationsList(-1); + } } - else if (DownloadApplication(m_ListView->GetSelectedData(), FALSE)) + else { - UpdateApplicationsList(-1); + // use the currently focused item in application-view + CAvailableApplicationInfo *FocusedApps = (CAvailableApplicationInfo *)m_ApplicationView->GetFocusedItemData(); + if (FocusedApps) + { + if (DownloadApplication(FocusedApps, FALSE)) + { + UpdateApplicationsList(-1); + } + } + else + { + // TODO: in this case, Install button in toolbar (and all other places) should be disabled + // or at least popup a messagebox telling user to select/check some app first + } } - } break; @@ -2318,28 +2658,11 @@ private: break; case ID_CHECK_ALL: - m_ListView->CheckAll(); + m_ApplicationView->CheckAll(); break; } } - VOID FreeInstalledAppList() - { - INT Count = m_ListView->GetItemCount() - 1; - PINSTALLED_INFO Info; - - while (Count >= 0) - { - Info = (PINSTALLED_INFO) m_ListView->GetItemData(Count); - if (Info) - { - RegCloseKey(Info->hSubKey); - delete Info; - } - Count--; - } - } - static BOOL SearchPatternMatch(LPCWSTR szHaystack, LPCWSTR szNeedle) { if (!*szNeedle) @@ -2348,91 +2671,42 @@ private: return StrStrIW(szHaystack, szNeedle) != NULL; } - BOOL CALLBACK EnumInstalledAppProc(INT ItemIndex, ATL::CStringW &m_szName, PINSTALLED_INFO Info) + BOOL CALLBACK EnumInstalledAppProc(CInstalledApplicationInfo * Info) { - PINSTALLED_INFO ItemInfo; - ATL::CStringW szText; - INT Index; - - if (!SearchPatternMatch(m_szName.GetString(), szSearchPattern)) + if (!SearchPatternMatch(Info->szDisplayName.GetString(), szSearchPattern)) { - RegCloseKey(Info->hSubKey); return TRUE; } - - ItemInfo = new INSTALLED_INFO(*Info); - if (!ItemInfo) - { - RegCloseKey(Info->hSubKey); - return FALSE; - } - - Index = m_ListView->AddItem(ItemIndex, 0, m_szName.GetString(), (LPARAM) ItemInfo); - - /* Get version info */ - ItemInfo->GetApplicationString(L"DisplayVersion", szText); - m_ListView->SetItemText(Index, 1, szText.GetString()); - - /* Get comments */ - ItemInfo->GetApplicationString(L"Comments", szText); - m_ListView->SetItemText(Index, 2, szText.GetString()); - - return TRUE; + return m_ApplicationView->AddInstalledApplication(Info, Info); // currently, the callback param is Info itself } - BOOL EnumAvailableAppProc(CAvailableApplicationInfo* Info, LPCWSTR szFolderPath) + BOOL CALLBACK EnumAvailableAppProc(CAvailableApplicationInfo * Info, BOOL bInitialCheckState) { - INT Index; - HICON hIcon = NULL; - - HIMAGELIST hImageListView = (HIMAGELIST)m_ListView->SendMessage(LVM_GETIMAGELIST, LVSIL_SMALL, 0); - if (!SearchPatternMatch(Info->m_szName.GetString(), szSearchPattern) && !SearchPatternMatch(Info->m_szDesc.GetString(), szSearchPattern)) { return TRUE; } - - /* Load icon from file */ - ATL::CStringW szIconPath; - if (Info->RetrieveIcon(szIconPath)) - { - 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 = m_ListView->AddItem(Info->m_Category, Index, Info->m_szName.GetString(), (LPARAM) Info); - m_ListView->SetImageList(hImageListView, LVSIL_SMALL); - m_ListView->SetItemText(Index, 1, Info->m_szVersion.GetString()); - m_ListView->SetItemText(Index, 2, Info->m_szDesc.GetString()); - m_ListView->SetCheckState(Index, Info->m_IsSelected); - - return TRUE; + return m_ApplicationView->AddAvailableApplication(Info, bInitialCheckState, Info); // currently, the callback param is Info itself } - static BOOL CALLBACK s_EnumInstalledAppProc(INT ItemIndex, ATL::CStringW &m_szName, PINSTALLED_INFO Info, PVOID param) + static BOOL CALLBACK s_EnumInstalledAppProc(CInstalledApplicationInfo * Info, PVOID param) { CMainWindow* pThis = (CMainWindow*)param; - return pThis->EnumInstalledAppProc(ItemIndex, m_szName, Info); + return pThis->EnumInstalledAppProc(Info); } - static BOOL CALLBACK s_EnumAvailableAppProc(CAvailableApplicationInfo* Info, LPCWSTR szFolderPath, PVOID param) + static BOOL CALLBACK s_EnumAvailableAppProc(CAvailableApplicationInfo* Info, BOOL bInitialCheckState, PVOID param) { CMainWindow* pThis = (CMainWindow*)param; - return pThis->EnumAvailableAppProc(Info, szFolderPath); + return pThis->EnumAvailableAppProc(Info, bInitialCheckState); + } + + static BOOL CALLBACK s_EnumSelectedAppForDownloadProc(CAvailableApplicationInfo *Info, BOOL bInitialCheckState, PVOID param) + { + ATL::CSimpleArray<CAvailableApplicationInfo> *pAppList = (ATL::CSimpleArray<CAvailableApplicationInfo> *)param; + pAppList->Add(*Info); + return TRUE; } VOID UpdateStatusBarText() @@ -2441,83 +2715,46 @@ private: { ATL::CStringW szBuffer; - szBuffer.Format(IDS_APPS_COUNT, m_ListView->GetItemCount(), nSelectedApps); + szBuffer.Format(IDS_APPS_COUNT, m_ApplicationView->GetItemCount(), m_AvailableApps.GetSelectedCount()); m_StatusBar->SetText(szBuffer); } } VOID UpdateApplicationsList(INT EnumType) { - ATL::CStringW szBuffer1, szBuffer2; - HIMAGELIST hImageListView; - BOOL bWasInInstalled = IsInstalledEnum(SelectedEnumType); - bUpdating = TRUE; - m_ListView->SetRedraw(FALSE); - if (EnumType < 0) + if (EnumType == -1) { + // keep the old enum type EnumType = SelectedEnumType; } - - //if previous one was INSTALLED purge the list - //TODO: make the Installed category a separate class to avoid doing this - if (bWasInInstalled) - { - FreeInstalledAppList(); - } - - m_ListView->DeleteAllItems(); - - // Create new ImageList - hImageListView = ImageList_Create(LISTVIEW_ICON_SIZE, - LISTVIEW_ICON_SIZE, - GetSystemColorDepth() | ILC_MASK, - 0, 1); - HIMAGELIST hImageListBuf = m_ListView->SetImageList(hImageListView, LVSIL_SMALL); - if (hImageListBuf) + else { - ImageList_Destroy(hImageListBuf); + SelectedEnumType = EnumType; } + m_ApplicationView->SetRedraw(FALSE); if (IsInstalledEnum(EnumType)) { - if (!bWasInInstalled) - { - m_ListView->SetCheckboxesVisible(FALSE); - } + // set the display mode of application-view. this will remove all the item in application-view too. + m_ApplicationView->SetDisplayMode(ApplicationViewInstalledApps); - HICON hIcon = (HICON) LoadIconW(hInst, MAKEINTRESOURCEW(IDI_MAIN)); - ImageList_AddIcon(hImageListView, hIcon); - DestroyIcon(hIcon); - - // Enum installed applications and updates - EnumInstalledApplications(EnumType, TRUE, s_EnumInstalledAppProc, this); - EnumInstalledApplications(EnumType, FALSE, s_EnumInstalledAppProc, this); + // enum installed softwares + m_InstalledApps.Enum(EnumType, s_EnumInstalledAppProc, this); } else if (IsAvailableEnum(EnumType)) { - if (bWasInInstalled) - { - m_ListView->SetCheckboxesVisible(TRUE); - } + // set the display mode of application-view. this will remove all the item in application-view too. + m_ApplicationView->SetDisplayMode(ApplicationViewAvailableApps); - // Enum available applications + // enum available softwares m_AvailableApps.Enum(EnumType, s_EnumAvailableAppProc, this); } - - SelectedEnumType = EnumType; + m_ApplicationView->SetRedraw(TRUE); + m_ApplicationView->RedrawWindow(0, 0, RDW_INVALIDATE | RDW_ALLCHILDREN); // force the child window to repaint UpdateStatusBarText(); - m_AppInfo->SetWelcomeText(); - - // Set automatic column width for program names if the list is not empty - if (m_ListView->GetItemCount() > 0) - { - ListView_SetColumnWidth(m_ListView->GetWindow(), 0, LVSCW_AUTOSIZE); - } - bUpdating = FALSE; - m_ListView->SetRedraw(TRUE); } public: @@ -2562,9 +2799,39 @@ public: return CWindowImpl::Create(NULL, r, szWindowName.GetString(), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_WINDOWEDGE); } + // this function is called when a item of application-view is checked/unchecked + // CallbackParam is the param passed to application-view when adding the item (the one getting focus now). + BOOL ItemCheckStateChanged(BOOL bChecked, LPVOID CallbackParam) + { + if (!bUpdating) + { + if (bChecked) + { + if (!m_AvailableApps.AddSelected((CAvailableApplicationInfo *)CallbackParam)) + { + return FALSE; + } + } + else + { + if (!m_AvailableApps.RemoveSelected((CAvailableApplicationInfo *)CallbackParam)) + { + return FALSE; + } + } + + UpdateStatusBarText(); + return TRUE; + } + else + { + return TRUE; + } + } + void HandleTabOrder(int direction) { - HWND Controls[] = { m_Toolbar->m_hWnd, m_SearchBar->m_hWnd, m_TreeView->m_hWnd, m_ListView->m_hWnd, m_AppInfo->m_hWnd }; + HWND Controls[] = { m_Toolbar->m_hWnd, m_SearchBar->m_hWnd, m_TreeView->m_hWnd, m_ApplicationView->m_hWnd}; // When there is no control found, go to the first or last (depending on tab vs shift-tab) int current = direction > 0 ? 0 : (_countof(Controls) - 1); HWND hActive = ::GetFocus(); @@ -2586,6 +2853,12 @@ public: } }; +BOOL CApplicationView::ItemCheckStateChanged(BOOL bChecked, LPVOID CallbackParam) +{ + m_MainWindow->ItemCheckStateChanged(bChecked, CallbackParam); + return TRUE; +} + VOID ShowMainWindow(INT nShowCmd) { HACCEL KeyBrd; diff --git a/base/applications/rapps/include/available.h b/base/applications/rapps/include/available.h index 259b644dce1..2ee8136cc91 100644 --- a/base/applications/rapps/include/available.h +++ b/base/applications/rapps/include/available.h @@ -37,10 +37,11 @@ struct AvailableStrings AvailableStrings(); }; -struct CAvailableApplicationInfo +class CAvailableApplicationInfo { +public: INT m_Category; - BOOL m_IsSelected; + //BOOL m_IsSelected; LicenseType m_LicenseType; ATL::CStringW m_szName; ATL::CStringW m_szRegName; @@ -98,11 +99,12 @@ private: inline BOOL FindInLanguages(LCID what) const; }; -typedef BOOL(CALLBACK *AVAILENUMPROC)(CAvailableApplicationInfo *Info, LPCWSTR szFolderPath, PVOID param); +typedef BOOL(CALLBACK *AVAILENUMPROC)(CAvailableApplicationInfo *Info, BOOL bInitialCheckState, PVOID param); class CAvailableApps { ATL::CAtlList<CAvailableApplicationInfo*> m_InfoList; + ATL::CAtlList< CAvailableApplicationInfo*> m_SelectedList; public: static AvailableStrings m_Strings; @@ -116,9 +118,15 @@ public: VOID FreeCachedEntries(); BOOL Enum(INT EnumType, AVAILENUMPROC lpEnumProc, PVOID param); + BOOL AddSelected(CAvailableApplicationInfo *AvlbInfo); + BOOL RemoveSelected(CAvailableApplicationInfo *AvlbInfo); + + VOID RemoveAllSelected(); + int GetSelectedCount(); + CAvailableApplicationInfo* FindInfo(const ATL::CStringW& szAppName) const; ATL::CSimpleArray<CAvailableApplicationInfo> FindInfoList(const ATL::CSimpleArray<ATL::CStringW> &arrAppsNames) const; - ATL::CSimpleArray<CAvailableApplicationInfo> GetSelected() const; + //ATL::CSimpleArray<CAvailableApplicationInfo> GetSelected() const; const ATL::CStringW& GetFolderPath() const; const ATL::CStringW& GetAppPath() const; diff --git a/base/applications/rapps/include/installed.h b/base/applications/rapps/include/installed.h index 76a12418c1c..f13e37e1b48 100644 --- a/base/applications/rapps/include/installed.h +++ b/base/applications/rapps/include/installed.h @@ -3,19 +3,51 @@ #include <windef.h> #include <atlstr.h> -struct INSTALLED_INFO +class CInstalledApplicationInfo { - HKEY hRootKey; +public: + BOOL IsUserKey; + REGSAM WowKey; HKEY hSubKey; + BOOL bIsUpdate = FALSE; + ATL::CStringW szKeyName; + CInstalledApplicationInfo(BOOL bIsUserKey, REGSAM RegWowKey, HKEY hKey); BOOL GetApplicationString(LPCWSTR lpKeyName, ATL::CStringW& String); + BOOL UninstallApplication(BOOL bModify); + LSTATUS RemoveFromRegistry(); + + ATL::CStringW szDisplayName; + ATL::CStringW szDisplayVersion; + ATL::CStringW szPublisher; + ATL::CStringW szRegOwner; + ATL::CStringW szProductID; + ATL::CStringW szHelpLink; + ATL::CStringW szHelpTelephone; + ATL::CStringW szReadme; + ATL::CStringW szContact; + ATL::CStringW szURLUpdateInfo; + ATL::CStringW szURLInfoAbout; + ATL::CStringW szComments; + ATL::CStringW szInstallDate; + ATL::CStringW szInstallLocation; + ATL::CStringW szInstallSource; + ATL::CStringW szUninstallString; + ATL::CStringW szModifyPath; + + ~CInstalledApplicationInfo(); }; -typedef INSTALLED_INFO *PINSTALLED_INFO; -typedef BOOL(CALLBACK *APPENUMPROC)(INT ItemIndex, ATL::CStringW &Name, PINSTALLED_INFO Info, PVOID param); +typedef BOOL(CALLBACK *APPENUMPROC)(CInstalledApplicationInfo * Info, PVOID param); -BOOL EnumInstalledApplications(INT EnumType, BOOL IsUserKey, APPENUMPROC lpEnumProc, PVOID param); -BOOL GetApplicationString(HKEY hKey, LPCWSTR lpKeyName, LPWSTR szString); +class CInstalledApps +{ + ATL::CAtlList<CInstalledApplicationInfo *> m_InfoList; + +public: + BOOL Enum(INT EnumType, APPENUMPROC lpEnumProc, PVOID param); + + VOID FreeCachedEntries(); +}; -BOOL UninstallApplication(PINSTALLED_INFO ItemInfo, BOOL bModify); diff --git a/base/applications/rapps/include/misc.h b/base/applications/rapps/include/misc.h index 4c1fc6a4b1d..7e3b1567b65 100644 --- a/base/applications/rapps/include/misc.h +++ b/base/applications/rapps/include/misc.h @@ -46,3 +46,5 @@ public: }; BOOL PathAppendNoDirEscapeW(LPWSTR pszPath, LPCWSTR pszMore); + +BOOL IsSystem64Bit(); diff --git a/base/applications/rapps/include/rosui.h b/base/applications/rapps/include/rosui.h index 378e677c053..19ba8d26f0d 100644 --- a/base/applications/rapps/include/rosui.h +++ b/base/applications/rapps/include/rosui.h @@ -495,7 +495,10 @@ public: virtual ~CUiWindow() { - T::DestroyWindow(); + if (T::IsWindow()) + { + T::DestroyWindow(); + } } VOID GetWindowTextW(ATL::CStringW& szText) diff --git a/base/applications/rapps/installed.cpp b/base/applications/rapps/installed.cpp index c35f141f526..065422762ad 100644 --- a/base/applications/rapps/installed.cpp +++ b/base/applications/rapps/installed.cpp @@ -12,149 +12,253 @@ #include "misc.h" -BOOL INSTALLED_INFO::GetApplicationString(LPCWSTR lpKeyName, ATL::CStringW& String) +CInstalledApplicationInfo::CInstalledApplicationInfo(BOOL bIsUserKey, REGSAM RegWowKey, HKEY hKey) + : IsUserKey(bIsUserKey), WowKey(RegWowKey), hSubKey(hKey) { - BOOL result = ::GetApplicationString(hSubKey, lpKeyName, String.GetBuffer(MAX_PATH)); - String.ReleaseBuffer(); - return result; + // if Initialize failed, hSubKey will be closed automatically and set to zero + + DWORD dwSize = MAX_PATH, dwType, dwValue; + BOOL bIsSystemComponent; + ATL::CStringW szParentKeyName; + + dwType = REG_DWORD; + dwSize = sizeof(DWORD); + + if (RegQueryValueExW(hSubKey, + L"SystemComponent", + NULL, + &dwType, + (LPBYTE)&dwValue, + &dwSize) == ERROR_SUCCESS) + { + bIsSystemComponent = (dwValue == 0x1); + } + else + { + bIsSystemComponent = FALSE; + } + + dwType = REG_SZ; + dwSize = MAX_PATH * sizeof(WCHAR); + bIsUpdate = (RegQueryValueExW(hSubKey, + L"ParentKeyName", + NULL, + &dwType, + (LPBYTE)szParentKeyName.GetBuffer(MAX_PATH), + &dwSize) == ERROR_SUCCESS); + szParentKeyName.ReleaseBuffer(); + + if (bIsSystemComponent) + { + CloseHandle(hSubKey); + hSubKey = NULL; + } + } -BOOL GetApplicationString(HKEY hKey, LPCWSTR lpKeyName, LPWSTR szString) +CInstalledApplicationInfo::~CInstalledApplicationInfo() { - DWORD dwSize = MAX_PATH * sizeof(WCHAR); - - if (RegQueryValueExW(hKey, - lpKeyName, - NULL, - NULL, - (LPBYTE) szString, - &dwSize) == ERROR_SUCCESS) + if (hSubKey) { - return TRUE; + CloseHandle(hSubKey); + hSubKey = NULL; } - - StringCchCopyW(szString, MAX_PATH, L"---"); - return FALSE; } -BOOL UninstallApplication(PINSTALLED_INFO ItemInfo, BOOL bModify) +BOOL CInstalledApplicationInfo::GetApplicationString(LPCWSTR lpKeyName, ATL::CStringW& String) { - LPCWSTR szModify = L"ModifyPath"; - LPCWSTR szUninstall = L"UninstallString"; - DWORD dwType, dwSize; - WCHAR szPath[MAX_PATH]; + DWORD dwSize = 0; + String.Empty(); + DWORD dwType; - dwType = REG_SZ; - dwSize = MAX_PATH * sizeof(WCHAR); - if (RegQueryValueExW(ItemInfo->hSubKey, - bModify ? szModify : szUninstall, - NULL, - &dwType, - (LPBYTE) szPath, - &dwSize) != ERROR_SUCCESS) + // retrieve the size of value first. + if (RegQueryValueExW(hSubKey, + lpKeyName, + NULL, + &dwType, + NULL, + &dwSize) != ERROR_SUCCESS) { return FALSE; } - return StartProcess(szPath, TRUE); + // TODO: I assume the type as REG_SZ. but I think REG_EXPAND_SZ should be handled correctly too. + if (dwType != REG_SZ) + { + return FALSE; + } + + // allocate buffer. + // attention: dwSize is size in bytes, and RegQueryValueExW does not guarantee the terminating null character. + String.GetBuffer(dwSize + sizeof(WCHAR)); + + // query the value + if (RegQueryValueExW(hSubKey, + lpKeyName, + NULL, + NULL, + (LPBYTE)String.GetBuffer(), + &dwSize) != ERROR_SUCCESS) + { + String.ReleaseBuffer(); + String.Empty(); + return FALSE; + } + String.GetBuffer()[dwSize / sizeof(WCHAR)] = L'\0'; // ensure zero terminated + String.ReleaseBuffer(); + return TRUE; } -BOOL EnumInstalledApplications(INT EnumType, BOOL IsUserKey, APPENUMPROC lpEnumProc, PVOID param) +BOOL CInstalledApplicationInfo::UninstallApplication(BOOL bModify) { - DWORD dwSize = MAX_PATH, dwType, dwValue; - BOOL bIsSystemComponent, bIsUpdate; - ATL::CStringW szParentKeyName; - ATL::CStringW szDisplayName; - INSTALLED_INFO Info; - HKEY hKey; - LONG ItemIndex = 0; + return StartProcess(bModify ? szModifyPath : szUninstallString, TRUE); +} + +LSTATUS CInstalledApplicationInfo::RemoveFromRegistry() +{ + ATL::CStringW szFullName = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + szKeyName; - Info.hRootKey = IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; + // TODO: if there are subkeys inside, simply RegDeleteKeyExW will fail + // we don't have RegDeleteTree for ReactOS now. (It's a WinVista API) + // write a function to delete all subkeys recursively to solve this + // or consider letting ReactOS having this API - if (RegOpenKeyW(Info.hRootKey, - L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall", - &hKey) != ERROR_SUCCESS) + return RegDeleteKeyExW(IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, szFullName, WowKey, 0); +} + +BOOL CInstalledApps::Enum(INT EnumType, APPENUMPROC lpEnumProc, PVOID param) +{ + FreeCachedEntries(); + + HKEY RootKeyEnum[3] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_LOCAL_MACHINE }; + REGSAM RegSamEnum[3] = { KEY_WOW64_32KEY, KEY_WOW64_32KEY, KEY_WOW64_64KEY }; + + int LoopTime; + + // test if the OS is 64 bit. + if (IsSystem64Bit()) { - return FALSE; + // loop for all 3 combination. + // note that HKEY_CURRENT_USER\Software don't have a redirect + //
https://docs.microsoft.com/en-us/windows/win32/winprog64/shared-registry-ke…
+ LoopTime = 3; + } + else + { + // loop for 2 combination for KEY_WOW64_32KEY only + LoopTime = 2; } - while (RegEnumKeyExW(hKey, ItemIndex, Info.szKeyName.GetBuffer(MAX_PATH), &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + // loop for all combination + for (int i = 0; i < LoopTime; i++) { - Info.szKeyName.ReleaseBuffer(); - if (RegOpenKeyW(hKey, Info.szKeyName.GetString(), &Info.hSubKey) == ERROR_SUCCESS) + DWORD dwSize = MAX_PATH; + HKEY hKey, hSubKey; + LONG ItemIndex = 0; + ATL::CStringW szKeyName; + + if (RegOpenKeyExW(RootKeyEnum[i], + L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall", + NULL, + KEY_READ | RegSamEnum[i], + &hKey) != ERROR_SUCCESS) { - dwType = REG_DWORD; - dwSize = sizeof(DWORD); - - if (RegQueryValueExW(Info.hSubKey, - L"SystemComponent", - NULL, - &dwType, - (LPBYTE) &dwValue, - &dwSize) == ERROR_SUCCESS) - { - bIsSystemComponent = (dwValue == 0x1); - } - else + return FALSE; + } + + while (1) + { + dwSize = MAX_PATH; + if (RegEnumKeyExW(hKey, ItemIndex, szKeyName.GetBuffer(MAX_PATH), &dwSize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) { - bIsSystemComponent = FALSE; + break; } - dwType = REG_SZ; - dwSize = MAX_PATH * sizeof(WCHAR); - bIsUpdate = (RegQueryValueExW(Info.hSubKey, - L"ParentKeyName", - NULL, - &dwType, - (LPBYTE) szParentKeyName.GetBuffer(MAX_PATH), - &dwSize) == ERROR_SUCCESS); - szParentKeyName.ReleaseBuffer(); - - dwType = REG_SZ; - dwSize = MAX_PATH * sizeof(WCHAR); - if (RegQueryValueExW(Info.hSubKey, - L"DisplayName", - NULL, - &dwType, - (LPBYTE) szDisplayName.GetBuffer(MAX_PATH), - &dwSize) == ERROR_SUCCESS) + ItemIndex++; + + szKeyName.ReleaseBuffer(); + if (RegOpenKeyW(hKey, szKeyName.GetString(), &hSubKey) == ERROR_SUCCESS) { - szDisplayName.ReleaseBuffer(); - if (EnumType < ENUM_ALL_INSTALLED || EnumType > ENUM_UPDATES) - EnumType = ENUM_ALL_INSTALLED; + BOOL bSuccess = FALSE; + CInstalledApplicationInfo *Info = new CInstalledApplicationInfo(RootKeyEnum[i] == HKEY_CURRENT_USER, RegSamEnum[i], hSubKey); + Info->szKeyName = szKeyName; - if (!bIsSystemComponent) + // check for failure. if failed to init, Info->hSubKey will be set to NULL + if (Info->hSubKey) { - if ((EnumType == ENUM_ALL_INSTALLED) || /* All components */ - ((EnumType == ENUM_INSTALLED_APPLICATIONS) && (!bIsUpdate)) || /* Applications only */ - ((EnumType == ENUM_UPDATES) && (bIsUpdate))) /* Updates only */ + // those items without display name are ignored + if (Info->GetApplicationString(L"DisplayName", Info->szDisplayName)) { - if (!lpEnumProc(ItemIndex, szDisplayName, &Info, param)) - break; + Info->GetApplicationString(L"DisplayVersion", Info->szDisplayVersion); + Info->GetApplicationString(L"Publisher", Info->szPublisher); + Info->GetApplicationString(L"RegOwner", Info->szRegOwner); + Info->GetApplicationString(L"ProductID", Info->szProductID); + Info->GetApplicationString(L"HelpLink", Info->szHelpLink); + Info->GetApplicationString(L"HelpTelephone", Info->szHelpTelephone); + Info->GetApplicationString(L"Readme", Info->szReadme); + Info->GetApplicationString(L"Contact", Info->szContact); + Info->GetApplicationString(L"URLUpdateInfo", Info->szURLUpdateInfo); + Info->GetApplicationString(L"URLInfoAbout", Info->szURLInfoAbout); + Info->GetApplicationString(L"Comments", Info->szComments); + Info->GetApplicationString(L"InstallDate", Info->szInstallDate); + Info->GetApplicationString(L"InstallLocation", Info->szInstallLocation); + Info->GetApplicationString(L"InstallSource", Info->szInstallSource); + Info->GetApplicationString(L"UninstallString", Info->szUninstallString); + Info->GetApplicationString(L"ModifyPath", Info->szModifyPath); + + bSuccess = TRUE; } - else + } + + // close handle + if (Info->hSubKey) + { + CloseHandle(Info->hSubKey); + Info->hSubKey = NULL; + } + + if (bSuccess) + { + // add to InfoList. + m_InfoList.AddTail(Info); + + // invoke callback + if (lpEnumProc) { - RegCloseKey(Info.hSubKey); + if ((EnumType == ENUM_ALL_INSTALLED) || /* All components */ + ((EnumType == ENUM_INSTALLED_APPLICATIONS) && (!Info->bIsUpdate)) || /* Applications only */ + ((EnumType == ENUM_UPDATES) && (Info->bIsUpdate))) /* Updates only */ + { + lpEnumProc(Info, param); + } } } else { - RegCloseKey(Info.hSubKey); + // destory object + delete Info; } } - else - { - szDisplayName.ReleaseBuffer(); - RegCloseKey(Info.hSubKey); - } } - dwSize = MAX_PATH; - ItemIndex++; + szKeyName.ReleaseBuffer(); + RegCloseKey(hKey); } - - Info.szKeyName.ReleaseBuffer(); - RegCloseKey(hKey); + return TRUE; } + +VOID CInstalledApps::FreeCachedEntries() +{ + POSITION InfoListPosition = m_InfoList.GetHeadPosition(); + + /* loop and deallocate all the cached app infos in the list */ + while (InfoListPosition) + { + CInstalledApplicationInfo *Info = m_InfoList.GetNext(InfoListPosition); + delete Info; + } + + m_InfoList.RemoveAll(); +} diff --git a/base/applications/rapps/misc.cpp b/base/applications/rapps/misc.cpp index 8e164db8648..90f4e88cd3c 100644 --- a/base/applications/rapps/misc.cpp +++ b/base/applications/rapps/misc.cpp @@ -13,6 +13,9 @@ static HANDLE hLog = NULL; +static BOOL bIsSys64ResultCached = FALSE; +static BOOL bIsSys64Result = FALSE; + INT GetWindowWidth(HWND hwnd) { RECT Rect; @@ -453,3 +456,33 @@ BOOL PathAppendNoDirEscapeW(LPWSTR pszPath, LPCWSTR pszMore) return TRUE; } + + + +BOOL IsSystem64Bit() +{ + if (bIsSys64ResultCached) + { + // just return cached result + return bIsSys64Result; + } + + SYSTEM_INFO si; + typedef void (WINAPI *LPFN_PGNSI)(LPSYSTEM_INFO); + LPFN_PGNSI pGetNativeSystemInfo = (LPFN_PGNSI)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "GetNativeSystemInfo"); + if (pGetNativeSystemInfo) + { + pGetNativeSystemInfo(&si); + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) + { + bIsSys64Result = TRUE; + } + } + else + { + bIsSys64Result = FALSE; + } + + bIsSys64ResultCached = TRUE; // next time calling this function, it will directly return bIsSys64Result + return bIsSys64Result; +}
4 years, 3 months
1
0
0
0
[reactos] 06/19: [RAPPS] move icon to a field in .txt file (#2941)
by He Yang
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4482d0f4557ec3df12e39…
commit 4482d0f4557ec3df12e3982c148353724ac3ebf3 Author: He Yang <1160386205(a)qq.com> AuthorDate: Tue Jun 30 04:40:40 2020 +0800 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Sep 6 17:09:20 2020 +0200 [RAPPS] move icon to a field in .txt file (#2941) * [RAPPS] move icon to a field in .txt file * [RAPPS] add function PathAppendNoDirEscapeW, apply it. --- base/applications/rapps/available.cpp | 37 ++++++++++++++++++++--- base/applications/rapps/gui.cpp | 22 +++++++------- base/applications/rapps/include/available.h | 2 ++ base/applications/rapps/include/misc.h | 2 ++ base/applications/rapps/misc.cpp | 46 +++++++++++++++++++++++++++++ 5 files changed, 93 insertions(+), 16 deletions(-) diff --git a/base/applications/rapps/available.cpp b/base/applications/rapps/available.cpp index c26c5aaf622..8af6c78a8b9 100644 --- a/base/applications/rapps/available.cpp +++ b/base/applications/rapps/available.cpp @@ -72,14 +72,33 @@ VOID CAvailableApplicationInfo::RetrieveGeneralInfo(AvailableStrings& AvlbString } else { - // TODO: Does the filename contain anything stuff like "\\" ".." ":" "<" ">" ? + // TODO: Does the filename contain anything stuff like ":" "<" ">" ? // these stuff may lead to security issues - ATL::CStringW ScrnshotName = AvlbStrings.szAppsPath; PathAppendW(ScrnshotName.GetBuffer(MAX_PATH), L"screenshots"); - PathAppendW(ScrnshotName.GetBuffer(), ScrnshotLocation.GetString()); + BOOL bSuccess = PathAppendNoDirEscapeW(ScrnshotName.GetBuffer(), ScrnshotLocation.GetString()); ScrnshotName.ReleaseBuffer(); - m_szScrnshotLocation.Add(ScrnshotName); + if (bSuccess) + { + m_szScrnshotLocation.Add(ScrnshotName); + } + } + } + + // TODO: are we going to support specify an URL for an icon ? + ATL::CStringW IconLocation; + if (GetString(L"Icon", IconLocation)) + { + // TODO: Does the filename contain anything stuff like ":" "<" ">" ? + // these stuff may lead to security issues + ATL::CStringW IconPath = AvlbStrings.szAppsPath; + PathAppendW(IconPath.GetBuffer(MAX_PATH), L"icons"); + BOOL bSuccess = PathAppendNoDirEscapeW(IconPath.GetBuffer(), IconLocation.GetString()); + IconPath.ReleaseBuffer(); + + if (bSuccess) + { + m_szIconLocation = IconPath; } } @@ -246,6 +265,16 @@ BOOL CAvailableApplicationInfo::RetrieveScrnshot(UINT Index,ATL::CStringW& Scrns return TRUE; } +BOOL CAvailableApplicationInfo::RetrieveIcon(ATL::CStringW& IconLocation) const +{ + if (m_szIconLocation.IsEmpty()) + { + return FALSE; + } + IconLocation = m_szIconLocation; + return TRUE; +} + VOID CAvailableApplicationInfo::SetLastWriteTime(FILETIME* ftTime) { RtlCopyMemory(&m_ftCacheStamp, ftTime, sizeof(FILETIME)); diff --git a/base/applications/rapps/gui.cpp b/base/applications/rapps/gui.cpp index 367a13bcb64..b0599074a47 100644 --- a/base/applications/rapps/gui.cpp +++ b/base/applications/rapps/gui.cpp @@ -2394,18 +2394,16 @@ private: } /* Load icon from file */ - ATL::CStringW szIconPath = szFolderPath; - PathAppendW(szIconPath.GetBuffer(MAX_PATH), L"icons"); - PathAppendW(szIconPath.GetBuffer(), Info->m_szName.GetString()); - PathAddExtensionW(szIconPath.GetBuffer(), L".ico"); - szIconPath.ReleaseBuffer(); - - hIcon = (HICON) LoadImageW(NULL, - szIconPath.GetString(), - IMAGE_ICON, - LISTVIEW_ICON_SIZE, - LISTVIEW_ICON_SIZE, - LR_LOADFROMFILE); + ATL::CStringW szIconPath; + if (Info->RetrieveIcon(szIconPath)) + { + hIcon = (HICON)LoadImageW(NULL, + szIconPath.GetString(), + IMAGE_ICON, + LISTVIEW_ICON_SIZE, + LISTVIEW_ICON_SIZE, + LR_LOADFROMFILE); + } if (!hIcon || GetLastError() != ERROR_SUCCESS) { diff --git a/base/applications/rapps/include/available.h b/base/applications/rapps/include/available.h index 917fd261b0e..259b644dce1 100644 --- a/base/applications/rapps/include/available.h +++ b/base/applications/rapps/include/available.h @@ -52,6 +52,7 @@ struct CAvailableApplicationInfo ATL::CStringW m_szUrlDownload; ATL::CSimpleArray<LCID> m_LanguageLCIDs; ATL::CSimpleArray<ATL::CStringW> m_szScrnshotLocation; + ATL::CStringW m_szIconLocation; ULONG m_SizeBytes; @@ -75,6 +76,7 @@ struct CAvailableApplicationInfo BOOL HasInstalledVersion() const; BOOL HasUpdate() const; BOOL RetrieveScrnshot(UINT Index, ATL::CStringW& ScrnshotLocation) const; + BOOL RetrieveIcon(ATL::CStringW& IconLocation) const; // Set a timestamp VOID SetLastWriteTime(FILETIME* ftTime); diff --git a/base/applications/rapps/include/misc.h b/base/applications/rapps/include/misc.h index 50354c0f7ff..4c1fc6a4b1d 100644 --- a/base/applications/rapps/include/misc.h +++ b/base/applications/rapps/include/misc.h @@ -44,3 +44,5 @@ public: BOOL GetString(const ATL::CStringW& KeyName, ATL::CStringW& ResultString); BOOL GetInt(const ATL::CStringW& KeyName, INT& iResult); }; + +BOOL PathAppendNoDirEscapeW(LPWSTR pszPath, LPCWSTR pszMore); diff --git a/base/applications/rapps/misc.cpp b/base/applications/rapps/misc.cpp index 9ee6a391f63..8e164db8648 100644 --- a/base/applications/rapps/misc.cpp +++ b/base/applications/rapps/misc.cpp @@ -407,3 +407,49 @@ BOOL CConfigParser::GetInt(const ATL::CStringW& KeyName, INT& iResult) return (iResult > 0); } // CConfigParser + + +BOOL PathAppendNoDirEscapeW(LPWSTR pszPath, LPCWSTR pszMore) +{ + WCHAR pszPathBuffer[MAX_PATH]; // buffer to store result + WCHAR pszPathCopy[MAX_PATH]; + + if (!PathCanonicalizeW(pszPathCopy, pszPath)) + { + return FALSE; + } + + PathRemoveBackslashW(pszPathCopy); + + if (StringCchCopyW(pszPathBuffer, _countof(pszPathBuffer), pszPathCopy) != S_OK) + { + return FALSE; + } + + if (!PathAppendW(pszPathBuffer, pszMore)) + { + return FALSE; + } + + size_t PathLen; + if (StringCchLengthW(pszPathCopy, _countof(pszPathCopy), &PathLen) != S_OK) + { + return FALSE; + } + int CommonPrefixLen = PathCommonPrefixW(pszPathCopy, pszPathBuffer, NULL); + + if ((unsigned int)CommonPrefixLen != PathLen) + { + // pszPathBuffer should be a file/folder under pszPath. + // but now common prefix len is smaller than length of pszPathCopy + // hacking use ".." ? + return FALSE; + } + + if (StringCchCopyW(pszPath, MAX_PATH, pszPathBuffer) != S_OK) + { + return FALSE; + } + + return TRUE; +}
4 years, 3 months
1
0
0
0
[reactos] 05/19: [RAPPS] rename snapshot to screenshot, filename to location (#2939)
by He Yang
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e636373016b0918550f06…
commit e636373016b0918550f0647d0df5bd041fbe8f58 Author: He Yang <1160386205(a)qq.com> AuthorDate: Mon Jun 22 00:20:45 2020 +0800 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Sep 6 17:09:20 2020 +0200 [RAPPS] rename snapshot to screenshot, filename to location (#2939) --- base/applications/rapps/available.cpp | 32 ++++---- base/applications/rapps/gui.cpp | 120 ++++++++++++++-------------- base/applications/rapps/include/available.h | 6 +- 3 files changed, 79 insertions(+), 79 deletions(-) diff --git a/base/applications/rapps/available.cpp b/base/applications/rapps/available.cpp index 5957e8cf31b..c26c5aaf622 100644 --- a/base/applications/rapps/available.cpp +++ b/base/applications/rapps/available.cpp @@ -54,32 +54,32 @@ VOID CAvailableApplicationInfo::RetrieveGeneralInfo(AvailableStrings& AvlbString GetString(L"URLSite", m_szUrlSite); GetString(L"SHA1", m_szSHA1); - static_assert(MAX_SNAPSHOT_NUM < 10000, "MAX_SNAPSHOT_NUM is too big"); - for (int i = 0; i < MAX_SNAPSHOT_NUM; i++) + static_assert(MAX_SCRNSHOT_NUM < 10000, "MAX_SCRNSHOT_NUM is too big"); + for (int i = 0; i < MAX_SCRNSHOT_NUM; i++) { - WCHAR SnapshotField[sizeof("Snapshot") + 4]; - wsprintfW(SnapshotField, L"Snapshot%d", i + 1); - ATL::CStringW SnapshotLocation; - if (!GetString(SnapshotField, SnapshotLocation)) + CStringW ScrnshotField; + ScrnshotField.Format(L"Screenshot%d", i + 1); + CStringW ScrnshotLocation; + if (!GetString(ScrnshotField, ScrnshotLocation)) { continue; } - if (PathIsURLW(SnapshotLocation.GetString())) + if (PathIsURLW(ScrnshotLocation.GetString())) { - m_szSnapshotLocation.Add(SnapshotLocation); + m_szScrnshotLocation.Add(ScrnshotLocation); } else { // TODO: Does the filename contain anything stuff like "\\" ".." ":" "<" ">" ? // these stuff may lead to security issues - ATL::CStringW SnapshotName = AvlbStrings.szAppsPath; - PathAppendW(SnapshotName.GetBuffer(MAX_PATH), L"snapshots"); - PathAppendW(SnapshotName.GetBuffer(), SnapshotLocation.GetString()); - SnapshotName.ReleaseBuffer(); - m_szSnapshotLocation.Add(SnapshotName); + ATL::CStringW ScrnshotName = AvlbStrings.szAppsPath; + PathAppendW(ScrnshotName.GetBuffer(MAX_PATH), L"screenshots"); + PathAppendW(ScrnshotName.GetBuffer(), ScrnshotLocation.GetString()); + ScrnshotName.ReleaseBuffer(); + m_szScrnshotLocation.Add(ScrnshotName); } } @@ -236,13 +236,13 @@ BOOL CAvailableApplicationInfo::HasUpdate() const return (m_szInstalledVersion.Compare(m_szVersion) < 0) ? TRUE : FALSE; } -BOOL CAvailableApplicationInfo::RetrieveSnapshot(UINT Index,ATL::CStringW& SnapshotFileName) const +BOOL CAvailableApplicationInfo::RetrieveScrnshot(UINT Index,ATL::CStringW& ScrnshotLocation) const { - if (Index >= (UINT)m_szSnapshotLocation.GetSize()) + if (Index >= (UINT)m_szScrnshotLocation.GetSize()) { return FALSE; } - SnapshotFileName = m_szSnapshotLocation[Index]; + ScrnshotLocation = m_szScrnshotLocation[Index]; return TRUE; } diff --git a/base/applications/rapps/gui.cpp b/base/applications/rapps/gui.cpp index a501690e3bb..367a13bcb64 100644 --- a/base/applications/rapps/gui.cpp +++ b/base/applications/rapps/gui.cpp @@ -35,10 +35,10 @@ using namespace Gdiplus; // default broken-image icon size #define BROKENIMG_ICON_SIZE 96 -// the boundary of w/h ratio of snapshot preview window -#define SNPSHT_MAX_ASPECT_RAT 2.5 +// the boundary of w/h ratio of scrnshot preview window +#define SCRNSHOT_MAX_ASPECT_RAT 2.5 -// padding between snapshot preview and richedit (in pixel) +// padding between scrnshot preview and richedit (in pixel) #define INFO_DISPLAY_PADDING 10 // minimum width of richedit @@ -46,15 +46,15 @@ using namespace Gdiplus; // user-defined window message -#define WM_RAPPS_DOWNLOAD_COMPLETE (WM_USER + 1) // notify download complete. wParam is error code, and lParam is a pointer to SnapshotDownloadParam +#define WM_RAPPS_DOWNLOAD_COMPLETE (WM_USER + 1) // notify download complete. wParam is error code, and lParam is a pointer to ScrnshotDownloadParam #define WM_RAPPS_RESIZE_CHILDREN (WM_USER + 2) // ask parent window to resize children. -enum SNPSHT_STATUS +enum SCRNSHOT_STATUS { - SNPSHTPREV_EMPTY, // show nothing - SNPSHTPREV_LOADING, // image is loading (most likely downloading) - SNPSHTPREV_IMAGE, // display image from a file - SNPSHTPREV_FAILED // image can not be shown (download failure or wrong image) + SCRNSHOT_PREV_EMPTY, // show nothing + SCRNSHOT_PREV_LOADING, // image is loading (most likely downloading) + SCRNSHOT_PREV_IMAGE, // display image from a file + SCRNSHOT_PREV_FAILED // image can not be shown (download failure or wrong image) }; #define TIMER_LOADING_ANIMATION 1 // Timer ID @@ -65,13 +65,13 @@ enum SNPSHT_STATUS #define PI 3.1415927 -typedef struct __SnapshotDownloadParam +typedef struct __ScrnshotDownloadParam { LONGLONG ID; HANDLE hFile; HWND hwndNotify; ATL::CStringW DownloadFileName; -} SnapshotDownloadParam; +} ScrnshotDownloadParam; INT GetSystemColorDepth() { @@ -304,7 +304,7 @@ public: } }; -int SnapshotDownloadCallback( +int ScrnshotDownloadCallback( pASYNCINET AsyncInet, ASYNC_EVENT Event, WPARAM wParam, @@ -312,7 +312,7 @@ int SnapshotDownloadCallback( VOID* Extension ) { - SnapshotDownloadParam* DownloadParam = (SnapshotDownloadParam*)Extension; + ScrnshotDownloadParam* DownloadParam = (ScrnshotDownloadParam*)Extension; switch (Event) { case ASYNCINET_DATA: @@ -338,12 +338,12 @@ int SnapshotDownloadCallback( return 0; } -class CAppSnapshotPreview : - public CWindowImpl<CAppSnapshotPreview> +class CAppScrnshotPreview : + public CWindowImpl<CAppScrnshotPreview> { private: - SNPSHT_STATUS SnpshtPrevStauts = SNPSHTPREV_EMPTY; + SCRNSHOT_STATUS ScrnshotPrevStauts = SCRNSHOT_PREV_EMPTY; Image* pImage = NULL; HICON hBrokenImgIcon = NULL; BOOL bLoadingTimerOn = FALSE; @@ -377,7 +377,7 @@ private: } case WM_RAPPS_DOWNLOAD_COMPLETE: { - SnapshotDownloadParam* DownloadParam = (SnapshotDownloadParam*)lParam; + ScrnshotDownloadParam* DownloadParam = (ScrnshotDownloadParam*)lParam; AsyncInetRelease(AsyncInet); AsyncInet = NULL; switch (wParam) @@ -477,7 +477,7 @@ private: VOID DisplayLoading() { - SetStatus(SNPSHTPREV_LOADING); + SetStatus(SCRNSHOT_PREV_LOADING); if (bLoadingTimerOn) { KillTimer(TIMER_LOADING_ANIMATION); @@ -490,14 +490,14 @@ private: VOID DisplayFailed() { InterlockedIncrement64(&ContentID); - SetStatus(SNPSHTPREV_FAILED); + SetStatus(SCRNSHOT_PREV_FAILED); PreviousDisplayCleanup(); } BOOL DisplayFile(LPCWSTR lpszFileName) { PreviousDisplayCleanup(); - SetStatus(SNPSHTPREV_IMAGE); + SetStatus(SCRNSHOT_PREV_IMAGE); pImage = Bitmap::FromFile(lpszFileName, 0); if (pImage->GetLastStatus() != Ok) { @@ -507,9 +507,9 @@ private: return TRUE; } - VOID SetStatus(SNPSHT_STATUS Status) + VOID SetStatus(SCRNSHOT_STATUS Status) { - SnpshtPrevStauts = Status; + ScrnshotPrevStauts = Status; } VOID PaintOnDC(HDC hdc, int width, int height, BOOL bDrawBkgnd) @@ -526,15 +526,15 @@ private: SelectObject(hdcMem, hOldBrush); } - switch (SnpshtPrevStauts) + switch (ScrnshotPrevStauts) { - case SNPSHTPREV_EMPTY: + case SCRNSHOT_PREV_EMPTY: { } break; - case SNPSHTPREV_LOADING: + case SCRNSHOT_PREV_LOADING: { Graphics graphics(hdcMem); Color color(255, 0, 0); @@ -564,7 +564,7 @@ private: } break; - case SNPSHTPREV_IMAGE: + case SCRNSHOT_PREV_IMAGE: { if (pImage) { @@ -581,7 +581,7 @@ private: } break; - case SNPSHTPREV_FAILED: + case SCRNSHOT_PREV_FAILED: { DrawIconEx(hdcMem, (width - BrokenImgSize) / 2, @@ -632,7 +632,7 @@ public: LoadCursorW(NULL, IDC_ARROW), (HBRUSH)(COLOR_BTNFACE + 1), 0, - L"RAppsSnapshotPreview", + L"RAppsScrnshotPreview", NULL }, NULL, NULL, IDC_ARROW, TRUE, 0, _T("") @@ -674,7 +674,7 @@ public: VOID DisplayEmpty() { InterlockedIncrement64(&ContentID); - SetStatus(SNPSHTPREV_EMPTY); + SetStatus(SCRNSHOT_PREV_EMPTY); PreviousDisplayCleanup(); } @@ -687,22 +687,22 @@ public: { DisplayLoading(); - SnapshotDownloadParam* DownloadParam = new SnapshotDownloadParam; + ScrnshotDownloadParam* DownloadParam = new ScrnshotDownloadParam; if (!DownloadParam) return FALSE; DownloadParam->hwndNotify = m_hWnd; DownloadParam->ID = ID; // generate a filename - ATL::CStringW SnapshotFolder = CAvailableApps::m_Strings.szAppsPath; - PathAppendW(SnapshotFolder.GetBuffer(MAX_PATH), L"snapshots"); - SnapshotFolder.ReleaseBuffer(); + ATL::CStringW ScrnshotFolder = CAvailableApps::m_Strings.szAppsPath; + PathAppendW(ScrnshotFolder.GetBuffer(MAX_PATH), L"screenshots"); + ScrnshotFolder.ReleaseBuffer(); - if (!PathIsDirectoryW(SnapshotFolder.GetString())) + if (!PathIsDirectoryW(ScrnshotFolder.GetString())) { - CreateDirectoryW(SnapshotFolder.GetString(), NULL); + CreateDirectoryW(ScrnshotFolder.GetString(), NULL); } - if (!GetTempFileNameW(SnapshotFolder.GetString(), L"img", + if (!GetTempFileNameW(ScrnshotFolder.GetString(), L"img", 0, DownloadParam->DownloadFileName.GetBuffer(MAX_PATH))) { DownloadParam->DownloadFileName.ReleaseBuffer(); @@ -721,7 +721,7 @@ public: return FALSE; } - AsyncInet = AsyncInetDownload(0, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, lpszLocation, TRUE, SnapshotDownloadCallback, DownloadParam); + AsyncInet = AsyncInetDownload(0, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, lpszLocation, TRUE, ScrnshotDownloadCallback, DownloadParam); if (!AsyncInet) { CloseHandle(DownloadParam->hFile); @@ -740,29 +740,29 @@ public: int GetRequestedWidth(int Height) // calculate requested window width by given height { - switch (SnpshtPrevStauts) + switch (ScrnshotPrevStauts) { - case SNPSHTPREV_EMPTY: + case SCRNSHOT_PREV_EMPTY: return 0; - case SNPSHTPREV_LOADING: + case SCRNSHOT_PREV_LOADING: return 200; - case SNPSHTPREV_IMAGE: + case SCRNSHOT_PREV_IMAGE: if (pImage) { // return the width needed to display image inside the window. - // and always keep window w/h ratio inside [ 1/SNPSHT_MAX_ASPECT_RAT, SNPSHT_MAX_ASPECT_RAT ] + // and always keep window w/h ratio inside [ 1/SCRNSHOT_MAX_ASPECT_RAT, SCRNSHOT_MAX_ASPECT_RAT ] return (int)floor((float)Height * - max(min((float)pImage->GetWidth() / (float)pImage->GetHeight(), (float)SNPSHT_MAX_ASPECT_RAT), 1.0/ (float)SNPSHT_MAX_ASPECT_RAT)); + max(min((float)pImage->GetWidth() / (float)pImage->GetHeight(), (float)SCRNSHOT_MAX_ASPECT_RAT), 1.0/ (float)SCRNSHOT_MAX_ASPECT_RAT)); } return 0; - case SNPSHTPREV_FAILED: + case SCRNSHOT_PREV_FAILED: return 200; default: return 0; } } - ~CAppSnapshotPreview() + ~CAppScrnshotPreview() { PreviousDisplayCleanup(); } @@ -784,8 +784,8 @@ private: RichEdit = new CAppRichEdit(); RichEdit->Create(hwnd); - SnpshtPrev = new CAppSnapshotPreview(); - SnpshtPrev->Create(hwnd); + ScrnshotPrev = new CAppScrnshotPreview(); + ScrnshotPrev->Create(hwnd); break; } case WM_SIZE: @@ -831,23 +831,23 @@ private: VOID ResizeChildren(int Width, int Height) { - int SnpshtWidth = SnpshtPrev->GetRequestedWidth(Height); + int ScrnshotWidth = ScrnshotPrev->GetRequestedWidth(Height); // make sure richedit always have room to display - SnpshtWidth = min(SnpshtWidth, Width - INFO_DISPLAY_PADDING - RICHEDIT_MIN_WIDTH); + ScrnshotWidth = min(ScrnshotWidth, Width - INFO_DISPLAY_PADDING - RICHEDIT_MIN_WIDTH); DWORD dwError = ERROR_SUCCESS; HDWP hDwp = BeginDeferWindowPos(2); if (hDwp) { - hDwp = ::DeferWindowPos(hDwp, SnpshtPrev->m_hWnd, NULL, - 0, 0, SnpshtWidth, Height, 0); + hDwp = ::DeferWindowPos(hDwp, ScrnshotPrev->m_hWnd, NULL, + 0, 0, ScrnshotWidth, Height, 0); if (hDwp) { - // hide the padding if snapshot window width == 0 - int RicheditPosX = SnpshtWidth ? (SnpshtWidth + INFO_DISPLAY_PADDING) : 0; + // hide the padding if scrnshot window width == 0 + int RicheditPosX = ScrnshotWidth ? (ScrnshotWidth + INFO_DISPLAY_PADDING) : 0; hDwp = ::DeferWindowPos(hDwp, RichEdit->m_hWnd, NULL, RicheditPosX, 0, Width - RicheditPosX, Height, 0); @@ -909,7 +909,7 @@ private: public: CAppRichEdit * RichEdit; - CAppSnapshotPreview * SnpshtPrev; + CAppScrnshotPreview * ScrnshotPrev; static ATL::CWndClassInfo& GetWndClassInfo() { @@ -944,14 +944,14 @@ public: BOOL ShowAvailableAppInfo(CAvailableApplicationInfo* Info) { - ATL::CStringW SnapshotLocation; - if (Info->RetrieveSnapshot(0, SnapshotLocation)) + ATL::CStringW ScrnshotLocation; + if (Info->RetrieveScrnshot(0, ScrnshotLocation)) { - SnpshtPrev->DisplayImage(SnapshotLocation); + ScrnshotPrev->DisplayImage(ScrnshotLocation); } else { - SnpshtPrev->DisplayEmpty(); + ScrnshotPrev->DisplayEmpty(); } ResizeChildren(); return RichEdit->ShowAvailableAppInfo(Info); @@ -959,14 +959,14 @@ public: BOOL ShowInstalledAppInfo(PINSTALLED_INFO Info) { - SnpshtPrev->DisplayEmpty(); + ScrnshotPrev->DisplayEmpty(); ResizeChildren(); return RichEdit->ShowInstalledAppInfo(Info); } VOID SetWelcomeText() { - SnpshtPrev->DisplayEmpty(); + ScrnshotPrev->DisplayEmpty(); ResizeChildren(); RichEdit->SetWelcomeText(); } diff --git a/base/applications/rapps/include/available.h b/base/applications/rapps/include/available.h index 53253e8563c..917fd261b0e 100644 --- a/base/applications/rapps/include/available.h +++ b/base/applications/rapps/include/available.h @@ -8,7 +8,7 @@ #include "misc.h" -#define MAX_SNAPSHOT_NUM 16 +#define MAX_SCRNSHOT_NUM 16 enum LicenseType { @@ -51,7 +51,7 @@ struct CAvailableApplicationInfo ATL::CStringW m_szUrlSite; ATL::CStringW m_szUrlDownload; ATL::CSimpleArray<LCID> m_LanguageLCIDs; - ATL::CSimpleArray<ATL::CStringW> m_szSnapshotLocation; + ATL::CSimpleArray<ATL::CStringW> m_szScrnshotLocation; ULONG m_SizeBytes; @@ -74,7 +74,7 @@ struct CAvailableApplicationInfo BOOL IsInstalled() const; BOOL HasInstalledVersion() const; BOOL HasUpdate() const; - BOOL RetrieveSnapshot(UINT Index, ATL::CStringW& SnapshotFileName) const; + BOOL RetrieveScrnshot(UINT Index, ATL::CStringW& ScrnshotLocation) const; // Set a timestamp VOID SetLastWriteTime(FILETIME* ftTime);
4 years, 3 months
1
0
0
0
← Newer
1
...
33
34
35
36
37
38
39
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Results per page:
10
25
50
100
200