|
|
//---------------------------------------------------------------------------
// This file contains Taskbar and Start Menu property sheet code
//---------------------------------------------------------------------------
#include "cabinet.h"
#include "rcids.h"
#include "util.h"
#include <help.h> // help ids
#include <regstr.h>
#include <atlstuff.h>
#include "dlg.h"
#include "tray.h"
#include "traycmn.h"
#include "startmnu.h"
#include "desktop2.h"
#include "uemapp.h"
#define GROUPID_CURRENTITEMS 5
#define GROUPID_PASTITEMS 6
#define MAX_PROGS_ALLOWED 30
const static DWORD aInitStartMenuHelpIDs[] = { IDC_NO_HELP_1, NO_HELP, IDC_NO_HELP_2, NO_HELP, IDC_NO_HELP_3, NO_HELP, IDC_NO_HELP_4, NO_HELP, IDC_GROUPBOX, IDH_COMM_GROUPBOX, IDC_GROUPBOX_2, IDH_MENUCONFIG_CLEAR, IDC_GROUPBOX_3, IDH_COMM_GROUPBOX, IDC_ADDSHORTCUT, IDH_TRAY_ADD_PROGRAM, IDC_DELSHORTCUT, IDH_TRAY_REMOVE_PROGRAM, IDC_EXPLOREMENUS, IDH_TRAY_ADVANCED, IDC_KILLDOCUMENTS, IDH_MENUCONFIG_CLEAR, IDC_RESORT, IDH_TRAY_RESORT_BUTTON, IDC_STARTMENUSETTINGSTEXT, IDH_TRAY_START_MENU_SETTINGS, 0, 0 };
const static DWORD aTaskOptionsHelpIDs[] = { // Context Help IDs
IDC_TASKBARAPPEARANCE,IDH_TASKBAR_OPTIONS_BITMAP, IDC_NOTIFYAPPEARANCE, IDH_TASKBAR_OPTIONS_BITMAP, IDC_TRAYOPTAUTOHIDE, IDH_TRAY_TASKBAR_AUTOHIDE, IDC_TRAYOPTSHOWCLOCK, IDH_TRAY_SHOW_CLOCK, IDC_TRAYOPTONTOP, IDH_TRAY_TASKBAR_ONTOP, IDC_LOCKTASKBAR, IDH_TRAY_ENABLEMOVERESIZE, IDC_GROUPITEMS, IDH_TRAY_GROUPING, IDC_NOTIFYMAN, IDH_TRAY_HIDE_ICONS, IDC_CUSTOMIZE, IDH_TRAY_CUSTOMIZE_ICONS, IDC_QUICKLAUNCH, IDH_TRAY_QUICKLAUNCH, 0, 0 };
const static DWORD aNotifyOptionsHelpIDs[] = { // Context Help IDs
IDC_NOTIFY_TEXT, NO_HELP, IDC_NOTIFY_TEXT2, NO_HELP, IDC_COMBO_ACTION, NO_HELP, IDC_NOTIFY_ITEMS, NO_HELP, IDB_NOTIFY_RESTOREDEFAULTS, IDH_TRAY_RESTOREDEFBUTTON, 0, 0 };
const static DWORD aStartTabHelpIDs[] = { IDC_STARTMENUPREVIEW, IDH_START_PREVIEW, IDC_NEWSCHOOL, IDH_START_SELECTPERSONAL, IDC_OLDSCHOOL, IDH_START_SELECTCLASSIC, IDC_NEWSTARTCUSTOMIZE, IDH_START_CUSTOMIZEPERSONAL, IDC_OLDSTARTCUSTOMIZE, IDH_START_CUSTOMIZECLASSIC, 0, 0 };
const static DWORD aStartCustGeneralTabHelpIDs[] = { IDC_SPCUST_ICONLARGE, IDH_START_SPCUST_LARGE, IDC_SPCUST_ICONSMALL, IDH_START_SPCUST_SMALL, IDC_SPCUST_LARGE, IDH_START_SPCUST_LARGE, IDC_SPCUST_SMALL, IDH_START_SPCUST_SMALL, IDC_SPCUST_MINPROGS, IDH_START_SPCUST_MINPROGS, IDC_SPCUST_MINPROGS_ARROW, IDH_START_SPCUST_MINPROGS, IDB_SPCUST_CLEARPROG, IDH_START_SPCUST_CLEARPROG, IDC_SPCUST_INTERNET, IDH_START_SPCUST_INTERNET, IDC_SPCUST_INTERNETCB, IDH_START_SPCUST_INTERNETCB, IDC_SPCUST_EMAIL, IDH_START_SPCUST_EMAIL, IDC_SPCUST_EMAILCB, IDH_START_SPCUST_EMAILCB, 0, 0 };
const static DWORD aStartCustAdvancedTabHelpIDs[] = { IDC_SPCUST_HOVEROPEN, IDH_START_SPCUST_HOVEROPEN, IDC_SPCUST_NOTIFYNEW, IDH_START_SPCUST_NOTIFYNEW, IDC_STARTMENUSETTINGS, IDH_START_STARTMENUSETTINGS, IDC_SPCUST_RECENT_GROUPBOX, NO_HELP, IDC_SPCUST_RECENT_TEXT, NO_HELP, IDC_SPCUST_RECENT, IDH_START_SPCUST_RECENT, IDB_SPCUST_CLEARDOCS, IDH_START_SPCUST_CLEARDOCS, 0, 0 };
#define REGSTR_VAL_LARGEICONSTEMP TEXT("Start_LargeIcons")
#define REGSTR_VAL_ADMINTOOLSTEMP TEXT("Start_AdminToolsTemp")
void SetDlgItemBitmap(HWND hDlg, int idStatic, int iResource); void SetDlgItemIcon(HWND hDlg, int idStatic, HICON hi); void SetProgramIcon(HWND hDlg, int idLarge, int idSmall);
void _TaskbarOptionsUpdateDisplay(HWND hDlg); void _TaskbarOptionsSizeControls(HWND hDlg); void _TaskbarOptionsDestroyBitmaps(HWND hDlg);
BOOL_PTR WINAPI AdvancedOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
typedef struct { HWND hwndTree; IRegTreeOptions *pTO; } SMADVANCED;
void SendPSMChanged(HWND hDlg) { SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L); }
class CPinHelper { public: CPinHelper(); ~CPinHelper();
void Save(BOOL bShowEmail, BOOL bShowBrowser); void GetPinInfo(BOOL *pbPinBrowser, BOOL *pbPinEmail);
private: void SavePinInfo(LPCITEMIDLIST pidlVictim, BOOL bOld, BOOL bNew);
LPITEMIDLIST _pidlBrowser; LPITEMIDLIST _pidlEmail;
IStartMenuPin *_psmp; };
CPinHelper::CPinHelper() { _pidlBrowser = ILCreateFromPath(TEXT("shell:::{2559a1f4-21d7-11d4-bdaf-00c04f60b9f0}")); _pidlEmail = ILCreateFromPath(TEXT("shell:::{2559a1f5-21d7-11d4-bdaf-00c04f60b9f0}")); CoCreateInstance(CLSID_StartMenuPin, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IStartMenuPin, &_psmp)); }
CPinHelper::~CPinHelper() { ILFree(_pidlBrowser); ILFree(_pidlEmail); ATOMICRELEASE(_psmp); }
void CPinHelper::GetPinInfo(BOOL *pbPinBrowser, BOOL *pbPinEmail) { *pbPinBrowser = FALSE; *pbPinEmail = FALSE; if (_psmp) { IEnumIDList *peidl; if (SUCCEEDED(_psmp->EnumObjects(&peidl))) { LPITEMIDLIST pidl; while (peidl->Next(1, &pidl, NULL) == S_OK) { if (ILIsEqual(pidl, _pidlBrowser)) *pbPinBrowser = TRUE; if (ILIsEqual(pidl, _pidlEmail)) *pbPinEmail = TRUE; ILFree(pidl); } peidl->Release(); } }
}
void CPinHelper::SavePinInfo(LPCITEMIDLIST pidlVictim, BOOL bOld, BOOL bNew) { ASSERT(bOld == TRUE || bOld == FALSE); ASSERT(bNew == TRUE || bNew == FALSE);
if (pidlVictim && _psmp && bOld != bNew) { if (bNew) { _psmp->Modify(NULL, pidlVictim); _psmp->Modify(pidlVictim, SMPIN_POS(0)); } else { _psmp->Modify(pidlVictim, NULL); } } }
void CPinHelper::Save(BOOL bShowEmail, BOOL bShowBrowser) { // Get old settings
BOOL bShowBrowserOld, bShowEmailOld; GetPinInfo(&bShowBrowserOld, &bShowEmailOld);
//
// Do in reverse order because we insert at the top of the list.
//
SavePinInfo(_pidlEmail, bShowEmailOld, bShowEmail); SavePinInfo(_pidlBrowser, bShowBrowserOld, bShowBrowser); }
class ATL_NO_VTABLE CNotificationsDlg : public CComObjectRootEx<CComSingleThreadModel>, public CDialogImpl<CNotificationsDlg>, public INotificationCB { public: CNotificationsDlg() { _pTrayNotify = NULL; _fItemChanged = FALSE; _hPlaceholderIcon = NULL; _nIndex = -1; _fComboBoxActive = FALSE; }; virtual ~CNotificationsDlg() { if (_pTrayNotify) { _pTrayNotify->Release(); _pTrayNotify = NULL; } };
DECLARE_NOT_AGGREGATABLE(CNotificationsDlg)
BEGIN_COM_MAP(CNotificationsDlg) COM_INTERFACE_ENTRY(INotificationCB) END_COM_MAP()
enum {IDD = DLG_NOTIFY}; BEGIN_MSG_MAP_EX(CNotificationsDlg) MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu) MESSAGE_HANDLER(WM_HELP, OnHelp) NOTIFY_HANDLER_EX(IDC_NOTIFY_ITEMS, LVN_ITEMCHANGED, OnItemChanged) NOTIFY_HANDLER_EX(IDC_NOTIFY_ITEMS, LVN_ENDSCROLL, OnEndScroll) NOTIFY_CODE_HANDLER(HDN_ITEMCHANGED, OnHeaderItemChanged) COMMAND_HANDLER_EX(IDC_COMBO_ACTION, CBN_SELENDOK, OnComboSelEnd) COMMAND_ID_HANDLER_EX(IDB_NOTIFY_RESTOREDEFAULTS, OnRestoreDefaults) COMMAND_RANGE_HANDLER(IDOK, IDNO, OnCloseCmd) END_MSG_MAP()
//*** INotificationCB ***
STDMETHODIMP Notify(DWORD dwMessage, LPNOTIFYITEM pNotifyItem);
//*** Message Callbacks ***
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnItemChanged(LPNMHDR pnmh); LRESULT OnEndScroll(LPNMHDR pnmh); LRESULT OnHeaderItemChanged(WPARAM wParam, LPNMHDR pnmh, LPARAM lParam); LRESULT OnComboSelEnd(UINT uMsg, UINT uID , HWND hwnd);
LRESULT OnRestoreDefaults(UINT uMsg, UINT uID , HWND hwnd); LRESULT OnCloseCmd(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
static LRESULT CALLBACK s_ListViewSubClassWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
static LRESULT CALLBACK s_ComboBoxSubClassWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
//*** Other ***
void ApplyChanges(void);
private: HRESULT _AddItem(CNotificationItem& ni, int iIndex); void _ShowComboBox(); int _GetCurSel(); void _LoadAndSetLVItemText(UINT uResourceID, DWORD nRow, DWORD nCol);
CSimpleArray<CNotificationItem> _saItems; //copy of the data, initialized by user
BOOL _fItemChanged; ITrayNotify* _pTrayNotify; int _nPrevIndex; HWND _hwndCombo; HWND _hwndListView; RECT _rcOldPos; HICON _hPlaceholderIcon; BOOL _fComboBoxActive; int _nIndex; };
HRESULT CNotificationsDlg::_AddItem(CNotificationItem& ni, int iIndex) { HIMAGELIST himl = ListView_GetImageList(_hwndListView, LVSIL_SMALL); BOOL fInsert = FALSE; LV_ITEM lvitem = {0}; int iImage = -1;
if (!ni.hIcon) { if (!_hPlaceholderIcon) { _hPlaceholderIcon = (HICON)LoadImage(hinstCabinet, MAKEINTRESOURCE(ICO_TRAYPROP_PLACEHOLDER), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_LOADMAP3DCOLORS); }
if (_hPlaceholderIcon) ni.hIcon = CopyIcon(_hPlaceholderIcon); } if (iIndex == -1) { iIndex = _saItems.GetSize(); iImage = ImageList_AddIcon(himl, ni.hIcon); fInsert = TRUE; } else { lvitem.mask = LVIF_IMAGE; lvitem.iItem = iIndex; lvitem.iSubItem = 0; ListView_GetItem(_hwndListView, &lvitem); ImageList_ReplaceIcon(himl, lvitem.iImage, ni.hIcon); iImage = lvitem.iImage; fInsert = FALSE; }
if (!ni.pszIconText || ni.pszIconText[0] == 0) { TCHAR szTemp[MAX_PATH]; if (LoadString(hinstCabinet, IDS_NOTITLE, szTemp, ARRAYSIZE(szTemp))) ni.SetIconText(szTemp); // ni.m_strText.LoadString(IDS_NOTITLE);
} else // Replace '\n' with ' '
{ LPTSTR szTemp = NULL; while (NULL != (szTemp = StrChr(ni.pszIconText, TEXT('\n')))) { ni.pszIconText[szTemp-ni.pszIconText] = TEXT(' '); } }
lvitem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_GROUPID; lvitem.iItem = iIndex; lvitem.iSubItem = 0; lvitem.pszText = ni.pszIconText; lvitem.iImage = iImage; lvitem.iGroupId = (ni.hWnd == NULL) ? GROUPID_PASTITEMS : GROUPID_CURRENTITEMS; if (fInsert) ListView_InsertItem(_hwndListView, &lvitem); else ListView_SetItem(_hwndListView, &lvitem);
lvitem.mask = LVIF_TEXT; lvitem.iItem = iIndex; lvitem.iSubItem = 1;
CString str; str.LoadString(IDS_NOTIFY_FIRST + ni.dwUserPref); lvitem.pszText = (LPTSTR)(LPCTSTR)str; ListView_SetItem(_hwndListView, &lvitem);
if (fInsert) { _saItems.Add(ni); } else { _saItems[iIndex] = ni; }
return S_OK; }
HRESULT CNotificationsDlg::Notify(DWORD dwMessage, NOTIFYITEM * pNotifyItem) { if (!pNotifyItem || (!pNotifyItem->hWnd && !pNotifyItem->pszExeName)) return E_INVALIDARG;
ASSERT(pNotifyItem); CNotificationItem ni = *pNotifyItem;
switch (dwMessage) { case NIM_ADD: case NIM_MODIFY: { // We never need to modify a Past Item
for (int i = 0; (i < _saItems.GetSize() && ni.hWnd); i++) { // If the Item is already in the list just update it
if (_saItems[i] == ni) { return _AddItem(ni, i); } }
// If it is not in the list add it
return _AddItem(ni, -1); } break;
case NIM_DELETE: { for (int i = 0; (i < _saItems.GetSize()); i++) { if (_saItems[i] == ni) { _saItems.RemoveAt(i); ListView_DeleteItem(_hwndListView, i); _ShowComboBox();
return S_OK; } } break; } }
return E_INVALIDARG; }
LRESULT CNotificationsDlg::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { _hwndListView = GetDlgItem(IDC_NOTIFY_ITEMS); _nPrevIndex = -2; _rcOldPos.top = -500;
CImageList il; int iSize = GetSystemMetrics(SM_CXSMICON); il.Create(iSize, iSize, SHGetImageListFlags(_hwndListView), _saItems.GetSize(), 4); if (il) { CString str; //list view control holding all the items
ListView_SetExtendedListViewStyle(_hwndListView, LVS_EX_FULLROWSELECT); ListView_EnableGroupView(_hwndListView, TRUE);
static const struct { int ids; int idGroup; } groupData[] = {{ IDS_NOTIFY_CURRENTITEMS, GROUPID_CURRENTITEMS }, { IDS_NOTIFY_PASTITEMS, GROUPID_PASTITEMS }};
for (int i = 0; i < ARRAYSIZE(groupData); i++) { str.LoadString(groupData[i].ids); LVGROUP lvgrp = { sizeof(LVGROUP) }; lvgrp.mask = LVGF_HEADER | LVGF_GROUPID; lvgrp.pszHeader = (LPTSTR)(LPCTSTR)str; lvgrp.cchHeader = lstrlen(lvgrp.pszHeader); lvgrp.iGroupId = groupData[i].idGroup; SendMessage(_hwndListView, LVM_INSERTGROUP, -1, (LPARAM)&lvgrp); }
//Split width of columns 3/5, 2/5
RECT rc; ::GetClientRect(_hwndListView, &rc); int width = rc.right - rc.left - GetSystemMetrics(SM_CXHSCROLL); int width0 = 3*width/5; int width1 = width-width0;
LV_COLUMN lvcol = {0}; lvcol.mask = LVCF_TEXT | LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM; str.LoadString(IDS_NOTIFYNAME); lvcol.pszText = (LPTSTR)(LPCTSTR)str; lvcol.cx = width0; lvcol.iSubItem = 0; ListView_InsertColumn(_hwndListView, 0, &lvcol);
str.LoadString(IDS_BEHAVIOR); lvcol.pszText = (LPTSTR)(LPCTSTR)str; lvcol.cx = width1; lvcol.iSubItem = 1; ListView_InsertColumn(_hwndListView, 1, &lvcol);
il.SetBkColor(GetSysColor(COLOR_WINDOW)); ListView_SetImageList(_hwndListView, il, LVSIL_SMALL); il.Detach();
_hwndCombo = GetDlgItem(IDC_COMBO_ACTION); // make sure combo box uses same font as list view
::SendMessage(_hwndCombo, WM_SETFONT, (WPARAM)::SendMessage(_hwndListView, WM_GETFONT, 0, 0), MAKELPARAM(TRUE, 0)); for (int i = IDS_NOTIFY_FIRST; i < IDS_NOTIFY_LAST; i++) { CString strTemp; strTemp.LoadString(i); ComboBox_AddString(_hwndCombo, strTemp); }
::SetParent(_hwndCombo, _hwndListView); HWND hwndHeader = ListView_GetHeader(_hwndListView); ::SetWindowPos(_hwndCombo, hwndHeader, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW);
::SetWindowSubclass(_hwndListView, s_ListViewSubClassWndProc, 0, reinterpret_cast<DWORD_PTR>(this));
::SetWindowSubclass(_hwndCombo, s_ComboBoxSubClassWndProc, 0, reinterpret_cast<DWORD_PTR>(this)); }
_saItems.RemoveAll(); if (_pTrayNotify) { _pTrayNotify->Release(); _pTrayNotify = NULL; }
if (SUCCEEDED(CoCreateInstance(CLSID_TrayNotify, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARG(ITrayNotify, &_pTrayNotify)))) { INotificationCB* pCB;
if (SUCCEEDED(QueryInterface(IID_PPV_ARG(INotificationCB, &pCB)))) { _pTrayNotify->RegisterCallback(pCB); pCB->Release(); } }
// Set the selected and focused state to the first item
// ListView_SetItemState(hwndLV, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
bHandled = TRUE; return 0; }
LRESULT CNotificationsDlg::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { ::WinHelp((HWND) wParam, NULL, HELP_CONTEXTMENU, (ULONG_PTR)(void *)aNotifyOptionsHelpIDs); bHandled = TRUE; return 0; }
LRESULT CNotificationsDlg::OnHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { ::WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, NULL, HELP_WM_HELP, (ULONG_PTR)(LPTSTR) aNotifyOptionsHelpIDs); bHandled = TRUE; return 0; }
LRESULT CNotificationsDlg::OnItemChanged(LPNMHDR pnmh) { _ShowComboBox(); return 0; }
LRESULT CNotificationsDlg::OnEndScroll(LPNMHDR pnmh) { _ShowComboBox(); return 0; }
LRESULT CNotificationsDlg::OnHeaderItemChanged(WPARAM wParam, LPNMHDR pnmh, LPARAM lParam) { HWND hwndHeader = ListView_GetHeader(_hwndListView); if (pnmh->hwndFrom == hwndHeader) { _ShowComboBox(); }
return 0; }
int CNotificationsDlg::_GetCurSel() { return (int)::SendMessage(_hwndListView, LVM_GETNEXTITEM, -1, MAKELPARAM(LVNI_ALL | LVNI_SELECTED, 0)); }
void CNotificationsDlg::_LoadAndSetLVItemText(UINT uResourceID, DWORD nRow, DWORD nCol) { CString str; str.LoadString(uResourceID); ListView_SetItemText(_hwndListView, nRow, nCol, (LPTSTR)(LPCTSTR)str); }
LRESULT CNotificationsDlg::OnComboSelEnd(UINT uMsg, UINT uID ,HWND hwnd) { int nCurIndex = _fComboBoxActive ? _nIndex : _GetCurSel(); if (nCurIndex != -1) { DWORD dwUserPref = ComboBox_GetCurSel(_hwndCombo); if (dwUserPref != _saItems[nCurIndex].dwUserPref) { _fItemChanged = TRUE; _saItems[nCurIndex].dwUserPref = dwUserPref; _LoadAndSetLVItemText(IDS_NOTIFY_FIRST + dwUserPref, nCurIndex, 1); } }
return 0; }
LRESULT CNotificationsDlg::OnRestoreDefaults(UINT uMsg, UINT uID , HWND hwnd) { for (int i=0;i<_saItems.GetSize();i++) { if (_saItems[i].dwUserPref != TNUP_AUTOMATIC) { _fItemChanged = TRUE; _saItems[i].dwUserPref = TNUP_AUTOMATIC; _LoadAndSetLVItemText(IDS_AUTOMATIC, i, 1); } }
return 0; }
LRESULT CNotificationsDlg::OnCloseCmd(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { if (wID == IDOK) { ApplyChanges(); }
if (_hPlaceholderIcon) { DestroyIcon(_hPlaceholderIcon); _hPlaceholderIcon = NULL; }
_saItems.RemoveAll();
if (_hwndListView) { RemoveWindowSubclass(_hwndListView, s_ListViewSubClassWndProc, 0); }
if (_hwndCombo) { RemoveWindowSubclass(_hwndCombo, s_ComboBoxSubClassWndProc, 0); }
if (_pTrayNotify) { _pTrayNotify->RegisterCallback(NULL); }
bHandled = TRUE; ::EndDialog(m_hWnd, wID); return 0; }
LRESULT CALLBACK CNotificationsDlg::s_ListViewSubClassWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) { CNotificationsDlg * pNotificationsDlg = reinterpret_cast<CNotificationsDlg*>(dwRefData); AssertMsg((pNotificationsDlg != NULL), TEXT("pNotificationsDlg SHOULD NOT be NULL."));
switch (uMsg) { case WM_KEYDOWN: { if (wParam == VK_RIGHT && !pNotificationsDlg->_fComboBoxActive) { int nIndex = pNotificationsDlg->_GetCurSel(); if (nIndex != -1) { pNotificationsDlg->_nIndex = nIndex; pNotificationsDlg->_fComboBoxActive = TRUE; ::SetFocus(pNotificationsDlg->_hwndCombo); } return 0; } } break; }
return DefSubclassProc(hwnd, uMsg, wParam, lParam); }
LRESULT CALLBACK CNotificationsDlg::s_ComboBoxSubClassWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData ) { CNotificationsDlg * pNotificationsDlg = reinterpret_cast<CNotificationsDlg*>(dwRefData); AssertMsg((pNotificationsDlg != NULL), TEXT("pNotificationsDlg SHOULD NOT be NULL."));
switch (uMsg) { case WM_KEYDOWN: { if (pNotificationsDlg->_fComboBoxActive) { if (wParam == VK_LEFT) { pNotificationsDlg->_fComboBoxActive = FALSE; pNotificationsDlg->_nIndex = 0; ::SetFocus(pNotificationsDlg->_hwndListView); return 0; } else if (wParam == VK_RIGHT) { // Disable selection in combo on right button
return 0; } } } break;
case WM_KILLFOCUS: { if (pNotificationsDlg->_fComboBoxActive) { pNotificationsDlg->_fComboBoxActive = FALSE; pNotificationsDlg->_nIndex = 0; } } break; }
return DefSubclassProc(hwnd, uMsg, wParam, lParam); }
void CNotificationsDlg::ApplyChanges(void) { if (!_fItemChanged) return; if (_pTrayNotify) { for (int i = 0; i < _saItems.GetSize(); i++) { _pTrayNotify->SetPreference(&_saItems[i]); } } }
void CNotificationsDlg::_ShowComboBox(void) { int nCurIndex = _GetCurSel(); if (!_fComboBoxActive && nCurIndex == -1) { ::ShowWindow(_hwndCombo, SW_HIDE); } else if (nCurIndex != -1) { RECT rcListView; ::GetClientRect(_hwndListView, &rcListView);
RECT rc; ListView_GetItemRect(_hwndListView, nCurIndex, &rc, LVIR_BOUNDS);
RECT rcHeader; HWND hwndHeader = ListView_GetHeader(_hwndListView); Header_GetItemRect(hwndHeader, 1, &rcHeader); rc.left = rcHeader.left; rc.right = rcHeader.right;
if (!EqualRect(&_rcOldPos, &rc)) { _rcOldPos = rc; ::MoveWindow(_hwndCombo, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); }
if (!::IsWindowVisible(_hwndCombo)) { ::ShowWindow(_hwndCombo, SW_SHOW); ComboBox_SetCurSel(_hwndCombo, _saItems[nCurIndex].dwUserPref); } } }
//This is the property sheet for all of the task bar stuff
class CTaskBarPropertySheet : public CPropertySheetImpl<CTaskBarPropertySheet> { public: CTaskBarPropertySheet(UINT nStartPage, HWND hwndParent, DWORD dwFlags) : CPropertySheetImpl<CTaskBarPropertySheet>((LPCTSTR)NULL, nStartPage, hwndParent), _dwFlags(dwFlags) { LoadString(hinstCabinet, IDS_STARTMENUANDTASKBAR, szPath, ARRAYSIZE(szPath)); SetTitle(szPath);
HPROPSHEETPAGE hpage; PROPSHEETPAGE psp;
psp.dwSize = sizeof(psp); psp.dwFlags = PSP_DEFAULT; psp.hInstance = hinstCabinet;
//taskbar page
psp.pszTemplate = MAKEINTRESOURCE(DLG_TRAY_OPTIONS); psp.pfnDlgProc = s_TaskbarOptionsDlgProc; psp.lParam = (LPARAM) this; hpage = CreatePropertySheetPage(&psp); if (hpage) AddPage(hpage);
//start page
psp.pszTemplate = MAKEINTRESOURCE(DLG_START); psp.pfnDlgProc = s_StartMenuDlgProc; psp.lParam = (LPARAM) this; hpage = CreatePropertySheetPage(&psp); if (hpage) AddPage(hpage);
//
// We really want to have the tree-options work like the StartPageOptionHelper class above, but
// it stores state in the treeview, which goes away when the child dialog is closed. So for now,
// have it save when the customize dialog is closed, not when the parent is closed.
// Still, have the lifetime of the object be controlled by the parent.
//
if (FAILED(CoCreateInstance(CLSID_CRegTreeOptions, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IRegTreeOptions, &_Adv.pTO)))) { TraceMsg(TF_WARNING, "ctbps failed to create CRegTreeOptions"); }
_pDlgNotify = new CComObject<CNotificationsDlg>; if (_pDlgNotify) { _pDlgNotify->AddRef(); } }
~CTaskBarPropertySheet() { ATOMICRELEASE(_Adv.pTO); ATOMICRELEASE(_pDlgNotify); }
// We aren't handling any messages special, so we just make an empty map
DECLARE_EMPTY_MSG_MAP() private:
// dlgproc's for the various pages
static BOOL_PTR s_TaskbarOptionsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); static BOOL_PTR s_StartMenuDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); BOOL_PTR TaskbarOptionsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); BOOL_PTR StartMenuDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void _ApplyTaskbarOptionsFromDialog(HWND hDlg); void _ApplyStartOptionsFromDialog(HWND hDlg);
// for the old style customize dialog
SMADVANCED _Adv; //need to keep storage for the title until the property sheet is created
TCHAR szPath[MAX_PATH]; CComObject<CNotificationsDlg>* _pDlgNotify;
DWORD _dwFlags; };
//
// RegSaveDefaultClient
//
void RegSaveDefaultClient(HWND hwndCB, LPCTSTR pszPath) { int iSelected = ComboBox_GetCurSel(hwndCB); if (iSelected >= 0) { LPTSTR pszKey = (LPTSTR)ComboBox_GetItemData(hwndCB, iSelected); if (pszKey) { if (SHSetValue(HKEY_CURRENT_USER, pszPath, NULL, REG_SZ, pszKey, sizeof(TCHAR) * (1 + lstrlen(pszKey))) == ERROR_SUCCESS) { SHSendMessageBroadcast(WM_SETTINGCHANGE, 0, (LPARAM)pszPath); } } } }
BOOL RegGetDefaultClient(HWND hwndCB, HKEY hkRoot, LPCTSTR pszPath) { TCHAR szCurrent[MAX_PATH]; LONG cb = sizeof(szCurrent);
cb = sizeof(szCurrent); if (RegQueryValue(hkRoot, pszPath, szCurrent, &cb) != ERROR_SUCCESS || szCurrent[0] == TEXT('\0')) { return FALSE; }
// Now make sure the selected client exists
int i = ComboBox_GetCount(hwndCB); while (--i >= 0) { LPTSTR pszKey = (LPTSTR)ComboBox_GetItemData(hwndCB, i); // Use StrCmpIC so we don't get faked out by Hungarian locale...
if (pszKey && StrCmpIC(pszKey, szCurrent) == 0) { ComboBox_SetCurSel(hwndCB, i); return TRUE; } }
return FALSE; }
void RegPopulateComboBox(HWND hwndCB, LPCTSTR pszPath) { TCHAR szFriendlyName [MAX_PATH]; TCHAR szKeyName [MAX_PATH];
DWORD i; // Index counter
HKEY hkeyProtocol;
// See if the clients key even exists...
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, pszPath, 0, KEY_READ, &hkeyProtocol) != ERROR_SUCCESS) return;
// populate the dropdown
for(i=0; // always start with 0
ERROR_SUCCESS==RegEnumKey(hkeyProtocol, i, szKeyName, ARRAYSIZE(szKeyName)); i++) // get next entry
{ // get the friendly name of the client
if (SUCCEEDED(SHLoadLegacyRegUIString(hkeyProtocol, szKeyName, szFriendlyName, ARRAYSIZE(szFriendlyName)))) { // save its key name so we can find it later
LPTSTR pszKeyName = StrDup(szKeyName); if (pszKeyName) { // add name to dropdown
int iAdded = ComboBox_AddString(hwndCB, szFriendlyName); if (iAdded >= 0) { ComboBox_SetItemData(hwndCB, iAdded, pszKeyName); } else { LocalFree(pszKeyName); } } } }
RegCloseKey(hkeyProtocol);
// Do this after populating the dropdown because we need to look into
// the dropdown to see if the current value is valid or not
//
// First try HKCU; then try HKLM...
//
if (!RegGetDefaultClient(hwndCB, HKEY_CURRENT_USER, pszPath)) { RegGetDefaultClient(hwndCB, HKEY_LOCAL_MACHINE, pszPath); } }
void RegClearClientComboBox(HWND hDlg, UINT idc) { HWND hwndCB = GetDlgItem(hDlg, idc);
int i = ComboBox_GetCount(hwndCB); while (--i >= 0) { LPTSTR pszKey = (LPTSTR)ComboBox_GetItemData(hwndCB, i); LocalFree(pszKey); } }
void HandleClearButtonClick(HWND hwndClear); void SetDocButton(HWND hDlg, int id);
//This is the property sheet for the "Customize Simple Start Menu" dlg
class CCustomizeSPPropSheet : public CPropertySheetImpl<CCustomizeSPPropSheet> { public: CCustomizeSPPropSheet(HWND hwndParent) : CPropertySheetImpl<CCustomizeSPPropSheet>((LPCTSTR)NULL, 0, hwndParent) , _fInsideInit(FALSE) { HPROPSHEETPAGE hpage; PROPSHEETPAGE psp;
// We are heap-allocated so these should be pre-initialized properly
ASSERT(_bDirtyTree == FALSE); ASSERT(_prto == NULL); ASSERT(_pph == NULL);
LoadString(hinstCabinet, IDS_SPCUST_TITLE, _szTitle, ARRAYSIZE(_szTitle)); SetTitle(_szTitle);
m_psh.dwFlags |= PSH_NOAPPLYNOW;
psp.dwSize = sizeof(psp); psp.dwFlags = PSP_DEFAULT; psp.hInstance = hinstCabinet;
//General page
psp.pszTemplate = MAKEINTRESOURCE(DLG_PAGE_SMGENERAL); psp.pfnDlgProc = s_GeneralTabDlgProc; psp.lParam = (LPARAM) this; hpage = CreatePropertySheetPage(&psp); if (hpage) AddPage(hpage);
//Advanced page
psp.pszTemplate = MAKEINTRESOURCE(DLG_PAGE_SMADVANCED); psp.pfnDlgProc = s_AdvancedTabDlgProc; psp.lParam = (LPARAM) this; hpage = CreatePropertySheetPage(&psp); if (hpage) AddPage(hpage);
};
~CCustomizeSPPropSheet() { if (_pph) delete _pph;
ATOMICRELEASE(_prto); }
private:
// dlgproc's for the various pages
static BOOL_PTR s_GeneralTabDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); static BOOL_PTR s_AdvancedTabDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); BOOL_PTR GeneralTabDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); BOOL_PTR AdvancedTabDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); BOOL GeneralTabInit(HWND hDlg); BOOL AdvancedTabInit(HWND hDlg);
BOOL OnCommand(UINT id, UINT code, HWND hwndCtl, HWND hwndDlg); // shared command handler
BOOL OnGeneralApply(HWND hwndDlg); BOOL_PTR OnAdvancedNotify(HWND hwndDlg, NMHDR * pnm); BOOL_PTR OnAdvancedHelp(HWND hDlg, HELPINFO *phi);
void _InitMagicEntries(); void _SaveMagicEntries();
//helpers
DWORD _ReadStartPageSetting(LPCTSTR pszVal, DWORD dwDefault) { DWORD dw, cb=sizeof(dw), dwType; SHRegGetUSValue(REGSTR_PATH_STARTPANE_SETTINGS, pszVal, &dwType, &dw, &cb, FALSE, &dwDefault, sizeof(dwDefault)); return dw; // since we passed a default value, above fn will return our default on failure
} BOOL _ReadStartPageCUSetting(LPCTSTR pszVal, DWORD *pdw) // returns TRUE/FALSE for present under CU or not, actual value in pdw
{ DWORD cb=sizeof(*pdw), dwType; return NO_ERROR == SHGetValue(HKEY_CURRENT_USER, REGSTR_PATH_STARTPANE_SETTINGS, pszVal, &dwType, pdw, &cb); } BOOL _WriteStartPageSetting(LPCTSTR pszVal, DWORD dwVal) { return SHSetValue(HKEY_CURRENT_USER, REGSTR_PATH_STARTPANE_SETTINGS, pszVal, REG_DWORD, &dwVal, sizeof(DWORD)) == NO_ERROR; } BOOL _ClearStartPageSetting(LPCTSTR pszVal) { return SHDeleteValue(HKEY_CURRENT_USER, REGSTR_PATH_STARTPANE_SETTINGS, pszVal) == NO_ERROR; }
// State
BOOL _bLargeIcons; IRegTreeOptions *_prto;
// Dirty Flags
BOOL _bDirtyTree; // to avoid saving the tree if we don't need to
BOOL _bDirtyClients; // to avoid saving the clients if we don't need to
BOOL _bDirtyPinList; // to avoid re-persisting the pin list (and possibly changing the order)
BOOL _bCustNetPlaces; // Did the user previously have net places customized?
BOOL _bCustNetConn; // Did the user previously have net connections customized?
// random bits
CPinHelper *_pph; TCHAR _szTitle[80]; // needed for the propsheet title...
// We need this to take care of initialization!
BOOL _fInsideInit; };
BOOL_PTR CCustomizeSPPropSheet::s_GeneralTabDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { CCustomizeSPPropSheet* self = NULL;
if (uMsg == WM_INITDIALOG) { ::SetWindowLongPtr(hDlg, DWLP_USER, lParam); self = (CCustomizeSPPropSheet*) ((PROPSHEETPAGE*)lParam)->lParam; } else { PROPSHEETPAGE* psp = (PROPSHEETPAGE*)::GetWindowLongPtr(hDlg, DWLP_USER); if (psp) self = (CCustomizeSPPropSheet*)psp->lParam; }
if (self) { return self->GeneralTabDlgProc(hDlg, uMsg, wParam, lParam); } else { return FALSE; } }
BOOL_PTR CCustomizeSPPropSheet::s_AdvancedTabDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { CCustomizeSPPropSheet* self = NULL;
if (uMsg == WM_INITDIALOG) { ::SetWindowLongPtr(hDlg, DWLP_USER, lParam); self = (CCustomizeSPPropSheet*) ((PROPSHEETPAGE*)lParam)->lParam; } else { PROPSHEETPAGE* psp = (PROPSHEETPAGE*)::GetWindowLongPtr(hDlg, DWLP_USER); if (psp) self = (CCustomizeSPPropSheet*)psp->lParam; }
if (self) { return self->AdvancedTabDlgProc(hDlg, uMsg, wParam, lParam); } else { return FALSE; } }
BOOL_PTR CCustomizeSPPropSheet::GeneralTabDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: return GeneralTabInit(hDlg); case WM_COMMAND: return OnCommand(LOWORD(wParam), HIWORD(wParam), (HWND) lParam, hDlg); case WM_DESTROY: { SetDlgItemIcon(hDlg, IDC_SPCUST_ICONSMALL, NULL); SetDlgItemIcon(hDlg, IDC_SPCUST_ICONLARGE, NULL); RegClearClientComboBox(hDlg, IDC_SPCUST_EMAILCB); RegClearClientComboBox(hDlg, IDC_SPCUST_INTERNETCB); break; } case WM_NOTIFY: switch (((NMHDR*)lParam)->code) { case PSN_APPLY: return OnGeneralApply(hDlg);
} break;
case WM_HELP: ::WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, NULL, HELP_WM_HELP, (ULONG_PTR)(LPTSTR) aStartCustGeneralTabHelpIDs); break;
case WM_CONTEXTMENU: ::WinHelp((HWND) wParam, NULL, HELP_CONTEXTMENU, (ULONG_PTR)(void *)aStartCustGeneralTabHelpIDs); break; } return FALSE; }
BOOL CCustomizeSPPropSheet::GeneralTabInit(HWND hDlg) { _fInsideInit = TRUE; //We are getting inside initilization!
::SendMessage(::GetDlgItem(hDlg, IDC_SPCUST_MINPROGS_ARROW), UDM_SETRANGE, 0, (LPARAM)MAKELONG(MAX_PROGS_ALLOWED, 0)); // set up icon size
_bLargeIcons = _ReadStartPageSetting(REGSTR_VAL_DV2_LARGEICONS, /*bDefault*/ TRUE); ::CheckDlgButton(hDlg, IDC_SPCUST_LARGE, _bLargeIcons); ::CheckDlgButton(hDlg, IDC_SPCUST_SMALL, !_bLargeIcons);
SetProgramIcon(hDlg, IDC_SPCUST_ICONLARGE, IDC_SPCUST_ICONSMALL);
// Set up the Number of programs dropdown
DWORD dwMinMFU = _ReadStartPageSetting(REGSTR_VAL_DV2_MINMFU, REGSTR_VAL_DV2_MINMFU_DEFAULT); ::SetDlgItemInt(hDlg, IDC_SPCUST_MINPROGS, dwMinMFU, FALSE);
// Set up internet, email checkboxes and comboboxes
BOOL bInternet=FALSE, bMail=FALSE; RegPopulateComboBox(::GetDlgItem(hDlg, IDC_SPCUST_EMAILCB), TEXT("SOFTWARE\\Clients\\mail")); RegPopulateComboBox(::GetDlgItem(hDlg, IDC_SPCUST_INTERNETCB), TEXT("SOFTWARE\\Clients\\StartMenuInternet"));
// if this fails, its not fatal, we just won't be able to persist the pin info
_pph = new CPinHelper(); if (_pph) { _pph->GetPinInfo(&bInternet, &bMail); }
::CheckDlgButton(hDlg, IDC_SPCUST_INTERNET, bInternet); ::CheckDlgButton(hDlg, IDC_SPCUST_EMAIL, bMail); ::EnableWindow(::GetDlgItem(hDlg, IDC_SPCUST_INTERNETCB), bInternet); ::EnableWindow(::GetDlgItem(hDlg, IDC_SPCUST_EMAILCB), bMail);
_fInsideInit = FALSE; //We are done initializing.
return TRUE; }
// Temp until the new UEM code gets in...
void ClearUEMData() { HKEY hk;
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_EXPLORER TEXT("\\UserAssist\\{75048700-EF1F-11D0-9888-006097DEACF9}\\Count"), 0, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_SET_VALUE, &hk)) { int cValues; if (ERROR_SUCCESS == RegQueryInfoKey(hk, NULL, NULL, NULL, NULL, NULL, NULL, (DWORD*) &cValues, NULL, NULL, NULL, NULL)) { while (cValues >= 0) { TCHAR szValue[MAX_PATH]; DWORD cch = ARRAYSIZE(szValue); DWORD cbData; if (ERROR_SUCCESS != RegEnumValue(hk, --cValues, szValue, &cch, NULL, NULL, NULL, &cbData)) break; // don't nuke the session value
if (cbData > 8) RegDeleteValue(hk, szValue); } #ifdef DEBUG
RegQueryInfoKey(hk, NULL, NULL, NULL, NULL, NULL, NULL, (DWORD*) &cValues, NULL, NULL, NULL, NULL); ASSERT(cValues == 1); // the session info value should still exist
#endif
}
RegCloseKey(hk);
// Set the "Apps installed prior to this point are not interesting"
// to the current time. Since we deleted all the usages, we have to
// do something to prevent all the user's apps from being redetected
// as "newly installed and not yet run".
FILETIME ftNow; GetSystemTimeAsFileTime(&ftNow); SHRegSetUSValue(DV2_REGPATH, DV2_SYSTEM_START_TIME, REG_BINARY, &ftNow, sizeof(ftNow), SHREGSET_FORCE_HKCU);
// Start a new session - this kick-starts anybody who is listening
// to UEM events to tell them their cache is invalid
UEMFireEvent(&UEMIID_SHELL, UEME_CTLSESSION, UEMF_XEVENT, TRUE, -1); } }
void AdjustNumOfProgsOnStartMenu(HWND hwndDlg, UINT Id) { BOOL fTranslated; int iNumOfProgs = (int)GetDlgItemInt(hwndDlg, Id, &fTranslated, FALSE); int iNewNumOfProgs = min(max(iNumOfProgs, 0), MAX_PROGS_ALLOWED); if((iNumOfProgs != iNewNumOfProgs) || (!fTranslated)) { SetDlgItemInt(hwndDlg, Id, (UINT)iNewNumOfProgs, FALSE); SendPSMChanged(hwndDlg); } }
// NOTE - shared WM_COMMAND handler
//
BOOL CCustomizeSPPropSheet::OnCommand(UINT id, UINT code, HWND hwndCtl, HWND hwndDlg) { switch (id) { ////// General Tab Controls
case IDC_SPCUST_LARGE: case IDC_SPCUST_SMALL: _bLargeIcons = (id == IDC_SPCUST_LARGE); SendPSMChanged(hwndDlg); return FALSE; case IDC_SPCUST_MINPROGS: if(code == EN_KILLFOCUS) AdjustNumOfProgsOnStartMenu(hwndDlg, id); else { if ((_fInsideInit == FALSE) && (code == EN_CHANGE)) SendPSMChanged(hwndDlg); } return FALSE; case IDB_SPCUST_CLEARPROG: ClearUEMData(); return FALSE;
case IDC_SPCUST_INTERNET: case IDC_SPCUST_EMAIL: COMPILETIME_ASSERT(IDC_SPCUST_INTERNETCB == IDC_SPCUST_INTERNET+1); COMPILETIME_ASSERT(IDC_SPCUST_EMAILCB == IDC_SPCUST_EMAIL+1); ::EnableWindow(::GetDlgItem(hwndDlg, id+1), ::IsDlgButtonChecked(hwndDlg, id)); _bDirtyPinList = TRUE; SendPSMChanged(hwndDlg); return FALSE;
case IDC_SPCUST_INTERNETCB: case IDC_SPCUST_EMAILCB: if (code == CBN_SELCHANGE) { _bDirtyClients = TRUE; SendPSMChanged(hwndDlg); } return FALSE;
////// Advanced Tab Controls
case IDC_SPCUST_RECENT: SendPSMChanged(hwndDlg); return FALSE; case IDB_SPCUST_CLEARDOCS: HandleClearButtonClick(hwndCtl); return FALSE;
case IDC_SPCUST_HOVEROPEN: case IDC_SPCUST_NOTIFYNEW: SendPSMChanged(hwndDlg); return FALSE; break;
} return TRUE; }
BOOL CCustomizeSPPropSheet::OnGeneralApply(HWND hDlg) { TraceMsg(TF_ALWAYS, "cspps.General apply", _bDirtyTree);
_WriteStartPageSetting(REGSTR_VAL_DV2_LARGEICONS, _bLargeIcons);
if (_pph && _bDirtyPinList) { BOOL bInternet = ::IsDlgButtonChecked(hDlg, IDC_SPCUST_INTERNET); BOOL bMail = ::IsDlgButtonChecked(hDlg, IDC_SPCUST_EMAIL); _pph->Save(bMail, bInternet); } if (_bDirtyClients) { // persist Internet, Mail comboboxes
RegSaveDefaultClient(::GetDlgItem(hDlg, IDC_SPCUST_EMAILCB), TEXT("Software\\Clients\\mail")); RegSaveDefaultClient(::GetDlgItem(hDlg, IDC_SPCUST_INTERNETCB), TEXT("SOFTWARE\\Clients\\StartMenuInternet")); }
BOOL bTranslated; DWORD dwMinMFU = ::GetDlgItemInt(hDlg, IDC_SPCUST_MINPROGS, &bTranslated, FALSE); if (EVAL(bTranslated)) { dwMinMFU = min(max(dwMinMFU, 0), MAX_PROGS_ALLOWED); _WriteStartPageSetting(REGSTR_VAL_DV2_MINMFU, dwMinMFU); }
return TRUE;
}
BOOL_PTR CCustomizeSPPropSheet::OnAdvancedNotify(HWND hwndDlg, NMHDR * pnm) { ::SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, 0); // handled
switch (pnm->code) { case PSN_APPLY: TraceMsg(TF_ALWAYS, "cspps.Advanced apply - _bDirtyTree=%d", _bDirtyTree); if (_bDirtyTree) { _prto->WalkTree(WALK_TREE_SAVE); }
_WriteStartPageSetting(REGSTR_VAL_DV2_SHOWRECDOCS, ::IsDlgButtonChecked(hwndDlg, IDC_SPCUST_RECENT) ? 2 : 0); // 2 so that it cascades
_WriteStartPageSetting(REGSTR_VAL_DV2_AUTOCASCADE, ::IsDlgButtonChecked(hwndDlg, IDC_SPCUST_HOVEROPEN)); _WriteStartPageSetting(REGSTR_VAL_DV2_NOTIFYNEW, ::IsDlgButtonChecked(hwndDlg, IDC_SPCUST_NOTIFYNEW)); // fall through to PSN_RESET case...
case PSN_RESET: _SaveMagicEntries(); // this must be called on both cancel and apply, so that it cleans up properly...
break;
case TVN_KEYDOWN: { TV_KEYDOWN *pnmtv = (TV_KEYDOWN*)pnm; if (pnmtv->wVKey == VK_SPACE) { HWND hwndTree = ::GetDlgItem(hwndDlg, IDC_STARTMENUSETTINGS); _prto->ToggleItem((HTREEITEM)SendMessage(hwndTree, TVM_GETNEXTITEM, (WPARAM)TVGN_CARET, 0L)); _bDirtyTree = TRUE; SendPSMChanged(hwndDlg); ::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); // eat the key
} break; }
case NM_CLICK: case NM_DBLCLK: // is this click in our tree?
if ( pnm->idFrom == IDC_STARTMENUSETTINGS ) { HWND hwndTree = ::GetDlgItem(hwndDlg, IDC_STARTMENUSETTINGS); TV_HITTESTINFO ht;
DWORD dwPos = GetMessagePos(); // get where we were hit
ht.pt.x = GET_X_LPARAM(dwPos); ht.pt.y = GET_Y_LPARAM(dwPos); ::ScreenToClient(hwndTree, &ht.pt); // translate it to our window
// retrieve the item hit
HTREEITEM hti = TreeView_HitTest(hwndTree, &ht); if (hti) { _prto->ToggleItem(hti); _bDirtyTree = TRUE; SendPSMChanged(hwndDlg); } }
break; // no help yet- needs ids/text from UA
#if 0
case NM_RCLICK: // right mouse click
if (pnm->hwndFrom == hwndTree) { _DoTreeHelp(pAdv, (WPARAM)pnm->hwndFrom); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); // eat the click
return TRUE; } break; #endif
} return TRUE; }
BOOL_PTR CCustomizeSPPropSheet::OnAdvancedHelp(HWND hDlg, HELPINFO *phi) { if (phi->iCtrlId != IDC_STARTMENUSETTINGS) { ::WinHelp((HWND)(phi->hItemHandle), NULL, HELP_WM_HELP, (ULONG_PTR)(LPTSTR)aStartCustAdvancedTabHelpIDs); } else { HTREEITEM hItem; HWND hwndTree = ::GetDlgItem(hDlg, IDC_STARTMENUSETTINGS);
//Is this help invoked throught F1 key
if (GetAsyncKeyState(VK_F1) < 0) { // Yes. WE need to give help for the currently selected item
hItem = TreeView_GetSelection(hwndTree); } else { //No, We need to give help for the item at the cursor position
TV_HITTESTINFO ht; ht.pt = phi->MousePos; ::ScreenToClient(hwndTree, &ht.pt); // Translate it to our window
hItem = TreeView_HitTest(hwndTree, &ht); }
if (hItem) _prto->ShowHelp(hItem, HELP_WM_HELP); } return TRUE; }
BOOL_PTR CCustomizeSPPropSheet::AdvancedTabDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: return AdvancedTabInit(hDlg); case WM_COMMAND: return OnCommand(LOWORD(wParam), HIWORD(wParam), (HWND) lParam, hDlg); case WM_NOTIFY: return OnAdvancedNotify(hDlg, (NMHDR*)lParam); case WM_HELP: return OnAdvancedHelp(hDlg, (HELPINFO*) lParam); break; case WM_CONTEXTMENU: ::WinHelp((HWND) wParam, NULL, HELP_CONTEXTMENU, (ULONG_PTR)(void *)aStartCustAdvancedTabHelpIDs); break; } return FALSE; }
int DefaultNetConValue() { return ShouldShowConnectTo() ? 2 : 0; // default to menu-style (2)
}
int DefaultNetPlacesValue() { return ShouldShowNetPlaces() ? 1 : 0; // default to link -style (1)
}
// These two "magic" functions maintain the proper behavior of the network places and network connections settings
// which, by default, turn on when there are n or more items in the folder. But they can also be customized by the
// user to force them on or off.
void CCustomizeSPPropSheet::_InitMagicEntries() { BOOL bNewNetPlaces; BOOL bNewNetConn;
_bCustNetPlaces = _ReadStartPageCUSetting(REGSTR_VAL_DV2_SHOWNETPL, (DWORD*) &bNewNetPlaces); _bCustNetConn = _ReadStartPageCUSetting(REGSTR_VAL_DV2_SHOWNETCONN, (DWORD*) &bNewNetConn); // if the user didn't previously customize these settings, then use the auto-magic setting
if (!_bCustNetPlaces) bNewNetPlaces = DefaultNetPlacesValue(); if (!_bCustNetConn) bNewNetConn = DefaultNetConValue();
// Write it out, so the rgtreeoption control will reflect either the user's customization, or the magic value
_WriteStartPageSetting(REGSTR_VAL_DV2_SHOWNETPL, bNewNetPlaces); _WriteStartPageSetting(REGSTR_VAL_DV2_SHOWNETCONN, bNewNetConn);
// for the admin tools radio buttons:
// 0 = don't show anywhere
// 1 = display in all programs (StartMenuAdminTools = 1, Start_AdminToolsRoot = 0)
// 2 = display in all programs and root (StartMenuAdminTools = 1, Start_AdminToolsRoot = 2)
int iAdminToolsTemp = _ReadStartPageSetting(REGSTR_VAL_DV2_ADMINTOOLSROOT, FALSE) ? 2 : (_ReadStartPageSetting(TEXT("StartMenuAdminTools"), FALSE) ? 1 : 0);
_WriteStartPageSetting(REGSTR_VAL_ADMINTOOLSTEMP, iAdminToolsTemp); }
void CCustomizeSPPropSheet::_SaveMagicEntries() { BOOL bNewNetPlaces = _ReadStartPageSetting(REGSTR_VAL_DV2_SHOWNETPL, FALSE); BOOL bNewNetConn = _ReadStartPageSetting(REGSTR_VAL_DV2_SHOWNETCONN, FALSE);
// if the user previously had it customized, then we don't need to clear it since it will either
// contain the original value we loaded in _InitMagicEntries, or the updated value if the user changed it.
// if it wasn't originally customized, then we need to clear it if the tree isn't even dirty, or the current value is the magic value we loaded
if (!_bCustNetPlaces && (!_bDirtyTree || bNewNetPlaces == DefaultNetPlacesValue())) _ClearStartPageSetting(REGSTR_VAL_DV2_SHOWNETPL);
if (!_bCustNetConn && (!_bDirtyTree || bNewNetConn == DefaultNetConValue())) _ClearStartPageSetting(REGSTR_VAL_DV2_SHOWNETCONN);
if (_bDirtyTree) { // see comment above for how this should work
int iAdminToolsTemp = _ReadStartPageSetting(REGSTR_VAL_ADMINTOOLSTEMP, FALSE); int iATRoot = 0; int iATPrograms = 0;
if (iAdminToolsTemp >= 1) { iATPrograms = 1; if (iAdminToolsTemp == 2) { iATRoot = 2; } } _WriteStartPageSetting(REGSTR_VAL_DV2_ADMINTOOLSROOT, iATRoot); _WriteStartPageSetting(TEXT("StartMenuAdminTools"), iATPrograms); } _ClearStartPageSetting(REGSTR_VAL_ADMINTOOLSTEMP); }
BOOL CCustomizeSPPropSheet::AdvancedTabInit(HWND hDlg) { if (SUCCEEDED(CoCreateInstance(CLSID_CRegTreeOptions, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IRegTreeOptions, &_prto)))) { HRESULT hr; HWND hwndTV = ::GetDlgItem(hDlg, IDC_STARTMENUSETTINGS);
// Compute the magic entries before we init the RegTreeOptions
// (so we will have correct information for him!)
_InitMagicEntries();
// HACKHACK - IRegTreeOptions is ANSI, so we temporarily turn off UNICODE
#undef TEXT
#define TEXT(s) s
hr = _prto->InitTree(hwndTV, HKEY_LOCAL_MACHINE, REGSTR_PATH_SMADVANCED "\\StartPanel", NULL);
#undef TEXT
#define TEXT(s) __TEXT(s)
TreeView_SelectSetFirstVisible(hwndTV, TreeView_GetRoot(hwndTV));
::CheckDlgButton(hDlg, IDC_SPCUST_RECENT, _ReadStartPageSetting(REGSTR_VAL_DV2_SHOWRECDOCS, IsOS(OS_PERSONAL) ? FALSE : TRUE)); ::CheckDlgButton(hDlg, IDC_SPCUST_HOVEROPEN,_ReadStartPageSetting(REGSTR_VAL_DV2_AUTOCASCADE, TRUE)); ::CheckDlgButton(hDlg, IDC_SPCUST_NOTIFYNEW,_ReadStartPageSetting(REGSTR_VAL_DV2_NOTIFYNEW, TRUE));
if(SHRestricted(REST_NORECENTDOCSMENU)) { //Since this policy is present, hide all the relevant controls
::ShowWindow(::GetDlgItem(hDlg, IDC_SPCUST_RECENT_GROUPBOX), FALSE);// Group box
::ShowWindow(::GetDlgItem(hDlg, IDC_SPCUST_RECENT_TEXT), FALSE); // Description Text.
::ShowWindow(::GetDlgItem(hDlg, IDC_SPCUST_RECENT), FALSE); // Check box
::ShowWindow(::GetDlgItem(hDlg, IDB_SPCUST_CLEARDOCS), FALSE); // Clear button.
}
SetDocButton(hDlg, IDB_SPCUST_CLEARDOCS);
return TRUE; }
return FALSE; }
BOOL_PTR CTaskBarPropertySheet::s_TaskbarOptionsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { CTaskBarPropertySheet* self = NULL;
if (uMsg == WM_INITDIALOG) { ::SetWindowLongPtr(hDlg, DWLP_USER, lParam); self = (CTaskBarPropertySheet*) ((PROPSHEETPAGE*)lParam)->lParam; } else { PROPSHEETPAGE* psp = (PROPSHEETPAGE*)::GetWindowLongPtr(hDlg, DWLP_USER); if (psp) self = (CTaskBarPropertySheet*)psp->lParam; }
BOOL_PTR fValue = FALSE; if (self) { self->TaskbarOptionsDlgProc(hDlg, uMsg, wParam, lParam); }
return fValue; }
void _TaskbarOptions_OnInitDialog(HWND hDlg) { TRAYVIEWOPTS tvo; c_tray.GetTrayViewOpts(&tvo); CheckDlgButton(hDlg, IDC_QUICKLAUNCH, tvo.fShowQuickLaunch); CheckDlgButton(hDlg, IDC_TRAYOPTONTOP, tvo.fAlwaysOnTop); CheckDlgButton(hDlg, IDC_TRAYOPTAUTOHIDE, (tvo.uAutoHide & AH_ON)); CheckDlgButton(hDlg, IDC_TRAYOPTSHOWCLOCK, !tvo.fHideClock); if (SHRestricted(REST_HIDECLOCK)) { EnableWindow(GetDlgItem(hDlg, IDC_TRAYOPTSHOWCLOCK), FALSE); }
if (SHRestricted(REST_NOTOOLBARSONTASKBAR)) { EnableWindow(GetDlgItem(hDlg, IDC_QUICKLAUNCH), FALSE); } // Restriction- either the tray is disabled by policy, or the "smart" auto tray
// is disabled by policy
if (tvo.fNoTrayItemsDisplayPolicyEnabled || tvo.fNoAutoTrayPolicyEnabled) { EnableWindow(GetDlgItem(hDlg, IDC_NOTIFYMAN), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_CUSTOMIZE), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_STATIC_NOTIFY), FALSE); } else { EnableWindow(GetDlgItem(hDlg, IDC_CUSTOMIZE), tvo.fAutoTrayEnabledByUser); CheckDlgButton(hDlg, IDC_NOTIFYMAN, tvo.fAutoTrayEnabledByUser); }
CheckDlgButton(hDlg, IDC_LOCKTASKBAR, !_IsSizeMoveEnabled()); BOOL fEnable = !_IsSizeMoveRestricted(); EnableWindow(GetDlgItem(hDlg, IDC_LOCKTASKBAR), fEnable);
if (SHRestricted(REST_NOTASKGROUPING)) { // If there is a restriction of any kine, hide the window
ShowWindow(GetDlgItem(hDlg, IDC_GROUPITEMS), FALSE); } else if (SHRegGetBoolUSValue(REGSTR_EXPLORER_ADVANCED, TEXT("TaskbarGlomming"), FALSE, TRUE)) { CheckDlgButton(hDlg, IDC_GROUPITEMS, TRUE); }
_TaskbarOptionsSizeControls(hDlg); _TaskbarOptionsUpdateDisplay(hDlg); }
BOOL_PTR CTaskBarPropertySheet::TaskbarOptionsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { INSTRUMENT_WNDPROC(SHCNFI_TRAYVIEWOPTIONS_DLGPROC, hDlg, uMsg, wParam, lParam);
switch (uMsg) { case WM_COMMAND: if (GET_WM_COMMAND_ID(wParam, lParam) == IDC_CUSTOMIZE) { if (_pDlgNotify) { _pDlgNotify->DoModal(); } }
_TaskbarOptionsUpdateDisplay(hDlg); SendPSMChanged(hDlg);
break;
case WM_INITDIALOG: _TaskbarOptions_OnInitDialog(hDlg); if (_dwFlags & TPF_INVOKECUSTOMIZE) { ::PostMessage(hDlg, WM_COMMAND, IDC_CUSTOMIZE, 0); } break;
case WM_SYSCOLORCHANGE: _TaskbarOptionsUpdateDisplay(hDlg); return TRUE;
case WM_DESTROY: _TaskbarOptionsDestroyBitmaps(hDlg); break;
case WM_NOTIFY: switch (((NMHDR *)lParam)->code) { case PSN_APPLY: // save settings here
_ApplyTaskbarOptionsFromDialog(hDlg); return TRUE;
case PSN_KILLACTIVE: case PSN_SETACTIVE: return TRUE;
} break;
case WM_HELP: ::WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, NULL, HELP_WM_HELP, (ULONG_PTR)(LPTSTR) aTaskOptionsHelpIDs); break;
case WM_CONTEXTMENU: ::WinHelp((HWND) wParam, NULL, HELP_CONTEXTMENU, (ULONG_PTR)(void *)aTaskOptionsHelpIDs); break; }
return FALSE; }
void _StartOptions_OnInitDialog(HWND hDlg) { // If StartPanel UI is turned off, then this check box should not show up!
if (SHRestricted(REST_NOSTARTPANEL)) { //If the restriction exists, then hide this check box.
ShowWindow(::GetDlgItem(hDlg, IDC_NEWSCHOOL), FALSE); ShowWindow(::GetDlgItem(hDlg, IDC_NEWSCHOOLDESCRIPTION), FALSE); ShowWindow(::GetDlgItem(hDlg, IDC_NEWSTARTCUSTOMIZE), FALSE);
// And the only thing you can do is check the OldSchool button
CheckDlgButton(hDlg, IDC_OLDSCHOOL, TRUE);
// TODO - PM's need to figure out what to do in the case where new start menu is restricted
// or not available. This propsheet page is rather pointless in that case...
SetDlgItemBitmap(hDlg, IDC_STARTMENUPREVIEW, IDB_STARTPREVIEWCLASSIC); } else { SHELLSTATE ss = {0}; SHGetSetSettings(&ss, SSF_STARTPANELON, FALSE); CheckDlgButton(hDlg, IDC_NEWSCHOOL, BOOLIFY(ss.fStartPanelOn)); CheckDlgButton(hDlg, IDC_OLDSCHOOL, !BOOLIFY(ss.fStartPanelOn));
SetDlgItemBitmap(hDlg, IDC_STARTMENUPREVIEW, ss.fStartPanelOn ? IDB_STARTPREVIEWNEW : IDB_STARTPREVIEWCLASSIC); // disable "customize" for the style thats off.
EnableWindow(GetDlgItem(hDlg, ss.fStartPanelOn ? IDC_OLDSTARTCUSTOMIZE : IDC_NEWSTARTCUSTOMIZE), FALSE); } }
// On destroy, clean up the bitmaps we loaded so we don't leak them
void _StartOptions_OnDestroy(HWND hDlg) { SetDlgItemBitmap(hDlg, IDC_STARTMENUPREVIEW, 0); }
BOOL_PTR CTaskBarPropertySheet::s_StartMenuDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { CTaskBarPropertySheet* self = NULL;
if (uMsg == WM_INITDIALOG) { ::SetWindowLongPtr(hDlg, DWLP_USER, lParam); self = (CTaskBarPropertySheet*) ((PROPSHEETPAGE*)lParam)->lParam; } else { PROPSHEETPAGE* psp = (PROPSHEETPAGE*)::GetWindowLongPtr(hDlg, DWLP_USER); if (psp) self = (CTaskBarPropertySheet*)psp->lParam; }
BOOL_PTR fValue = FALSE; if (self) { self->StartMenuDlgProc(hDlg, uMsg, wParam, lParam); }
return fValue; }
BOOL_PTR CTaskBarPropertySheet::StartMenuDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_NEWSCHOOL: case IDC_OLDSCHOOL: if (HIWORD(wParam) == BN_CLICKED) { ::EnableWindow(::GetDlgItem(hDlg, IDC_NEWSTARTCUSTOMIZE), GET_WM_COMMAND_ID(wParam, lParam) == IDC_NEWSCHOOL); ::EnableWindow(::GetDlgItem(hDlg, IDC_OLDSTARTCUSTOMIZE), GET_WM_COMMAND_ID(wParam, lParam) == IDC_OLDSCHOOL); SetDlgItemBitmap(hDlg, IDC_STARTMENUPREVIEW, GET_WM_COMMAND_ID(wParam, lParam) == IDC_NEWSCHOOL ? IDB_STARTPREVIEWNEW : IDB_STARTPREVIEWCLASSIC); SendPSMChanged(hDlg); } break;
case IDC_NEWSTARTCUSTOMIZE: { CCustomizeSPPropSheet *pps = new CCustomizeSPPropSheet(hDlg); if (pps) { if (pps->DoModal() == IDOK) { // if anything changed, let the propsheet know
SendPSMChanged(hDlg); } delete pps; } break; } case IDC_OLDSTARTCUSTOMIZE: { if (DialogBoxParam(hinstCabinet, MAKEINTRESOURCE(DLG_STARTMENU_CONFIG), hDlg, AdvancedOptDlgProc, (LPARAM)&_Adv)) { // if anything changed, let the propsheet know
SendPSMChanged(hDlg); } break; } }
break;
case WM_INITDIALOG: { _StartOptions_OnInitDialog(hDlg);
} break;
case WM_DESTROY: _StartOptions_OnDestroy(hDlg); break;
case WM_NOTIFY: switch (((NMHDR *)lParam)->code) { case PSN_APPLY: // save settings here
_ApplyStartOptionsFromDialog(hDlg); return TRUE;
case PSN_KILLACTIVE: case PSN_SETACTIVE: return TRUE;
} break;
case WM_HELP: ::WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, NULL, HELP_WM_HELP, (ULONG_PTR)(LPTSTR) aStartTabHelpIDs); break;
case WM_CONTEXTMENU: ::WinHelp((HWND) wParam, NULL, HELP_CONTEXTMENU, (ULONG_PTR)(void *)aStartTabHelpIDs); break; }
return FALSE; }
void _UpdateNotifySetting(BOOL fNotifySetting) { ITrayNotify * pTrayNotify = NULL; if (SUCCEEDED(CoCreateInstance(CLSID_TrayNotify, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARG(ITrayNotify, &pTrayNotify)))) { pTrayNotify->EnableAutoTray(fNotifySetting); pTrayNotify->Release(); } }
void CTaskBarPropertySheet ::_ApplyTaskbarOptionsFromDialog(HWND hDlg) { // We need to get the Cabinet structure from the property sheet info.
BOOL fAlwaysOnTop; BOOL fAutoHide; BOOL fChanged; LONG lRet; TRAYVIEWOPTS tvo;
// First check for Always on Top
fAlwaysOnTop = ::IsDlgButtonChecked(hDlg, IDC_TRAYOPTONTOP); c_tray._UpdateAlwaysOnTop(fAlwaysOnTop);
// And change the Autohide state
fAutoHide = ::IsDlgButtonChecked(hDlg, IDC_TRAYOPTAUTOHIDE); lRet = c_tray._SetAutoHideState(fAutoHide); c_tray.GetTrayViewOpts(&tvo); if (!HIWORD(lRet) && fAutoHide) { // we tried and failed.
if (!(tvo.uAutoHide & AH_ON)) { ::CheckDlgButton(hDlg, IDC_TRAYOPTAUTOHIDE, FALSE); _TaskbarOptionsUpdateDisplay(hDlg); } } fChanged = LOWORD(lRet);
if (fChanged) c_tray._AppBarNotifyAll(NULL, ABN_STATECHANGE, NULL, 0);
// show/hide the clock
tvo.fHideClock = !::IsDlgButtonChecked(hDlg, IDC_TRAYOPTSHOWCLOCK);
if (!tvo.fNoTrayItemsDisplayPolicyEnabled && !tvo.fNoAutoTrayPolicyEnabled) { BOOL fNotifySetting = ::IsDlgButtonChecked(hDlg, IDC_NOTIFYMAN); if (tvo.fAutoTrayEnabledByUser != fNotifySetting) { tvo.fAutoTrayEnabledByUser = fNotifySetting; _UpdateNotifySetting(fNotifySetting); } } tvo.fShowQuickLaunch = ::IsDlgButtonChecked(hDlg, IDC_QUICKLAUNCH);
c_tray.SetTrayViewOpts(&tvo); SendMessage(c_tray.GetTrayNotifyHWND(), TNM_HIDECLOCK, 0, tvo.fHideClock);
c_tray.SizeWindows();
// Update registry for locked taskbar
DWORD dwEnableSizeMove = !::IsDlgButtonChecked(hDlg, IDC_LOCKTASKBAR); SHRegSetUSValue(REGSTR_EXPLORER_ADVANCED, TEXT("TaskbarSizeMove"), REG_DWORD, &dwEnableSizeMove, sizeof(DWORD), SHREGSET_FORCE_HKCU);
//Update registry for grouping behavior
DWORD dwGlom = ::IsDlgButtonChecked(hDlg, IDC_GROUPITEMS); SHRegSetUSValue(REGSTR_EXPLORER_ADVANCED, TEXT("TaskbarGlomming"), REG_DWORD, &dwGlom, sizeof(DWORD), SHREGSET_FORCE_HKCU);
::SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, NULL, (LPARAM)TEXT("TraySettings"), SMTO_NOTIMEOUTIFNOTHUNG, 1000, NULL); }
void CTaskBarPropertySheet::_ApplyStartOptionsFromDialog(HWND hDlg) { if(!SHRestricted(REST_NOSTARTPANEL)) { //Get the current state of the check box
BOOL fStartPanelOn = BOOLIFY(::IsDlgButtonChecked(hDlg, IDC_NEWSCHOOL) ); SHELLSTATE ss = {0}; //See if Startpage is currently on or off.
SHGetSetSettings(&ss, SSF_STARTPANELON, FALSE); //Check if the check box has been toggled
if(fStartPanelOn != BOOLIFY(ss.fStartPanelOn)) { // Toggle the setting
ss.fStartPanelOn = fStartPanelOn; SHGetSetSettings(&ss, SSF_STARTPANELON, TRUE);
//Tell the desktop window so it can add/remove the desktop icons
::PostMessage(v_hwndDesktop, DTM_STARTPAGEONOFF, 0, 0); }
// Tell the Start Menu to rebuild itself now that we changed it
// (This part is unconditional since the user may have merely
// changed a setting with the Start Menu)
::PostMessage(v_hwndTray, SBM_REBUILDMENU, 0, 0);
} }
//---------------------------------------------------------------------------
void _TaskbarOptionsDestroyBitmaps(HWND hDlg) { SetDlgItemBitmap(hDlg, IDC_TASKBARAPPEARANCE, 0); SetDlgItemBitmap(hDlg, IDC_NOTIFYAPPEARANCE, 0); }
typedef struct { int idc; int iAdd; } CONTROLBITMAP;
int _TaskbarPickBitmap(HWND hDlg, int iBmpBase, const CONTROLBITMAP* pca, int cca) { for (int i = 0; i < cca; i++) { if (!IsDlgButtonChecked(hDlg, pca[i].idc)) { iBmpBase += pca[i].iAdd; } } return iBmpBase; }
void _TaskbarOptionsUpdateDisplay(HWND hDlg) { static const CONTROLBITMAP c_caTaskbar[] = { { IDC_LOCKTASKBAR, 1 }, { IDC_GROUPITEMS, 2 }, { IDC_QUICKLAUNCH, 4 }, }; static const CONTROLBITMAP c_caNotify[] = { { IDC_TRAYOPTSHOWCLOCK, 1 }, { IDC_NOTIFYMAN, 2 }, };
//
// top preview
//
int iBmp; if (IsDlgButtonChecked(hDlg, IDC_TRAYOPTAUTOHIDE)) { iBmp = IDB_TAAUTOHIDE; } else { iBmp = _TaskbarPickBitmap(hDlg, IDB_TAQLLOCKGROUP, c_caTaskbar, ARRAYSIZE(c_caTaskbar)); } SetDlgItemBitmap(hDlg, IDC_TASKBARAPPEARANCE, iBmp);
//
// bottom preview
//
iBmp = _TaskbarPickBitmap(hDlg, IDB_NACLOCKCLEAN, c_caNotify, ARRAYSIZE(c_caNotify)); SetDlgItemBitmap(hDlg, IDC_NOTIFYAPPEARANCE, iBmp);
//
// customize button
//
EnableWindow(GetDlgItem(hDlg, IDC_CUSTOMIZE), IsDlgButtonChecked(hDlg, IDC_NOTIFYMAN)); }
#define CX_PREVIEW 336
#define CY_PREVIEW 35
// need to do this by hand because dialog units to pixels will change,
// but the bitmaps won't
void _TaskbarOptionsSizeControls(HWND hDlg) { static const int c_IDC[] = { IDC_TASKBARAPPEARANCE, IDC_NOTIFYAPPEARANCE };
for (int i = 0; i < ARRAYSIZE(c_IDC); i++) { SetWindowPos(GetDlgItem(hDlg, c_IDC[i]), NULL, 0, 0, CX_PREVIEW, CY_PREVIEW, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); } }
typedef BOOL (* PFCFGSTART) (HWND, BOOL);
void CallAppWiz(HWND hDlg, BOOL bDelItems) { HINSTANCE hmodWiz = LoadLibrary(TEXT("AppWiz.Cpl")); if (hmodWiz) { PFCFGSTART pfnCfgStart = (PFCFGSTART)GetProcAddress(hmodWiz, "ConfigStartMenu"); if (pfnCfgStart) { pfnCfgStart(hDlg, bDelItems); } FreeLibrary(hmodWiz); } }
BOOL ExecExplorerAtStartMenu(HWND hDlg) { SHELLEXECUTEINFO ei; BOOL fWorked= FALSE; TCHAR szParams[MAX_PATH];
ei.cbSize = sizeof(ei); ei.hwnd = hDlg; ei.lpVerb = NULL; ei.fMask = 0; ei.lpFile = TEXT("Explorer.exe");
if (IsUserAnAdmin()) { lstrcpy(szParams, TEXT("/E,")); SHGetSpecialFolderPath(hDlg, &(szParams[ARRAYSIZE(TEXT("/E,"))-1]), CSIDL_STARTMENU, FALSE); } else { lstrcpy(szParams, TEXT("/E,/Root,")); SHGetSpecialFolderPath(hDlg, &(szParams[ARRAYSIZE(TEXT("/E,/Root,"))-1]), CSIDL_STARTMENU, FALSE); }
ei.lpParameters = szParams; ei.lpDirectory = NULL; ei.lpClass = NULL; ei.nShow = SW_SHOWDEFAULT; ei.hInstApp = hinstCabinet;
return(ShellExecuteEx(&ei)); }
const TCHAR *c_szRegMruKeysToDelete[] = { TEXT("Software\\Microsoft\\Internet Explorer\\TypedURLs"), TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU"), TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Doc Find Spec MRU"),
// New for Whistler (should've been in Windows 2000 and Millennium but we forgot)
TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Comdlg32\\OpenSaveMRU"), TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Comdlg32\\LastVisitedMRU"), };
void SetDocButton(HWND hDlg, int id) { LPITEMIDLIST pidl; BOOL bAreDocs = FALSE;
HRESULT hr = SHGetSpecialFolderLocation(hDlg, CSIDL_RECENT, &pidl); if (SUCCEEDED(hr)) { IShellFolder *psf = BindToFolder(pidl); if (psf) { HRESULT hres; LPENUMIDLIST penum; hres = psf->EnumObjects(hDlg, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &penum); if (SUCCEEDED(hres)) { unsigned long celt; LPITEMIDLIST pidlenum; if ((S_OK == penum->Next(1, &pidlenum, &celt)) && (celt == 1)) { SHFree(pidlenum); bAreDocs = TRUE; } penum->Release(); } psf->Release(); } SHFree(pidl); }
// Check other MRU registry keys
if (!bAreDocs) { int i; for (i = 0; i < ARRAYSIZE(c_szRegMruKeysToDelete); i++) { HKEY hkey; if (RegOpenKeyEx(HKEY_CURRENT_USER, c_szRegMruKeysToDelete[i], 0L, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS) { bAreDocs = TRUE; RegCloseKey(hkey); } } } Button_Enable(GetDlgItem(hDlg, id), bAreDocs); }
void ClearRecentDocumentsAndMRUStuff(BOOL fBroadcastChange) { int i; SHAddToRecentDocs(0, NULL);
// Flush other MRUs in the registry for privacy
for (i = 0; i < ARRAYSIZE(c_szRegMruKeysToDelete); i++) { SHDeleteKey(HKEY_CURRENT_USER, c_szRegMruKeysToDelete[i]);
if (fBroadcastChange) SHSendMessageBroadcast(WM_SETTINGCHANGE, 0, (LPARAM)c_szRegMruKeysToDelete[i]); } }
void HandleClearButtonClick(HWND hwndClear) { HCURSOR hc = SetCursor(LoadCursor(NULL, IDC_WAIT)); ClearRecentDocumentsAndMRUStuff(TRUE); SetCursor(hc);
//
// Before disabling the button, shove focus off it.
//
if (GetFocus() == hwndClear) { SendMessage(GetParent(hwndClear), WM_NEXTDLGCTL, 0, MAKELONG(FALSE, 0)); }
Button_Enable(hwndClear, FALSE); }
void Reorder(HDPA hdpa) { for (int i = DPA_GetPtrCount(hdpa) - 1; i >= 0; i--) { PORDERITEM poi = (PORDERITEM)DPA_FastGetPtr(hdpa, i); poi->nOrder = i; } }
void MenuOrderSort(HKEY hkeyRoot, IShellFolder* psf);
void MenuOrderSortKeyWithFolder(HKEY hkeyRoot, LPTSTR pszKey, IShellFolder* psf) { HKEY hkey; if (ERROR_SUCCESS == RegOpenKeyEx(hkeyRoot, pszKey, 0, KEY_READ | KEY_WRITE, &hkey)) { MenuOrderSort(hkey, psf); RegCloseKey(hkey); } }
// Binds to the Key pszKey, under hkey root, using psf, and sorts the resultant order.
void MenuOrderSortSubKey(HKEY hkeyRoot, LPTSTR szFolder, LPTSTR pszKey, IShellFolder* psf) { LPITEMIDLIST pidl; DWORD cbEaten; DWORD dwAttrib; WCHAR wszKey[MAX_PATH]; SHTCharToUnicode(szFolder, wszKey, ARRAYSIZE(wszKey));
if (SUCCEEDED(psf->ParseDisplayName(NULL, NULL, wszKey, &cbEaten, &pidl, &dwAttrib))) { IShellFolder* psfSub; if (SUCCEEDED(psf->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfSub)))) { MenuOrderSortKeyWithFolder(hkeyRoot, pszKey, psfSub); psfSub->Release(); } ILFree(pidl); } }
void MenuOrderSort(HKEY hkeyRoot, IShellFolder* psf) { // Try to open Value Order
IStream* pstm = SHOpenRegStream(hkeyRoot, TEXT(""), TEXT("Order"), STGM_READWRITE); if (pstm) { IOrderList2* pol2; if (SUCCEEDED(CoCreateInstance(CLSID_OrderListExport, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IOrderList2, &pol2)))) { HDPA hdpa; if (SUCCEEDED(pol2->LoadFromStream(pstm, &hdpa, psf))) { // Since it's stored ordered by name, this should be no problem.
Reorder(hdpa);
// Set the seek pointer at the beginning.
LARGE_INTEGER liZero = {0}; pstm->Seek(liZero, STREAM_SEEK_SET, NULL);
pol2->SaveToStream(pstm, hdpa); DPA_Destroy(hdpa); } pol2->Release(); } pstm->Release(); }
// Now enumerate sub keys.
TCHAR szKey[MAX_PATH]; DWORD cbKey = ARRAYSIZE(szKey); int iIndex = 0; while (ERROR_SUCCESS == RegEnumKeyEx(hkeyRoot, iIndex, szKey, &cbKey, NULL, NULL, NULL, NULL)) { MenuOrderSortSubKey(hkeyRoot, szKey, szKey, psf); iIndex++; cbKey = ARRAYSIZE(szKey); } }
// Defined in Tray.c
IShellFolder* BindToFolder(LPCITEMIDLIST pidl);
void StartMenuSort() { IShellFolder* psf = NULL; LPITEMIDLIST pidl;
HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_STARTMENU, &pidl); if (SUCCEEDED(hr)) { LPITEMIDLIST pidl2; if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_STARTMENU, &pidl2))) { IAugmentedShellFolder2* pasf; IShellFolder* psfCommon; IShellFolder* psfUser; HRESULT hres = CoCreateInstance(CLSID_MergedFolder, NULL, CLSCTX_INPROC, IID_PPV_ARG(IAugmentedShellFolder2, &pasf)); if (SUCCEEDED(hres)) { psfUser = BindToFolder(pidl); if (psfUser) { pasf->AddNameSpace(NULL, psfUser, pidl, ASFF_DEFAULT | ASFF_DEFNAMESPACE_ALL); psfUser->Release(); }
psfCommon = BindToFolder(pidl2);
if (psfCommon) { pasf->AddNameSpace(NULL, psfCommon, pidl2, ASFF_DEFAULT); psfCommon->Release(); }
hres = pasf->QueryInterface(IID_PPV_ARG(IShellFolder, &psf)); pasf->Release(); }
ILFree(pidl2); } else { psf = BindToFolder(pidl); } ILFree(pidl); }
if (psf) { HKEY hkeyRoot;
// Recursivly sort the orders. Should this be on another thread?
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, STRREG_STARTMENU, 0, KEY_READ | KEY_WRITE, &hkeyRoot)) { MenuOrderSort(hkeyRoot, psf);
// Sort the My Documents menu item:
LPITEMIDLIST pidlMyDocs; SHGetFolderLocation(NULL, CSIDL_PERSONAL, NULL, 0, &pidlMyDocs); if (pidlMyDocs) { IShellFolder* psfMyDocs; if (SUCCEEDED(SHBindToObjectEx(NULL, pidlMyDocs, NULL, IID_PPV_ARG(IShellFolder, &psfMyDocs)))) { MenuOrderSortKeyWithFolder(hkeyRoot, TEXT("MyDocuments"), psfMyDocs); psfMyDocs->Release(); } ILFree(pidlMyDocs); }
// What happens if the Filesystem programs is not equal to the hard coded string "Programs"? This
// happens on German: Programme != Programs and we fail to sort. So let's verify:
TCHAR szPath[MAX_PATH]; SHGetFolderPath(NULL, CSIDL_PROGRAMS, NULL, 0, szPath); LPTSTR pszName = PathFindFileName(szPath);
if (StrCmpI(pszName, TEXT("Programs")) != 0) { // Ok, It's not the same, so go bind to that sub tree and sort it.
MenuOrderSortSubKey(hkeyRoot, pszName, TEXT("Programs"), psf); } RegCloseKey(hkeyRoot); } psf->Release(); } }
BOOL Advanced_OnInitDialog(HWND hwndDlg, SMADVANCED* pAdv) { if (!pAdv || !pAdv->pTO) { EndDialog(hwndDlg, 0); return FALSE; // no memory?
}
SetWindowPtr(hwndDlg, DWLP_USER, pAdv);
// since the large icon setting is stored in the tray state, not as a standalone reg key, we need to have a temp reg key for the regtreeop to use...
TRAYVIEWOPTS tvo; c_tray.GetTrayViewOpts(&tvo); BOOL fLargePrev = !tvo.fSMSmallIcons; SHSetValue(HKEY_CURRENT_USER, REGSTR_EXPLORER_ADVANCED, REGSTR_VAL_LARGEICONSTEMP, REG_DWORD, (void*) &fLargePrev, sizeof(fLargePrev));
pAdv->hwndTree = GetDlgItem( hwndDlg, IDC_STARTMENUSETTINGS );
// HACKHACK - IRegTreeOptions is ANSI, so we temporarily turn off UNICODE
#undef TEXT
#define TEXT(s) s
HRESULT hr = pAdv->pTO->InitTree(pAdv->hwndTree, HKEY_LOCAL_MACHINE, REGSTR_PATH_SMADVANCED "\\StartMenu", NULL);
#undef TEXT
#define TEXT(s) __TEXT(s)
// find the first root and make sure that it is visible
TreeView_EnsureVisible(pAdv->hwndTree, TreeView_GetRoot( pAdv->hwndTree ));
SetDocButton(hwndDlg, IDC_KILLDOCUMENTS);
return SUCCEEDED(hr); }
void InitStartMenu_DoTreeHelp(SMADVANCED* pAdv, WPARAM wParam) { TV_HITTESTINFO ht;
GetCursorPos( &ht.pt ); // get where we were hit
if (pAdv->hwndTree == WindowFromPoint(ht.pt)) { ScreenToClient( pAdv->hwndTree, &ht.pt ); // translate it to our window
// retrieve the item hit
pAdv->pTO->ShowHelp(TreeView_HitTest( pAdv->hwndTree, &ht),HELP_CONTEXTMENU); } else { WinHelp((HWND) wParam, NULL, HELP_CONTEXTMENU, (ULONG_PTR)(LPVOID)aInitStartMenuHelpIDs); } }
BOOL_PTR CALLBACK AdvancedOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { SMADVANCED* pAdv = (SMADVANCED*)GetWindowPtr(hwndDlg, DWLP_USER); INSTRUMENT_WNDPROC(SHCNFI_INITSTARTMENU_DLGPROC, hwndDlg, msg, wParam, lParam);
if (msg != WM_INITDIALOG && !pAdv) { // We've been re-entered after being destroyed. Bail.
return FALSE; }
switch (msg) { case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_ADDSHORTCUT: CallAppWiz(hwndDlg, FALSE); break;
case IDC_DELSHORTCUT: CallAppWiz(hwndDlg, TRUE); break; case IDC_RESORT: { SHChangeDWORDAsIDList dwidl;
StartMenuSort();
// Notify everyone that the order changed
dwidl.cb = sizeof(dwidl) - sizeof(dwidl.cbZero); dwidl.dwItem1 = SHCNEE_ORDERCHANGED; dwidl.dwItem2 = 0; dwidl.cbZero = 0;
SHChangeNotify(SHCNE_EXTENDED_EVENT, SHCNF_FLUSH, (LPCITEMIDLIST)&dwidl, NULL); break; } case IDC_EXPLOREMENUS: ExecExplorerAtStartMenu(hwndDlg); break;
case IDC_KILLDOCUMENTS: { HandleClearButtonClick(GET_WM_COMMAND_HWND(wParam, lParam)); } break;
case IDOK: { pAdv->pTO->WalkTree(WALK_TREE_SAVE);
TRAYVIEWOPTS tvo; c_tray.GetTrayViewOpts(&tvo); BOOL fSmallPrev = tvo.fSMSmallIcons; // note that we are loading the classic setting for large icons here....
BOOL fSmallNew = !SHRegGetBoolUSValue(REGSTR_EXPLORER_ADVANCED, REGSTR_VAL_LARGEICONSTEMP, FALSE, TRUE /* default to large*/); if (fSmallPrev != fSmallNew) { tvo.fSMSmallIcons = fSmallNew; c_tray.SetTrayViewOpts(&tvo); IMenuPopup_SetIconSize(c_tray.GetStartMenu(), fSmallNew ? BMICON_SMALL : BMICON_LARGE); }
::SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, NULL, (LPARAM)TEXT("TraySettings"), SMTO_NOTIMEOUTIFNOTHUNG, 1000, NULL); } // fall through
case IDCANCEL: SHDeleteValue(HKEY_CURRENT_USER, REGSTR_EXPLORER_ADVANCED, REGSTR_VAL_LARGEICONSTEMP); EndDialog(hwndDlg, FALSE); // false to not enable parent's apply
break; } break;
case WM_INITDIALOG: return Advanced_OnInitDialog(hwndDlg, (SMADVANCED *)lParam);
case WM_NOTIFY: { LPNMHDR pnm = (NMHDR *)lParam; SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, 0); // handled
switch (pnm->code) { case TVN_KEYDOWN: { TV_KEYDOWN *pnmKeyDown = (TV_KEYDOWN*)((NMHDR *)lParam); if (pnmKeyDown->wVKey == VK_SPACE) { pAdv->pTO->ToggleItem((HTREEITEM)SendMessage(pAdv->hwndTree, TVM_GETNEXTITEM, (WPARAM)TVGN_CARET, 0L)); SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0L); SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, TRUE); // eat the key
} break; }
case NM_CLICK: case NM_DBLCLK: // is this click in our tree?
if ( pnm->idFrom == IDC_STARTMENUSETTINGS ) { TV_HITTESTINFO ht;
DWORD dwPos = GetMessagePos(); // get where we were hit
ht.pt.x = GET_X_LPARAM(dwPos); ht.pt.y = GET_Y_LPARAM(dwPos); ScreenToClient( pAdv->hwndTree, &ht.pt ); // translate it to our window
// retrieve the item hit
pAdv->pTO->ToggleItem(TreeView_HitTest( pAdv->hwndTree, &ht)); SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0L); }
break;
case NM_RCLICK: // right mouse click
if (pnm->hwndFrom == pAdv->hwndTree) { InitStartMenu_DoTreeHelp(pAdv, (WPARAM)pnm->hwndFrom); SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, TRUE); // eat the click
return TRUE; } break; } break; }
case WM_HELP: // F1
{ LPHELPINFO phi = (LPHELPINFO)lParam;
if (phi->iCtrlId != IDC_STARTMENUSETTINGS) { WinHelp( (HWND)(phi->hItemHandle), NULL, HELP_WM_HELP, (ULONG_PTR)(LPTSTR)aInitStartMenuHelpIDs); } else { HTREEITEM hItem; //Is this help invoked throught F1 key
if (GetAsyncKeyState(VK_F1) < 0) { // Yes. WE need to give help for the currently selected item
hItem = TreeView_GetSelection(pAdv->hwndTree); } else { //No, We need to give help for the item at the cursor position
TV_HITTESTINFO ht; ht.pt = phi->MousePos; ScreenToClient(pAdv->hwndTree, &ht.pt); // Translate it to our window
hItem = TreeView_HitTest(pAdv->hwndTree, &ht); }
pAdv->pTO->ShowHelp(hItem, HELP_WM_HELP); } break; }
case WM_CONTEXTMENU: // right mouse click
{ InitStartMenu_DoTreeHelp(pAdv, wParam); break; } case WM_DESTROY: { // will be free'd when our parent is destroyed
pAdv->pTO->WalkTree(WALK_TREE_DELETE);
// make sure we don't re-enter
SetWindowPtr( hwndDlg, DWLP_USER, NULL ); } break; // WM_DESTORY
default: return FALSE; }
return TRUE; }
#define TPF_PAGEFLAGS (TPF_STARTMENUPAGE | TPF_TASKBARPAGE)
void DoTaskBarProperties(HWND hwnd, DWORD dwFlags) { ASSERT(((dwFlags & TPF_PAGEFLAGS) == TPF_STARTMENUPAGE) || ((dwFlags & TPF_PAGEFLAGS) == TPF_TASKBARPAGE));
UINT nStartPage = (dwFlags & TPF_TASKBARPAGE) ? 0 : 1; CTaskBarPropertySheet sheet(nStartPage, hwnd, dwFlags);
sheet.DoModal(hwnd); }
// Passing iResource=0 deletes the bitmap in the control
void SetDlgItemBitmap(HWND hDlg, int idStatic, int iResource) { HBITMAP hbm;
if (iResource) { hbm = (HBITMAP)LoadImage(hinstCabinet, MAKEINTRESOURCE(iResource), IMAGE_BITMAP, 0,0, LR_LOADMAP3DCOLORS); } else { hbm = NULL; }
hbm = (HBITMAP)SendDlgItemMessage(hDlg, idStatic, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbm); if (hbm) DeleteObject(hbm);
}
void SetDlgItemIcon(HWND hDlg, int idStatic, HICON hIcon) { HICON hiOld = (HICON)SendDlgItemMessage(hDlg, idStatic, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); if (hiOld) DestroyIcon(hiOld); }
// REVIEW - use SHGetFileInfo?
void SetProgramIcon(HWND hDlg, int idLarge, int idSmall) { HICON hIconLarge = NULL; HICON hIconSmall = NULL; LPITEMIDLIST pidlMyComp = ILCreateFromPath(TEXT("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")); // CLSID_MyComputer;
if (pidlMyComp) { IShellFolder *psfDesktop; if (SUCCEEDED(SHGetDesktopFolder(&psfDesktop))) { IExtractIcon *pxi; if (SUCCEEDED(psfDesktop->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pidlMyComp, IID_PPV_ARG_NULL(IExtractIcon, &pxi)))) { TCHAR szIconFile[MAX_PATH]; int iIndex; UINT wFlags; if (S_OK == pxi->GetIconLocation(GIL_FORSHELL, szIconFile, ARRAYSIZE(szIconFile), &iIndex, &wFlags)) { pxi->Extract(szIconFile, iIndex, &hIconLarge, &hIconSmall, (GetSystemMetrics(SM_CXSMICON)<<16) | GetSystemMetrics(SM_CXICON)); } pxi->Release(); } psfDesktop->Release(); } ILFree(pidlMyComp); }
if (hIconLarge) SetDlgItemIcon(hDlg, idLarge, hIconLarge); if (hIconSmall) SetDlgItemIcon(hDlg, idSmall, hIconSmall); }
|