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