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 22 #define LISTVIEW_ICON_SIZE 32 23 24 // default broken-image icon size 25 #define BROKENIMG_ICON_SIZE 96 26 27 // the boundary of w/h ratio of scrnshot preview window 28 #define SCRNSHOT_MAX_ASPECT_RAT 2.5 29 30 // padding between scrnshot preview and richedit (in pixel) 31 #define INFO_DISPLAY_PADDING 10 32 33 // minimum width of richedit 34 #define RICHEDIT_MIN_WIDTH 160 35 36 // padding between controls in toolbar 37 #define TOOLBAR_PADDING 6 38 39 // user-defined window message 40 #define WM_RAPPS_DOWNLOAD_COMPLETE \ 41 (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 #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 END_MSG_MAP() 214 215 LRESULT 216 OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 217 218 public: 219 CAppsListView(); 220 ~CAppsListView(); 221 222 VOID 223 SetWatermark(const CStringW &Text); 224 VOID 225 SetCheckboxesVisible(BOOL bIsVisible); 226 227 VOID 228 ColumnClick(LPNMLISTVIEW pnmv); 229 230 BOOL 231 AddColumn(INT Index, CStringW &Text, INT Width, INT Format); 232 void 233 DeleteColumn(INT Index); 234 235 INT 236 AddItem(INT ItemIndex, INT IconIndex, LPCWSTR lpText, LPARAM lParam); 237 238 HIMAGELIST 239 GetImageList(int iImageList); 240 241 static INT CALLBACK 242 s_CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); 243 244 INT 245 CompareFunc(LPARAM lParam1, LPARAM lParam2, INT iSubItem); 246 247 HWND 248 Create(HWND hwndParent); 249 250 BOOL 251 GetCheckState(INT item); 252 VOID 253 SetCheckState(INT item, BOOL fCheck); 254 VOID 255 CheckAll(); 256 257 PVOID 258 GetFocusedItemData(); 259 260 BOOL 261 SetDisplayAppType(APPLICATION_VIEW_TYPE AppType); 262 BOOL 263 SetViewMode(DWORD ViewMode); 264 265 BOOL 266 AddApplication(CAppInfo *AppInfo, BOOL InitialCheckState); 267 268 // this function is called when parent window receiving an notification about checkstate changing 269 VOID 270 ItemCheckStateNotify(int iItem, BOOL bCheck); 271 }; 272 273 class CMainToolbar : public CUiWindow<CToolbar<>> 274 { 275 const INT m_iToolbarHeight; 276 DWORD m_dButtonsWidthMax; 277 278 WCHAR szInstallBtn[MAX_STR_LEN]; 279 WCHAR szUninstallBtn[MAX_STR_LEN]; 280 WCHAR szModifyBtn[MAX_STR_LEN]; 281 WCHAR szSelectAll[MAX_STR_LEN]; 282 WCHAR szRefreshBtn[MAX_STR_LEN]; 283 WCHAR szUpdateDbBtn[MAX_STR_LEN]; 284 285 VOID 286 AddImageToImageList(HIMAGELIST hImageList, UINT ImageIndex); 287 288 HIMAGELIST 289 InitImageList(); 290 291 public: 292 CMainToolbar(); 293 294 VOID 295 OnGetDispInfo(LPTOOLTIPTEXT lpttt); 296 297 HWND 298 Create(HWND hwndParent); 299 300 VOID 301 HideButtonCaption(); 302 VOID 303 ShowButtonCaption(); 304 305 DWORD 306 GetMaxButtonsWidth() const; 307 }; 308 309 class CSearchBar : public CWindow 310 { 311 public: 312 const INT m_Width; 313 const INT m_Height; 314 315 CSearchBar(); 316 317 VOID 318 SetText(LPCWSTR lpszText); 319 320 HWND 321 Create(HWND hwndParent); 322 }; 323 324 class CComboBox : public CWindow 325 { 326 // ID refers to different types of view 327 enum 328 { 329 m_AppDisplayTypeDetails, 330 m_AppDisplayTypeList, 331 m_AppDisplayTypeTile 332 }; 333 334 // string ID for different. this should correspond with the enum above. 335 const UINT m_TypeStringID[3] = {IDS_APP_DISPLAY_DETAILS, IDS_APP_DISPLAY_LIST, IDS_APP_DISPLAY_TILE}; 336 337 const int m_DefaultSelectType = m_AppDisplayTypeDetails; 338 339 public: 340 int m_Width; 341 int m_Height; 342 343 CComboBox(); 344 345 HWND 346 Create(HWND hwndParent); 347 }; 348 349 class CApplicationView : public CUiWindow<CWindowImpl<CApplicationView>> 350 { 351 private: 352 CUiPanel *m_Panel = NULL; 353 CMainToolbar *m_Toolbar = NULL; 354 CUiWindow<CComboBox> *m_ComboBox = NULL; 355 CUiWindow<CSearchBar> *m_SearchBar = NULL; 356 CAppsListView *m_ListView = NULL; 357 CAppInfoDisplay *m_AppsInfo = NULL; 358 CUiSplitPanel *m_HSplitter = NULL; 359 CMainWindow *m_MainWindow = NULL; 360 APPLICATION_VIEW_TYPE ApplicationViewType = AppViewTypeAvailableApps; 361 362 BOOL 363 ProcessWindowMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT &theResult, DWORD dwMapId); 364 365 BOOL 366 CreateToolbar(); 367 BOOL 368 CreateSearchBar(); 369 BOOL 370 CreateComboBox(); 371 BOOL 372 CreateHSplitter(); 373 BOOL 374 CreateListView(); 375 BOOL 376 CreateAppInfoDisplay(); 377 378 VOID 379 OnSize(HWND hwnd, WPARAM wParam, LPARAM lParam); 380 VOID 381 OnCommand(WPARAM wParam, LPARAM lParam); 382 383 public: 384 CApplicationView(CMainWindow *MainWindow); 385 ~CApplicationView(); 386 387 static ATL::CWndClassInfo & 388 GetWndClassInfo(); 389 390 HWND 391 Create(HWND hwndParent); 392 void 393 SetRedraw(BOOL bRedraw); 394 void 395 SetFocusOnSearchBar(); 396 BOOL 397 SetDisplayAppType(APPLICATION_VIEW_TYPE AppType); 398 399 BOOL 400 AddApplication(CAppInfo *InstAppInfo, BOOL InitialCheckState); 401 VOID 402 SetWatermark(const CStringW &Text); 403 404 void 405 CheckAll(); 406 PVOID 407 GetFocusedItemData(); 408 int 409 GetItemCount(); 410 VOID 411 AppendTabOrderWindow(int Direction, ATL::CSimpleArray<HWND> &TabOrderList); 412 413 // this function is called when a item of listview get focus. 414 // CallbackParam is the param passed to listview when adding the item (the one getting focus now). 415 VOID 416 ItemGetFocus(LPVOID CallbackParam); 417 418 // this function is called when a item of listview is checked/unchecked 419 // CallbackParam is the param passed to listview when adding the item (the one getting focus now). 420 VOID 421 ItemCheckStateChanged(BOOL bChecked, LPVOID CallbackParam); 422 }; 423