[RAPPS] Fixes
[reactos.git] / reactos / base / applications / rapps / gui.cpp
1 /* PROJECT: ReactOS CE Applications Manager
2 * LICENSE: GPL - See COPYING in the top level directory
3 * AUTHORS: David Quintana <gigaherz@gmail.com>
4 * Alexander Shaposhnikov <chaez.san@gmail.com>
5 */
6
7 #include "rapps.h"
8
9 #include <shlobj_undoc.h>
10 #include <shlguid_undoc.h>
11
12 #include <atlbase.h>
13 #include <atlcom.h>
14 #include <atlwin.h>
15 #include <wininet.h>
16 #include <shellutils.h>
17
18 #include <rosctrls.h>
19
20 #include "rosui.h"
21 #include "crichedit.h"
22
23 #define SEARCH_TIMER_ID 'SR'
24
25 HWND hListView = NULL;
26
27 class CMainToolbar :
28 public CUiWindow< CToolbar<> >
29 {
30 #define TOOLBAR_HEIGHT 24
31
32 WCHAR szInstallBtn[MAX_STR_LEN];
33 WCHAR szUninstallBtn[MAX_STR_LEN];
34 WCHAR szModifyBtn[MAX_STR_LEN];
35
36 VOID AddImageToImageList(HIMAGELIST hImageList, UINT ImageIndex)
37 {
38 HICON hImage;
39
40 if (!(hImage = (HICON) LoadImage(hInst,
41 MAKEINTRESOURCE(ImageIndex),
42 IMAGE_ICON,
43 TOOLBAR_HEIGHT,
44 TOOLBAR_HEIGHT,
45 0)))
46 {
47 /* TODO: Error message */
48 }
49
50 ImageList_AddIcon(hImageList, hImage);
51 DeleteObject(hImage);
52 }
53
54 HIMAGELIST InitImageList(VOID)
55 {
56 HIMAGELIST hImageList;
57
58 /* Create the toolbar icon image list */
59 hImageList = ImageList_Create(TOOLBAR_HEIGHT,//GetSystemMetrics(SM_CXSMICON),
60 TOOLBAR_HEIGHT,//GetSystemMetrics(SM_CYSMICON),
61 ILC_MASK | GetSystemColorDepth(),
62 1,
63 1);
64 if (!hImageList)
65 {
66 /* TODO: Error message */
67 return NULL;
68 }
69
70 AddImageToImageList(hImageList, IDI_INSTALL);
71 AddImageToImageList(hImageList, IDI_UNINSTALL);
72 AddImageToImageList(hImageList, IDI_MODIFY);
73 AddImageToImageList(hImageList, IDI_REFRESH);
74 AddImageToImageList(hImageList, IDI_UPDATE_DB);
75 AddImageToImageList(hImageList, IDI_SETTINGS);
76 AddImageToImageList(hImageList, IDI_EXIT);
77
78 return hImageList;
79 }
80
81 public:
82 VOID OnGetDispInfo(LPTOOLTIPTEXT lpttt)
83 {
84 UINT idButton = (UINT) lpttt->hdr.idFrom;
85
86 switch (idButton)
87 {
88 case ID_EXIT:
89 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXIT);
90 break;
91
92 case ID_INSTALL:
93 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_INSTALL);
94 break;
95
96 case ID_UNINSTALL:
97 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_UNINSTALL);
98 break;
99
100 case ID_MODIFY:
101 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_MODIFY);
102 break;
103
104 case ID_SETTINGS:
105 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_SETTINGS);
106 break;
107
108 case ID_REFRESH:
109 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH);
110 break;
111
112 case ID_RESETDB:
113 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_UPDATE_DB);
114 break;
115 }
116 }
117
118 HWND Create(HWND hwndParent)
119 {
120 HIMAGELIST hImageList;
121
122 // buttons
123 static TBBUTTON Buttons[] =
124 { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
125 { 0, ID_INSTALL, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE, { 0 }, 0, (INT_PTR) szInstallBtn },
126 { 1, ID_UNINSTALL, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE, { 0 }, 0, (INT_PTR) szUninstallBtn },
127 { 2, ID_MODIFY, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE, { 0 }, 0, (INT_PTR) szModifyBtn },
128 { 5, 0, TBSTATE_ENABLED, BTNS_SEP, { 0 }, 0, 0 },
129 { 3, ID_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE, { 0 }, 0, 0 },
130 { 4, ID_RESETDB, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE, {0}, 0, 0},
131 { 5, 0, TBSTATE_ENABLED, BTNS_SEP, { 0 }, 0, 0 },
132 { 5, ID_SETTINGS, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE, { 0 }, 0, 0 },
133 { 6, ID_EXIT, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE, { 0 }, 0, 0 }
134 };
135
136 LoadStringW(hInst, IDS_INSTALL, szInstallBtn, _countof(szInstallBtn));
137 LoadStringW(hInst, IDS_UNINSTALL, szUninstallBtn, _countof(szUninstallBtn));
138 LoadStringW(hInst, IDS_MODIFY, szModifyBtn, _countof(szModifyBtn));
139
140 m_hWnd = CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL,
141 WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | TBSTYLE_LIST,
142 0, 0, 0, 0,
143 hwndParent,
144 0, hInst, NULL);
145
146 if (!m_hWnd)
147 {
148 /* TODO: Show error message */
149 return FALSE;
150 }
151
152 SendMessageW(TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_HIDECLIPPEDBUTTONS);
153 SetButtonStructSize();
154
155 hImageList = InitImageList();
156
157 if (!hImageList)
158 {
159 /* TODO: Show error message */
160 return FALSE;
161 }
162
163 ImageList_Destroy((HIMAGELIST) SetImageList(hImageList));
164
165 AddButtons(_countof(Buttons), Buttons);
166
167 return m_hWnd;
168 }
169 };
170
171 class CAppsListView :
172 public CUiWindow<CListView>
173 {
174 struct SortContext
175 {
176 CAppsListView * lvw;
177 int iSubItem;
178 };
179
180 public:
181 BOOL bAscending;
182
183 CAppsListView()
184 {
185 bAscending = TRUE;
186 }
187
188 VOID ColumnClick(LPNMLISTVIEW pnmv)
189 {
190 SortContext ctx = {this, pnmv->iSubItem};
191
192 SortItems(s_CompareFunc, &ctx);
193
194 bAscending = !bAscending;
195 }
196
197 PVOID GetLParam(INT Index)
198 {
199 INT ItemIndex;
200 LVITEM Item;
201
202 if (Index == -1)
203 {
204 ItemIndex = (INT) SendMessage(LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
205 if (ItemIndex == -1)
206 return NULL;
207 }
208 else
209 {
210 ItemIndex = Index;
211 }
212
213 ZeroMemory(&Item, sizeof(Item));
214
215 Item.mask = LVIF_PARAM;
216 Item.iItem = ItemIndex;
217 if (!GetItem(&Item))
218 return NULL;
219
220 return (PVOID) Item.lParam;
221 }
222
223 BOOL AddColumn(INT Index, ATL::CStringW& Text, INT Width, INT Format)
224 {
225 BOOL result = AddColumn(Index, Text.GetBuffer(), Width, Format);
226
227 return result;
228 }
229
230 BOOL AddColumn(INT Index, LPWSTR lpText, INT Width, INT Format)
231 {
232 LV_COLUMN Column;
233
234 ZeroMemory(&Column, sizeof(Column));
235
236 Column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
237 Column.iSubItem = Index;
238 Column.pszText = (LPTSTR) lpText;
239 Column.cx = Width;
240 Column.fmt = Format;
241
242 return (InsertColumn(Index, &Column) == -1) ? FALSE : TRUE;
243 }
244
245 INT AddItem(INT ItemIndex, INT IconIndex, LPWSTR lpText, LPARAM lParam)
246 {
247 LV_ITEMW Item;
248
249 ZeroMemory(&Item, sizeof(Item));
250
251 Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
252 Item.pszText = lpText;
253 Item.lParam = lParam;
254 Item.iItem = ItemIndex;
255 Item.iImage = IconIndex;
256
257 return InsertItem(&Item);
258 }
259
260 static INT CALLBACK s_CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
261 {
262 SortContext * ctx = ((SortContext*) lParamSort);
263 return ctx->lvw->CompareFunc(lParam1, lParam2, ctx->iSubItem);
264 }
265
266 INT CompareFunc(LPARAM lParam1, LPARAM lParam2, INT iSubItem)
267 {
268 ATL::CStringW Item1, Item2;
269 LVFINDINFO IndexInfo;
270 INT Index;
271
272 IndexInfo.flags = LVFI_PARAM;
273
274 IndexInfo.lParam = lParam1;
275 Index = FindItem(-1, &IndexInfo);
276 GetItemText(Index, iSubItem, Item1.GetBuffer(MAX_STR_LEN), MAX_STR_LEN);
277 Item1.ReleaseBuffer();
278
279 IndexInfo.lParam = lParam2;
280 Index = FindItem(-1, &IndexInfo);
281 GetItemText(Index, iSubItem, Item2.GetBuffer(MAX_STR_LEN), MAX_STR_LEN);
282 Item2.ReleaseBuffer();
283
284 if (bAscending)
285 return Item2 == Item1;
286 else
287 return Item1 == Item2;
288
289 return 0;
290 }
291
292 HWND Create(HWND hwndParent)
293 {
294 RECT r = {205, 28, 465, 250};
295 DWORD style = WS_CHILD | WS_VISIBLE | LVS_SORTASCENDING | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS;
296 HMENU menu = GetSubMenu(LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATIONMENU)), 0);
297
298 HWND hwnd = CListView::Create(hwndParent, r, NULL, style, WS_EX_CLIENTEDGE, menu);
299
300 if (hwnd)
301 SetExtendedListViewStyle(LVS_EX_FULLROWSELECT);
302
303 return hwnd;
304 }
305
306 };
307
308 class CSideTreeView :
309 public CUiWindow<CTreeView>
310 {
311 HIMAGELIST hImageTreeView = ImageList_Create(TREEVIEW_ICON_SIZE, TREEVIEW_ICON_SIZE,
312 GetSystemColorDepth() | ILC_MASK,
313 0, 1);
314
315 public:
316 HTREEITEM AddItem(HTREEITEM hParent, ATL::CStringW &Text, INT Image, INT SelectedImage, LPARAM lParam)
317 {
318 HTREEITEM result = CUiWindow<CTreeView>::AddItem(hParent, Text.GetBuffer(), Image, SelectedImage, lParam);
319 Text.ReleaseBuffer();
320 return result;
321 }
322
323 HTREEITEM AddCategory(HTREEITEM hRootItem, UINT TextIndex, UINT IconIndex)
324 {
325 ATL::CStringW szText;
326 INT Index;
327 HICON hIcon;
328
329 hIcon = (HICON) LoadImage(hInst,
330 MAKEINTRESOURCE(IconIndex),
331 IMAGE_ICON,
332 TREEVIEW_ICON_SIZE,
333 TREEVIEW_ICON_SIZE,
334 LR_CREATEDIBSECTION);
335 if (hIcon)
336 {
337 Index = ImageList_AddIcon(hImageTreeView, hIcon);
338 DestroyIcon(hIcon);
339 }
340
341 szText.LoadStringW(hInst, TextIndex);
342 return AddItem(hRootItem, szText, Index, Index, TextIndex);
343 }
344
345 HIMAGELIST SetImageList()
346 {
347 return CUiWindow<CTreeView>::SetImageList(hImageTreeView, TVSIL_NORMAL);
348 }
349
350 VOID DestroyImageList()
351 {
352 if (hImageTreeView)
353 ImageList_Destroy(hImageTreeView);
354 }
355
356 ~CSideTreeView()
357 {
358 DestroyImageList();
359 CUiWindow<CTreeView>::~CUiWindow();
360 }
361 };
362
363 class CSearchBar :
364 public CWindow
365 {
366 public:
367 VOID SetText(LPCWSTR lpszText)
368 {
369 SendMessage(SB_SETTEXT, SBT_NOBORDERS, (LPARAM) lpszText);
370 }
371
372 HWND Create(HWND hwndParent)
373 {
374 ATL::CStringW szBuf;
375 m_hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"Edit", NULL,
376 WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOHSCROLL,
377 0, 0, 200, 22,
378 hwndParent, (HMENU) NULL,
379 hInst, 0);
380
381 SendMessageW(WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
382 szBuf.LoadStringW(hInst, IDS_SEARCH_TEXT);
383 SetWindowTextW(szBuf);
384 return m_hWnd;
385 }
386
387 };
388
389 class CMainWindow :
390 public CWindowImpl<CMainWindow, CWindow, CFrameWinTraits>
391 {
392 CUiPanel * m_ClientPanel;
393 CUiSplitPanel * m_VSplitter;
394 CUiSplitPanel * m_HSplitter;
395
396 CMainToolbar * m_Toolbar;
397 CAppsListView * m_ListView;
398
399 CSideTreeView * m_TreeView;
400 CUiWindow<CStatusBar> * m_StatusBar;
401 CUiWindow<CRichEdit> * m_RichEdit;
402
403 CUiWindow<CSearchBar> * m_SearchBar;
404
405 LPWSTR pLink;
406
407 BOOL SearchEnabled;
408
409 public:
410 CMainWindow() :
411 m_ClientPanel(NULL),
412 pLink(NULL),
413 SearchEnabled(TRUE)
414 {
415 }
416
417 private:
418
419 VOID InitApplicationsList(VOID)
420 {
421 ATL::CStringW szText;
422
423 /* Add columns to ListView */
424 szText.LoadStringW(hInst, IDS_APP_NAME);
425 m_ListView->AddColumn(0, szText, 200, LVCFMT_LEFT);
426
427 szText.LoadStringW(hInst, IDS_APP_INST_VERSION);
428 m_ListView->AddColumn(1, szText, 90, LVCFMT_RIGHT);
429
430 szText.LoadStringW(hInst, IDS_APP_DESCRIPTION);
431 m_ListView->AddColumn(3, szText, 250, LVCFMT_LEFT);
432
433 UpdateApplicationsList(ENUM_ALL_COMPONENTS);
434 }
435
436 HTREEITEM AddCategory(HTREEITEM hRootItem, UINT TextIndex, UINT IconIndex)
437 {
438 return m_TreeView->AddCategory(hRootItem, TextIndex, IconIndex);
439 }
440
441 VOID InitCategoriesList(VOID)
442 {
443 HTREEITEM hRootItem;
444
445 hRootItem = AddCategory(TVI_ROOT, IDS_AVAILABLEFORINST, IDI_CATEGORY);
446 AddCategory(hRootItem, IDS_CAT_AUDIO, IDI_CAT_AUDIO);
447 AddCategory(hRootItem, IDS_CAT_VIDEO, IDI_CAT_VIDEO);
448 AddCategory(hRootItem, IDS_CAT_GRAPHICS, IDI_CAT_GRAPHICS);
449 AddCategory(hRootItem, IDS_CAT_GAMES, IDI_CAT_GAMES);
450 AddCategory(hRootItem, IDS_CAT_INTERNET, IDI_CAT_INTERNET);
451 AddCategory(hRootItem, IDS_CAT_OFFICE, IDI_CAT_OFFICE);
452 AddCategory(hRootItem, IDS_CAT_DEVEL, IDI_CAT_DEVEL);
453 AddCategory(hRootItem, IDS_CAT_EDU, IDI_CAT_EDU);
454 AddCategory(hRootItem, IDS_CAT_ENGINEER, IDI_CAT_ENGINEER);
455 AddCategory(hRootItem, IDS_CAT_FINANCE, IDI_CAT_FINANCE);
456 AddCategory(hRootItem, IDS_CAT_SCIENCE, IDI_CAT_SCIENCE);
457 AddCategory(hRootItem, IDS_CAT_TOOLS, IDI_CAT_TOOLS);
458 AddCategory(hRootItem, IDS_CAT_DRIVERS, IDI_CAT_DRIVERS);
459 AddCategory(hRootItem, IDS_CAT_LIBS, IDI_CAT_LIBS);
460 AddCategory(hRootItem, IDS_CAT_OTHER, IDI_CAT_OTHER);
461
462 m_TreeView->SetImageList();
463 m_TreeView->Expand(hRootItem, TVE_EXPAND);
464 m_TreeView->SelectItem(hRootItem);
465 }
466
467 BOOL CreateStatusBar()
468 {
469 m_StatusBar = new CUiWindow<CStatusBar>();
470 m_StatusBar->m_VerticalAlignment = UiAlign_RightBtm;
471 m_StatusBar->m_HorizontalAlignment = UiAlign_Stretch;
472 m_ClientPanel->Children().Append(m_StatusBar);
473
474 return m_StatusBar->Create(m_hWnd, (HMENU) IDC_STATUSBAR) != NULL;
475 }
476
477 BOOL CreateToolbar()
478 {
479 m_Toolbar = new CMainToolbar();
480 m_Toolbar->m_VerticalAlignment = UiAlign_LeftTop;
481 m_Toolbar->m_HorizontalAlignment = UiAlign_Stretch;
482 m_ClientPanel->Children().Append(m_Toolbar);
483
484 return m_Toolbar->Create(m_hWnd) != NULL;
485 }
486
487 BOOL CreateTreeView()
488 {
489 m_TreeView = new CSideTreeView();
490 m_TreeView->m_VerticalAlignment = UiAlign_Stretch;
491 m_TreeView->m_HorizontalAlignment = UiAlign_Stretch;
492 m_VSplitter->First().Append(m_TreeView);
493
494 return m_TreeView->Create(m_hWnd) != NULL;
495 }
496
497 BOOL CreateListView()
498 {
499 m_ListView = new CAppsListView();
500 m_ListView->m_VerticalAlignment = UiAlign_Stretch;
501 m_ListView->m_HorizontalAlignment = UiAlign_Stretch;
502 m_HSplitter->First().Append(m_ListView);
503
504 hListView = m_ListView->Create(m_hWnd);
505 return hListView != NULL;
506 }
507
508 BOOL CreateRichEdit()
509 {
510 m_RichEdit = new CUiWindow<CRichEdit>();
511 m_RichEdit->m_VerticalAlignment = UiAlign_Stretch;
512 m_RichEdit->m_HorizontalAlignment = UiAlign_Stretch;
513 m_HSplitter->Second().Append(m_RichEdit);
514
515 return m_RichEdit->Create(m_hWnd) != NULL;
516 }
517
518 BOOL CreateVSplitter()
519 {
520 m_VSplitter = new CUiSplitPanel();
521 m_VSplitter->m_VerticalAlignment = UiAlign_Stretch;
522 m_VSplitter->m_HorizontalAlignment = UiAlign_Stretch;
523 m_VSplitter->m_DynamicFirst = FALSE;
524 m_VSplitter->m_Horizontal = FALSE;
525 m_VSplitter->m_MinFirst = 240;
526 m_VSplitter->m_MinSecond = 300;
527 m_ClientPanel->Children().Append(m_VSplitter);
528
529 return m_VSplitter->Create(m_hWnd) != NULL;
530 }
531
532 BOOL CreateHSplitter()
533 {
534 m_HSplitter = new CUiSplitPanel();
535 m_HSplitter->m_VerticalAlignment = UiAlign_Stretch;
536 m_HSplitter->m_HorizontalAlignment = UiAlign_Stretch;
537 m_HSplitter->m_DynamicFirst = TRUE;
538 m_HSplitter->m_Horizontal = TRUE;
539 m_HSplitter->m_Pos = 32768;
540 m_HSplitter->m_MinFirst = 300;
541 m_HSplitter->m_MinSecond = 80;
542 m_VSplitter->Second().Append(m_HSplitter);
543
544 return m_HSplitter->Create(m_hWnd) != NULL;
545 }
546
547 BOOL CreateSearchBar(VOID)
548 {
549 m_SearchBar = new CUiWindow<CSearchBar>();
550 m_SearchBar->m_VerticalAlignment = UiAlign_LeftTop;
551 m_SearchBar->m_HorizontalAlignment = UiAlign_RightBtm;
552 m_SearchBar->m_Margin.top = 6;
553 m_SearchBar->m_Margin.right = 6;
554
555 return m_SearchBar->Create(m_Toolbar->m_hWnd) != NULL;
556 }
557
558 BOOL CreateLayout()
559 {
560 bool b = TRUE;
561
562 m_ClientPanel = new CUiPanel();
563 m_ClientPanel->m_VerticalAlignment = UiAlign_Stretch;
564 m_ClientPanel->m_HorizontalAlignment = UiAlign_Stretch;
565
566 // Top level
567 b = b && CreateStatusBar();
568 b = b && CreateToolbar();
569 b = b && CreateSearchBar();
570 b = b && CreateVSplitter();
571
572 // Inside V Splitter
573 b = b && CreateHSplitter();
574 b = b && CreateTreeView();
575
576 // Inside H Splitter
577 b = b && CreateListView();
578 b = b && CreateRichEdit();
579
580 if (b)
581 {
582 RECT rTop;
583 RECT rBottom;
584
585 /* Size status bar */
586 m_StatusBar->SendMessage(WM_SIZE, 0, 0);
587
588 /* Size tool bar */
589 m_Toolbar->AutoSize();
590
591 ::GetWindowRect(m_Toolbar->m_hWnd, &rTop);
592 ::GetWindowRect(m_StatusBar->m_hWnd, &rBottom);
593
594 m_VSplitter->m_Margin.top = rTop.bottom - rTop.top;
595 m_VSplitter->m_Margin.bottom = rBottom.bottom - rBottom.top;
596 }
597
598 return b;
599 }
600
601 BOOL InitControls()
602 {
603 if (CreateLayout())
604 {
605 ATL::CStringW szBuffer1, szBuffer2;
606
607 InitApplicationsList();
608
609 InitCategoriesList();
610
611 szBuffer2.LoadStringW(hInst, IDS_APPS_COUNT);
612 szBuffer1.Format(szBuffer2, m_ListView->GetItemCount());
613
614 m_StatusBar->SetText(szBuffer1);
615 return TRUE;
616 }
617
618 return FALSE;
619 }
620
621 VOID OnSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
622 {
623 /* Size status bar */
624 m_StatusBar->SendMessage(WM_SIZE, 0, 0);
625
626 /* Size tool bar */
627 m_Toolbar->AutoSize();
628
629
630 RECT r = {0, 0, LOWORD(lParam), HIWORD(lParam)};
631
632 HDWP hdwp = NULL;
633
634 int count = m_ClientPanel->CountSizableChildren();
635 hdwp = BeginDeferWindowPos(count);
636 if (hdwp) hdwp = m_ClientPanel->OnParentSize(r, hdwp);
637 if (hdwp) EndDeferWindowPos(hdwp);
638
639 // TODO: Sub-layouts for children of children
640 count = m_SearchBar->CountSizableChildren();
641 hdwp = BeginDeferWindowPos(count);
642 if (hdwp) hdwp = m_SearchBar->OnParentSize(r, hdwp);
643 if (hdwp) EndDeferWindowPos(hdwp);
644 }
645
646 BOOL ProcessWindowMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT& theResult, DWORD dwMapId)
647 {
648 theResult = 0;
649 switch (Msg)
650 {
651 case WM_CREATE:
652 if (!InitControls())
653 ::PostMessage(hwnd, WM_CLOSE, 0, 0);
654 break;
655
656 case WM_DESTROY:
657 {
658 ShowWindow(SW_HIDE);
659 SaveSettings(hwnd);
660
661 FreeLogs();
662
663 FreeCachedAvailableEntries();
664
665 if (IS_INSTALLED_ENUM(SelectedEnumType))
666 FreeInstalledAppList();
667
668 delete m_ClientPanel;
669
670 PostQuitMessage(0);
671 return 0;
672 }
673
674 case WM_COMMAND:
675 OnCommand(wParam, lParam);
676 break;
677
678 case WM_NOTIFY:
679 {
680 LPNMHDR data = (LPNMHDR) lParam;
681
682 switch (data->code)
683 {
684 case TVN_SELCHANGED:
685 {
686 if (data->hwndFrom == m_TreeView->m_hWnd)
687 {
688 switch (((LPNMTREEVIEW) lParam)->itemNew.lParam)
689 {
690 case IDS_INSTALLED:
691 UpdateApplicationsList(ENUM_ALL_COMPONENTS);
692 break;
693
694 case IDS_APPLICATIONS:
695 UpdateApplicationsList(ENUM_APPLICATIONS);
696 break;
697
698 case IDS_UPDATES:
699 UpdateApplicationsList(ENUM_UPDATES);
700 break;
701
702 case IDS_AVAILABLEFORINST:
703 UpdateApplicationsList(ENUM_ALL_AVAILABLE);
704 break;
705
706 case IDS_CAT_AUDIO:
707 UpdateApplicationsList(ENUM_CAT_AUDIO);
708 break;
709
710 case IDS_CAT_DEVEL:
711 UpdateApplicationsList(ENUM_CAT_DEVEL);
712 break;
713
714 case IDS_CAT_DRIVERS:
715 UpdateApplicationsList(ENUM_CAT_DRIVERS);
716 break;
717
718 case IDS_CAT_EDU:
719 UpdateApplicationsList(ENUM_CAT_EDU);
720 break;
721
722 case IDS_CAT_ENGINEER:
723 UpdateApplicationsList(ENUM_CAT_ENGINEER);
724 break;
725
726 case IDS_CAT_FINANCE:
727 UpdateApplicationsList(ENUM_CAT_FINANCE);
728 break;
729
730 case IDS_CAT_GAMES:
731 UpdateApplicationsList(ENUM_CAT_GAMES);
732 break;
733
734 case IDS_CAT_GRAPHICS:
735 UpdateApplicationsList(ENUM_CAT_GRAPHICS);
736 break;
737
738 case IDS_CAT_INTERNET:
739 UpdateApplicationsList(ENUM_CAT_INTERNET);
740 break;
741
742 case IDS_CAT_LIBS:
743 UpdateApplicationsList(ENUM_CAT_LIBS);
744 break;
745
746 case IDS_CAT_OFFICE:
747 UpdateApplicationsList(ENUM_CAT_OFFICE);
748 break;
749
750 case IDS_CAT_OTHER:
751 UpdateApplicationsList(ENUM_CAT_OTHER);
752 break;
753
754 case IDS_CAT_SCIENCE:
755 UpdateApplicationsList(ENUM_CAT_SCIENCE);
756 break;
757
758 case IDS_CAT_TOOLS:
759 UpdateApplicationsList(ENUM_CAT_TOOLS);
760 break;
761
762 case IDS_CAT_VIDEO:
763 UpdateApplicationsList(ENUM_CAT_VIDEO);
764 break;
765 }
766 }
767
768 HMENU mainMenu = ::GetMenu(hwnd);
769 HMENU lvwMenu = ::GetMenu(m_ListView->m_hWnd);
770
771 /* Disable/enable items based on treeview selection */
772 if (IsSelectedNodeInstalled())
773 {
774 EnableMenuItem(mainMenu, ID_REGREMOVE, MF_ENABLED);
775 EnableMenuItem(mainMenu, ID_INSTALL, MF_GRAYED);
776 EnableMenuItem(mainMenu, ID_UNINSTALL, MF_ENABLED);
777 EnableMenuItem(mainMenu, ID_MODIFY, MF_ENABLED);
778
779 EnableMenuItem(lvwMenu, ID_REGREMOVE, MF_ENABLED);
780 EnableMenuItem(lvwMenu, ID_INSTALL, MF_GRAYED);
781 EnableMenuItem(lvwMenu, ID_UNINSTALL, MF_ENABLED);
782 EnableMenuItem(lvwMenu, ID_MODIFY, MF_ENABLED);
783
784 m_Toolbar->SendMessage(TB_ENABLEBUTTON, ID_REGREMOVE, TRUE);
785 m_Toolbar->SendMessage(TB_ENABLEBUTTON, ID_INSTALL, FALSE);
786 m_Toolbar->SendMessage(TB_ENABLEBUTTON, ID_UNINSTALL, TRUE);
787 m_Toolbar->SendMessage(TB_ENABLEBUTTON, ID_MODIFY, TRUE);
788 }
789 else
790 {
791 EnableMenuItem(mainMenu, ID_REGREMOVE, MF_GRAYED);
792 EnableMenuItem(mainMenu, ID_INSTALL, MF_ENABLED);
793 EnableMenuItem(mainMenu, ID_UNINSTALL, MF_GRAYED);
794 EnableMenuItem(mainMenu, ID_MODIFY, MF_GRAYED);
795
796 EnableMenuItem(lvwMenu, ID_REGREMOVE, MF_GRAYED);
797 EnableMenuItem(lvwMenu, ID_INSTALL, MF_ENABLED);
798 EnableMenuItem(lvwMenu, ID_UNINSTALL, MF_GRAYED);
799 EnableMenuItem(lvwMenu, ID_MODIFY, MF_GRAYED);
800
801 m_Toolbar->SendMessage(TB_ENABLEBUTTON, ID_REGREMOVE, FALSE);
802 m_Toolbar->SendMessage(TB_ENABLEBUTTON, ID_INSTALL, TRUE);
803 m_Toolbar->SendMessage(TB_ENABLEBUTTON, ID_UNINSTALL, FALSE);
804 m_Toolbar->SendMessage(TB_ENABLEBUTTON, ID_MODIFY, FALSE);
805 }
806 }
807 break;
808
809 case LVN_ITEMCHANGED:
810 {
811 LPNMLISTVIEW pnic = (LPNMLISTVIEW) lParam;
812
813 if (pnic->hdr.hwndFrom == m_ListView->m_hWnd)
814 {
815 /* Check if this is a valid item
816 * (technically, it can be also an unselect) */
817 INT ItemIndex = pnic->iItem;
818 if (ItemIndex == -1 ||
819 ItemIndex >= ListView_GetItemCount(pnic->hdr.hwndFrom))
820 {
821 break;
822 }
823
824 /* Check if the focus has been moved to another item */
825 if ((pnic->uChanged & LVIF_STATE) &&
826 (pnic->uNewState & LVIS_FOCUSED) &&
827 !(pnic->uOldState & LVIS_FOCUSED))
828 {
829 if (IS_INSTALLED_ENUM(SelectedEnumType))
830 ShowInstalledAppInfo(ItemIndex);
831 if (IS_AVAILABLE_ENUM(SelectedEnumType))
832 ShowAvailableAppInfo(ItemIndex);
833 }
834 }
835 }
836 break;
837
838 case LVN_COLUMNCLICK:
839 {
840 LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
841
842 m_ListView->ColumnClick(pnmv);
843 }
844 break;
845
846 case NM_CLICK:
847 {
848 if (data->hwndFrom == m_ListView->m_hWnd && ((LPNMLISTVIEW) lParam)->iItem != -1)
849 {
850 if (IS_INSTALLED_ENUM(SelectedEnumType))
851 ShowInstalledAppInfo(-1);
852 if (IS_AVAILABLE_ENUM(SelectedEnumType))
853 ShowAvailableAppInfo(-1);
854 }
855 }
856 break;
857
858 case NM_DBLCLK:
859 {
860 if (data->hwndFrom == m_ListView->m_hWnd && ((LPNMLISTVIEW) lParam)->iItem != -1)
861 {
862 /* this won't do anything if the program is already installed */
863 SendMessage(hwnd, WM_COMMAND, ID_INSTALL, 0);
864 }
865 }
866 break;
867
868 case NM_RCLICK:
869 {
870 if (data->hwndFrom == m_ListView->m_hWnd && ((LPNMLISTVIEW) lParam)->iItem != -1)
871 {
872 ShowPopupMenu(m_ListView->m_hWnd, 0, ID_INSTALL);
873 }
874 }
875 break;
876
877 case EN_LINK:
878 OnLink((ENLINK*) lParam);
879 break;
880
881 case TTN_GETDISPINFO:
882 m_Toolbar->OnGetDispInfo((LPTOOLTIPTEXT) lParam);
883 break;
884 }
885 }
886 break;
887
888 case WM_SIZE:
889 OnSize(hwnd, wParam, lParam);
890 break;
891
892 case WM_SIZING:
893 {
894 LPRECT pRect = (LPRECT) lParam;
895
896 if (pRect->right - pRect->left < 565)
897 pRect->right = pRect->left + 565;
898
899 if (pRect->bottom - pRect->top < 300)
900 pRect->bottom = pRect->top + 300;
901
902 return TRUE;
903 }
904
905 case WM_SYSCOLORCHANGE:
906 {
907 /* Forward WM_SYSCOLORCHANGE to common controls */
908 m_ListView->SendMessage(WM_SYSCOLORCHANGE, 0, 0);
909 m_TreeView->SendMessage(WM_SYSCOLORCHANGE, 0, 0);
910 m_Toolbar->SendMessage(WM_SYSCOLORCHANGE, 0, 0);
911 m_ListView->SendMessage(EM_SETBKGNDCOLOR, 0, GetSysColor(COLOR_BTNFACE));
912 }
913 break;
914
915 case WM_TIMER:
916 if (wParam == SEARCH_TIMER_ID)
917 {
918 ::KillTimer(hwnd, SEARCH_TIMER_ID);
919 UpdateApplicationsList(-1);
920 }
921 break;
922 }
923
924 return FALSE;
925 }
926
927 virtual VOID OnLink(ENLINK *Link)
928 {
929 switch (Link->msg)
930 {
931 case WM_LBUTTONUP:
932 case WM_RBUTTONUP:
933 {
934 if (pLink) HeapFree(GetProcessHeap(), 0, pLink);
935
936 pLink = (LPWSTR) HeapAlloc(GetProcessHeap(), 0,
937 (max(Link->chrg.cpMin, Link->chrg.cpMax) -
938 min(Link->chrg.cpMin, Link->chrg.cpMax) + 1) * sizeof(WCHAR));
939 if (!pLink)
940 {
941 /* TODO: Error message */
942 return;
943 }
944
945 m_RichEdit->SendMessageW(EM_SETSEL, Link->chrg.cpMin, Link->chrg.cpMax);
946 m_RichEdit->SendMessageW(EM_GETSELTEXT, 0, (LPARAM) pLink);
947
948 ShowPopupMenu(m_RichEdit->m_hWnd, IDR_LINKMENU, -1);
949 }
950 break;
951 }
952 }
953
954 BOOL IsSelectedNodeInstalled(void)
955 {
956 HTREEITEM hSelectedItem = m_TreeView->GetSelection();
957 TV_ITEM tItem;
958
959 tItem.mask = TVIF_PARAM | TVIF_HANDLE;
960 tItem.hItem = hSelectedItem;
961 m_TreeView->GetItem(&tItem);
962 switch (tItem.lParam)
963 {
964 case IDS_INSTALLED:
965 case IDS_APPLICATIONS:
966 case IDS_UPDATES:
967 return TRUE;
968 default:
969 return FALSE;
970 }
971 }
972
973 VOID OnCommand(WPARAM wParam, LPARAM lParam)
974 {
975 WORD wCommand = LOWORD(wParam);
976
977 if (lParam == (LPARAM) m_SearchBar->m_hWnd)
978 {
979 ATL::CStringW szBuf;
980
981 switch (HIWORD(wParam))
982 {
983 case EN_SETFOCUS:
984 {
985 ATL::CStringW szWndText;
986
987 szBuf.LoadStringW(hInst, IDS_SEARCH_TEXT);
988 m_SearchBar->GetWindowTextW(szWndText);
989 if (szBuf == szWndText)
990 {
991 SearchEnabled = FALSE;
992 m_SearchBar->SetWindowTextW(L"");
993 }
994 }
995 break;
996
997 case EN_KILLFOCUS:
998 {
999 m_SearchBar->GetWindowTextW(szBuf);
1000 if (szBuf.IsEmpty())
1001 {
1002 szBuf.LoadStringW(hInst, IDS_SEARCH_TEXT);
1003 SearchEnabled = FALSE;
1004 m_SearchBar->SetWindowTextW(szBuf.GetString());
1005 }
1006 }
1007 break;
1008
1009 case EN_CHANGE:
1010 {
1011 ATL::CStringW szWndText;
1012
1013 if (!SearchEnabled)
1014 {
1015 SearchEnabled = TRUE;
1016 break;
1017 }
1018
1019 szBuf.LoadStringW(hInst, IDS_SEARCH_TEXT);
1020 m_SearchBar->GetWindowTextW(szWndText);
1021 if (szBuf == szWndText)
1022 {
1023 szSearchPattern.Empty();
1024 }
1025 else
1026 {
1027 szSearchPattern = szWndText;
1028 }
1029
1030 DWORD dwDelay;
1031 SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &dwDelay, 0);
1032 SetTimer(SEARCH_TIMER_ID, dwDelay);
1033 }
1034 break;
1035 }
1036
1037 return;
1038 }
1039
1040 switch (wCommand)
1041 {
1042 case ID_OPEN_LINK:
1043 ShellExecuteW(m_hWnd, L"open", pLink, NULL, NULL, SW_SHOWNOACTIVATE);
1044 HeapFree(GetProcessHeap(), 0, pLink);
1045 break;
1046
1047 case ID_COPY_LINK:
1048 CopyTextToClipboard(pLink);
1049 HeapFree(GetProcessHeap(), 0, pLink);
1050 break;
1051
1052 case ID_SETTINGS:
1053 CreateSettingsDlg(m_hWnd);
1054 break;
1055
1056 case ID_EXIT:
1057 PostMessageW(WM_CLOSE, 0, 0);
1058 break;
1059
1060 case ID_INSTALL:
1061 if (DownloadApplication(-1))
1062 /* TODO: Implement install dialog
1063 * if (InstallApplication(-1))
1064 */
1065 UpdateApplicationsList(-1);
1066 break;
1067
1068 case ID_UNINSTALL:
1069 if (UninstallApplication(-1, FALSE))
1070 UpdateApplicationsList(-1);
1071 break;
1072
1073 case ID_MODIFY:
1074 if (UninstallApplication(-1, TRUE))
1075 UpdateApplicationsList(-1);
1076 break;
1077
1078 case ID_REGREMOVE:
1079 RemoveAppFromRegistry(-1);
1080 break;
1081
1082 case ID_REFRESH:
1083 UpdateApplicationsList(-1);
1084 break;
1085
1086 case ID_RESETDB:
1087 UpdateAppsDB();
1088 UpdateApplicationsList(-1);
1089 break;
1090
1091 case ID_HELP:
1092 MessageBoxW(L"Help not implemented yet", NULL, MB_OK);
1093 break;
1094
1095 case ID_ABOUT:
1096 ShowAboutDialog();
1097 break;
1098 }
1099 }
1100
1101 VOID FreeInstalledAppList(VOID)
1102 {
1103 INT Count = ListView_GetItemCount(hListView) - 1;
1104 PINSTALLED_INFO Info;
1105
1106 while (Count >= 0)
1107 {
1108 Info = (PINSTALLED_INFO) ListViewGetlParam(Count);
1109 if (Info)
1110 {
1111 RegCloseKey(Info->hSubKey);
1112 delete Info;
1113 }
1114 Count--;
1115 }
1116 }
1117
1118 static BOOL SearchPatternMatch(PCWSTR szHaystack, PCWSTR szNeedle)
1119 {
1120 if (!*szNeedle)
1121 return TRUE;
1122 /* TODO: Improve pattern search beyond a simple case-insensitive substring search. */
1123 return StrStrIW(szHaystack, szNeedle) != NULL;
1124 }
1125
1126 static BOOL CALLBACK s_EnumInstalledAppProc(INT ItemIndex, LPWSTR lpName, PINSTALLED_INFO Info)
1127 {
1128 PINSTALLED_INFO ItemInfo;
1129 ATL::CStringW szText;
1130 INT Index;
1131
1132 if (!SearchPatternMatch(lpName, szSearchPattern))
1133 {
1134 RegCloseKey(Info->hSubKey);
1135 return TRUE;
1136 }
1137
1138 ItemInfo = (PINSTALLED_INFO) HeapAlloc(GetProcessHeap(), 0, sizeof(INSTALLED_INFO));
1139 if (!ItemInfo)
1140 {
1141 RegCloseKey(Info->hSubKey);
1142 return FALSE;
1143 }
1144
1145 RtlCopyMemory(ItemInfo, Info, sizeof(INSTALLED_INFO));
1146
1147 Index = ListViewAddItem(ItemIndex, 0, lpName, (LPARAM) ItemInfo);
1148
1149 /* Get version info */
1150 GetApplicationString(ItemInfo->hSubKey, L"DisplayVersion", szText);
1151 ListView_SetItemText(hListView, Index, 1, szText.GetBuffer());
1152 szText.ReleaseBuffer();
1153
1154 /* Get comments */
1155 GetApplicationString(ItemInfo->hSubKey, L"Comments", szText);
1156 ListView_SetItemText(hListView, Index, 2, szText.GetBuffer());
1157 szText.ReleaseBuffer();
1158 return TRUE;
1159 }
1160
1161 static BOOL CALLBACK s_EnumAvailableAppProc(PAPPLICATION_INFO Info)
1162 {
1163 INT Index;
1164 HICON hIcon = NULL;
1165 ATL::CStringW szIconPath;
1166 HIMAGELIST hImageListView = ListView_GetImageList(hListView, LVSIL_SMALL);
1167
1168 if (!SearchPatternMatch(Info->szName, szSearchPattern) &&
1169 !SearchPatternMatch(Info->szDesc, szSearchPattern))
1170 {
1171 return TRUE;
1172 }
1173
1174 if (GetStorageDirectory(szIconPath))
1175 {
1176 /* Load icon from file */
1177 szIconPath += L"\\rapps\\icons\\" + Info->szName + L".ico";
1178 hIcon = (HICON) LoadImageW(NULL,
1179 szIconPath.GetString(),
1180 IMAGE_ICON,
1181 LISTVIEW_ICON_SIZE,
1182 LISTVIEW_ICON_SIZE,
1183 LR_LOADFROMFILE);
1184 }
1185
1186 if (!hIcon)
1187 {
1188 /* Load default icon */
1189 hIcon = (HICON) LoadIcon(hInst, MAKEINTRESOURCEW(IDI_MAIN));
1190 }
1191 Index = ImageList_AddIcon(hImageListView, hIcon);
1192 DestroyIcon(hIcon);
1193
1194 Index = ListViewAddItem(Info->Category, Index, Info->szName, (LPARAM) Info);
1195 hImageListView = ListView_SetImageList(hListView, hImageListView, LVSIL_SMALL);
1196
1197 ListView_SetItemText(hListView, Index, 1, Info->szVersion.GetBuffer());
1198 Info->szVersion.ReleaseBuffer();
1199
1200 ListView_SetItemText(hListView, Index, 2, Info->szDesc.GetBuffer());
1201 Info->szDesc.ReleaseBuffer();
1202 return TRUE;
1203 }
1204
1205
1206 VOID UpdateApplicationsList(INT EnumType)
1207 {
1208 ATL::CStringW szBuffer1, szBuffer2;
1209 HIMAGELIST hImageListView = NULL;
1210
1211 m_ListView->SendMessage(WM_SETREDRAW, FALSE, 0);
1212
1213 if (EnumType < 0) EnumType = SelectedEnumType;
1214
1215 if (IS_INSTALLED_ENUM(SelectedEnumType))
1216 FreeInstalledAppList();
1217
1218 (VOID) ListView_DeleteAllItems(hListView);
1219 /* Create new ImageList */
1220 hImageListView = ImageList_Create(LISTVIEW_ICON_SIZE,
1221 LISTVIEW_ICON_SIZE,
1222 GetSystemColorDepth() | ILC_MASK,
1223 0, 1);
1224 hImageListView = ListView_SetImageList(hListView, hImageListView, LVSIL_SMALL);
1225
1226 if (hImageListView)
1227 ImageList_Destroy(hImageListView);
1228
1229 if (IS_AVAILABLE_ENUM(EnumType))
1230 {
1231 /* Enum available applications */
1232 EnumAvailableApplications(EnumType, s_EnumAvailableAppProc);
1233 }
1234
1235 SelectedEnumType = EnumType;
1236
1237 szBuffer2.LoadStringW(hInst, IDS_APPS_COUNT);
1238 szBuffer1.Format(szBuffer2, ListView_GetItemCount(hListView));
1239 SetStatusBarText(szBuffer1);
1240
1241 SetWelcomeText();
1242
1243 /* set automatic column width for program names if the list is not empty */
1244 if (ListView_GetItemCount(hListView) > 0)
1245 ListView_SetColumnWidth(hListView, 0, LVSCW_AUTOSIZE);
1246
1247 SendMessage(hListView, WM_SETREDRAW, TRUE, 0);
1248 }
1249
1250 public:
1251 static ATL::CWndClassInfo& GetWndClassInfo()
1252 {
1253 DWORD csStyle = CS_VREDRAW | CS_HREDRAW;
1254 static ATL::CWndClassInfo wc =
1255 {
1256 { sizeof(WNDCLASSEX), csStyle, StartWindowProc,
1257 0, 0, NULL,
1258 LoadIcon(_AtlBaseModule.GetModuleInstance(), MAKEINTRESOURCE(IDI_MAIN)),
1259 LoadCursor(NULL, IDC_ARROW),
1260 (HBRUSH) (COLOR_BTNFACE + 1), MAKEINTRESOURCE(IDR_MAINMENU),
1261 L"RAppsWnd", NULL },
1262 NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
1263 };
1264 return wc;
1265 }
1266
1267 HWND Create()
1268 {
1269 ATL::CStringW szWindowName;
1270 szWindowName.LoadStringW(hInst, IDS_APPTITLE);
1271
1272 RECT r = {
1273 (SettingsInfo.bSaveWndPos ? SettingsInfo.Left : CW_USEDEFAULT),
1274 (SettingsInfo.bSaveWndPos ? SettingsInfo.Top : CW_USEDEFAULT),
1275 (SettingsInfo.bSaveWndPos ? SettingsInfo.Width : 680),
1276 (SettingsInfo.bSaveWndPos ? SettingsInfo.Height : 450)
1277 };
1278 r.right += r.left;
1279 r.bottom += r.top;
1280
1281 return CWindowImpl::Create(NULL, r, szWindowName.GetString(), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_WINDOWEDGE);
1282 }
1283
1284 CStatusBar * GetStatusBar()
1285 {
1286 return m_StatusBar;
1287 }
1288
1289 CAppsListView * GetListView()
1290 {
1291 return m_ListView;
1292 }
1293
1294 CRichEdit * GetRichEdit()
1295 {
1296 return m_RichEdit;
1297 }
1298 };
1299
1300 CMainWindow * g_MainWindow;
1301
1302 HWND CreateMainWindow()
1303 {
1304 g_MainWindow = new CMainWindow();
1305 return g_MainWindow->Create();
1306 }
1307
1308 DWORD_PTR ListViewGetlParam(INT item)
1309 {
1310 if (item < 0)
1311 {
1312 item = g_MainWindow->GetListView()->GetSelectionMark();
1313 }
1314 return g_MainWindow->GetListView()->GetItemData(item);
1315 }
1316
1317 VOID SetStatusBarText(LPCWSTR szText)
1318 {
1319 g_MainWindow->GetStatusBar()->SetText(szText);
1320 }
1321
1322 INT ListViewAddItem(INT ItemIndex, INT IconIndex, LPWSTR lpName, LPARAM lParam)
1323 {
1324 return g_MainWindow->GetListView()->AddItem(ItemIndex, IconIndex, lpName, lParam);
1325 }
1326
1327 VOID NewRichEditText(LPCWSTR szText, DWORD flags)
1328 {
1329 g_MainWindow->GetRichEdit()->SetText(szText, flags);
1330 }
1331
1332 VOID InsertRichEditText(LPCWSTR szText, DWORD flags)
1333 {
1334 g_MainWindow->GetRichEdit()->InsertText(szText, flags);
1335 }
1336
1337 /* ATL version of functions */
1338 VOID SetStatusBarText(const ATL::CStringW& szText)
1339 {
1340 SetStatusBarText(szText.GetString());
1341 }
1342
1343 INT ListViewAddItem(INT ItemIndex, INT IconIndex, ATL::CStringW & Name, LPARAM lParam)
1344 {
1345 INT result = ListViewAddItem(ItemIndex, IconIndex, Name.GetBuffer(), lParam);
1346 Name.ReleaseBuffer();
1347 return result;
1348 }
1349
1350 VOID NewRichEditText(const ATL::CStringW& szText, DWORD flags)
1351 {
1352 NewRichEditText(szText.GetString(), flags);
1353 }
1354
1355 VOID InsertRichEditText(const ATL::CStringW& szText, DWORD flags)
1356 {
1357 InsertRichEditText(szText.GetString(), flags);
1358 }
1359