Something went wrong. Try again.
Reactos
Something went wrong. Try again.
28 kB · 933 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934/* * PROJECT: ReactOS Applications Manager * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: GUI classes for RAPPS * COPYRIGHT: Copyright 2015 David Quintana (gigaherz@gmail.com) * Copyright 2017 Alexander Shaposhnikov (sanchaez@reactos.org) * Copyright 2020 He Yang (1160386205@qq.com) */
#include "rapps.h"#include "rosui.h"#include "crichedit.h"#include "asyncinet.h"#include "gui.h"#include <shlobj_undoc.h>#include <shlguid_undoc.h>
#include <atlbase.h>#include <atlcom.h>#include <atltypes.h>#include <atlwin.h>#include <wininet.h>#include <shellutils.h>#include <ui/rosctrls.h>#include <gdiplus.h>#include <math.h>
#define SEARCH_TIMER_ID 'SR'#define TREEVIEW_ICON_SIZE 24
// **** CSideTreeView ****
CSideTreeView::CSideTreeView() : CUiWindow(), hImageTreeView(ImageList_Create(TREEVIEW_ICON_SIZE, TREEVIEW_ICON_SIZE, GetSystemColorDepth() | ILC_MASK, 0, 1)){}
HTREEITEMCSideTreeView::AddItem(HTREEITEM hParent, CStringW &Text, INT Image, INT SelectedImage, LPARAM lParam){ return CUiWindow<CTreeView>::AddItem(hParent, const_cast<LPWSTR>(Text.GetString()), Image, SelectedImage, lParam);}
HTREEITEMCSideTreeView::AddCategory(HTREEITEM hRootItem, UINT TextIndex, UINT IconIndex){ CStringW szText; INT Index = 0; HICON hIcon;
hIcon = (HICON)LoadImageW( hInst, MAKEINTRESOURCE(IconIndex), IMAGE_ICON, TREEVIEW_ICON_SIZE, TREEVIEW_ICON_SIZE, LR_CREATEDIBSECTION); if (hIcon) { Index = ImageList_AddIcon(hImageTreeView, hIcon); DestroyIcon(hIcon); }
szText.LoadStringW(TextIndex); return AddItem(hRootItem, szText, Index, Index, TextIndex);}
HIMAGELISTCSideTreeView::SetImageList(){ return CUiWindow<CTreeView>::SetImageList(hImageTreeView, TVSIL_NORMAL);}
VOIDCSideTreeView::DestroyImageList(){ if (hImageTreeView) ImageList_Destroy(hImageTreeView);}
CSideTreeView::~CSideTreeView(){ DestroyImageList();}// **** CSideTreeView ****
// **** CMainWindow ****HWND CMainWindow::m_hLastFocus = NULL;bool CMainWindow::m_PendingInstalledViewRefresh = false;
CMainWindow::CMainWindow(CAppDB *db, BOOL bAppwiz) : m_ClientPanel(NULL), m_Db(db), m_bAppwizMode(bAppwiz), SelectedEnumType(ENUM_ALL_INSTALLED){}
CMainWindow::~CMainWindow(){ LayoutCleanup();}
VOIDCMainWindow::InitCategoriesList(){ HTREEITEM hRootItemAvailable;
hRootItemInstalled = m_TreeView->AddCategory(TVI_ROOT, IDS_INSTALLED, IDI_CATEGORY); m_TreeView->AddCategory(hRootItemInstalled, IDS_APPLICATIONS, IDI_APPS); m_TreeView->AddCategory(hRootItemInstalled, IDS_UPDATES, IDI_APPUPD);
// Do not show any other categories in APPWIZ-mode. if (m_bAppwizMode) goto Finish;
m_TreeView->AddCategory(TVI_ROOT, IDS_SELECTEDFORINST, IDI_SELECTEDFORINST);
hRootItemAvailable = m_TreeView->AddCategory(TVI_ROOT, IDS_AVAILABLEFORINST, IDI_CATEGORY); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_AUDIO, IDI_CAT_AUDIO); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_VIDEO, IDI_CAT_VIDEO); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_GRAPHICS, IDI_CAT_GRAPHICS); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_GAMES, IDI_CAT_GAMES); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_INTERNET, IDI_CAT_INTERNET); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_OFFICE, IDI_CAT_OFFICE); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_DEVEL, IDI_CAT_DEVEL); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_EDU, IDI_CAT_EDU); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_ENGINEER, IDI_CAT_ENGINEER); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_FINANCE, IDI_CAT_FINANCE); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_SCIENCE, IDI_CAT_SCIENCE); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_TOOLS, IDI_CAT_TOOLS); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_DRIVERS, IDI_CAT_DRIVERS); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_LIBS, IDI_CAT_LIBS); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_THEMES, IDI_CAT_THEMES); m_TreeView->AddCategory(hRootItemAvailable, IDS_CAT_OTHER, IDI_CAT_OTHER);
Finish: m_TreeView->SetImageList(); m_TreeView->Expand(hRootItemInstalled, TVE_EXPAND); if (!m_bAppwizMode) m_TreeView->Expand(hRootItemAvailable, TVE_EXPAND); m_TreeView->SelectItem(m_bAppwizMode ? hRootItemInstalled : hRootItemAvailable);}
BOOLCMainWindow::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;}
BOOLCMainWindow::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;}
BOOLCMainWindow::CreateApplicationView(){ m_ApplicationView = new CApplicationView(this); // pass this to ApplicationView for callback purpose m_ApplicationView->m_VerticalAlignment = UiAlign_Stretch; m_ApplicationView->m_HorizontalAlignment = UiAlign_Stretch; m_VSplitter->Second().Append(m_ApplicationView);
return m_ApplicationView->Create(m_hWnd) != NULL;}
BOOLCMainWindow::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 = 0;
// TODO: m_MinSecond should be calculate dynamically instead of hard-coded m_VSplitter->m_MinSecond = 480; m_VSplitter->m_Pos = 240; m_ClientPanel->Children().Append(m_VSplitter);
return m_VSplitter->Create(m_hWnd) != NULL;}
BOOLCMainWindow::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 && CreateVSplitter();
// Inside V Splitter b = b && CreateTreeView(); b = b && CreateApplicationView();
if (b) { RECT rBottom;
/* Size status bar */ m_StatusBar->SendMessageW(WM_SIZE, 0, 0);
::GetWindowRect(m_StatusBar->m_hWnd, &rBottom);
m_VSplitter->m_Margin.bottom = rBottom.bottom - rBottom.top; }
bUpdating = FALSE; return b;}
VOIDCMainWindow::LayoutCleanup(){ delete m_TreeView; delete m_ApplicationView; delete m_VSplitter; delete m_StatusBar; return;}
BOOLCMainWindow::InitControls(){ if (CreateLayout()) { InitCategoriesList(); UpdateStatusBarText();
return TRUE; }
return FALSE;}
VOIDCMainWindow::OnSize(HWND hwnd, WPARAM wParam, LPARAM lParam){ if (wParam == SIZE_MINIMIZED) return;
/* Size status bar */ m_StatusBar->SendMessage(WM_SIZE, 0, 0);
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); } }}
BOOLCMainWindow::RemoveSelectedAppFromRegistry(){ if (!IsInstalledEnum(SelectedEnumType)) return FALSE;
CStringW szMsgText, szMsgTitle;
if (!szMsgText.LoadStringW(IDS_APP_REG_REMOVE) || !szMsgTitle.LoadStringW(IDS_INFORMATION)) return FALSE;
CAppInfo *InstalledApp = (CAppInfo *)m_ApplicationView->GetFocusedItemData(); if (!InstalledApp) return FALSE;
if (MessageBoxW(szMsgText, szMsgTitle, MB_YESNO | MB_ICONQUESTION) == IDYES) return m_Db->RemoveInstalledAppFromRegistry(InstalledApp) == ERROR_SUCCESS;
return FALSE;}
BOOLCMainWindow::UninstallSelectedApp(BOOL bModify){ if (!IsInstalledEnum(SelectedEnumType)) return FALSE;
CAppInfo *InstalledApp = (CAppInfo *)m_ApplicationView->GetFocusedItemData(); if (!InstalledApp) return FALSE;
return InstalledApp->UninstallApplication(bModify ? UCF_MODIFY : UCF_NONE);}
VOIDCMainWindow::CheckAvailable(){ if (m_Db->GetAvailableCount() == 0) { CUpdateDatabaseMutex lock; m_Db->RemoveCached(); m_Db->UpdateAvailable(); }}
BOOLCMainWindow::ProcessWindowMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT &theResult, DWORD dwMapId){ theResult = 0; switch (Msg) { case WM_CREATE: if (!InitControls()) ::PostMessageW(hwnd, WM_CLOSE, 0, 0); ::PostMessageW(hwnd, DM_REPOSITION, 0, 0); break;
case WM_DESTROY: { hMainWnd = NULL; SaveSettings(hwnd, &SettingsInfo); FreeLogs();
delete m_ClientPanel;
PostQuitMessage(0); return 0; }
case WM_CLOSE: ShowWindow(SW_HIDE); return g_Busy;
case WM_NOTIFY_OPERATIONCOMPLETED: if (!g_Busy && !IsWindowVisible()) SendMessage(WM_CLOSE, 0, 0); break;
case WM_NOTIFY_INSTALLERFINISHED: m_PendingInstalledViewRefresh = true; // Something just installed, our uninstall list is probably outdated m_ApplicationView->RefreshAvailableItem((PCWSTR)lParam); break;
case DM_REPOSITION: EmulateDialogReposition(hwnd); // We are not a real dialog, we need help from a real one break;
case WM_ACTIVATE: if (LOWORD(wParam) == WA_INACTIVE) m_hLastFocus = ::GetFocus(); break;
case WM_SETFOCUS: if (m_hLastFocus) ::SetFocus(m_hLastFocus); break;
case WM_NEXTDLGCTL: if (!LOWORD(lParam)) HandleTabOrder(wParam ? -1 : 1); else if (wParam) ::SetFocus((HWND)wParam); break;
case WM_COMMAND: OnCommand(wParam, lParam); break;
case WM_NOTIFY: { LPNMHDR data = (LPNMHDR)lParam;
switch (data->code) { case TVN_ITEMEXPANDING: { if (data->hwndFrom == m_TreeView->m_hWnd) { // APPWIZ-mode: forbid item collapse. // FIXME: Prevent collapse (COMCTL32 is buggy) // https://bugs.winehq.org/show_bug.cgi?id=53727 if (m_bAppwizMode && (((LPNMTREEVIEW)lParam)->action & TVE_TOGGLE) == TVE_COLLAPSE) { theResult = TRUE; return TRUE; // Handled } } break; }
case TVN_SELCHANGED: { if (data->hwndFrom == m_TreeView->m_hWnd) { switch (((LPNMTREEVIEW)lParam)->itemNew.lParam) { case IDS_INSTALLED: UpdateApplicationsList(ENUM_ALL_INSTALLED); break;
case IDS_APPLICATIONS: UpdateApplicationsList(ENUM_INSTALLED_APPLICATIONS); break;
case IDS_UPDATES: UpdateApplicationsList(ENUM_UPDATES); break;
case IDS_AVAILABLEFORINST: UpdateApplicationsList(ENUM_ALL_AVAILABLE, FALSE, TRUE); break;
case IDS_CAT_AUDIO: UpdateApplicationsList(ENUM_CAT_AUDIO, FALSE, TRUE); break;
case IDS_CAT_DEVEL: UpdateApplicationsList(ENUM_CAT_DEVEL, FALSE, TRUE); break;
case IDS_CAT_DRIVERS: UpdateApplicationsList(ENUM_CAT_DRIVERS, FALSE, TRUE); break;
case IDS_CAT_EDU: UpdateApplicationsList(ENUM_CAT_EDU, FALSE, TRUE); break;
case IDS_CAT_ENGINEER: UpdateApplicationsList(ENUM_CAT_ENGINEER, FALSE, TRUE); break;
case IDS_CAT_FINANCE: UpdateApplicationsList(ENUM_CAT_FINANCE, FALSE, TRUE); break;
case IDS_CAT_GAMES: UpdateApplicationsList(ENUM_CAT_GAMES, FALSE, TRUE); break;
case IDS_CAT_GRAPHICS: UpdateApplicationsList(ENUM_CAT_GRAPHICS, FALSE, TRUE); break;
case IDS_CAT_INTERNET: UpdateApplicationsList(ENUM_CAT_INTERNET, FALSE, TRUE); break;
case IDS_CAT_LIBS: UpdateApplicationsList(ENUM_CAT_LIBS, FALSE, TRUE); break;
case IDS_CAT_OFFICE: UpdateApplicationsList(ENUM_CAT_OFFICE, FALSE, TRUE); break;
case IDS_CAT_OTHER: UpdateApplicationsList(ENUM_CAT_OTHER, FALSE, TRUE); break;
case IDS_CAT_SCIENCE: UpdateApplicationsList(ENUM_CAT_SCIENCE, FALSE, TRUE); break;
case IDS_CAT_TOOLS: UpdateApplicationsList(ENUM_CAT_TOOLS, FALSE, TRUE); break;
case IDS_CAT_VIDEO: UpdateApplicationsList(ENUM_CAT_VIDEO, FALSE, TRUE); break;
case IDS_CAT_THEMES: UpdateApplicationsList(ENUM_CAT_THEMES, FALSE, TRUE); break;
case IDS_SELECTEDFORINST: UpdateApplicationsList(ENUM_CAT_SELECTED); break; } } } 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_ApplicationView->SendMessageW(WM_SYSCOLORCHANGE, wParam, lParam); m_TreeView->SendMessageW(WM_SYSCOLORCHANGE, wParam, lParam); } break;
case WM_SETTINGCHANGE: if (wParam == SPI_SETNONCLIENTMETRICS || wParam == SPI_SETICONMETRICS) { DestroyIcon(g_hDefaultPackageIcon); g_hDefaultPackageIcon = NULL; // Trigger imagelist recreation on next load } break;
case WM_TIMER: if (wParam == SEARCH_TIMER_ID) { ::KillTimer(hwnd, SEARCH_TIMER_ID);
UpdateApplicationsList(SelectedEnumType); } break; }
return FALSE;}
VOIDCMainWindow::ShowAboutDlg(){ CStringW szApp; CStringW szAuthors;
szApp.LoadStringW(IDS_APPTITLE); szAuthors.LoadStringW(IDS_APP_AUTHORS); ShellAboutW(m_hWnd, szApp, szAuthors, LoadIconW(hInst, MAKEINTRESOURCEW(IDI_MAIN)));}
VOIDCMainWindow::OnCommand(WPARAM wParam, LPARAM lParam){ const BOOL bReload = TRUE; WORD wCommand = LOWORD(wParam);
if (!lParam) { switch (wCommand) { case ID_SETTINGS: CreateSettingsDlg(m_hWnd); break;
case ID_EXIT: PostMessageW(WM_CLOSE, 0, 0); break;
case ID_SEARCH: m_ApplicationView->SetFocusOnSearchBar(); break;
case ID_INSTALL: if (IsAvailableEnum(SelectedEnumType)) { if (!m_Selected.IsEmpty()) { if (DownloadListOfApplications(m_Selected)) { m_Selected.RemoveAll(); UpdateApplicationsList(SelectedEnumType); } } else { CAppInfo *App = (CAppInfo *)m_ApplicationView->GetFocusedItemData(); if (App) { InstallApplication(App); } } } break;
case ID_UNINSTALL: if (UninstallSelectedApp(FALSE)) UpdateApplicationsList(SelectedEnumType, bReload); break;
case ID_MODIFY: if (UninstallSelectedApp(TRUE)) UpdateApplicationsList(SelectedEnumType, bReload); break;
case ID_REGREMOVE: if (RemoveSelectedAppFromRegistry()) UpdateApplicationsList(SelectedEnumType, bReload); break;
case ID_REFRESH: UpdateApplicationsList(SelectedEnumType, bReload); break;
case ID_RESETDB: { CUpdateDatabaseMutex lock; m_Db->RemoveCached(); UpdateApplicationsList(SelectedEnumType, bReload); break; }
case ID_HELP: MessageBoxW(L"Help not implemented yet", NULL, MB_OK); break;
case ID_ABOUT: ShowAboutDlg(); break;
case ID_CHECK_ALL: m_ApplicationView->CheckAll(); break;
case ID_ACTIVATE_APPWIZ: if (hRootItemInstalled) m_TreeView->SelectItem(hRootItemInstalled); break; } }}
VOIDCMainWindow::UpdateStatusBarText(){ if (m_StatusBar) { CStringW szBuffer; szBuffer.Format(IDS_APPS_COUNT, m_ApplicationView->GetItemCount());
// Append the number of selected apps if not in APPWIZ-mode. if (!m_bAppwizMode) { CStringW szBuffer2; szBuffer2.Format(IDS_APPS_SELECT_COUNT, m_Selected.GetCount()); szBuffer += szBuffer2; }
m_StatusBar->SetText(szBuffer); }}
VOIDCMainWindow::AddApplicationsToView(CAtlList<CAppInfo *> &List){ POSITION CurrentListPosition = List.GetHeadPosition(); while (CurrentListPosition) { CAppInfo *Info = List.GetNext(CurrentListPosition); if (szSearchPattern.IsEmpty() || SearchPatternMatch(Info->szDisplayName, szSearchPattern) || SearchPatternMatch(Info->szComments, szSearchPattern)) { BOOL bSelected = m_Selected.Find(Info) != NULL; m_ApplicationView->AddApplication(Info, bSelected); } } m_ApplicationView->AddApplication(NULL, FALSE); // Tell the list we are done}
VOIDCMainWindow::UpdateApplicationsList(AppsCategories EnumType, BOOL bReload, BOOL bCheckAvailable){ // Only installed applications should be enumerated in APPWIZ-mode. if (m_bAppwizMode && !IsInstalledEnum(EnumType)) { ATLASSERT(FALSE && "Should not be called in APPWIZ-mode"); return; }
bUpdating = TRUE;
if (HCURSOR hCursor = LoadCursor(NULL, IDC_APPSTARTING)) { // The database (.ini files) is parsed on the UI thread, let the user know we are busy SetCursor(hCursor); PostMessage(WM_SETCURSOR, (WPARAM)m_hWnd, MAKELONG(HTCLIENT, WM_MOUSEMOVE)); }
if (bCheckAvailable) CheckAvailable();
if (m_PendingInstalledViewRefresh && IsInstalledEnum(EnumType) && !IsInstalledEnum(SelectedEnumType)) { m_PendingInstalledViewRefresh = FALSE; bReload = TRUE; // Reload because we are switching from Available to Installed after something installed }
BOOL TryRestoreSelection = SelectedEnumType == EnumType; if (SelectedEnumType != EnumType) SelectedEnumType = EnumType;
CApplicationView::RESTORELISTSELECTION RestoreSelection; if (TryRestoreSelection) m_ApplicationView->GetRestoreListSelectionData(RestoreSelection);
if (bReload) m_Selected.RemoveAll();
m_ApplicationView->SetRedraw(FALSE); if (IsInstalledEnum(EnumType)) { if (bReload) m_Db->UpdateInstalled();
// set the display type of application-view. this will remove all the item in application-view too. m_ApplicationView->SetDisplayAppType(AppViewTypeInstalledApps);
CAtlList<CAppInfo *> List; m_Db->GetApps(List, EnumType); AddApplicationsToView(List); } else if (IsAvailableEnum(EnumType)) { // We shouldn't get there in APPWIZ-mode. ATLASSERT(!m_bAppwizMode);
if (bReload) m_Db->UpdateAvailable();
// set the display type of application-view. this will remove all the item in application-view too. m_ApplicationView->SetDisplayAppType(AppViewTypeAvailableApps);
// enum available softwares if (EnumType == ENUM_CAT_SELECTED) { AddApplicationsToView(m_Selected); } else { CAtlList<CAppInfo *> List; m_Db->GetApps(List, EnumType); AddApplicationsToView(List); } } else { ATLASSERT(0 && "This should be unreachable!"); }
if (TryRestoreSelection) m_ApplicationView->RestoreListSelection(RestoreSelection); m_ApplicationView->SetRedraw(TRUE); m_ApplicationView->RedrawWindow(0, 0, RDW_INVALIDATE | RDW_ALLCHILDREN); // force the child window to repaint UpdateStatusBarText();
CStringW text; if (m_ApplicationView->GetItemCount() == 0 && !szSearchPattern.IsEmpty()) { text.LoadString(IDS_NO_SEARCH_RESULTS); } m_ApplicationView->SetWatermark(text);
bUpdating = FALSE;}
ATL::CWndClassInfo &CMainWindow::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), szWindowClass, NULL}, NULL, NULL, IDC_ARROW, TRUE, 0, _T("")}; return wc;}
HWNDCMainWindow::Create(){ const CStringW szWindowName(MAKEINTRESOURCEW(m_bAppwizMode ? IDS_APPWIZ_TITLE : 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);}
// this function is called when a item of application-view is checked/unchecked// CallbackParam is the param passed to application-view when adding the item (the one getting focus now).VOIDCMainWindow::ItemCheckStateChanged(BOOL bChecked, LPVOID CallbackParam){ if (bUpdating) return;
CAppInfo *Info = (CAppInfo *)CallbackParam;
if (bChecked) { m_Selected.AddTail(Info); } else { POSITION Pos = m_Selected.Find(Info); ATLASSERT(Pos != NULL);
if (Pos != NULL) { m_Selected.RemoveAt(Pos); } }
UpdateStatusBarText();}
// this function is called when one or more application(s) should be installed// if Info is not zero, this app should be installed. otherwise those checked apps should be installedBOOLCMainWindow::InstallApplication(CAppInfo *Info){ return Info && DownloadApplication(Info);}
BOOLCMainWindow::SearchTextChanged(CStringW &SearchText){ if (szSearchPattern == SearchText) { return FALSE; }
szSearchPattern = SearchText;
DWORD dwDelay = 0; SystemParametersInfoW(SPI_GETMENUSHOWDELAY, 0, &dwDelay, 0); SetTimer(SEARCH_TIMER_ID, dwDelay);
return TRUE;}
voidCMainWindow::HandleTabOrder(int direction){ ATL::CSimpleArray<HWND> TabOrderHwndList;
m_TreeView->AppendTabOrderWindow(direction, TabOrderHwndList); m_ApplicationView->AppendTabOrderWindow(direction, TabOrderHwndList);
if (TabOrderHwndList.GetSize() == 0) { // in case the list is empty return; }
int FocusIndex;
if ((FocusIndex = TabOrderHwndList.Find(GetFocus())) == -1) { FocusIndex = 0; // focus the first window in the list } else { FocusIndex += direction; FocusIndex += TabOrderHwndList.GetSize(); // FocusIndex might be negative. we don't want to mod a negative number FocusIndex %= TabOrderHwndList.GetSize(); }
::SetFocus(TabOrderHwndList[FocusIndex]); return;}// **** CMainWindow ****
VOIDMainWindowLoop(CMainWindow *wnd, INT nShowCmd){ HACCEL KeyBrd; MSG Msg;
hMainWnd = wnd->Create(); if (!hMainWnd) return;
/* Maximize it if we must */ wnd->ShowWindow((SettingsInfo.bSaveWndPos && SettingsInfo.Maximized) ? SW_MAXIMIZE : nShowCmd); wnd->UpdateWindow();
/* Load the menu hotkeys */ KeyBrd = LoadAcceleratorsW(NULL, MAKEINTRESOURCEW(HOTKEYS));
/* Message Loop */ while (GetMessageW(&Msg, NULL, 0, 0)) { if (!TranslateAcceleratorW(hMainWnd, KeyBrd, &Msg)) { if (Msg.message == WM_CHAR && Msg.wParam == VK_TAB) { // Move backwards if shift is held down int direction = (GetKeyState(VK_SHIFT) & 0x8000) ? -1 : 1;
wnd->HandleTabOrder(direction); continue; }
TranslateMessage(&Msg); DispatchMessageW(&Msg); } }}