reactos/base/applications/rapps/include/appview.h
Oleg Dubinskiy 7eb90143f8
[RAPPS] Display custom applications icons for installed applications CORE-17257 (#3144)
* [RAPPS] Display custom applications icons for installed applications
- Implement `RetrieveIcon` helper function in `CInstalledApplicationInfo` class, which retrueves the current app's icon from registry, same as it done for `CAvailableApplicationInfo`.
- Use it for loading the icon in `CAppsListView::AddInstalledApplication` function, via `ExtractIconW`. Load default Rapps icon only when the app has no its custom icon.
- Retrieve `DisplayIcon` value from registry in `CInstalledApps::Enum` function, same as other registry values (like app name, description, etc).Store it in `szDisplayIcon` string, which is used in `CInstalledApplicationInfo::RetrieveIcon` for retrieving the data of that value.
- Increase `LISTVIEW_ICON_SIZE` macro from 24 to 32, so 32x32 icon size is now used instead of 24x24. This makes displayed icons more accurate, since most of apps contain 32x32 icon, so they look a bit distorted with 24x24 size.
2020-09-20 19:19:59 +02:00

400 lines
9.9 KiB
C++

#pragma once
#include "rapps.h"
#include "rosui.h"
#include "crichedit.h"
#include "asyncinet.h"
#include <shlobj_undoc.h>
#include <shlguid_undoc.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atltypes.h>
#include <atlwin.h>
#include <wininet.h>
#include <shellutils.h>
#include <rosctrls.h>
#include <gdiplus.h>
#include <math.h>
using namespace Gdiplus;
#define LISTVIEW_ICON_SIZE 32
// default broken-image icon size
#define BROKENIMG_ICON_SIZE 96
// the boundary of w/h ratio of scrnshot preview window
#define SCRNSHOT_MAX_ASPECT_RAT 2.5
// padding between scrnshot preview and richedit (in pixel)
#define INFO_DISPLAY_PADDING 10
// minimum width of richedit
#define RICHEDIT_MIN_WIDTH 160
// padding between controls in toolbar
#define TOOLBAR_PADDING 6
// 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 ScrnshotDownloadParam
#define WM_RAPPS_RESIZE_CHILDREN (WM_USER + 2) // ask parent window to resize children.
enum SCRNSHOT_STATUS
{
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
#define LOADING_ANIMATION_PERIOD 3 // Animation cycling period (in seconds)
#define LOADING_ANIMATION_FPS 18 // Animation Frame Per Second
#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-styles
#define STATEIMAGE_UNCHECKED 1
#define STATEIMAGE_CHECKED 2
class CMainWindow;
enum APPLICATION_VIEW_TYPE
{
AppViewTypeEmpty,
AppViewTypeAvailableApps,
AppViewTypeInstalledApps
};
typedef struct __ScrnshotDownloadParam
{
LONGLONG ID;
HANDLE hFile;
HWND hwndNotify;
ATL::CStringW DownloadFileName;
} ScrnshotDownloadParam;
class CAppRichEdit :
public CUiWindow<CRichEdit>
{
private:
VOID LoadAndInsertText(UINT uStringID,
const ATL::CStringW &szText,
DWORD StringFlags,
DWORD TextFlags);
VOID LoadAndInsertText(UINT uStringID,
DWORD StringFlags);
VOID InsertVersionInfo(CAvailableApplicationInfo *Info);
VOID InsertLicenseInfo(CAvailableApplicationInfo *Info);
VOID InsertLanguageInfo(CAvailableApplicationInfo *Info);
public:
BOOL ShowAvailableAppInfo(CAvailableApplicationInfo *Info);
inline VOID InsertTextWithString(UINT StringID, DWORD StringFlags, const ATL::CStringW &Text, DWORD TextFlags);
BOOL ShowInstalledAppInfo(CInstalledApplicationInfo *Info);
VOID SetWelcomeText();
};
int ScrnshotDownloadCallback(
pASYNCINET AsyncInet,
ASYNC_EVENT Event,
WPARAM wParam,
LPARAM lParam,
VOID *Extension
);
class CAppScrnshotPreview :
public CWindowImpl<CAppScrnshotPreview>
{
private:
SCRNSHOT_STATUS ScrnshotPrevStauts = SCRNSHOT_PREV_EMPTY;
Image *pImage = NULL;
HICON hBrokenImgIcon = NULL;
BOOL bLoadingTimerOn = FALSE;
int LoadingAnimationFrame = 0;
int BrokenImgSize = BROKENIMG_ICON_SIZE;
pASYNCINET AsyncInet = NULL;
LONGLONG ContentID = 0; // used to determine whether image has been switched when download complete. Increase by 1 each time the content of this window changed
ATL::CStringW TempImagePath; // currently displayed temp file
BOOL ProcessWindowMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT &theResult, DWORD dwMapId);
VOID DisplayLoading();
VOID DisplayFailed();
BOOL DisplayFile(LPCWSTR lpszFileName);
VOID SetStatus(SCRNSHOT_STATUS Status);
VOID PaintOnDC(HDC hdc, int width, int height, BOOL bDrawBkgnd);
float GetLoadingDotWidth(int width, int height);
float GetFrameDotShift(int Frame, int width, int height);
public:
static ATL::CWndClassInfo &GetWndClassInfo();
HWND Create(HWND hParent);
VOID PreviousDisplayCleanup();
VOID DisplayEmpty();
BOOL DisplayImage(LPCWSTR lpszLocation);
// calculate requested window width by given height
int GetRequestedWidth(int Height);
~CAppScrnshotPreview();
};
class CAppInfoDisplay :
public CUiWindow<CWindowImpl<CAppInfoDisplay>>
{
LPWSTR pLink = NULL;
private:
BOOL ProcessWindowMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT &theResult, DWORD dwMapId);
VOID ResizeChildren();
VOID ResizeChildren(int Width, int Height);
VOID OnLink(ENLINK *Link);
public:
CAppRichEdit *RichEdit = NULL;
CAppScrnshotPreview *ScrnshotPrev = NULL;
static ATL::CWndClassInfo &GetWndClassInfo();
HWND Create(HWND hwndParent);
BOOL ShowAvailableAppInfo(CAvailableApplicationInfo *Info);
BOOL ShowInstalledAppInfo(CInstalledApplicationInfo *Info);
VOID SetWelcomeText();
VOID OnCommand(WPARAM wParam, LPARAM lParam);
~CAppInfoDisplay();
};
class CAppsListView :
public CUiWindow<CListView>
{
struct SortContext
{
CAppsListView *lvw;
INT iSubItem;
};
BOOL bIsAscending = TRUE;
BOOL bHasCheckboxes;
INT ItemCount = 0;
INT CheckedItemCount = 0;
INT ColumnCount = 0;
INT nLastHeaderID;
APPLICATION_VIEW_TYPE ApplicationViewType = AppViewTypeEmpty;
HIMAGELIST m_hImageListView;
public:
CAppsListView();
VOID SetCheckboxesVisible(BOOL bIsVisible);
VOID ColumnClick(LPNMLISTVIEW pnmv);
BOOL AddColumn(INT Index, ATL::CStringW &Text, INT Width, INT Format);
int AddColumn(INT Index, LPWSTR lpText, INT Width, INT Format);
void DeleteColumn(INT Index);
INT AddItem(INT ItemIndex, INT IconIndex, LPCWSTR lpText, LPARAM lParam);
HIMAGELIST GetImageList(int iImageList);
static INT CALLBACK s_CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
INT CompareFunc(LPARAM lParam1, LPARAM lParam2, INT iSubItem);
HWND Create(HWND hwndParent);
BOOL GetCheckState(INT item);
VOID SetCheckState(INT item, BOOL fCheck);
VOID CheckAll();
PVOID GetFocusedItemData();
BOOL SetDisplayAppType(APPLICATION_VIEW_TYPE AppType);
BOOL SetViewMode(DWORD ViewMode);
BOOL AddInstalledApplication(CInstalledApplicationInfo *InstAppInfo, LPVOID CallbackParam);
BOOL AddAvailableApplication(CAvailableApplicationInfo *AvlbAppInfo, BOOL InitCheckState, LPVOID CallbackParam);
// this function is called when parent window receiving an notification about checkstate changing
VOID ItemCheckStateNotify(int iItem, BOOL bCheck);
};
class CMainToolbar :
public CUiWindow< CToolbar<> >
{
const INT m_iToolbarHeight;
DWORD m_dButtonsWidthMax;
WCHAR szInstallBtn[MAX_STR_LEN];
WCHAR szUninstallBtn[MAX_STR_LEN];
WCHAR szModifyBtn[MAX_STR_LEN];
WCHAR szSelectAll[MAX_STR_LEN];
VOID AddImageToImageList(HIMAGELIST hImageList, UINT ImageIndex);
HIMAGELIST InitImageList();
public:
CMainToolbar();
VOID OnGetDispInfo(LPTOOLTIPTEXT lpttt);
HWND Create(HWND hwndParent);
VOID HideButtonCaption();
VOID ShowButtonCaption();
DWORD GetMaxButtonsWidth() const;
};
class CSearchBar :
public CWindow
{
public:
const INT m_Width;
const INT m_Height;
CSearchBar();
VOID SetText(LPCWSTR lpszText);
HWND Create(HWND hwndParent);
};
class CComboBox :
public CWindow
{
// ID refers to different types of view
enum
{ m_AppDisplayTypeDetails, m_AppDisplayTypeList, m_AppDisplayTypeTile };
// string ID for different. this should correspond with the enum above.
const UINT m_TypeStringID[3] =
{ IDS_APP_DISPLAY_DETAILS, IDS_APP_DISPLAY_LIST, IDS_APP_DISPLAY_TILE };
const int m_DefaultSelectType = m_AppDisplayTypeDetails;
public:
int m_Width;
int m_Height;
CComboBox();
HWND Create(HWND hwndParent);
};
class CApplicationView :
public CUiWindow<CWindowImpl<CApplicationView>>
{
private:
CUiPanel *m_Panel = NULL;
CMainToolbar *m_Toolbar = NULL;
CUiWindow<CComboBox> *m_ComboBox = NULL;
CUiWindow<CSearchBar> *m_SearchBar = NULL;
CAppsListView *m_ListView = NULL;
CAppInfoDisplay *m_AppsInfo = NULL;
CUiSplitPanel *m_HSplitter = NULL;
CMainWindow *m_MainWindow = NULL;
APPLICATION_VIEW_TYPE ApplicationViewType = AppViewTypeEmpty;
BOOL ProcessWindowMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT &theResult, DWORD dwMapId);
BOOL CreateToolbar();
BOOL CreateSearchBar();
BOOL CreateComboBox();
BOOL CreateHSplitter();
BOOL CreateListView();
BOOL CreateAppInfoDisplay();
VOID OnSize(HWND hwnd, WPARAM wParam, LPARAM lParam);
VOID OnCommand(WPARAM wParam, LPARAM lParam);
public:
CApplicationView(CMainWindow *MainWindow);
~CApplicationView();
static ATL::CWndClassInfo &GetWndClassInfo();
HWND Create(HWND hwndParent);
BOOL SetDisplayAppType(APPLICATION_VIEW_TYPE AppType);
BOOL AddInstalledApplication(CInstalledApplicationInfo *InstAppInfo, LPVOID param);
BOOL AddAvailableApplication(CAvailableApplicationInfo *AvlbAppInfo, BOOL InitCheckState, LPVOID param);
void CheckAll();
PVOID GetFocusedItemData();
int GetItemCount();
VOID AppendTabOrderWindow(int Direction, ATL::CSimpleArray<HWND> &TabOrderList);
// 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);
// 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);
};