Files
reactos/reactos/base/applications/rapps/gui.cpp
T
Alexander Shaposhnikov e3fdbe5806 [RAPPS] Bulk install!
- Added ListView class
- Added ListView to a dialog
  Dialog shows the install progress of individual apps. It also waits for an installator to finish before issuing another download-install cycle.
- Fixed: Downloads pointing to "\"
- Fixed: Selection data is not retrieved correctly
- Yet again replacing some macros to wide functions
- Minor improvements

svn path=/branches/GSoC_2017/rapps/; revision=75433
2017-07-28 22:37:24 +00:00

1599 lines
47 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* PROJECT: ReactOS CE Applications Manager
* LICENSE: GPL - See COPYING in the top level directory
* AUTHORS: David Quintana <[email protected]>
* Alexander Shaposhnikov <[email protected]>
*/
#include "rapps.h"
#include <shlobj_undoc.h>
#include <shlguid_undoc.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include <wininet.h>
#include <shellutils.h>
#include <rosctrls.h>
#include "rosui.h"
#include "crichedit.h"
#define SEARCH_TIMER_ID 'SR'
HWND hListView = NULL;
class CAvailableAppView
{
static inline VOID InsertTextAfterLoaded_RichEdit(UINT uStringID,
const ATL::CStringW& szText,
DWORD StringFlags,
DWORD TextFlags)
{
ATL::CStringW szLoadedText;
if (!szText.IsEmpty() && szLoadedText.LoadStringW(hInst, uStringID))
{
InsertRichEditText(szLoadedText, StringFlags);
InsertRichEditText(szText, TextFlags);
}
}
static inline VOID InsertLoadedTextNewl_RichEdit(UINT uStringID,
DWORD StringFlags)
{
ATL::CStringW szLoadedText;
if (szLoadedText.LoadStringW(hInst, uStringID))
{
InsertRichEditText(L"\n", 0);
InsertRichEditText(szLoadedText, StringFlags);
InsertRichEditText(L"\n", 0);
}
}
static VOID InsertVersionInfo_RichEdit(CAvailableApplicationInfo* Info)
{
if (Info->IsInstalled())
{
if (Info->HasInstalledVersion())
{
if (Info->HasUpdate())
InsertLoadedTextNewl_RichEdit(IDS_STATUS_UPDATE_AVAILABLE, CFE_ITALIC);
else
InsertLoadedTextNewl_RichEdit(IDS_STATUS_INSTALLED, CFE_ITALIC);
InsertTextAfterLoaded_RichEdit(IDS_AINFO_VERSION, Info->szInstalledVersion, CFE_BOLD, 0);
}
else
{
InsertLoadedTextNewl_RichEdit(IDS_STATUS_INSTALLED, CFE_ITALIC);
}
}
else
{
InsertLoadedTextNewl_RichEdit(IDS_STATUS_NOTINSTALLED, CFE_ITALIC);
}
InsertTextAfterLoaded_RichEdit(IDS_AINFO_AVAILABLEVERSION, Info->szVersion, CFE_BOLD, 0);
}
static VOID InsertLicenseInfo_RichEdit(CAvailableApplicationInfo* Info)
{
ATL::CStringW szLicense;
switch (Info->LicenseType)
{
case LICENSE_TYPE::OpenSource:
szLicense.LoadStringW(hInst, IDS_LICENSE_OPENSOURCE);
break;
case LICENSE_TYPE::Freeware:
szLicense.LoadStringW(hInst, IDS_LICENSE_FREEWARE);
break;
case LICENSE_TYPE::Trial:
szLicense.LoadStringW(hInst, IDS_LICENSE_TRIAL);
break;
default:
InsertTextAfterLoaded_RichEdit(IDS_AINFO_LICENSE, Info->szLicense, CFE_BOLD, 0);
return;
}
szLicense += L" (" + Info->szLicense + L")";
InsertTextAfterLoaded_RichEdit(IDS_AINFO_LICENSE, szLicense, CFE_BOLD, 0);
}
static VOID InsertLanguageInfo_RichEdit(CAvailableApplicationInfo* Info)
{
if (!Info->HasLanguageInfo())
{
return;
}
const INT nTranslations = Info->Languages.GetSize();
ATL::CStringW szLangInfo;
ATL::CStringW szLoadedTextAvailability;
ATL::CStringW szLoadedAInfoText;
szLoadedAInfoText.LoadStringW(IDS_AINFO_LANGUAGES);
//TODO: replace those hardcoded strings
if (Info->HasNativeLanguage())
{
szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_AVAILABLE_TRANSLATION);
if (nTranslations > 1)
{
szLangInfo.Format(L" (+%d more)", nTranslations - 1);
}
else
{
szLangInfo.LoadStringW(IDS_LANGUAGE_SINGLE);
szLangInfo = L" (" + szLangInfo + L")";
}
}
else if (Info->HasEnglishLanguage())
{
szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_ENGLISH_TRANSLATION);
if (nTranslations > 1)
{
szLangInfo.Format(L" (+%d available)", nTranslations - 1);
}
else
{
szLangInfo.LoadStringW(IDS_LANGUAGE_SINGLE);
szLangInfo = L" (" + szLangInfo + L")";
}
}
else
{
szLoadedTextAvailability.LoadStringW(IDS_LANGUAGE_NO_TRANSLATION);
}
InsertRichEditText(szLoadedAInfoText, CFE_BOLD);
InsertRichEditText(szLoadedTextAvailability, NULL);
InsertRichEditText(szLangInfo, CFE_ITALIC);
}
public:
static BOOL ShowAvailableAppInfo(INT Index)
{
CAvailableApplicationInfo* Info = (CAvailableApplicationInfo*) ListViewGetlParam(Index);
if (!Info) return FALSE;
NewRichEditText(Info->szName, CFE_BOLD);
InsertVersionInfo_RichEdit(Info);
InsertLicenseInfo_RichEdit(Info);
InsertLanguageInfo_RichEdit(Info);
InsertTextAfterLoaded_RichEdit(IDS_AINFO_SIZE, Info->szSize, CFE_BOLD, 0);
InsertTextAfterLoaded_RichEdit(IDS_AINFO_URLSITE, Info->szUrlSite, CFE_BOLD, CFE_LINK);
InsertTextAfterLoaded_RichEdit(IDS_AINFO_DESCRIPTION, Info->szDesc, CFE_BOLD, 0);
InsertTextAfterLoaded_RichEdit(IDS_AINFO_URLDOWNLOAD, Info->szUrlDownload, CFE_BOLD, CFE_LINK);
return TRUE;
}
};
class CMainToolbar :
public CUiWindow< CToolbar<> >
{
#define TOOLBAR_HEIGHT 24
WCHAR szInstallBtn[MAX_STR_LEN];
WCHAR szUninstallBtn[MAX_STR_LEN];
WCHAR szModifyBtn[MAX_STR_LEN];
WCHAR szSelectAll[MAX_STR_LEN];
VOID AddImageToImageList(HIMAGELIST hImageList, UINT ImageIndex)
{
HICON hImage;
if (!(hImage = (HICON) LoadImageW(hInst,
MAKEINTRESOURCE(ImageIndex),
IMAGE_ICON,
TOOLBAR_HEIGHT,
TOOLBAR_HEIGHT,
0)))
{
/* TODO: Error message */
}
ImageList_AddIcon(hImageList, hImage);
DeleteObject(hImage);
}
HIMAGELIST InitImageList()
{
HIMAGELIST hImageList;
/* Create the toolbar icon image list */
hImageList = ImageList_Create(TOOLBAR_HEIGHT,//GetSystemMetrics(SM_CXSMICON),
TOOLBAR_HEIGHT,//GetSystemMetrics(SM_CYSMICON),
ILC_MASK | GetSystemColorDepth(),
1,
1);
if (!hImageList)
{
/* TODO: Error message */
return NULL;
}
AddImageToImageList(hImageList, IDI_INSTALL);
AddImageToImageList(hImageList, IDI_UNINSTALL);
AddImageToImageList(hImageList, IDI_MODIFY);
AddImageToImageList(hImageList, IDI_CHECK_ALL);
AddImageToImageList(hImageList, IDI_REFRESH);
AddImageToImageList(hImageList, IDI_UPDATE_DB);
AddImageToImageList(hImageList, IDI_SETTINGS);
AddImageToImageList(hImageList, IDI_EXIT);
return hImageList;
}
public:
VOID OnGetDispInfo(LPTOOLTIPTEXT lpttt)
{
UINT idButton = (UINT) lpttt->hdr.idFrom;
switch (idButton)
{
case ID_EXIT:
lpttt->lpszText = MAKEINTRESOURCEW(IDS_TOOLTIP_EXIT);
break;
case ID_INSTALL:
lpttt->lpszText = MAKEINTRESOURCEW(IDS_TOOLTIP_INSTALL);
break;
case ID_UNINSTALL:
lpttt->lpszText = MAKEINTRESOURCEW(IDS_TOOLTIP_UNINSTALL);
break;
case ID_MODIFY:
lpttt->lpszText = MAKEINTRESOURCEW(IDS_TOOLTIP_MODIFY);
break;
case ID_SETTINGS:
lpttt->lpszText = MAKEINTRESOURCEW(IDS_TOOLTIP_SETTINGS);
break;
case ID_REFRESH:
lpttt->lpszText = MAKEINTRESOURCEW(IDS_TOOLTIP_REFRESH);
break;
case ID_RESETDB:
lpttt->lpszText = MAKEINTRESOURCEW(IDS_TOOLTIP_UPDATE_DB);
break;
}
}
HWND Create(HWND hwndParent)
{
HIMAGELIST hImageList;
// buttons
static TBBUTTON Buttons[] =
{ /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
{ 0, ID_INSTALL, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE, { 0 }, 0, (INT_PTR) szInstallBtn },
{ 1, ID_UNINSTALL, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE, { 0 }, 0, (INT_PTR) szUninstallBtn },
{ 2, ID_MODIFY, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE, { 0 }, 0, (INT_PTR) szModifyBtn },
{ 3, ID_CHECK_ALL, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE,{0}, 0, (INT_PTR) szSelectAll},
{-1, 0, TBSTATE_ENABLED, BTNS_SEP, { 0 }, 0, 0 },
{ 4, ID_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE, { 0 }, 0, 0 },
{ 5, ID_RESETDB, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE, { 0 }, 0, 0 },
{-1, 0, TBSTATE_ENABLED, BTNS_SEP, { 0 }, 0, 0 },
{ 6, ID_SETTINGS, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE, { 0 }, 0, 0 },
{ 7, ID_EXIT, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_AUTOSIZE, { 0 }, 0, 0 },
};
LoadStringW(hInst, IDS_INSTALL, szInstallBtn, _countof(szInstallBtn));
LoadStringW(hInst, IDS_UNINSTALL, szUninstallBtn, _countof(szUninstallBtn));
LoadStringW(hInst, IDS_MODIFY, szModifyBtn, _countof(szModifyBtn));
LoadStringW(hInst, IDS_SELECT_ALL, szSelectAll, _countof(szSelectAll));
m_hWnd = CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL,
WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | TBSTYLE_LIST,
0, 0, 0, 0,
hwndParent,
0, hInst, NULL);
if (!m_hWnd)
{
/* TODO: Show error message */
return FALSE;
}
SendMessageW(TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_HIDECLIPPEDBUTTONS);
SetButtonStructSize();
hImageList = InitImageList();
if (!hImageList)
{
/* TODO: Show error message */
return FALSE;
}
ImageList_Destroy((HIMAGELIST) SetImageList(hImageList));
AddButtons(_countof(Buttons), Buttons);
return m_hWnd;
}
};
class CAppsListView :
public CUiWindow<CListView>
{
struct SortContext
{
CAppsListView * lvw;
int iSubItem;
};
BOOL bHasAllChecked;
BOOL bAscending;
public:
CAppsListView() :
bAscending(TRUE),
bHasAllChecked(FALSE)
{
}
VOID ColumnClick(LPNMLISTVIEW pnmv)
{
SortContext ctx = {this, pnmv->iSubItem};
SortItems(s_CompareFunc, &ctx);
bAscending = !bAscending;
}
PVOID GetLParam(INT Index)
{
INT ItemIndex;
LVITEMW Item;
if (Index == -1)
{
ItemIndex = (INT) SendMessage(LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
if (ItemIndex == -1)
return NULL;
}
else
{
ItemIndex = Index;
}
ZeroMemory(&Item, sizeof(Item));
Item.mask = LVIF_PARAM;
Item.iItem = ItemIndex;
if (!GetItem(&Item))
return NULL;
return (PVOID) Item.lParam;
}
BOOL AddColumn(INT Index, ATL::CStringW& Text, INT Width, INT Format)
{
return AddColumn(Index, const_cast<LPWSTR>(Text.GetString()), Width, Format);
}
BOOL AddColumn(INT Index, LPWSTR lpText, INT Width, INT Format)
{
LVCOLUMNW Column;
ZeroMemory(&Column, sizeof(Column));
Column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
Column.iSubItem = Index;
Column.pszText = lpText;
Column.cx = Width;
Column.fmt = Format;
return (InsertColumn(Index, &Column) == -1) ? FALSE : TRUE;
}
INT AddItem(INT ItemIndex, INT IconIndex, LPWSTR lpText, LPARAM lParam)
{
LVITEMW Item;
ZeroMemory(&Item, sizeof(Item));
Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
Item.pszText = lpText;
Item.lParam = lParam;
Item.iItem = ItemIndex;
Item.iImage = IconIndex;
return InsertItem(&Item);
}
static INT CALLBACK s_CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
SortContext * ctx = ((SortContext*) lParamSort);
return ctx->lvw->CompareFunc(lParam1, lParam2, ctx->iSubItem);
}
INT CompareFunc(LPARAM lParam1, LPARAM lParam2, INT iSubItem)
{
ATL::CStringW Item1, Item2;
LVFINDINFOW IndexInfo;
INT Index;
IndexInfo.flags = LVFI_PARAM;
IndexInfo.lParam = lParam1;
Index = FindItem(-1, &IndexInfo);
GetItemText(Index, iSubItem, Item1.GetBuffer(MAX_STR_LEN), MAX_STR_LEN);
Item1.ReleaseBuffer();
IndexInfo.lParam = lParam2;
Index = FindItem(-1, &IndexInfo);
GetItemText(Index, iSubItem, Item2.GetBuffer(MAX_STR_LEN), MAX_STR_LEN);
Item2.ReleaseBuffer();
if (bAscending)
return Item2 == Item1;
else
return Item1 == Item2;
return 0;
}
HWND Create(HWND hwndParent)
{
RECT r = {205, 28, 465, 250};
DWORD style = WS_CHILD | WS_VISIBLE | LVS_SORTASCENDING | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS;
HMENU menu = GetSubMenu(LoadMenuW(hInst, MAKEINTRESOURCEW(IDR_APPLICATIONMENU)), 0);
HWND hwnd = CListView::Create(hwndParent, r, NULL, style, WS_EX_CLIENTEDGE, menu);
if (hwnd)
{
SetExtendedListViewStyle(LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT);
}
return hwnd;
}
BOOL GetCheckState(INT item)
{
return (BOOL) (GetItemState(item, LVIS_STATEIMAGEMASK) >> 12) - 1;
}
VOID SetCheckState(INT item, BOOL fCheck)
{
SetItemState(item, INDEXTOSTATEIMAGEMASK((fCheck) ? 2 : 1), LVIS_STATEIMAGEMASK);
}
VOID CheckAll()
{
bHasAllChecked = !bHasAllChecked;
SetCheckState(-1, bHasAllChecked);
}
ATL::CSimpleArray<PAPPLICATION_INFO> GetCheckedItems()
{
ATL::CSimpleArray<PAPPLICATION_INFO> list;
for (INT i = 0; i >= 0; i = GetNextItem(i, LVNI_ALL))
{
if (GetCheckState(i) != FALSE)
{
PAPPLICATION_INFO pAppInfo = (PAPPLICATION_INFO) GetItemData(i);
list.Add(pAppInfo);
}
}
return list;
}
PAPPLICATION_INFO GetSelectedData()
{
INT item = GetSelectionMark();
return (PAPPLICATION_INFO) GetItemData(item);
}
};
class CSideTreeView :
public CUiWindow<CTreeView>
{
HIMAGELIST hImageTreeView = ImageList_Create(TREEVIEW_ICON_SIZE, TREEVIEW_ICON_SIZE,
GetSystemColorDepth() | ILC_MASK,
0, 1);
public:
HTREEITEM AddItem(HTREEITEM hParent, ATL::CStringW &Text, INT Image, INT SelectedImage, LPARAM lParam)
{
return CUiWindow<CTreeView>::AddItem(hParent, const_cast<LPWSTR>(Text.GetString()), Image, SelectedImage, lParam);
}
HTREEITEM AddCategory(HTREEITEM hRootItem, UINT TextIndex, UINT IconIndex)
{
ATL::CStringW szText;
INT Index;
HICON hIcon;
hIcon = (HICON) LoadImage(hInst,
MAKEINTRESOURCE(IconIndex),
IMAGE_ICON,
TREEVIEW_ICON_SIZE,
TREEVIEW_ICON_SIZE,
LR_CREATEDIBSECTION);
if (hIcon)
{
Index = ImageList_AddIcon(hImageTreeView, hIcon);
DestroyIcon(hIcon);
}
szText.LoadStringW(hInst, TextIndex);
return AddItem(hRootItem, szText, Index, Index, TextIndex);
}
HIMAGELIST SetImageList()
{
return CUiWindow<CTreeView>::SetImageList(hImageTreeView, TVSIL_NORMAL);
}
VOID DestroyImageList()
{
if (hImageTreeView)
ImageList_Destroy(hImageTreeView);
}
~CSideTreeView()
{
DestroyImageList();
CUiWindow<CTreeView>::~CUiWindow();
}
};
class CSearchBar :
public CWindow
{
public:
VOID SetText(LPCWSTR lpszText)
{
SendMessageW(SB_SETTEXT, SBT_NOBORDERS, (LPARAM) lpszText);
}
HWND Create(HWND hwndParent)
{
ATL::CStringW szBuf;
m_hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"Edit", NULL,
WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOHSCROLL,
0, 0, 200, 22,
hwndParent, (HMENU) NULL,
hInst, 0);
SendMessageW(WM_SETFONT, (WPARAM) GetStockObject(DEFAULT_GUI_FONT), 0);
szBuf.LoadStringW(hInst, IDS_SEARCH_TEXT);
SetWindowTextW(szBuf);
return m_hWnd;
}
};
class CMainWindow :
public CWindowImpl<CMainWindow, CWindow, CFrameWinTraits>
{
CUiPanel * m_ClientPanel;
CUiSplitPanel * m_VSplitter;
CUiSplitPanel * m_HSplitter;
CMainToolbar * m_Toolbar;
CAppsListView * m_ListView;
CSideTreeView * m_TreeView;
CUiWindow<CStatusBar> * m_StatusBar;
CUiWindow<CRichEdit> * m_RichEdit;
CUiWindow<CSearchBar> * m_SearchBar;
CAvailableApps m_AvailableApps;
LPWSTR pLink;
INT nSelectedApps;
BOOL bSearchEnabled;
BOOL bUpdating;
public:
CMainWindow() :
m_ClientPanel(NULL),
pLink(NULL),
bSearchEnabled(FALSE)
{
}
private:
VOID InitApplicationsList()
{
ATL::CStringW szText;
/* Add columns to ListView */
szText.LoadStringW(hInst, IDS_APP_NAME);
m_ListView->AddColumn(0, szText, 200, LVCFMT_LEFT);
szText.LoadStringW(hInst, IDS_APP_INST_VERSION);
m_ListView->AddColumn(1, szText, 90, LVCFMT_RIGHT);
szText.LoadStringW(hInst, IDS_APP_DESCRIPTION);
m_ListView->AddColumn(3, szText, 250, LVCFMT_LEFT);
// Unnesesary since the list updates on every TreeView selection
// UpdateApplicationsList(ENUM_ALL_COMPONENTS);
}
HTREEITEM AddCategory(HTREEITEM hRootItem, UINT TextIndex, UINT IconIndex)
{
return m_TreeView->AddCategory(hRootItem, TextIndex, IconIndex);
}
VOID InitCategoriesList()
{
HTREEITEM hRootItem;
hRootItem = AddCategory(TVI_ROOT, IDS_AVAILABLEFORINST, IDI_CATEGORY);
AddCategory(hRootItem, IDS_CAT_AUDIO, IDI_CAT_AUDIO);
AddCategory(hRootItem, IDS_CAT_VIDEO, IDI_CAT_VIDEO);
AddCategory(hRootItem, IDS_CAT_GRAPHICS, IDI_CAT_GRAPHICS);
AddCategory(hRootItem, IDS_CAT_GAMES, IDI_CAT_GAMES);
AddCategory(hRootItem, IDS_CAT_INTERNET, IDI_CAT_INTERNET);
AddCategory(hRootItem, IDS_CAT_OFFICE, IDI_CAT_OFFICE);
AddCategory(hRootItem, IDS_CAT_DEVEL, IDI_CAT_DEVEL);
AddCategory(hRootItem, IDS_CAT_EDU, IDI_CAT_EDU);
AddCategory(hRootItem, IDS_CAT_ENGINEER, IDI_CAT_ENGINEER);
AddCategory(hRootItem, IDS_CAT_FINANCE, IDI_CAT_FINANCE);
AddCategory(hRootItem, IDS_CAT_SCIENCE, IDI_CAT_SCIENCE);
AddCategory(hRootItem, IDS_CAT_TOOLS, IDI_CAT_TOOLS);
AddCategory(hRootItem, IDS_CAT_DRIVERS, IDI_CAT_DRIVERS);
AddCategory(hRootItem, IDS_CAT_LIBS, IDI_CAT_LIBS);
AddCategory(hRootItem, IDS_CAT_OTHER, IDI_CAT_OTHER);
m_TreeView->SetImageList();
m_TreeView->Expand(hRootItem, TVE_EXPAND);
m_TreeView->SelectItem(hRootItem);
}
BOOL CreateStatusBar()
{
m_StatusBar = new CUiWindow<CStatusBar>();
m_StatusBar->m_VerticalAlignment = UiAlign_RightBtm;
m_StatusBar->m_HorizontalAlignment = UiAlign_Stretch;
m_ClientPanel->Children().Append(m_StatusBar);
return m_StatusBar->Create(m_hWnd, (HMENU) IDC_STATUSBAR) != NULL;
}
BOOL CreateToolbar()
{
m_Toolbar = new CMainToolbar();
m_Toolbar->m_VerticalAlignment = UiAlign_LeftTop;
m_Toolbar->m_HorizontalAlignment = UiAlign_Stretch;
m_ClientPanel->Children().Append(m_Toolbar);
return m_Toolbar->Create(m_hWnd) != NULL;
}
BOOL CreateTreeView()
{
m_TreeView = new CSideTreeView();
m_TreeView->m_VerticalAlignment = UiAlign_Stretch;
m_TreeView->m_HorizontalAlignment = UiAlign_Stretch;
m_VSplitter->First().Append(m_TreeView);
return m_TreeView->Create(m_hWnd) != NULL;
}
BOOL CreateListView()
{
m_ListView = new CAppsListView();
m_ListView->m_VerticalAlignment = UiAlign_Stretch;
m_ListView->m_HorizontalAlignment = UiAlign_Stretch;
m_HSplitter->First().Append(m_ListView);
hListView = m_ListView->Create(m_hWnd);
return hListView != NULL;
}
BOOL CreateRichEdit()
{
m_RichEdit = new CUiWindow<CRichEdit>();
m_RichEdit->m_VerticalAlignment = UiAlign_Stretch;
m_RichEdit->m_HorizontalAlignment = UiAlign_Stretch;
m_HSplitter->Second().Append(m_RichEdit);
return m_RichEdit->Create(m_hWnd) != NULL;
}
BOOL CreateVSplitter()
{
m_VSplitter = new CUiSplitPanel();
m_VSplitter->m_VerticalAlignment = UiAlign_Stretch;
m_VSplitter->m_HorizontalAlignment = UiAlign_Stretch;
m_VSplitter->m_DynamicFirst = FALSE;
m_VSplitter->m_Horizontal = FALSE;
m_VSplitter->m_MinFirst = 240;
m_VSplitter->m_MinSecond = 300;
m_ClientPanel->Children().Append(m_VSplitter);
return m_VSplitter->Create(m_hWnd) != NULL;
}
BOOL CreateHSplitter()
{
m_HSplitter = new CUiSplitPanel();
m_HSplitter->m_VerticalAlignment = UiAlign_Stretch;
m_HSplitter->m_HorizontalAlignment = UiAlign_Stretch;
m_HSplitter->m_DynamicFirst = TRUE;
m_HSplitter->m_Horizontal = TRUE;
m_HSplitter->m_Pos = 32768;
m_HSplitter->m_MinFirst = 300;
m_HSplitter->m_MinSecond = 150;
m_VSplitter->Second().Append(m_HSplitter);
return m_HSplitter->Create(m_hWnd) != NULL;
}
BOOL CreateSearchBar()
{
m_SearchBar = new CUiWindow<CSearchBar>();
m_SearchBar->m_VerticalAlignment = UiAlign_LeftTop;
m_SearchBar->m_HorizontalAlignment = UiAlign_RightBtm;
m_SearchBar->m_Margin.top = 6;
m_SearchBar->m_Margin.right = 6;
return m_SearchBar->Create(m_Toolbar->m_hWnd) != NULL;
}
BOOL CreateLayout()
{
BOOL b = TRUE;
bUpdating = TRUE;
m_ClientPanel = new CUiPanel();
m_ClientPanel->m_VerticalAlignment = UiAlign_Stretch;
m_ClientPanel->m_HorizontalAlignment = UiAlign_Stretch;
// Top level
b = b && CreateStatusBar();
b = b && CreateToolbar();
b = b && CreateSearchBar();
b = b && CreateVSplitter();
// Inside V Splitter
b = b && CreateHSplitter();
b = b && CreateTreeView();
// Inside H Splitter
b = b && CreateListView();
b = b && CreateRichEdit();
if (b)
{
RECT rTop;
RECT rBottom;
/* Size status bar */
m_StatusBar->SendMessageW(WM_SIZE, 0, 0);
/* Size tool bar */
m_Toolbar->AutoSize();
::GetWindowRect(m_Toolbar->m_hWnd, &rTop);
::GetWindowRect(m_StatusBar->m_hWnd, &rBottom);
m_VSplitter->m_Margin.top = rTop.bottom - rTop.top;
m_VSplitter->m_Margin.bottom = rBottom.bottom - rBottom.top;
}
bUpdating = FALSE;
return b;
}
BOOL InitControls()
{
if (CreateLayout())
{
InitApplicationsList();
InitCategoriesList();
nSelectedApps = 0;
UpdateStatusBarText();
return TRUE;
}
return FALSE;
}
VOID OnSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
/* Size status bar */
m_StatusBar->SendMessage(WM_SIZE, 0, 0);
/* Size tool bar */
m_Toolbar->AutoSize();
RECT r = {0, 0, LOWORD(lParam), HIWORD(lParam)};
HDWP hdwp = NULL;
int count = m_ClientPanel->CountSizableChildren();
hdwp = BeginDeferWindowPos(count);
if (hdwp)
{
hdwp = m_ClientPanel->OnParentSize(r, hdwp);
}
if (hdwp)
{
EndDeferWindowPos(hdwp);
}
// TODO: Sub-layouts for children of children
count = m_SearchBar->CountSizableChildren();
hdwp = BeginDeferWindowPos(count);
if (hdwp)
{
hdwp = m_SearchBar->OnParentSize(r, hdwp);
}
if (hdwp)
{
EndDeferWindowPos(hdwp);
}
}
BOOL ProcessWindowMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT& theResult, DWORD dwMapId)
{
theResult = 0;
switch (Msg)
{
case WM_CREATE:
if (!InitControls())
::PostMessage(hwnd, WM_CLOSE, 0, 0);
break;
case WM_DESTROY:
{
ShowWindow(SW_HIDE);
SaveSettings(hwnd);
FreeLogs();
if (IS_INSTALLED_ENUM(SelectedEnumType))
FreeInstalledAppList();
delete m_ClientPanel;
PostQuitMessage(0);
return 0;
}
case WM_COMMAND:
OnCommand(wParam, lParam);
break;
case WM_NOTIFY:
{
LPNMHDR data = (LPNMHDR) lParam;
switch (data->code)
{
case TVN_SELCHANGED:
{
if (data->hwndFrom == m_TreeView->m_hWnd)
{
switch (((LPNMTREEVIEW) lParam)->itemNew.lParam)
{
case IDS_INSTALLED:
UpdateApplicationsList(ENUM_ALL_COMPONENTS);
break;
case IDS_APPLICATIONS:
UpdateApplicationsList(ENUM_APPLICATIONS);
break;
case IDS_UPDATES:
UpdateApplicationsList(ENUM_UPDATES);
break;
case IDS_AVAILABLEFORINST:
UpdateApplicationsList(ENUM_ALL_AVAILABLE);
break;
case IDS_CAT_AUDIO:
UpdateApplicationsList(ENUM_CAT_AUDIO);
break;
case IDS_CAT_DEVEL:
UpdateApplicationsList(ENUM_CAT_DEVEL);
break;
case IDS_CAT_DRIVERS:
UpdateApplicationsList(ENUM_CAT_DRIVERS);
break;
case IDS_CAT_EDU:
UpdateApplicationsList(ENUM_CAT_EDU);
break;
case IDS_CAT_ENGINEER:
UpdateApplicationsList(ENUM_CAT_ENGINEER);
break;
case IDS_CAT_FINANCE:
UpdateApplicationsList(ENUM_CAT_FINANCE);
break;
case IDS_CAT_GAMES:
UpdateApplicationsList(ENUM_CAT_GAMES);
break;
case IDS_CAT_GRAPHICS:
UpdateApplicationsList(ENUM_CAT_GRAPHICS);
break;
case IDS_CAT_INTERNET:
UpdateApplicationsList(ENUM_CAT_INTERNET);
break;
case IDS_CAT_LIBS:
UpdateApplicationsList(ENUM_CAT_LIBS);
break;
case IDS_CAT_OFFICE:
UpdateApplicationsList(ENUM_CAT_OFFICE);
break;
case IDS_CAT_OTHER:
UpdateApplicationsList(ENUM_CAT_OTHER);
break;
case IDS_CAT_SCIENCE:
UpdateApplicationsList(ENUM_CAT_SCIENCE);
break;
case IDS_CAT_TOOLS:
UpdateApplicationsList(ENUM_CAT_TOOLS);
break;
case IDS_CAT_VIDEO:
UpdateApplicationsList(ENUM_CAT_VIDEO);
break;
}
}
HMENU mainMenu = ::GetMenu(hwnd);
HMENU lvwMenu = ::GetMenu(m_ListView->m_hWnd);
/* Disable/enable items based on treeview selection */
if (IsSelectedNodeInstalled())
{
EnableMenuItem(mainMenu, ID_REGREMOVE, MF_ENABLED);
EnableMenuItem(mainMenu, ID_INSTALL, MF_GRAYED);
EnableMenuItem(mainMenu, ID_UNINSTALL, MF_ENABLED);
EnableMenuItem(mainMenu, ID_MODIFY, MF_ENABLED);
EnableMenuItem(lvwMenu, ID_REGREMOVE, MF_ENABLED);
EnableMenuItem(lvwMenu, ID_INSTALL, MF_GRAYED);
EnableMenuItem(lvwMenu, ID_UNINSTALL, MF_ENABLED);
EnableMenuItem(lvwMenu, ID_MODIFY, MF_ENABLED);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_REGREMOVE, TRUE);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_INSTALL, FALSE);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_UNINSTALL, TRUE);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_MODIFY, TRUE);
}
else
{
EnableMenuItem(mainMenu, ID_REGREMOVE, MF_GRAYED);
EnableMenuItem(mainMenu, ID_INSTALL, MF_ENABLED);
EnableMenuItem(mainMenu, ID_UNINSTALL, MF_GRAYED);
EnableMenuItem(mainMenu, ID_MODIFY, MF_GRAYED);
EnableMenuItem(lvwMenu, ID_REGREMOVE, MF_GRAYED);
EnableMenuItem(lvwMenu, ID_INSTALL, MF_ENABLED);
EnableMenuItem(lvwMenu, ID_UNINSTALL, MF_GRAYED);
EnableMenuItem(lvwMenu, ID_MODIFY, MF_GRAYED);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_REGREMOVE, FALSE);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_INSTALL, TRUE);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_UNINSTALL, FALSE);
m_Toolbar->SendMessageW(TB_ENABLEBUTTON, ID_MODIFY, FALSE);
}
}
break;
case LVN_ITEMCHANGED:
{
LPNMLISTVIEW pnic = (LPNMLISTVIEW) lParam;
if (pnic->hdr.hwndFrom == m_ListView->m_hWnd)
{
/* Check if this is a valid item
* (technically, it can be also an unselect) */
INT ItemIndex = pnic->iItem;
if (ItemIndex == -1 ||
ItemIndex >= ListView_GetItemCount(pnic->hdr.hwndFrom))
{
break;
}
/* Check if the focus has been moved to another item */
if ((pnic->uChanged & LVIF_STATE) &&
(pnic->uNewState & LVIS_FOCUSED) &&
!(pnic->uOldState & LVIS_FOCUSED))
{
if (IS_INSTALLED_ENUM(SelectedEnumType))
ShowInstalledAppInfo(ItemIndex);
if (IS_AVAILABLE_ENUM(SelectedEnumType))
CAvailableAppView::ShowAvailableAppInfo(ItemIndex);
}
/* Check if the item is checked */
if ((pnic->uNewState & LVIS_STATEIMAGEMASK) && !bUpdating)
{
BOOL checked = ListView_GetCheckState(pnic->hdr.hwndFrom, pnic->iItem);
nSelectedApps += (checked) ? 1 : -1;
UpdateStatusBarText();
}
}
}
break;
case LVN_COLUMNCLICK:
{
LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
m_ListView->ColumnClick(pnmv);
}
break;
case NM_CLICK:
{
if (data->hwndFrom == m_ListView->m_hWnd && ((LPNMLISTVIEW) lParam)->iItem != -1)
{
if (IS_INSTALLED_ENUM(SelectedEnumType))
ShowInstalledAppInfo(-1);
if (IS_AVAILABLE_ENUM(SelectedEnumType))
CAvailableAppView::ShowAvailableAppInfo(-1);
}
}
break;
case NM_DBLCLK:
{
if (data->hwndFrom == m_ListView->m_hWnd && ((LPNMLISTVIEW) lParam)->iItem != -1)
{
/* this won't do anything if the program is already installed */
SendMessageW(hwnd, WM_COMMAND, ID_INSTALL, 0);
}
}
break;
case NM_RCLICK:
{
if (data->hwndFrom == m_ListView->m_hWnd && ((LPNMLISTVIEW) lParam)->iItem != -1)
{
ShowPopupMenu(m_ListView->m_hWnd, 0, ID_INSTALL);
}
}
break;
case EN_LINK:
OnLink((ENLINK*) lParam);
break;
case TTN_GETDISPINFO:
m_Toolbar->OnGetDispInfo((LPTOOLTIPTEXT) lParam);
break;
}
}
break;
case WM_SIZE:
OnSize(hwnd, wParam, lParam);
break;
case WM_SIZING:
{
LPRECT pRect = (LPRECT) lParam;
if (pRect->right - pRect->left < 565)
pRect->right = pRect->left + 565;
if (pRect->bottom - pRect->top < 300)
pRect->bottom = pRect->top + 300;
return TRUE;
}
case WM_SYSCOLORCHANGE:
{
/* Forward WM_SYSCOLORCHANGE to common controls */
m_ListView->SendMessageW(WM_SYSCOLORCHANGE, 0, 0);
m_TreeView->SendMessageW(WM_SYSCOLORCHANGE, 0, 0);
m_Toolbar->SendMessageW(WM_SYSCOLORCHANGE, 0, 0);
m_ListView->SendMessageW(EM_SETBKGNDCOLOR, 0, GetSysColor(COLOR_BTNFACE));
}
break;
case WM_TIMER:
if (wParam == SEARCH_TIMER_ID)
{
::KillTimer(hwnd, SEARCH_TIMER_ID);
if (bSearchEnabled)
UpdateApplicationsList(-1);
}
break;
}
return FALSE;
}
virtual VOID OnLink(ENLINK *Link)
{
switch (Link->msg)
{
case WM_LBUTTONUP:
case WM_RBUTTONUP:
{
if (pLink) HeapFree(GetProcessHeap(), 0, pLink);
pLink = (LPWSTR) HeapAlloc(GetProcessHeap(), 0,
(max(Link->chrg.cpMin, Link->chrg.cpMax) -
min(Link->chrg.cpMin, Link->chrg.cpMax) + 1) * sizeof(WCHAR));
if (!pLink)
{
/* TODO: Error message */
return;
}
m_RichEdit->SendMessageW(EM_SETSEL, Link->chrg.cpMin, Link->chrg.cpMax);
m_RichEdit->SendMessageW(EM_GETSELTEXT, 0, (LPARAM) pLink);
ShowPopupMenu(m_RichEdit->m_hWnd, IDR_LINKMENU, -1);
}
break;
}
}
BOOL IsSelectedNodeInstalled()
{
HTREEITEM hSelectedItem = m_TreeView->GetSelection();
TV_ITEM tItem;
tItem.mask = TVIF_PARAM | TVIF_HANDLE;
tItem.hItem = hSelectedItem;
m_TreeView->GetItem(&tItem);
switch (tItem.lParam)
{
case IDS_INSTALLED:
case IDS_APPLICATIONS:
case IDS_UPDATES:
return TRUE;
default:
return FALSE;
}
}
VOID OnCommand(WPARAM wParam, LPARAM lParam)
{
WORD wCommand = LOWORD(wParam);
if (lParam == (LPARAM) m_SearchBar->m_hWnd)
{
ATL::CStringW szBuf;
switch (HIWORD(wParam))
{
case EN_SETFOCUS:
{
ATL::CStringW szWndText;
szBuf.LoadStringW(hInst, IDS_SEARCH_TEXT);
m_SearchBar->GetWindowTextW(szWndText);
if (szBuf == szWndText)
{
bSearchEnabled = FALSE;
m_SearchBar->SetWindowTextW(L"");
}
}
break;
case EN_KILLFOCUS:
{
m_SearchBar->GetWindowTextW(szBuf);
if (szBuf.IsEmpty())
{
szBuf.LoadStringW(hInst, IDS_SEARCH_TEXT);
bSearchEnabled = FALSE;
m_SearchBar->SetWindowTextW(szBuf.GetString());
}
}
break;
case EN_CHANGE:
{
ATL::CStringW szWndText;
if (!bSearchEnabled)
{
bSearchEnabled = TRUE;
break;
}
szBuf.LoadStringW(hInst, IDS_SEARCH_TEXT);
m_SearchBar->GetWindowTextW(szWndText);
if (szBuf == szWndText)
{
szSearchPattern.Empty();
}
else
{
szSearchPattern = szWndText;
}
DWORD dwDelay;
SystemParametersInfoW(SPI_GETMENUSHOWDELAY, 0, &dwDelay, 0);
SetTimer(SEARCH_TIMER_ID, dwDelay);
}
break;
}
return;
}
switch (wCommand)
{
case ID_OPEN_LINK:
ShellExecuteW(m_hWnd, L"open", pLink, NULL, NULL, SW_SHOWNOACTIVATE);
HeapFree(GetProcessHeap(), 0, pLink);
break;
case ID_COPY_LINK:
CopyTextToClipboard(pLink);
HeapFree(GetProcessHeap(), 0, pLink);
break;
case ID_SETTINGS:
CreateSettingsDlg(m_hWnd);
break;
case ID_EXIT:
PostMessageW(WM_CLOSE, 0, 0);
break;
case ID_INSTALL:
if (nSelectedApps)
{
СDownloadManager::DownloadListOfApplications(m_ListView->GetCheckedItems());
UpdateApplicationsList(-1);
}
else if(СDownloadManager::DownloadApplication(m_ListView->GetSelectedData()))
{
UpdateApplicationsList(-1);
}
break;
case ID_UNINSTALL:
if (UninstallApplication(-1, FALSE))
UpdateApplicationsList(-1);
break;
case ID_MODIFY:
if (UninstallApplication(-1, TRUE))
UpdateApplicationsList(-1);
break;
case ID_REGREMOVE:
RemoveAppFromRegistry(-1);
break;
case ID_REFRESH:
UpdateApplicationsList(-1);
break;
case ID_RESETDB:
m_AvailableApps.UpdateAppsDB();
UpdateApplicationsList(-1);
break;
case ID_HELP:
MessageBoxW(L"Help not implemented yet", NULL, MB_OK);
break;
case ID_ABOUT:
ShowAboutDialog();
break;
case ID_CHECK_ALL:
m_ListView->CheckAll();
break;
}
}
VOID FreeInstalledAppList()
{
INT Count = m_ListView->GetItemCount() - 1;
PINSTALLED_INFO Info;
while (Count >= 0)
{
Info = (PINSTALLED_INFO) ListViewGetlParam(Count);
if (Info)
{
RegCloseKey(Info->hSubKey);
delete Info;
}
Count--;
}
}
static BOOL SearchPatternMatch(PCWSTR szHaystack, PCWSTR szNeedle)
{
if (!*szNeedle)
return TRUE;
/* TODO: Improve pattern search beyond a simple case-insensitive substring search. */
return StrStrIW(szHaystack, szNeedle) != NULL;
}
static BOOL CALLBACK s_EnumInstalledAppProc(INT ItemIndex, LPWSTR lpName, PINSTALLED_INFO Info)
{
PINSTALLED_INFO ItemInfo;
ATL::CStringW szText;
INT Index;
if (!SearchPatternMatch(lpName, szSearchPattern))
{
RegCloseKey(Info->hSubKey);
return TRUE;
}
ItemInfo = (PINSTALLED_INFO) HeapAlloc(GetProcessHeap(), 0, sizeof(INSTALLED_INFO));
if (!ItemInfo)
{
RegCloseKey(Info->hSubKey);
return FALSE;
}
RtlCopyMemory(ItemInfo, Info, sizeof(INSTALLED_INFO));
Index = ListViewAddItem(ItemIndex, 0, lpName, (LPARAM) ItemInfo);
/* Get version info */
GetApplicationString(ItemInfo->hSubKey, L"DisplayVersion", szText);
ListView_SetItemText(hListView, Index, 1, const_cast<LPWSTR>(szText.GetString()));
/* Get comments */
GetApplicationString(ItemInfo->hSubKey, L"Comments", szText);
ListView_SetItemText(hListView, Index, 2, const_cast<LPWSTR>(szText.GetString()));
return TRUE;
}
static BOOL CALLBACK s_EnumAvailableAppProc(PAPPLICATION_INFO Info, LPCWSTR szFolderPath)
{
INT Index;
HICON hIcon = NULL;
HIMAGELIST hImageListView = ListView_GetImageList(hListView, LVSIL_SMALL);
if (!SearchPatternMatch(Info->szName, szSearchPattern) &&
!SearchPatternMatch(Info->szDesc, szSearchPattern))
{
return TRUE;
}
/* Load icon from file */
ATL::CStringW szIconPath;
szIconPath.Format(L"%lsicons\\%ls.ico", szFolderPath, Info->szName);
hIcon = (HICON) LoadImageW(NULL,
szIconPath.GetString(),
IMAGE_ICON,
LISTVIEW_ICON_SIZE,
LISTVIEW_ICON_SIZE,
LR_LOADFROMFILE);
if (!hIcon || GetLastError() != ERROR_SUCCESS)
{
/* Load default icon */
hIcon = (HICON) LoadIconW(hInst, MAKEINTRESOURCEW(IDI_MAIN));
}
Index = ImageList_AddIcon(hImageListView, hIcon);
DestroyIcon(hIcon);
Index = ListViewAddItem(Info->Category, Index, Info->szName, (LPARAM) Info);
ListView_SetImageList(hListView, hImageListView, LVSIL_SMALL);
ListView_SetItemText(hListView, Index, 1, const_cast<LPWSTR>(Info->szVersion.GetString()));
ListView_SetItemText(hListView, Index, 2, const_cast<LPWSTR>(Info->szDesc.GetString()));
return TRUE;
}
VOID UpdateStatusBarText()
{
if (m_StatusBar)
{
ATL::CStringW szBuffer;
szBuffer.Format(IDS_APPS_COUNT, m_ListView->GetItemCount(), nSelectedApps);
m_StatusBar->SetText(szBuffer);
}
}
VOID UpdateApplicationsList(INT EnumType)
{
ATL::CStringW szBuffer1, szBuffer2;
HIMAGELIST hImageListView;
bUpdating = TRUE;
m_ListView->SetRedraw(FALSE);
nSelectedApps = 0;
if (EnumType < 0) EnumType = SelectedEnumType;
if (IS_INSTALLED_ENUM(SelectedEnumType))
FreeInstalledAppList();
m_ListView->DeleteAllItems();
/* Create new ImageList */
hImageListView = ImageList_Create(LISTVIEW_ICON_SIZE,
LISTVIEW_ICON_SIZE,
GetSystemColorDepth() | ILC_MASK,
0, 1);
HIMAGELIST hImageListBuf = m_ListView->SetImageList(hImageListView, LVSIL_SMALL);
if (hImageListBuf)
{
ImageList_Destroy(hImageListBuf);
}
if (IS_AVAILABLE_ENUM(EnumType))
{
/* Enum available applications */
m_AvailableApps.EnumAvailableApplications(EnumType, s_EnumAvailableAppProc);
}
SelectedEnumType = EnumType;
UpdateStatusBarText();
SetWelcomeText();
/* set automatic column width for program names if the list is not empty */
if (m_ListView->GetItemCount() > 0)
ListView_SetColumnWidth(m_ListView->GetWindow(), 0, LVSCW_AUTOSIZE);
bUpdating = FALSE;
m_ListView->SetRedraw(TRUE);
}
public:
static ATL::CWndClassInfo& GetWndClassInfo()
{
DWORD csStyle = CS_VREDRAW | CS_HREDRAW;
static ATL::CWndClassInfo wc =
{
{
sizeof(WNDCLASSEX),
csStyle,
StartWindowProc,
0,
0,
NULL,
LoadIconW(_AtlBaseModule.GetModuleInstance(), MAKEINTRESOURCEW(IDI_MAIN)),
LoadCursorW(NULL, IDC_ARROW),
(HBRUSH) (COLOR_BTNFACE + 1),
MAKEINTRESOURCEW(IDR_MAINMENU),
L"RAppsWnd",
NULL
},
NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
};
return wc;
}
HWND Create()
{
ATL::CStringW szWindowName;
szWindowName.LoadStringW(hInst, IDS_APPTITLE);
RECT r = {
(SettingsInfo.bSaveWndPos ? SettingsInfo.Left : CW_USEDEFAULT),
(SettingsInfo.bSaveWndPos ? SettingsInfo.Top : CW_USEDEFAULT),
(SettingsInfo.bSaveWndPos ? SettingsInfo.Width : 680),
(SettingsInfo.bSaveWndPos ? SettingsInfo.Height : 450)
};
r.right += r.left;
r.bottom += r.top;
return CWindowImpl::Create(NULL, r, szWindowName.GetString(), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_WINDOWEDGE);
}
CStatusBar * GetStatusBar()
{
return m_StatusBar;
}
CAppsListView * GetListView()
{
return m_ListView;
}
CRichEdit * GetRichEdit()
{
return m_RichEdit;
}
CAvailableApps * GetAvailableApps()
{
return &m_AvailableApps;
}
};
// File interface
CMainWindow * g_MainWindow;
HWND CreateMainWindow()
{
g_MainWindow = new CMainWindow();
return g_MainWindow->Create();
}
DWORD_PTR ListViewGetlParam(INT item)
{
if (item < 0)
{
item = g_MainWindow->GetListView()->GetSelectionMark();
}
return g_MainWindow->GetListView()->GetItemData(item);
}
VOID SetStatusBarText(LPCWSTR szText)
{
g_MainWindow->GetStatusBar()->SetText(szText);
}
INT ListViewAddItem(INT ItemIndex, INT IconIndex, LPWSTR lpName, LPARAM lParam)
{
return g_MainWindow->GetListView()->AddItem(ItemIndex, IconIndex, lpName, lParam);
}
VOID NewRichEditText(LPCWSTR szText, DWORD flags)
{
g_MainWindow->GetRichEdit()->SetText(szText, flags);
}
VOID InsertRichEditText(LPCWSTR szText, DWORD flags)
{
g_MainWindow->GetRichEdit()->InsertText(szText, flags);
}
/* ATL version of functions */
VOID SetStatusBarText(const ATL::CStringW& szText)
{
SetStatusBarText(szText.GetString());
}
INT ListViewAddItem(INT ItemIndex, INT IconIndex, ATL::CStringW & Name, LPARAM lParam)
{
return ListViewAddItem(ItemIndex, IconIndex, const_cast<LPWSTR>(Name.GetString()), lParam);
}
VOID NewRichEditText(const ATL::CStringW& szText, DWORD flags)
{
NewRichEditText(szText.GetString(), flags);
}
VOID InsertRichEditText(const ATL::CStringW& szText, DWORD flags)
{
InsertRichEditText(szText.GetString(), flags);
}
CAvailableApps* GetAvailableApps()
{
return g_MainWindow->GetAvailableApps();
}