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 <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 
195     BOOL ShowInstalledAppInfo(CInstalledApplicationInfo *Info);
196 
197     VOID SetWelcomeText();
198 
199     VOID OnCommand(WPARAM wParam, LPARAM lParam);
200 
201     ~CAppInfoDisplay();
202 };
203 
204 class CAppsListView :
205     public CUiWindow<CListView>
206 {
207     struct SortContext
208     {
209         CAppsListView *lvw;
210         INT iSubItem;
211     };
212 
213     BOOL bIsAscending = TRUE;
214     BOOL bHasCheckboxes;
215 
216     INT ItemCount = 0;
217     INT CheckedItemCount = 0;
218     INT ColumnCount = 0;
219 
220     INT nLastHeaderID;
221 
222     APPLICATION_VIEW_TYPE ApplicationViewType = AppViewTypeEmpty;
223 
224     HIMAGELIST m_hImageListView;
225 
226 public:
227     CAppsListView();
228 
229     VOID SetCheckboxesVisible(BOOL bIsVisible);
230 
231     VOID ColumnClick(LPNMLISTVIEW pnmv);
232 
233     BOOL AddColumn(INT Index, ATL::CStringW &Text, INT Width, INT Format);
234 
235     int AddColumn(INT Index, LPWSTR lpText, INT Width, INT Format);
236 
237     void DeleteColumn(INT Index);
238 
239     INT AddItem(INT ItemIndex, INT IconIndex, LPCWSTR lpText, LPARAM lParam);
240 
241     HIMAGELIST GetImageList(int iImageList);
242 
243     static INT CALLBACK s_CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
244 
245     INT CompareFunc(LPARAM lParam1, LPARAM lParam2, INT iSubItem);
246 
247     HWND Create(HWND hwndParent);
248 
249     BOOL GetCheckState(INT item);
250 
251     VOID SetCheckState(INT item, BOOL fCheck);
252 
253     VOID CheckAll();
254 
255     PVOID GetFocusedItemData();
256 
257     BOOL SetDisplayAppType(APPLICATION_VIEW_TYPE AppType);
258 
259     BOOL SetViewMode(DWORD ViewMode);
260 
261     BOOL AddInstalledApplication(CInstalledApplicationInfo *InstAppInfo, LPVOID CallbackParam);
262 
263     BOOL AddAvailableApplication(CAvailableApplicationInfo *AvlbAppInfo, BOOL InitCheckState, LPVOID CallbackParam);
264 
265     // this function is called when parent window receiving an notification about checkstate changing
266     VOID ItemCheckStateNotify(int iItem, BOOL bCheck);
267 };
268 
269 class CMainToolbar :
270     public CUiWindow< CToolbar<> >
271 {
272     const INT m_iToolbarHeight;
273     DWORD m_dButtonsWidthMax;
274 
275     WCHAR szInstallBtn[MAX_STR_LEN];
276     WCHAR szUninstallBtn[MAX_STR_LEN];
277     WCHAR szModifyBtn[MAX_STR_LEN];
278     WCHAR szSelectAll[MAX_STR_LEN];
279 
280     VOID AddImageToImageList(HIMAGELIST hImageList, UINT ImageIndex);
281 
282     HIMAGELIST InitImageList();
283 
284 public:
285 
286     CMainToolbar();
287 
288     VOID OnGetDispInfo(LPTOOLTIPTEXT lpttt);
289 
290     HWND Create(HWND hwndParent);
291 
292     VOID HideButtonCaption();
293 
294     VOID ShowButtonCaption();
295 
296     DWORD GetMaxButtonsWidth() const;
297 };
298 
299 class CSearchBar :
300     public CWindow
301 {
302 public:
303     const INT m_Width;
304     const INT m_Height;
305 
306     CSearchBar();
307 
308     VOID SetText(LPCWSTR lpszText);
309 
310     HWND Create(HWND hwndParent);
311 
312 };
313 
314 class CComboBox :
315     public CWindow
316 {
317     // ID refers to different types of view
318     enum
319     { m_AppDisplayTypeDetails, m_AppDisplayTypeList, m_AppDisplayTypeTile };
320 
321     // string ID for different. this should correspond with the enum above.
322     const UINT m_TypeStringID[3] =
323     { IDS_APP_DISPLAY_DETAILS, IDS_APP_DISPLAY_LIST, IDS_APP_DISPLAY_TILE };
324 
325     const int m_DefaultSelectType = m_AppDisplayTypeDetails;
326 public:
327 
328     int m_Width;
329     int m_Height;
330 
331     CComboBox();
332 
333     HWND Create(HWND hwndParent);
334 };
335 
336 class CApplicationView :
337     public CUiWindow<CWindowImpl<CApplicationView>>
338 {
339 private:
340     CUiPanel *m_Panel = NULL;
341     CMainToolbar *m_Toolbar = NULL;
342     CUiWindow<CComboBox> *m_ComboBox = NULL;
343     CUiWindow<CSearchBar> *m_SearchBar = NULL;
344     CAppsListView *m_ListView = NULL;
345     CAppInfoDisplay *m_AppsInfo = NULL;
346     CUiSplitPanel *m_HSplitter = NULL;
347     CMainWindow *m_MainWindow = NULL;
348     APPLICATION_VIEW_TYPE ApplicationViewType = AppViewTypeEmpty;
349 
350     BOOL ProcessWindowMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT &theResult, DWORD dwMapId);
351 
352     BOOL CreateToolbar();
353 
354     BOOL CreateSearchBar();
355 
356     BOOL CreateComboBox();
357 
358     BOOL CreateHSplitter();
359 
360     BOOL CreateListView();
361 
362     BOOL CreateAppInfoDisplay();
363 
364     VOID OnSize(HWND hwnd, WPARAM wParam, LPARAM lParam);
365 
366     VOID OnCommand(WPARAM wParam, LPARAM lParam);
367 public:
368 
369     CApplicationView(CMainWindow *MainWindow);
370 
371     ~CApplicationView();
372 
373     static ATL::CWndClassInfo &GetWndClassInfo();
374 
375     HWND Create(HWND hwndParent);
376 
377     BOOL SetDisplayAppType(APPLICATION_VIEW_TYPE AppType);
378 
379     BOOL AddInstalledApplication(CInstalledApplicationInfo *InstAppInfo, LPVOID param);
380 
381     BOOL AddAvailableApplication(CAvailableApplicationInfo *AvlbAppInfo, BOOL InitCheckState, LPVOID param);
382 
383     void CheckAll();
384 
385     PVOID GetFocusedItemData();
386 
387     int GetItemCount();
388 
389     VOID AppendTabOrderWindow(int Direction, ATL::CSimpleArray<HWND> &TabOrderList);
390 
391     // this function is called when a item of listview get focus.
392     // CallbackParam is the param passed to listview when adding the item (the one getting focus now).
393     BOOL ItemGetFocus(LPVOID CallbackParam);
394 
395     // this function is called when a item of listview is checked/unchecked
396     // CallbackParam is the param passed to listview when adding the item (the one getting focus now).
397     BOOL ItemCheckStateChanged(BOOL bChecked, LPVOID CallbackParam);
398 
399 };
400