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 }; 93 94 int 95 ScrnshotDownloadCallback(pASYNCINET AsyncInet, ASYNC_EVENT Event, WPARAM wParam, LPARAM lParam, VOID *Extension); 96 97 class CAppScrnshotPreview : public CWindowImpl<CAppScrnshotPreview> 98 { 99 private: 100 CStringW m_BasePath; 101 SCRNSHOT_STATUS ScrnshotPrevStauts = SCRNSHOT_PREV_EMPTY; 102 Gdiplus::Image *pImage = NULL; 103 HICON hBrokenImgIcon = NULL; 104 BOOL bLoadingTimerOn = FALSE; 105 int LoadingAnimationFrame = 0; 106 int BrokenImgSize = BROKENIMG_ICON_SIZE; 107 pASYNCINET AsyncInet = NULL; 108 LONGLONG ContentID = 0; // used to determine whether image has been switched when download complete. Increase by 1 109 // each time the content of this window changed 110 CStringW TempImagePath; // currently displayed temp file 111 112 BOOL 113 ProcessWindowMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT &theResult, DWORD dwMapId); 114 115 VOID 116 DisplayLoading(); 117 VOID 118 DisplayFailed(); 119 BOOL 120 DisplayFile(LPCWSTR lpszFileName); 121 VOID 122 SetStatus(SCRNSHOT_STATUS Status); 123 124 VOID 125 PaintOnDC(HDC hdc, int width, int height, BOOL bDrawBkgnd); 126 float 127 GetLoadingDotWidth(int width, int height); 128 float 129 GetFrameDotShift(int Frame, int width, int height); 130 131 public: 132 static ATL::CWndClassInfo & 133 GetWndClassInfo(); 134 135 HWND 136 Create(HWND hParent); 137 VOID 138 PreviousDisplayCleanup(); 139 VOID 140 DisplayEmpty(); 141 BOOL 142 DisplayImage(LPCWSTR lpszLocation); 143 144 // calculate requested window width by given height 145 int 146 GetRequestedWidth(int Height); 147 148 CAppScrnshotPreview(const CStringW &BasePath); 149 ~CAppScrnshotPreview(); 150 }; 151 152 class CAppInfoDisplay : public CUiWindow<CWindowImpl<CAppInfoDisplay>> 153 { 154 LPWSTR pLink = NULL; 155 156 private: 157 BOOL 158 ProcessWindowMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT &theResult, DWORD dwMapId); 159 VOID 160 OnLink(ENLINK *Link); 161 162 VOID 163 ResizeChildren(); 164 VOID 165 ResizeChildren(int Width, int Height); 166 167 public: 168 CAppRichEdit *RichEdit = NULL; 169 CAppScrnshotPreview *ScrnshotPrev = NULL; 170 171 static ATL::CWndClassInfo & 172 GetWndClassInfo(); 173 174 HWND 175 Create(HWND hwndParent); 176 177 VOID 178 ShowAppInfo(CAppInfo *Info); 179 void 180 SetWelcomeText(bool bAppwiz); 181 VOID 182 OnCommand(WPARAM wParam, LPARAM lParam); 183 184 ~CAppInfoDisplay(); 185 }; 186 187 class CAppsListView : public CUiWindow<CWindowImpl<CAppsListView, CListView>> 188 { 189 struct SortContext 190 { 191 CAppsListView *lvw; 192 INT iSubItem; 193 }; 194 195 BOOL bIsAscending = TRUE; 196 bool bHasCheckboxes = false; 197 198 INT ItemCount = 0; 199 INT CheckedItemCount = 0; 200 INT ColumnCount = 0; 201 202 INT nLastHeaderID = -1; 203 204 APPLICATION_VIEW_TYPE ApplicationViewType = AppViewTypeAvailableApps; 205 206 HIMAGELIST m_hImageListView = NULL; 207 CStringW m_Watermark; 208 209 BEGIN_MSG_MAP(CAppsListView) 210 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) 211 MESSAGE_HANDLER(WM_RAPPSLIST_ASYNCICON, OnAsyncIcon) 212 END_MSG_MAP() 213 214 LRESULT 215 OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 216 LRESULT 217 OnAsyncIcon(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 218 219 public: 220 CAppsListView(); 221 ~CAppsListView(); 222 223 VOID 224 SetWatermark(const CStringW &Text); 225 226 void 227 ShowCheckboxes(bool bShow); 228 229 VOID 230 ColumnClick(LPNMLISTVIEW pnmv); 231 232 BOOL 233 AddColumn(INT Index, CStringW &Text, INT Width, INT Format); 234 void 235 DeleteColumn(INT Index); 236 237 INT 238 AddItem(INT ItemIndex, INT IconIndex, LPCWSTR lpText, LPARAM lParam); 239 240 HIMAGELIST 241 GetImageList(int iImageList); 242 243 static INT CALLBACK 244 s_CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); 245 246 INT 247 CompareFunc(LPARAM lParam1, LPARAM lParam2, INT iSubItem); 248 249 HWND 250 Create(HWND hwndParent); 251 252 BOOL 253 GetCheckState(INT item); 254 VOID 255 SetCheckState(INT item, BOOL fCheck); 256 VOID 257 CheckAll(); 258 259 PVOID 260 GetFocusedItemData(); 261 262 BOOL 263 SetDisplayAppType(APPLICATION_VIEW_TYPE AppType); 264 BOOL 265 SetViewMode(DWORD ViewMode); 266 267 BOOL 268 AddApplication(CAppInfo *AppInfo, BOOL InitialCheckState); 269 270 // this function is called when parent window receiving an notification about checkstate changing 271 VOID 272 ItemCheckStateNotify(int iItem, BOOL bCheck); 273 }; 274 275 class CMainToolbar : public CUiWindow<CToolbar<>> 276 { 277 const INT m_iToolbarHeight; 278 DWORD m_dButtonsWidthMax; 279 280 VOID 281 AddImageToImageList(HIMAGELIST hImageList, UINT ImageIndex); 282 283 HIMAGELIST 284 InitImageList(); 285 286 public: 287 CMainToolbar(); 288 289 VOID 290 OnGetDispInfo(LPTOOLTIPTEXT lpttt); 291 292 HWND 293 Create(HWND hwndParent); 294 295 void 296 ShowButtonCaption(bool bShow); 297 298 void 299 UpdateMaxButtonsWidth(); 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