1 #pragma once 2 3 #include "rapps.h" 4 #include "rosui.h" 5 #include "crichedit.h" 6 #include "asyncinet.h" 7 8 #include <shlobj_undoc.h> 9 #include <shlguid_undoc.h> 10 11 #include <atlbase.h> 12 #include <atlcom.h> 13 #include <atltypes.h> 14 #include <atlwin.h> 15 #include <wininet.h> 16 #include <shellutils.h> 17 #include <ui/rosctrls.h> 18 #include <gdiplus.h> 19 #include <math.h> 20 21 using namespace Gdiplus; 22 23 #define LISTVIEW_ICON_SIZE 32 24 25 // default broken-image icon size 26 #define BROKENIMG_ICON_SIZE 96 27 28 // the boundary of w/h ratio of scrnshot preview window 29 #define SCRNSHOT_MAX_ASPECT_RAT 2.5 30 31 // padding between scrnshot preview and richedit (in pixel) 32 #define INFO_DISPLAY_PADDING 10 33 34 // minimum width of richedit 35 #define RICHEDIT_MIN_WIDTH 160 36 37 // padding between controls in toolbar 38 #define TOOLBAR_PADDING 6 39 40 // user-defined window message 41 #define WM_RAPPS_DOWNLOAD_COMPLETE (WM_USER + 1) // notify download complete. wParam is error code, and lParam is a pointer to ScrnshotDownloadParam 42 #define WM_RAPPS_RESIZE_CHILDREN (WM_USER + 2) // ask parent window to resize children. 43 44 enum SCRNSHOT_STATUS 45 { 46 SCRNSHOT_PREV_EMPTY, // show nothing 47 SCRNSHOT_PREV_LOADING, // image is loading (most likely downloading) 48 SCRNSHOT_PREV_IMAGE, // display image from a file 49 SCRNSHOT_PREV_FAILED // image can not be shown (download failure or wrong image) 50 }; 51 52 #define TIMER_LOADING_ANIMATION 1 // Timer ID 53 54 #define LOADING_ANIMATION_PERIOD 3 // Animation cycling period (in seconds) 55 #define LOADING_ANIMATION_FPS 18 // Animation Frame Per Second 56 57 58 #define PI 3.1415927 59 60 // retrieve the value using a mask 61 #define STATEIMAGETOINDEX(x) (((x) & LVIS_STATEIMAGEMASK) >> 12) 62 63 // for listview with extend style LVS_EX_CHECKBOXES, State image 1 is the unchecked box, and state image 2 is the checked box. 64 // see this: https://docs.microsoft.com/en-us/windows/win32/controls/extended-list-view-styles 65 #define STATEIMAGE_UNCHECKED 1 66 #define STATEIMAGE_CHECKED 2 67 68 class CMainWindow; 69 70 enum APPLICATION_VIEW_TYPE 71 { 72 AppViewTypeEmpty, 73 AppViewTypeAvailableApps, 74 AppViewTypeInstalledApps 75 }; 76 77 typedef struct __ScrnshotDownloadParam 78 { 79 LONGLONG ID; 80 HANDLE hFile; 81 HWND hwndNotify; 82 ATL::CStringW DownloadFileName; 83 } ScrnshotDownloadParam; 84 85 86 class CAppRichEdit : 87 public CUiWindow<CRichEdit> 88 { 89 private: 90 VOID LoadAndInsertText(UINT uStringID, 91 const ATL::CStringW &szText, 92 DWORD StringFlags, 93 DWORD TextFlags); 94 95 VOID LoadAndInsertText(UINT uStringID, 96 DWORD StringFlags); 97 98 VOID InsertVersionInfo(CAvailableApplicationInfo *Info); 99 100 VOID InsertLicenseInfo(CAvailableApplicationInfo *Info); 101 102 VOID InsertLanguageInfo(CAvailableApplicationInfo *Info); 103 104 public: 105 BOOL ShowAvailableAppInfo(CAvailableApplicationInfo *Info); 106 107 inline VOID InsertTextWithString(UINT StringID, DWORD StringFlags, const ATL::CStringW &Text, DWORD TextFlags); 108 109 BOOL ShowInstalledAppInfo(CInstalledApplicationInfo *Info); 110 111 VOID SetWelcomeText(); 112 }; 113 114 int ScrnshotDownloadCallback( 115 pASYNCINET AsyncInet, 116 ASYNC_EVENT Event, 117 WPARAM wParam, 118 LPARAM lParam, 119 VOID *Extension 120 ); 121 122 class CAppScrnshotPreview : 123 public CWindowImpl<CAppScrnshotPreview> 124 { 125 private: 126 127 SCRNSHOT_STATUS ScrnshotPrevStauts = SCRNSHOT_PREV_EMPTY; 128 Image *pImage = NULL; 129 HICON hBrokenImgIcon = NULL; 130 BOOL bLoadingTimerOn = FALSE; 131 int LoadingAnimationFrame = 0; 132 int BrokenImgSize = BROKENIMG_ICON_SIZE; 133 pASYNCINET AsyncInet = NULL; 134 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 135 ATL::CStringW TempImagePath; // currently displayed temp file 136 137 BOOL ProcessWindowMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT &theResult, DWORD dwMapId); 138 139 VOID DisplayLoading(); 140 141 VOID DisplayFailed(); 142 143 BOOL DisplayFile(LPCWSTR lpszFileName); 144 145 VOID SetStatus(SCRNSHOT_STATUS Status); 146 147 VOID PaintOnDC(HDC hdc, int width, int height, BOOL bDrawBkgnd); 148 149 float GetLoadingDotWidth(int width, int height); 150 151 float GetFrameDotShift(int Frame, int width, int height); 152 153 public: 154 static ATL::CWndClassInfo &GetWndClassInfo(); 155 156 HWND Create(HWND hParent); 157 158 VOID PreviousDisplayCleanup(); 159 160 VOID DisplayEmpty(); 161 162 BOOL DisplayImage(LPCWSTR lpszLocation); 163 164 // calculate requested window width by given height 165 int GetRequestedWidth(int Height); 166 167 ~CAppScrnshotPreview(); 168 }; 169 170 class CAppInfoDisplay : 171 public CUiWindow<CWindowImpl<CAppInfoDisplay>> 172 { 173 LPWSTR pLink = NULL; 174 175 private: 176 BOOL ProcessWindowMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT &theResult, DWORD dwMapId); 177 178 VOID ResizeChildren(); 179 180 VOID ResizeChildren(int Width, int Height); 181 182 VOID OnLink(ENLINK *Link); 183 184 public: 185 186 CAppRichEdit *RichEdit = NULL; 187 CAppScrnshotPreview *ScrnshotPrev = NULL; 188 189 static ATL::CWndClassInfo &GetWndClassInfo(); 190 191 HWND Create(HWND hwndParent); 192 193 BOOL ShowAvailableAppInfo(CAvailableApplicationInfo *Info); 194 BOOL ShowInstalledAppInfo(CInstalledApplicationInfo *Info); 195 196 VOID SetWelcomeText(); 197 198 VOID OnCommand(WPARAM wParam, LPARAM lParam); 199 200 ~CAppInfoDisplay(); 201 }; 202 203 class CAppsListView : 204 public CUiWindow<CWindowImpl<CAppsListView, CListView>> 205 { 206 struct SortContext 207 { 208 CAppsListView *lvw; 209 INT iSubItem; 210 }; 211 212 BOOL bIsAscending = TRUE; 213 BOOL bHasCheckboxes = FALSE; 214 215 INT ItemCount = 0; 216 INT CheckedItemCount = 0; 217 INT ColumnCount = 0; 218 219 INT nLastHeaderID = -1; 220 221 APPLICATION_VIEW_TYPE ApplicationViewType = AppViewTypeEmpty; 222 223 HIMAGELIST m_hImageListView = NULL; 224 CStringW m_Watermark; 225 226 BEGIN_MSG_MAP(CAppsListView) 227 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) 228 END_MSG_MAP() 229 230 231 LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); 232 233 public: 234 CAppsListView(); 235 ~CAppsListView(); 236 237 VOID SetWatermark(const CStringW& Text); 238 VOID SetCheckboxesVisible(BOOL bIsVisible); 239 240 VOID ColumnClick(LPNMLISTVIEW pnmv); 241 242 BOOL AddColumn(INT Index, ATL::CStringW &Text, INT Width, INT Format); 243 244 int AddColumn(INT Index, LPWSTR lpText, INT Width, INT Format); 245 246 void DeleteColumn(INT Index); 247 248 INT AddItem(INT ItemIndex, INT IconIndex, LPCWSTR lpText, LPARAM lParam); 249 250 HIMAGELIST GetImageList(int iImageList); 251 252 static INT CALLBACK s_CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); 253 254 INT CompareFunc(LPARAM lParam1, LPARAM lParam2, INT iSubItem); 255 256 HWND Create(HWND hwndParent); 257 258 BOOL GetCheckState(INT item); 259 260 VOID SetCheckState(INT item, BOOL fCheck); 261 262 VOID CheckAll(); 263 264 PVOID GetFocusedItemData(); 265 266 BOOL SetDisplayAppType(APPLICATION_VIEW_TYPE AppType); 267 268 BOOL SetViewMode(DWORD ViewMode); 269 270 BOOL AddInstalledApplication(CInstalledApplicationInfo *InstAppInfo, LPVOID CallbackParam); 271 272 BOOL AddAvailableApplication(CAvailableApplicationInfo *AvlbAppInfo, BOOL InitCheckState, LPVOID CallbackParam); 273 274 // this function is called when parent window receiving an notification about checkstate changing 275 VOID ItemCheckStateNotify(int iItem, BOOL bCheck); 276 }; 277 278 class CMainToolbar : 279 public CUiWindow< CToolbar<> > 280 { 281 const INT m_iToolbarHeight; 282 DWORD m_dButtonsWidthMax; 283 284 WCHAR szInstallBtn[MAX_STR_LEN]; 285 WCHAR szUninstallBtn[MAX_STR_LEN]; 286 WCHAR szModifyBtn[MAX_STR_LEN]; 287 WCHAR szSelectAll[MAX_STR_LEN]; 288 289 VOID AddImageToImageList(HIMAGELIST hImageList, UINT ImageIndex); 290 291 HIMAGELIST InitImageList(); 292 293 public: 294 295 CMainToolbar(); 296 297 VOID OnGetDispInfo(LPTOOLTIPTEXT lpttt); 298 299 HWND Create(HWND hwndParent); 300 301 VOID HideButtonCaption(); 302 303 VOID ShowButtonCaption(); 304 305 DWORD GetMaxButtonsWidth() const; 306 }; 307 308 class CSearchBar : 309 public CWindow 310 { 311 public: 312 const INT m_Width; 313 const INT m_Height; 314 315 CSearchBar(); 316 317 VOID SetText(LPCWSTR lpszText); 318 319 HWND Create(HWND hwndParent); 320 321 }; 322 323 class CComboBox : 324 public CWindow 325 { 326 // ID refers to different types of view 327 enum 328 { m_AppDisplayTypeDetails, m_AppDisplayTypeList, m_AppDisplayTypeTile }; 329 330 // string ID for different. this should correspond with the enum above. 331 const UINT m_TypeStringID[3] = 332 { IDS_APP_DISPLAY_DETAILS, IDS_APP_DISPLAY_LIST, IDS_APP_DISPLAY_TILE }; 333 334 const int m_DefaultSelectType = m_AppDisplayTypeDetails; 335 public: 336 337 int m_Width; 338 int m_Height; 339 340 CComboBox(); 341 342 HWND Create(HWND hwndParent); 343 }; 344 345 class CApplicationView : 346 public CUiWindow<CWindowImpl<CApplicationView>> 347 { 348 private: 349 CUiPanel *m_Panel = NULL; 350 CMainToolbar *m_Toolbar = NULL; 351 CUiWindow<CComboBox> *m_ComboBox = NULL; 352 CUiWindow<CSearchBar> *m_SearchBar = NULL; 353 CAppsListView *m_ListView = NULL; 354 CAppInfoDisplay *m_AppsInfo = NULL; 355 CUiSplitPanel *m_HSplitter = NULL; 356 CMainWindow *m_MainWindow = NULL; 357 APPLICATION_VIEW_TYPE ApplicationViewType = AppViewTypeEmpty; 358 359 BOOL ProcessWindowMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT &theResult, DWORD dwMapId); 360 361 BOOL CreateToolbar(); 362 BOOL CreateSearchBar(); 363 BOOL CreateComboBox(); 364 BOOL CreateHSplitter(); 365 BOOL CreateListView(); 366 BOOL CreateAppInfoDisplay(); 367 368 VOID OnSize(HWND hwnd, WPARAM wParam, LPARAM lParam); 369 VOID OnCommand(WPARAM wParam, LPARAM lParam); 370 public: 371 372 CApplicationView(CMainWindow *MainWindow); 373 ~CApplicationView(); 374 375 static ATL::CWndClassInfo &GetWndClassInfo(); 376 377 HWND Create(HWND hwndParent); 378 void SetRedraw(BOOL bRedraw); 379 void SetFocusOnSearchBar(); 380 BOOL SetDisplayAppType(APPLICATION_VIEW_TYPE AppType); 381 382 BOOL AddInstalledApplication(CInstalledApplicationInfo *InstAppInfo, LPVOID param); 383 BOOL AddAvailableApplication(CAvailableApplicationInfo *AvlbAppInfo, BOOL InitCheckState, LPVOID param); 384 VOID SetWatermark(const CStringW& Text); 385 386 387 void CheckAll(); 388 PVOID GetFocusedItemData(); 389 int GetItemCount(); 390 VOID AppendTabOrderWindow(int Direction, ATL::CSimpleArray<HWND> &TabOrderList); 391 392 // this function is called when a item of listview get focus. 393 // CallbackParam is the param passed to listview when adding the item (the one getting focus now). 394 BOOL ItemGetFocus(LPVOID CallbackParam); 395 396 // this function is called when a item of listview is checked/unchecked 397 // CallbackParam is the param passed to listview when adding the item (the one getting focus now). 398 BOOL ItemCheckStateChanged(BOOL bChecked, LPVOID CallbackParam); 399 400 }; 401