[RAPPS] More code improvements
[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) LoadImageW(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 LVFINDINFOW 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 SendMessageW(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 RECT r = {0, 0, LOWORD(lParam), HIWORD(lParam)};
630 HDWP hdwp = NULL;
631 int count = m_ClientPanel->CountSizableChildren();
632
633 hdwp = BeginDeferWindowPos(count);
634 if (hdwp)
635 {
636 hdwp = m_ClientPanel->OnParentSize(r, hdwp);
637 }
638 if (hdwp)
639 {
640 EndDeferWindowPos(hdwp);
641 }
642
643 // TODO: Sub-layouts for children of children
644 count = m_SearchBar->CountSizableChildren();
645 hdwp = BeginDeferWindowPos(count);
646 if (hdwp)
647 {
648 hdwp = m_SearchBar->OnParentSize(r, hdwp);
649 }
650 if (hdwp)
651 {
652 EndDeferWindowPos(hdwp);
653 }
654 }
655
656 BOOL ProcessWindowMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT& theResult, DWORD dwMapId)
657 {
658 theResult = 0;
659 switch (Msg)
660 {
661 case WM_CREATE:
662 if (!InitControls())
663 ::PostMessage(hwnd, WM_CLOSE, 0, 0);
664 break;
665
666 case WM_DESTROY:
667 {
668 ShowWindow(SW_HIDE);
669 SaveSettings(hwnd);
670
671 FreeLogs();
672
673 FreeCachedAvailableEntries();
674
675 if (IS_INSTALLED_ENUM(SelectedEnumType))
676 FreeInstalledAppList();
677
678 delete m_ClientPanel;
679
680 PostQuitMessage(0);
681 return 0;
682 }
683
684 case WM_COMMAND:
685 OnCommand(wParam, lParam);
686 break;
687
688 case WM_NOTIFY:
689 {
690 LPNMHDR data = (LPNMHDR) lParam;
691
692 switch (data->code)
693 {
694 case TVN_SELCHANGED:
695 {
696 if (data->hwndFrom == m_TreeView->m_hWnd)
697 {
698 switch (((LPNMTREEVIEW) lParam)->itemNew.lParam)
699 {
700 case IDS_INSTALLED:
701 UpdateApplicationsList(ENUM_ALL_COMPONENTS);
702 break;
703
704 case IDS_APPLICATIONS:
705 UpdateApplicationsList(ENUM_APPLICATIONS);
706 break;
707
708 case IDS_UPDATES:
709 UpdateApplicationsList(ENUM_UPDATES);
710 break;
711
712 case IDS_AVAILABLEFORINST:
713 UpdateApplicationsList(ENUM_ALL_AVAILABLE);
714 break;
715
716 case IDS_CAT_AUDIO:
717 UpdateApplicationsList(ENUM_CAT_AUDIO);
718 break;
719
720 case IDS_CAT_DEVEL:
721 UpdateApplicationsList(ENUM_CAT_DEVEL);
722 break;
723
724 case IDS_CAT_DRIVERS:
725 UpdateApplicationsList(ENUM_CAT_DRIVERS);
726 break;
727
728 case IDS_CAT_EDU:
729 UpdateApplicationsList(ENUM_CAT_EDU);
730 break;
731
732 case IDS_CAT_ENGINEER:
733 UpdateApplicationsList(ENUM_CAT_ENGINEER);
734 break;
735
736 case IDS_CAT_FINANCE:
737 UpdateApplicationsList(ENUM_CAT_FINANCE);
738 break;
739
740 case IDS_CAT_GAMES:
741 UpdateApplicationsList(ENUM_CAT_GAMES);
742 break;
743
744 case IDS_CAT_GRAPHICS:
745 UpdateApplicationsList(ENUM_CAT_GRAPHICS);
746 break;
747
748 case IDS_CAT_INTERNET:
749 UpdateApplicationsList(ENUM_CAT_INTERNET);
750 break;
751
752 case IDS_CAT_LIBS:
753 UpdateApplicationsList(ENUM_CAT_LIBS);
754 break;
755
756 case IDS_CAT_OFFICE:
757 UpdateApplicationsList(ENUM_CAT_OFFICE);
758 break;
759
760 case IDS_CAT_OTHER:
761 UpdateApplicationsList(ENUM_CAT_OTHER);
762 break;
763
764 case IDS_CAT_SCIENCE:
765 UpdateApplicationsList(ENUM_CAT_SCIENCE);
766 break;
767
768 case IDS_CAT_TOOLS:
769 UpdateApplicationsList(ENUM_CAT_TOOLS);
770 break;
771
772 case IDS_CAT_VIDEO:
773 UpdateApplicationsList(ENUM_CAT_VIDEO);
774 break;
775 }
776 }
777
778 HMENU mainMenu = ::GetMenu(hwnd);
779 HMENU lvwMenu = ::GetMenu(m_ListView->m_hWnd);
780
781 /* Disable/enable items based on treeview selection */
782 if (IsSelectedNodeInstalled())
783 {
784 EnableMenuItem(mainMenu, ID_REGREMOVE, MF_ENABLED);
785 EnableMenuItem(mainMenu, ID_INSTALL, MF_GRAYED);
786 EnableMenuItem(mainMenu, ID_UNINSTALL, MF_ENABLED);
787 EnableMenuItem(mainMenu, ID_MODIFY, MF_ENABLED);
788
789 EnableMenuItem(lvwMenu, ID_REGREMOVE, MF_ENABLED);
790 EnableMenuItem(lvwMenu, ID_INSTALL, MF_GRAYED);
791 EnableMenuItem(lvwMenu, ID_UNINSTALL, MF_ENABLED);
792 EnableMenuItem(lvwMenu, ID_MODIFY, MF_ENABLED);
793
794 m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_REGREMOVE, TRUE);
795 m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_INSTALL, FALSE);
796 m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_UNINSTALL, TRUE);
797 m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_MODIFY, TRUE);
798 }
799 else
800 {
801 EnableMenuItem(mainMenu, ID_REGREMOVE, MF_GRAYED);
802 EnableMenuItem(mainMenu, ID_INSTALL, MF_ENABLED);
803 EnableMenuItem(mainMenu, ID_UNINSTALL, MF_GRAYED);
804 EnableMenuItem(mainMenu, ID_MODIFY, MF_GRAYED);
805
806 EnableMenuItem(lvwMenu, ID_REGREMOVE, MF_GRAYED);
807 EnableMenuItem(lvwMenu, ID_INSTALL, MF_ENABLED);
808 EnableMenuItem(lvwMenu, ID_UNINSTALL, MF_GRAYED);
809 EnableMenuItem(lvwMenu, ID_MODIFY, MF_GRAYED);
810
811 m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_REGREMOVE, FALSE);
812 m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_INSTALL, TRUE);
813 m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_UNINSTALL, FALSE);
814 m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_MODIFY, FALSE);
815 }
816 }
817 break;
818
819 case LVN_ITEMCHANGED:
820 {
821 LPNMLISTVIEW pnic = (LPNMLISTVIEW) lParam;
822
823 if (pnic->hdr.hwndFrom == m_ListView->m_hWnd)
824 {
825 /* Check if this is a valid item
826 * (technically, it can be also an unselect) */
827 INT ItemIndex = pnic->iItem;
828 if (ItemIndex == -1 ||
829 ItemIndex >= ListView_GetItemCount(pnic->hdr.hwndFrom))
830 {
831 break;
832 }
833
834 /* Check if the focus has been moved to another item */
835 if ((pnic->uChanged & LVIF_STATE) &&
836 (pnic->uNewState & LVIS_FOCUSED) &&
837 !(pnic->uOldState & LVIS_FOCUSED))
838 {
839 if (IS_INSTALLED_ENUM(SelectedEnumType))
840 ShowInstalledAppInfo(ItemIndex);
841 if (IS_AVAILABLE_ENUM(SelectedEnumType))
842 ShowAvailableAppInfo(ItemIndex);
843 }
844 }
845 }
846 break;
847
848 case LVN_COLUMNCLICK:
849 {
850 LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
851
852 m_ListView->ColumnClick(pnmv);
853 }
854 break;
855
856 case NM_CLICK:
857 {
858 if (data->hwndFrom == m_ListView->m_hWnd && ((LPNMLISTVIEW) lParam)->iItem != -1)
859 {
860 if (IS_INSTALLED_ENUM(SelectedEnumType))
861 ShowInstalledAppInfo(-1);
862 if (IS_AVAILABLE_ENUM(SelectedEnumType))
863 ShowAvailableAppInfo(-1);
864 }
865 }
866 break;
867
868 case NM_DBLCLK:
869 {
870 if (data->hwndFrom == m_ListView->m_hWnd && ((LPNMLISTVIEW) lParam)->iItem != -1)
871 {
872 /* this won't do anything if the program is already installed */
873 SendMessage(hwnd, WM_COMMAND, ID_INSTALL, 0);
874 }
875 }
876 break;
877
878 case NM_RCLICK:
879 {
880 if (data->hwndFrom == m_ListView->m_hWnd && ((LPNMLISTVIEW) lParam)->iItem != -1)
881 {
882 ShowPopupMenu(m_ListView->m_hWnd, 0, ID_INSTALL);
883 }
884 }
885 break;
886
887 case EN_LINK:
888 OnLink((ENLINK*) lParam);
889 break;
890
891 case TTN_GETDISPINFO:
892 m_Toolbar->OnGetDispInfo((LPTOOLTIPTEXT) lParam);
893 break;
894 }
895 }
896 break;
897
898 case WM_SIZE:
899 OnSize(hwnd, wParam, lParam);
900 break;
901
902 case WM_SIZING:
903 {
904 LPRECT pRect = (LPRECT) lParam;
905
906 if (pRect->right - pRect->left < 565)
907 pRect->right = pRect->left + 565;
908
909 if (pRect->bottom - pRect->top < 300)
910 pRect->bottom = pRect->top + 300;
911
912 return TRUE;
913 }
914
915 case WM_SYSCOLORCHANGE:
916 {
917 /* Forward WM_SYSCOLORCHANGE to common controls */
918 m_ListView->SendMessageW(WM_SYSCOLORCHANGE, 0, 0);
919 m_TreeView->SendMessageW(WM_SYSCOLORCHANGE, 0, 0);
920 m_Toolbar->SendMessageW(WM_SYSCOLORCHANGE, 0, 0);
921 m_ListView->SendMessageW(EM_SETBKGNDCOLOR, 0, GetSysColor(COLOR_BTNFACE));
922 }
923 break;
924
925 case WM_TIMER:
926 if (wParam == SEARCH_TIMER_ID)
927 {
928 ::KillTimer(hwnd, SEARCH_TIMER_ID);
929 UpdateApplicationsList(-1);
930 }
931 break;
932 }
933
934 return FALSE;
935 }
936
937 virtual VOID OnLink(ENLINK *Link)
938 {
939 switch (Link->msg)
940 {
941 case WM_LBUTTONUP:
942 case WM_RBUTTONUP:
943 {
944 if (pLink) HeapFree(GetProcessHeap(), 0, pLink);
945
946 pLink = (LPWSTR) HeapAlloc(GetProcessHeap(), 0,
947 (max(Link->chrg.cpMin, Link->chrg.cpMax) -
948 min(Link->chrg.cpMin, Link->chrg.cpMax) + 1) * sizeof(WCHAR));
949 if (!pLink)
950 {
951 /* TODO: Error message */
952 return;
953 }
954
955 m_RichEdit->SendMessageW(EM_SETSEL, Link->chrg.cpMin, Link->chrg.cpMax);
956 m_RichEdit->SendMessageW(EM_GETSELTEXT, 0, (LPARAM) pLink);
957
958 ShowPopupMenu(m_RichEdit->m_hWnd, IDR_LINKMENU, -1);
959 }
960 break;
961 }
962 }
963
964 BOOL IsSelectedNodeInstalled(void)
965 {
966 HTREEITEM hSelectedItem = m_TreeView->GetSelection();
967 TV_ITEM tItem;
968
969 tItem.mask = TVIF_PARAM | TVIF_HANDLE;
970 tItem.hItem = hSelectedItem;
971 m_TreeView->GetItem(&tItem);
972 switch (tItem.lParam)
973 {
974 case IDS_INSTALLED:
975 case IDS_APPLICATIONS:
976 case IDS_UPDATES:
977 return TRUE;
978 default:
979 return FALSE;
980 }
981 }
982
983 VOID OnCommand(WPARAM wParam, LPARAM lParam)
984 {
985 WORD wCommand = LOWORD(wParam);
986
987 if (lParam == (LPARAM) m_SearchBar->m_hWnd)
988 {
989 ATL::CStringW szBuf;
990
991 switch (HIWORD(wParam))
992 {
993 case EN_SETFOCUS:
994 {
995 ATL::CStringW szWndText;
996
997 szBuf.LoadStringW(hInst, IDS_SEARCH_TEXT);
998 m_SearchBar->GetWindowTextW(szWndText);
999 if (szBuf == szWndText)
1000 {
1001 SearchEnabled = FALSE;
1002 m_SearchBar->SetWindowTextW(L"");
1003 }
1004 }
1005 break;
1006
1007 case EN_KILLFOCUS:
1008 {
1009 m_SearchBar->GetWindowTextW(szBuf);
1010 if (szBuf.IsEmpty())
1011 {
1012 szBuf.LoadStringW(hInst, IDS_SEARCH_TEXT);
1013 SearchEnabled = FALSE;
1014 m_SearchBar->SetWindowTextW(szBuf.GetString());
1015 }
1016 }
1017 break;
1018
1019 case EN_CHANGE:
1020 {
1021 ATL::CStringW szWndText;
1022
1023 if (!SearchEnabled)
1024 {
1025 SearchEnabled = TRUE;
1026 break;
1027 }
1028
1029 szBuf.LoadStringW(hInst, IDS_SEARCH_TEXT);
1030 m_SearchBar->GetWindowTextW(szWndText);
1031 if (szBuf == szWndText)
1032 {
1033 szSearchPattern.Empty();
1034 }
1035 else
1036 {
1037 szSearchPattern = szWndText;
1038 }
1039
1040 DWORD dwDelay;
1041 SystemParametersInfoW(SPI_GETMENUSHOWDELAY, 0, &dwDelay, 0);
1042 SetTimer(SEARCH_TIMER_ID, dwDelay);
1043 }
1044 break;
1045 }
1046
1047 return;
1048 }
1049
1050 switch (wCommand)
1051 {
1052 case ID_OPEN_LINK:
1053 ShellExecuteW(m_hWnd, L"open", pLink, NULL, NULL, SW_SHOWNOACTIVATE);
1054 HeapFree(GetProcessHeap(), 0, pLink);
1055 break;
1056
1057 case ID_COPY_LINK:
1058 CopyTextToClipboard(pLink);
1059 HeapFree(GetProcessHeap(), 0, pLink);
1060 break;
1061
1062 case ID_SETTINGS:
1063 CreateSettingsDlg(m_hWnd);
1064 break;
1065
1066 case ID_EXIT:
1067 PostMessageW(WM_CLOSE, 0, 0);
1068 break;
1069
1070 case ID_INSTALL:
1071 if (DownloadApplication(-1))
1072 /* TODO: Implement install dialog
1073 * if (InstallApplication(-1))
1074 */
1075 UpdateApplicationsList(-1);
1076 break;
1077
1078 case ID_UNINSTALL:
1079 if (UninstallApplication(-1, FALSE))
1080 UpdateApplicationsList(-1);
1081 break;
1082
1083 case ID_MODIFY:
1084 if (UninstallApplication(-1, TRUE))
1085 UpdateApplicationsList(-1);
1086 break;
1087
1088 case ID_REGREMOVE:
1089 RemoveAppFromRegistry(-1);
1090 break;
1091
1092 case ID_REFRESH:
1093 UpdateApplicationsList(-1);
1094 break;
1095
1096 case ID_RESETDB:
1097 UpdateAppsDB();
1098 UpdateApplicationsList(-1);
1099 break;
1100
1101 case ID_HELP:
1102 MessageBoxW(L"Help not implemented yet", NULL, MB_OK);
1103 break;
1104
1105 case ID_ABOUT:
1106 ShowAboutDialog();
1107 break;
1108 }
1109 }
1110
1111 VOID FreeInstalledAppList(VOID)
1112 {
1113 INT Count = ListView_GetItemCount(hListView) - 1;
1114 PINSTALLED_INFO Info;
1115
1116 while (Count >= 0)
1117 {
1118 Info = (PINSTALLED_INFO) ListViewGetlParam(Count);
1119 if (Info)
1120 {
1121 RegCloseKey(Info->hSubKey);
1122 delete Info;
1123 }
1124 Count--;
1125 }
1126 }
1127
1128 static BOOL SearchPatternMatch(PCWSTR szHaystack, PCWSTR szNeedle)
1129 {
1130 if (!*szNeedle)
1131 return TRUE;
1132 /* TODO: Improve pattern search beyond a simple case-insensitive substring search. */
1133 return StrStrIW(szHaystack, szNeedle) != NULL;
1134 }
1135
1136 static BOOL CALLBACK s_EnumInstalledAppProc(INT ItemIndex, LPWSTR lpName, PINSTALLED_INFO Info)
1137 {
1138 PINSTALLED_INFO ItemInfo;
1139 ATL::CStringW szText;
1140 INT Index;
1141
1142 if (!SearchPatternMatch(lpName, szSearchPattern))
1143 {
1144 RegCloseKey(Info->hSubKey);
1145 return TRUE;
1146 }
1147
1148 ItemInfo = (PINSTALLED_INFO) HeapAlloc(GetProcessHeap(), 0, sizeof(INSTALLED_INFO));
1149 if (!ItemInfo)
1150 {
1151 RegCloseKey(Info->hSubKey);
1152 return FALSE;
1153 }
1154
1155 RtlCopyMemory(ItemInfo, Info, sizeof(INSTALLED_INFO));
1156
1157 Index = ListViewAddItem(ItemIndex, 0, lpName, (LPARAM) ItemInfo);
1158
1159 /* Get version info */
1160 GetApplicationString(ItemInfo->hSubKey, L"DisplayVersion", szText);
1161 ListView_SetItemText(hListView, Index, 1, szText.GetBuffer());
1162 szText.ReleaseBuffer();
1163
1164 /* Get comments */
1165 GetApplicationString(ItemInfo->hSubKey, L"Comments", szText);
1166 ListView_SetItemText(hListView, Index, 2, szText.GetBuffer());
1167 szText.ReleaseBuffer();
1168 return TRUE;
1169 }
1170
1171 static BOOL CALLBACK s_EnumAvailableAppProc(PAPPLICATION_INFO Info)
1172 {
1173 INT Index;
1174 HICON hIcon = NULL;
1175 ATL::CStringW szIconPath;
1176 HIMAGELIST hImageListView = ListView_GetImageList(hListView, LVSIL_SMALL);
1177
1178 if (!SearchPatternMatch(Info->szName, szSearchPattern) &&
1179 !SearchPatternMatch(Info->szDesc, szSearchPattern))
1180 {
1181 return TRUE;
1182 }
1183
1184 if (GetStorageDirectory(szIconPath))
1185 {
1186 /* Load icon from file */
1187 szIconPath += L"\\rapps\\icons\\" + Info->szName + L".ico";
1188 hIcon = (HICON) LoadImageW(NULL,
1189 szIconPath.GetString(),
1190 IMAGE_ICON,
1191 LISTVIEW_ICON_SIZE,
1192 LISTVIEW_ICON_SIZE,
1193 LR_LOADFROMFILE);
1194 }
1195
1196 if (!hIcon)
1197 {
1198 /* Load default icon */
1199 hIcon = (HICON) LoadIconW(hInst, MAKEINTRESOURCEW(IDI_MAIN));
1200 }
1201 Index = ImageList_AddIcon(hImageListView, hIcon);
1202 DestroyIcon(hIcon);
1203
1204 Index = ListViewAddItem(Info->Category, Index, Info->szName, (LPARAM) Info);
1205 hImageListView = ListView_SetImageList(hListView, hImageListView, LVSIL_SMALL);
1206
1207 ListView_SetItemText(hListView, Index, 1, Info->szVersion.GetBuffer());
1208 Info->szVersion.ReleaseBuffer();
1209
1210 ListView_SetItemText(hListView, Index, 2, Info->szDesc.GetBuffer());
1211 Info->szDesc.ReleaseBuffer();
1212 return TRUE;
1213 }
1214
1215
1216 VOID UpdateApplicationsList(INT EnumType)
1217 {
1218 ATL::CStringW szBuffer1, szBuffer2;
1219 HIMAGELIST hImageListView = NULL;
1220
1221 m_ListView->SendMessageW(WM_SETREDRAW, FALSE, 0);
1222
1223 if (EnumType < 0) EnumType = SelectedEnumType;
1224
1225 if (IS_INSTALLED_ENUM(SelectedEnumType))
1226 FreeInstalledAppList();
1227
1228 (VOID) ListView_DeleteAllItems(hListView);
1229 /* Create new ImageList */
1230 hImageListView = ImageList_Create(LISTVIEW_ICON_SIZE,
1231 LISTVIEW_ICON_SIZE,
1232 GetSystemColorDepth() | ILC_MASK,
1233 0, 1);
1234 hImageListView = ListView_SetImageList(hListView, hImageListView, LVSIL_SMALL);
1235
1236 if (hImageListView)
1237 ImageList_Destroy(hImageListView);
1238
1239 if (IS_AVAILABLE_ENUM(EnumType))
1240 {
1241 /* Enum available applications */
1242 EnumAvailableApplications(EnumType, s_EnumAvailableAppProc);
1243 }
1244
1245 SelectedEnumType = EnumType;
1246
1247 szBuffer2.LoadStringW(hInst, IDS_APPS_COUNT);
1248 szBuffer1.Format(szBuffer2, ListView_GetItemCount(hListView));
1249 SetStatusBarText(szBuffer1);
1250
1251 SetWelcomeText();
1252
1253 /* set automatic column width for program names if the list is not empty */
1254 if (ListView_GetItemCount(hListView) > 0)
1255 ListView_SetColumnWidth(hListView, 0, LVSCW_AUTOSIZE);
1256
1257 SendMessageW(hListView, WM_SETREDRAW, TRUE, 0);
1258 }
1259
1260 public:
1261 static ATL::CWndClassInfo& GetWndClassInfo()
1262 {
1263 DWORD csStyle = CS_VREDRAW | CS_HREDRAW;
1264 static ATL::CWndClassInfo wc =
1265 {
1266 {
1267 sizeof(WNDCLASSEX),
1268 csStyle,
1269 StartWindowProc,
1270 0,
1271 0,
1272 NULL,
1273 LoadIconW(_AtlBaseModule.GetModuleInstance(), MAKEINTRESOURCEW(IDI_MAIN)),
1274 LoadCursorW(NULL, IDC_ARROW),
1275 (HBRUSH) (COLOR_BTNFACE + 1),
1276 MAKEINTRESOURCEW(IDR_MAINMENU),
1277 L"RAppsWnd",
1278 NULL
1279 },
1280 NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
1281 };
1282 return wc;
1283 }
1284
1285 HWND Create()
1286 {
1287 ATL::CStringW szWindowName;
1288 szWindowName.LoadStringW(hInst, IDS_APPTITLE);
1289
1290 RECT r = {
1291 (SettingsInfo.bSaveWndPos ? SettingsInfo.Left : CW_USEDEFAULT),
1292 (SettingsInfo.bSaveWndPos ? SettingsInfo.Top : CW_USEDEFAULT),
1293 (SettingsInfo.bSaveWndPos ? SettingsInfo.Width : 680),
1294 (SettingsInfo.bSaveWndPos ? SettingsInfo.Height : 450)
1295 };
1296 r.right += r.left;
1297 r.bottom += r.top;
1298
1299 return CWindowImpl::Create(NULL, r, szWindowName.GetString(), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_WINDOWEDGE);
1300 }
1301
1302 CStatusBar * GetStatusBar()
1303 {
1304 return m_StatusBar;
1305 }
1306
1307 CAppsListView * GetListView()
1308 {
1309 return m_ListView;
1310 }
1311
1312 CRichEdit * GetRichEdit()
1313 {
1314 return m_RichEdit;
1315 }
1316 };
1317
1318 CMainWindow * g_MainWindow;
1319
1320 HWND CreateMainWindow()
1321 {
1322 g_MainWindow = new CMainWindow();
1323 return g_MainWindow->Create();
1324 }
1325
1326 DWORD_PTR ListViewGetlParam(INT item)
1327 {
1328 if (item < 0)
1329 {
1330 item = g_MainWindow->GetListView()->GetSelectionMark();
1331 }
1332 return g_MainWindow->GetListView()->GetItemData(item);
1333 }
1334
1335 VOID SetStatusBarText(LPCWSTR szText)
1336 {
1337 g_MainWindow->GetStatusBar()->SetText(szText);
1338 }
1339
1340 INT ListViewAddItem(INT ItemIndex, INT IconIndex, LPWSTR lpName, LPARAM lParam)
1341 {
1342 return g_MainWindow->GetListView()->AddItem(ItemIndex, IconIndex, lpName, lParam);
1343 }
1344
1345 VOID NewRichEditText(LPCWSTR szText, DWORD flags)
1346 {
1347 g_MainWindow->GetRichEdit()->SetText(szText, flags);
1348 }
1349
1350 VOID InsertRichEditText(LPCWSTR szText, DWORD flags)
1351 {
1352 g_MainWindow->GetRichEdit()->InsertText(szText, flags);
1353 }
1354
1355 /* ATL version of functions */
1356 VOID SetStatusBarText(const ATL::CStringW& szText)
1357 {
1358 SetStatusBarText(szText.GetString());
1359 }
1360
1361 INT ListViewAddItem(INT ItemIndex, INT IconIndex, ATL::CStringW & Name, LPARAM lParam)
1362 {
1363 INT result = ListViewAddItem(ItemIndex, IconIndex, Name.GetBuffer(), lParam);
1364 Name.ReleaseBuffer();
1365 return result;
1366 }
1367
1368 VOID NewRichEditText(const ATL::CStringW& szText, DWORD flags)
1369 {
1370 NewRichEditText(szText.GetString(), flags);
1371 }
1372
1373 VOID InsertRichEditText(const ATL::CStringW& szText, DWORD flags)
1374 {
1375 InsertRichEditText(szText.GetString(), flags);
1376 }
1377