mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[SHELL32][SHLWAPI][BROWSEUI][EXPLORER] Save folder view state (#7127)
Saves/restores the Listview icon mode, columns and sort info per-folder.
This commit is contained in:
parent
fa95a96e9b
commit
802dc9714b
9 changed files with 365 additions and 48 deletions
|
@ -660,8 +660,18 @@ public:
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
void SaveState()
|
||||
{
|
||||
if (SHRestricted(REST_NOSAVESET))
|
||||
return;
|
||||
|
||||
SendMessage(m_DesktopWnd, WM_PROGMAN_SAVESTATE, 0, 0);
|
||||
}
|
||||
|
||||
LRESULT DoExitWindows()
|
||||
{
|
||||
SaveState();
|
||||
|
||||
/* Display the ReactOS Shutdown Dialog */
|
||||
ExitWindowsDialog(m_hWnd);
|
||||
|
||||
|
@ -983,6 +993,7 @@ public:
|
|||
DisplayRunFileDlg();
|
||||
break;
|
||||
case TRAYCMD_LOGOFF_DIALOG:
|
||||
SaveState();
|
||||
LogoffWindowsDialog(m_hWnd); // FIXME: Maybe handle it in a similar way as DoExitWindows?
|
||||
break;
|
||||
case TRAYCMD_CASCADE:
|
||||
|
@ -2629,6 +2640,13 @@ ChangePos:
|
|||
return 0;
|
||||
}
|
||||
|
||||
LRESULT OnEndSession(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (wParam)
|
||||
SaveState();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (m_Theme)
|
||||
|
@ -3581,6 +3599,7 @@ HandleTrayContextMenu:
|
|||
MESSAGE_HANDLER(WM_SIZE, OnSize)
|
||||
MESSAGE_HANDLER(WM_CREATE, OnCreate)
|
||||
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
|
||||
MESSAGE_HANDLER(WM_ENDSESSION, OnEndSession)
|
||||
MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest)
|
||||
MESSAGE_HANDLER(WM_COMMAND, OnCommand)
|
||||
MESSAGE_HANDLER(WM_SYSCOMMAND, OnSysCommand)
|
||||
|
|
|
@ -332,6 +332,7 @@ public:
|
|||
HRESULT BrowseToPIDL(LPCITEMIDLIST pidl, long flags);
|
||||
HRESULT BrowseToPath(IShellFolder *newShellFolder, LPCITEMIDLIST absolutePIDL,
|
||||
FOLDERSETTINGS *folderSettings, long flags);
|
||||
void SaveViewState();
|
||||
HRESULT GetMenuBand(REFIID riid, void **shellMenu);
|
||||
HRESULT GetBaseBar(bool vertical, REFIID riid, void **theBaseBar);
|
||||
BOOL IsBandLoaded(const CLSID clsidBand, bool vertical, DWORD *pdwBandID);
|
||||
|
@ -406,7 +407,7 @@ public:
|
|||
// *** IServiceProvider methods ***
|
||||
STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void **ppvObject) override;
|
||||
|
||||
// *** IShellBowserService methods ***
|
||||
// *** IShellBrowserService methods ***
|
||||
STDMETHOD(GetPropertyBag)(long flags, REFIID riid, void **ppvObject) override;
|
||||
|
||||
// *** IDispatch methods ***
|
||||
|
@ -826,6 +827,8 @@ HRESULT CShellBrowser::ApplyBrowserDefaultFolderSettings(IShellView *pvs)
|
|||
{
|
||||
m_settings.Reset();
|
||||
hr = CGlobalFolderSettings::ResetBrowserSettings();
|
||||
if (SUCCEEDED(hr))
|
||||
m_deffoldersettings.Load();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
@ -995,6 +998,13 @@ HRESULT IEGetNameAndFlags(LPITEMIDLIST pidl, SHGDNF uFlags, LPWSTR pszBuf, UINT
|
|||
return IEGetNameAndFlagsEx(pidl, uFlags, 0, pszBuf, cchBuf, rgfInOut);
|
||||
}
|
||||
|
||||
void CShellBrowser::SaveViewState()
|
||||
{
|
||||
// TODO: Also respect EBO_NOPERSISTVIEWSTATE?
|
||||
if (gCabinetState.fSaveLocalView && fCurrentShellView && !SHRestricted(REST_NOSAVESET))
|
||||
fCurrentShellView->SaveViewState();
|
||||
}
|
||||
|
||||
HRESULT CShellBrowser::BrowseToPath(IShellFolder *newShellFolder,
|
||||
LPCITEMIDLIST absolutePIDL, FOLDERSETTINGS *folderSettings, long flags)
|
||||
{
|
||||
|
@ -1029,6 +1039,7 @@ HRESULT CShellBrowser::BrowseToPath(IShellFolder *newShellFolder,
|
|||
|
||||
if (fCurrentShellView)
|
||||
{
|
||||
SaveViewState();
|
||||
fCurrentShellView->UIActivate(SVUIA_DEACTIVATE);
|
||||
}
|
||||
|
||||
|
@ -2204,6 +2215,7 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::Exec(const GUID *pguidCmdGroup, DWORD n
|
|||
switch (nCmdID)
|
||||
{
|
||||
case DVCMDID_RESET_DEFAULTFOLDER_SETTINGS:
|
||||
ApplyBrowserDefaultFolderSettings(NULL);
|
||||
IUnknown_Exec(fCurrentShellView, CGID_DefView, nCmdID, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
|
@ -3615,6 +3627,7 @@ LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &
|
|||
{
|
||||
fToolbarProxy.Destroy();
|
||||
|
||||
SaveViewState();
|
||||
fCurrentShellView->DestroyViewWindow();
|
||||
fCurrentShellView->UIActivate(SVUIA_DEACTIVATE);
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
/*
|
||||
TODO:
|
||||
- Load/Save the view state from/into the stream provided by the ShellBrowser unless FWF_NOBROWSERVIEWSTATE is set.
|
||||
- When editing starts on item, set edit text to for editing value.
|
||||
- Fix shell view to handle view mode popup exec.
|
||||
- The background context menu should have a pidl just like foreground menus. This
|
||||
|
@ -60,8 +59,18 @@ enum {
|
|||
|
||||
typedef struct
|
||||
{
|
||||
BOOL bIsAscending;
|
||||
INT8 Direction;
|
||||
bool bLoadedFromViewState;
|
||||
bool bColumnIsFolderColumn;
|
||||
UINT8 Reserved; // Unused
|
||||
INT ListColumn;
|
||||
|
||||
enum { UNSPECIFIEDCOLUMN = -1 };
|
||||
void Reset()
|
||||
{
|
||||
*(UINT*)this = 0;
|
||||
ListColumn = UNSPECIFIEDCOLUMN;
|
||||
}
|
||||
} LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
|
||||
|
||||
#define SHV_CHANGE_NOTIFY (WM_USER + 0x1111)
|
||||
|
@ -71,6 +80,25 @@ typedef struct
|
|||
// to call TrackPopupMenu and let it use the 0 value as an indication that the menu was canceled
|
||||
#define CONTEXT_MENU_BASE_ID 1
|
||||
|
||||
struct PERSISTCOLUMNS
|
||||
{
|
||||
enum { MAXCOUNT = 100 };
|
||||
static const UINT SIG = ('R' << 0) | ('O' << 8) | ('S' << 16) | (('c') << 24);
|
||||
UINT Signature;
|
||||
UINT Count;
|
||||
UINT Columns[MAXCOUNT];
|
||||
};
|
||||
|
||||
struct PERSISTCLASSICVIEWSTATE
|
||||
{
|
||||
static const UINT SIG = ('R' << 0) | ('O' << 8) | ('S' << 16) | (('c' ^ 'v' ^ 's') << 24);
|
||||
UINT Signature;
|
||||
WORD SortColId;
|
||||
INT8 SortDir;
|
||||
static const UINT VALIDFWF = FWF_AUTOARRANGE | FWF_SNAPTOGRID | FWF_NOGROUPING; // Note: The desktop applies FWF_NOICONS when appropriate
|
||||
FOLDERSETTINGS FolderSettings;
|
||||
};
|
||||
|
||||
static UINT
|
||||
GetContextMenuFlags(IShellBrowser *pSB, SFGAOF sfgao)
|
||||
{
|
||||
|
@ -215,6 +243,7 @@ private:
|
|||
UINT m_cidl;
|
||||
PCUITEMID_CHILD *m_apidl;
|
||||
PIDLIST_ABSOLUTE m_pidlParent;
|
||||
HDPA m_LoadColumnsList;
|
||||
HDPA m_ListToFolderColMap;
|
||||
LISTVIEW_SORT_INFO m_sortInfo;
|
||||
ULONG m_hNotify; // Change notification handle
|
||||
|
@ -274,8 +303,8 @@ public:
|
|||
HRESULT MapListColumnToFolderColumn(UINT ListCol);
|
||||
HRESULT GetDetailsByFolderColumn(PCUITEMID_CHILD pidl, UINT FoldCol, SHELLDETAILS &sd);
|
||||
HRESULT GetDetailsByListColumn(PCUITEMID_CHILD pidl, UINT ListCol, SHELLDETAILS &sd);
|
||||
HRESULT LoadColumn(UINT FoldCol, UINT ListCol, BOOL Insert);
|
||||
HRESULT LoadColumns(UINT *pColList = NULL, UINT ColListCount = 0);
|
||||
HRESULT LoadColumn(UINT FoldCol, UINT ListCol, BOOL Insert, UINT ForceWidth = 0);
|
||||
HRESULT LoadColumns(SIZE_T *pColList = NULL, UINT ColListCount = 0);
|
||||
void ColumnListChanged();
|
||||
PCUITEMID_CHILD _PidlByItem(int i);
|
||||
PCUITEMID_CHILD _PidlByItem(LVITEM& lvItem);
|
||||
|
@ -301,6 +330,11 @@ public:
|
|||
HRESULT drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
||||
HRESULT InvokeContextMenuCommand(CComPtr<IContextMenu>& pCM, LPCSTR lpVerb, POINT* pt = NULL);
|
||||
LRESULT OnExplorerCommand(UINT uCommand, BOOL bUseSelection);
|
||||
FOLDERVIEWMODE GetDefaultViewMode();
|
||||
HRESULT GetDefaultViewStream(DWORD Stgm, IStream **ppStream);
|
||||
HRESULT LoadViewState();
|
||||
HRESULT SaveViewState(IStream *pStream);
|
||||
void UpdateFolderViewFlags();
|
||||
|
||||
// *** IOleWindow methods ***
|
||||
STDMETHOD(GetWindow)(HWND *lphwnd) override;
|
||||
|
@ -529,6 +563,7 @@ CDefView::CDefView() :
|
|||
m_cidl(0),
|
||||
m_apidl(NULL),
|
||||
m_pidlParent(NULL),
|
||||
m_LoadColumnsList(NULL),
|
||||
m_hNotify(0),
|
||||
m_hAccel(NULL),
|
||||
m_dwAspects(0),
|
||||
|
@ -541,13 +576,13 @@ CDefView::CDefView() :
|
|||
m_Destroyed(FALSE)
|
||||
{
|
||||
ZeroMemory(&m_FolderSettings, sizeof(m_FolderSettings));
|
||||
ZeroMemory(&m_sortInfo, sizeof(m_sortInfo));
|
||||
ZeroMemory(&m_ptLastMousePos, sizeof(m_ptLastMousePos));
|
||||
ZeroMemory(&m_Category, sizeof(m_Category));
|
||||
m_viewinfo_data.clrText = GetSysColor(COLOR_WINDOWTEXT);
|
||||
m_viewinfo_data.clrTextBack = GetSysColor(COLOR_WINDOW);
|
||||
m_viewinfo_data.hbmBack = NULL;
|
||||
|
||||
m_sortInfo.Reset();
|
||||
m_ListToFolderColMap = DPA_Create(0);
|
||||
m_hMyComputerIcon = LoadIconW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_COMPUTER_DESKTOP));
|
||||
}
|
||||
|
@ -570,6 +605,7 @@ CDefView::~CDefView()
|
|||
}
|
||||
|
||||
SHFree(m_apidl);
|
||||
DPA_Destroy(m_LoadColumnsList);
|
||||
DPA_Destroy(m_ListToFolderColMap);
|
||||
}
|
||||
|
||||
|
@ -757,20 +793,21 @@ BOOL CDefView::CreateList()
|
|||
TRACE("%p\n", this);
|
||||
|
||||
dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
|
||||
LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_AUTOARRANGE; // FIXME: Why is LVS_AUTOARRANGE here?
|
||||
dwExStyle = WS_EX_CLIENTEDGE;
|
||||
ListExStyle = 0;
|
||||
LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_AUTOARRANGE; // FIXME: Remove LVS_AUTOARRANGE when the view is able to save ItemPos
|
||||
dwExStyle = (m_FolderSettings.fFlags & FWF_NOCLIENTEDGE) ? 0 : WS_EX_CLIENTEDGE;
|
||||
ListExStyle = LVS_EX_INFOTIP | LVS_EX_LABELTIP;
|
||||
|
||||
if (m_FolderSettings.fFlags & FWF_DESKTOP)
|
||||
{
|
||||
m_FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
|
||||
dwStyle |= LVS_ALIGNLEFT;
|
||||
// LVS_EX_REGIONAL?
|
||||
}
|
||||
else
|
||||
{
|
||||
dwStyle |= LVS_SHOWSELALWAYS; // MSDN says FWF_SHOWSELALWAYS is deprecated, always turn on for folders
|
||||
dwStyle |= (m_FolderSettings.fFlags & FWF_ALIGNLEFT) ? LVS_ALIGNLEFT : LVS_ALIGNTOP;
|
||||
ListExStyle = LVS_EX_DOUBLEBUFFER;
|
||||
ListExStyle |= LVS_EX_DOUBLEBUFFER;
|
||||
}
|
||||
|
||||
ViewMode = m_FolderSettings.ViewMode;
|
||||
|
@ -839,9 +876,6 @@ BOOL CDefView::CreateList()
|
|||
|
||||
m_ListView.SetExtendedListViewStyle(ListExStyle);
|
||||
|
||||
m_sortInfo.bIsAscending = TRUE;
|
||||
m_sortInfo.ListColumn = -1;
|
||||
|
||||
/* UpdateShellSettings(); */
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -916,7 +950,16 @@ BOOL CDefView::InitList()
|
|||
m_ListView.SetImageList(small_icons, LVSIL_SMALL);
|
||||
|
||||
m_hMenuArrangeModes = CreateMenu();
|
||||
LoadColumns();
|
||||
|
||||
SIZE_T *pColumns = m_LoadColumnsList ? (SIZE_T*)DPA_GetPtrPtr(m_LoadColumnsList) : NULL;
|
||||
UINT ColumnCount = pColumns ? DPA_GetPtrCount(m_LoadColumnsList) : 0;
|
||||
LoadColumns(pColumns, ColumnCount);
|
||||
if (m_sortInfo.bColumnIsFolderColumn)
|
||||
{
|
||||
m_sortInfo.bColumnIsFolderColumn = FALSE;
|
||||
HRESULT hr = MapFolderColumnToListColumn(m_sortInfo.ListColumn);
|
||||
m_sortInfo.ListColumn = SUCCEEDED(hr) ? hr : 0;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -998,7 +1041,7 @@ HRESULT CDefView::GetDetailsByListColumn(PCUITEMID_CHILD pidl, UINT ListCol, SHE
|
|||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CDefView::LoadColumn(UINT FoldCol, UINT ListCol, BOOL Insert)
|
||||
HRESULT CDefView::LoadColumn(UINT FoldCol, UINT ListCol, BOOL Insert, UINT ForceWidth)
|
||||
{
|
||||
WCHAR buf[MAX_PATH];
|
||||
SHELLDETAILS sd;
|
||||
|
@ -1020,7 +1063,7 @@ HRESULT CDefView::LoadColumn(UINT FoldCol, UINT ListCol, BOOL Insert)
|
|||
lvc.mask = LVCF_TEXT | LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
|
||||
lvc.pszText = buf;
|
||||
lvc.fmt = sd.fmt;
|
||||
lvc.cx = sd.cxChar * chavewidth; // FIXME: DPI?
|
||||
lvc.cx = ForceWidth ? ForceWidth : (sd.cxChar * chavewidth); // FIXME: DPI?
|
||||
lvc.iSubItem = FoldCol; // Used by MapFolderColumnToListColumn & MapListColumnToFolderColumn
|
||||
if ((int)ListCol == -1)
|
||||
{
|
||||
|
@ -1035,11 +1078,11 @@ HRESULT CDefView::LoadColumn(UINT FoldCol, UINT ListCol, BOOL Insert)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDefView::LoadColumns(UINT *pColList, UINT ColListCount)
|
||||
HRESULT CDefView::LoadColumns(SIZE_T *pColList, UINT ColListCount)
|
||||
{
|
||||
HWND hWndHdr = ListView_GetHeader(m_ListView.m_hWnd);
|
||||
UINT newColCount = 0, oldColCount = Header_GetItemCount(hWndHdr);
|
||||
UINT foldCol, i;
|
||||
UINT width = 0, foldCol, i;
|
||||
HRESULT hr = S_FALSE;
|
||||
|
||||
m_ListView.SetRedraw(FALSE);
|
||||
|
@ -1052,7 +1095,8 @@ HRESULT CDefView::LoadColumns(UINT *pColList, UINT ColListCount)
|
|||
{
|
||||
if (i >= ColListCount)
|
||||
break;
|
||||
foldCol = pColList[i++];
|
||||
width = HIWORD(pColList[i]);
|
||||
foldCol = LOWORD(pColList[i++]);
|
||||
}
|
||||
|
||||
SHCOLSTATEF state = 0;
|
||||
|
@ -1074,7 +1118,7 @@ HRESULT CDefView::LoadColumns(UINT *pColList, UINT ColListCount)
|
|||
|
||||
bool insert = newColCount >= oldColCount;
|
||||
UINT listCol = insert ? -1 : newColCount;
|
||||
hr = LoadColumn(foldCol, listCol, insert);
|
||||
hr = LoadColumn(foldCol, listCol, insert, width);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
if (!pColList)
|
||||
|
@ -1091,6 +1135,11 @@ HRESULT CDefView::LoadColumns(UINT *pColList, UINT ColListCount)
|
|||
m_ListView.SetRedraw(TRUE);
|
||||
ColumnListChanged();
|
||||
assert(SUCCEEDED(MapFolderColumnToListColumn(0))); // We don't allow turning off the Name column
|
||||
if (m_LoadColumnsList)
|
||||
{
|
||||
DPA_Destroy(m_LoadColumnsList);
|
||||
m_LoadColumnsList = NULL;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -1170,9 +1219,7 @@ INT CALLBACK CDefView::ListViewCompareItems(LPARAM lParam1, LPARAM lParam2, LPAR
|
|||
return 0;
|
||||
|
||||
SHORT nDiff = HRESULT_CODE(hres);
|
||||
if (!pThis->m_sortInfo.bIsAscending)
|
||||
nDiff = -nDiff;
|
||||
return nDiff;
|
||||
return nDiff * pThis->m_sortInfo.Direction;
|
||||
}
|
||||
|
||||
BOOL CDefView::_Sort(int Col)
|
||||
|
@ -1180,6 +1227,7 @@ BOOL CDefView::_Sort(int Col)
|
|||
HWND hHeader;
|
||||
HDITEM hColumn;
|
||||
int prevCol = m_sortInfo.ListColumn;
|
||||
m_sortInfo.bLoadedFromViewState = FALSE;
|
||||
|
||||
// FIXME: Is this correct? Who sets this style?
|
||||
// And if it is set, should it also block sorting using the menu?
|
||||
|
@ -1197,11 +1245,13 @@ BOOL CDefView::_Sort(int Col)
|
|||
}
|
||||
|
||||
if (prevCol == Col)
|
||||
m_sortInfo.bIsAscending = !m_sortInfo.bIsAscending;
|
||||
m_sortInfo.Direction *= -1;
|
||||
else
|
||||
m_sortInfo.bIsAscending = TRUE;
|
||||
m_sortInfo.Direction = 0;
|
||||
m_sortInfo.ListColumn = Col;
|
||||
}
|
||||
if (!m_sortInfo.Direction)
|
||||
m_sortInfo.Direction += 1;
|
||||
|
||||
/* If the sorting column changed, remove the sorting style from the old column */
|
||||
if (prevCol != -1 && prevCol != m_sortInfo.ListColumn)
|
||||
|
@ -1215,11 +1265,12 @@ BOOL CDefView::_Sort(int Col)
|
|||
/* Set the sorting style on the new column */
|
||||
hColumn.mask = HDI_FORMAT;
|
||||
Header_GetItem(hHeader, m_sortInfo.ListColumn, &hColumn);
|
||||
hColumn.fmt &= (m_sortInfo.bIsAscending ? ~HDF_SORTDOWN : ~HDF_SORTUP );
|
||||
hColumn.fmt |= (m_sortInfo.bIsAscending ? HDF_SORTUP : HDF_SORTDOWN);
|
||||
hColumn.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP);
|
||||
hColumn.fmt |= (m_sortInfo.Direction > 0 ? HDF_SORTUP : HDF_SORTDOWN);
|
||||
Header_SetItem(hHeader, m_sortInfo.ListColumn, &hColumn);
|
||||
|
||||
/* Sort the list, using the current values of ListColumn and bIsAscending */
|
||||
ASSERT(m_sortInfo.Direction == 1 || m_sortInfo.Direction == -1);
|
||||
return m_ListView.SortItems(ListViewCompareItems, this);
|
||||
}
|
||||
|
||||
|
@ -1453,9 +1504,9 @@ HRESULT CDefView::FillList(BOOL IsRefreshCommand)
|
|||
|
||||
/* sort the array */
|
||||
int sortCol = -1;
|
||||
if (!IsRefreshCommand) // Are we loading for the first time?
|
||||
if (!IsRefreshCommand && !m_sortInfo.bLoadedFromViewState) // Are we loading for the first time?
|
||||
{
|
||||
m_sortInfo.bIsAscending = TRUE;
|
||||
m_sortInfo.Direction = 0;
|
||||
sortCol = 0; // In case the folder does not know/care
|
||||
if (m_pSF2Parent)
|
||||
{
|
||||
|
@ -3073,11 +3124,190 @@ HRESULT WINAPI CDefView::AddPropertySheetPages(DWORD dwReserved, LPFNADDPROPSHEE
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT Read(IStream *pS, LPVOID buffer, ULONG cb)
|
||||
{
|
||||
ULONG read;
|
||||
HRESULT hr = pS->Read(buffer, cb, &read);
|
||||
return FAILED(hr) ? hr : (cb == read ? S_OK : HResultFromWin32(ERROR_MORE_DATA));
|
||||
}
|
||||
|
||||
static DWORD ReadDWORD(IPropertyBag *pPB, LPCWSTR name, DWORD def)
|
||||
{
|
||||
DWORD value;
|
||||
HRESULT hr = SHPropertyBag_ReadDWORD(pPB, name, &value);
|
||||
return SUCCEEDED(hr) ? value : def;
|
||||
}
|
||||
|
||||
HRESULT CDefView::GetDefaultViewStream(DWORD Stgm, IStream **ppStream)
|
||||
{
|
||||
CLSID clsid;
|
||||
HRESULT hr = IUnknown_GetClassID(m_pSFParent, &clsid);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
WCHAR path[MAX_PATH], name[39];
|
||||
wsprintfW(path, L"%s\\%s", REGSTR_PATH_EXPLORER, L"Streams\\Default");
|
||||
StringFromGUID2(clsid, name, 39);
|
||||
*ppStream = SHOpenRegStream2W(HKEY_CURRENT_USER, path, name, Stgm);
|
||||
hr = *ppStream ? S_OK : E_FAIL;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT LoadColumnsStream(PERSISTCOLUMNS &cols, IStream *pS)
|
||||
{
|
||||
HRESULT hr = Read(pS, &cols, FIELD_OFFSET(PERSISTCOLUMNS, Columns));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
if (cols.Signature != PERSISTCOLUMNS::SIG || cols.Count > cols.MAXCOUNT)
|
||||
return HResultFromWin32(ERROR_INVALID_DATA);
|
||||
return Read(pS, &cols.Columns, sizeof(*cols.Columns) * cols.Count);
|
||||
}
|
||||
|
||||
HRESULT CDefView::LoadViewState()
|
||||
{
|
||||
PERSISTCLASSICVIEWSTATE cvs;
|
||||
PERSISTCOLUMNS cols;
|
||||
CComPtr<IStream> pS;
|
||||
CComPtr<IPropertyBag> pPB;
|
||||
bool fallback = false;
|
||||
HRESULT hrColumns = E_FAIL;
|
||||
HRESULT hr = IUnknown_QueryServicePropertyBag(m_pShellBrowser, SHGVSPB_FOLDER, IID_PPV_ARG(IPropertyBag, &pPB));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
DWORD data;
|
||||
if (FAILED(hr = SHPropertyBag_ReadDWORD(pPB, L"Mode", &data)))
|
||||
goto loadfallback;
|
||||
cvs.FolderSettings.ViewMode = data;
|
||||
cvs.FolderSettings.fFlags = ReadDWORD(pPB, L"FFlags", FWF_NOGROUPING);
|
||||
data = ReadDWORD(pPB, L"Sort", ~0ul);
|
||||
cvs.SortColId = data != ~0ul ? (WORD)data : LISTVIEW_SORT_INFO::UNSPECIFIEDCOLUMN;
|
||||
cvs.SortDir = (INT8)ReadDWORD(pPB, L"SortDir", 1);
|
||||
if (SUCCEEDED(hrColumns = SHPropertyBag_ReadStream(pPB, L"ColInfo", &pS)))
|
||||
hrColumns = LoadColumnsStream(cols, pS);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FAILED(hr = (m_pShellBrowser ? m_pShellBrowser->GetViewStateStream(STGM_READ, &pS) : E_UNEXPECTED)))
|
||||
{
|
||||
loadfallback:
|
||||
hr = GetDefaultViewStream(STGM_READ, &pS);
|
||||
fallback = true;
|
||||
}
|
||||
if (FAILED(hr) || FAILED(hr = Read(pS, &cvs, sizeof(cvs))))
|
||||
return hr;
|
||||
if (cvs.Signature != cvs.SIG)
|
||||
return HResultFromWin32(ERROR_INVALID_DATA);
|
||||
hrColumns = LoadColumnsStream(cols, pS);
|
||||
}
|
||||
m_FolderSettings.ViewMode = cvs.FolderSettings.ViewMode;
|
||||
m_FolderSettings.fFlags &= ~cvs.VALIDFWF;
|
||||
m_FolderSettings.fFlags |= cvs.FolderSettings.fFlags & cvs.VALIDFWF;
|
||||
if (SUCCEEDED(hrColumns))
|
||||
{
|
||||
BOOL failed = FALSE;
|
||||
if ((m_LoadColumnsList = DPA_Create(cols.Count)) != NULL)
|
||||
{
|
||||
for (UINT i = 0; i < cols.Count; ++i)
|
||||
{
|
||||
failed |= !DPA_SetPtr(m_LoadColumnsList, i, UlongToPtr(cols.Columns[i]));
|
||||
}
|
||||
}
|
||||
if (failed || !cols.Count)
|
||||
{
|
||||
DPA_Destroy(m_LoadColumnsList);
|
||||
m_LoadColumnsList = NULL;
|
||||
}
|
||||
}
|
||||
m_sortInfo.bLoadedFromViewState = !fallback && m_LoadColumnsList && cvs.SortColId != LISTVIEW_SORT_INFO::UNSPECIFIEDCOLUMN;
|
||||
m_sortInfo.bColumnIsFolderColumn = TRUE;
|
||||
m_sortInfo.Direction = cvs.SortDir > 0 ? 1 : -1;
|
||||
m_sortInfo.ListColumn = cvs.SortColId;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CDefView::SaveViewState(IStream *pStream)
|
||||
{
|
||||
int sortcol = MapListColumnToFolderColumn(m_sortInfo.ListColumn);
|
||||
PERSISTCLASSICVIEWSTATE cvs;
|
||||
cvs.SortColId = sortcol >= 0 ? (WORD)sortcol : 0;
|
||||
cvs.SortDir = m_sortInfo.Direction;
|
||||
PERSISTCOLUMNS cols;
|
||||
cols.Signature = PERSISTCOLUMNS::SIG;
|
||||
cols.Count = 0;
|
||||
LVCOLUMN lvc;
|
||||
lvc.mask = LVCF_WIDTH | LVCF_SUBITEM;
|
||||
for (UINT i = 0, j = 0; i < PERSISTCOLUMNS::MAXCOUNT && ListView_GetColumn(m_ListView, j, &lvc); ++j)
|
||||
{
|
||||
HRESULT hr = MapListColumnToFolderColumn(lvc.iSubItem);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
cols.Columns[i] = MAKELONG(hr, lvc.cx);
|
||||
cols.Count = ++i;
|
||||
}
|
||||
}
|
||||
UINT cbColumns = FIELD_OFFSET(PERSISTCOLUMNS, Columns) + (sizeof(*cols.Columns) * cols.Count);
|
||||
UpdateFolderViewFlags();
|
||||
|
||||
IPropertyBag *pPB;
|
||||
HRESULT hr = S_OK;
|
||||
if (pStream)
|
||||
{
|
||||
pStream->AddRef();
|
||||
goto stream;
|
||||
}
|
||||
hr = IUnknown_QueryServicePropertyBag(m_pShellBrowser, SHGVSPB_FOLDER, IID_PPV_ARG(IPropertyBag, &pPB));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
UINT uViewMode;
|
||||
GetCurrentViewMode(&uViewMode);
|
||||
hr = SHPropertyBag_WriteDWORD(pPB, L"Mode", uViewMode);
|
||||
SHPropertyBag_WriteDWORD(pPB, L"FFlags", m_FolderSettings.fFlags);
|
||||
SHPropertyBag_WriteDWORD(pPB, L"Sort", cvs.SortColId);
|
||||
SHPropertyBag_WriteDWORD(pPB, L"SortDir", cvs.SortDir);
|
||||
pStream = cols.Count ? SHCreateMemStream((LPBYTE)&cols, cbColumns) : NULL;
|
||||
if (!pStream || FAILED(SHPropertyBag_WriteStream(pPB, L"ColInfo", pStream)))
|
||||
SHPropertyBag_Delete(pPB, L"ColInfo");
|
||||
#if 0 // TODO
|
||||
WCHAR name[MAX_PATH];
|
||||
memcpy(name, L"ItemPos", sizeof(L"ItemPos"));
|
||||
if (SHGetPerScreenResName(name + 7, _countof(name) - 7, 0))
|
||||
{
|
||||
if (GetAutoArrange() == S_FALSE)
|
||||
// TODO: Save listview item positions
|
||||
else
|
||||
SHPropertyBag_Delete(pPB, name);
|
||||
}
|
||||
#endif
|
||||
pPB->Release();
|
||||
}
|
||||
else if (SUCCEEDED(hr = (m_pShellBrowser ? m_pShellBrowser->GetViewStateStream(STGM_WRITE, &pStream) : E_UNEXPECTED)))
|
||||
{
|
||||
stream:
|
||||
ULONG written;
|
||||
cvs.Signature = cvs.SIG;
|
||||
cvs.FolderSettings = m_FolderSettings;
|
||||
hr = pStream->Write(&cvs, sizeof(cvs), &written);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = pStream->Write(&cols, cbColumns, &written);
|
||||
}
|
||||
if (pStream)
|
||||
pStream->Release();
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT WINAPI CDefView::SaveViewState()
|
||||
{
|
||||
FIXME("(%p) stub\n", this);
|
||||
if (!(m_FolderSettings.fFlags & FWF_NOBROWSERVIEWSTATE))
|
||||
return SaveViewState(NULL);
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
#define UPDATEFOLDERVIEWFLAGS(bits, bit, set) ( (bits) = ((bits) & ~(bit)) | ((set) ? (bit) : 0) )
|
||||
void CDefView::UpdateFolderViewFlags()
|
||||
{
|
||||
UPDATEFOLDERVIEWFLAGS(m_FolderSettings.fFlags, FWF_AUTOARRANGE, GetAutoArrange() == S_OK);
|
||||
UPDATEFOLDERVIEWFLAGS(m_FolderSettings.fFlags, FWF_SNAPTOGRID, _GetSnapToGrid() == S_OK);
|
||||
UPDATEFOLDERVIEWFLAGS(m_FolderSettings.fFlags, FWF_NOGROUPING, !ListView_IsGroupViewEnabled(m_ListView.m_hWnd));
|
||||
}
|
||||
|
||||
HRESULT WINAPI CDefView::SelectItem(PCUITEMID_CHILD pidl, UINT uFlags)
|
||||
|
@ -3186,6 +3416,15 @@ HRESULT WINAPI CDefView::GetItemObject(UINT uItem, REFIID riid, LPVOID *ppvOut)
|
|||
return hr;
|
||||
}
|
||||
|
||||
FOLDERVIEWMODE CDefView::GetDefaultViewMode()
|
||||
{
|
||||
FOLDERVIEWMODE mode = ((m_FolderSettings.fFlags & FWF_DESKTOP) || !IsOS(OS_SERVERADMINUI)) ? FVM_ICON : FVM_DETAILS;
|
||||
FOLDERVIEWMODE temp;
|
||||
if (SUCCEEDED(_DoFolderViewCB(SFVM_DEFVIEWMODE, 0, (LPARAM)&temp)) && temp >= FVM_FIRST && temp <= FVM_LAST)
|
||||
mode = temp;
|
||||
return mode;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CDefView::GetCurrentViewMode(UINT *pViewMode)
|
||||
{
|
||||
TRACE("(%p)->(%p), stub\n", this, pViewMode);
|
||||
|
@ -3422,6 +3661,8 @@ HRESULT STDMETHODCALLTYPE CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_para
|
|||
HRESULT STDMETHODCALLTYPE CDefView::CreateViewWindow3(IShellBrowser *psb, IShellView *psvPrevious, SV3CVW3_FLAGS view_flags, FOLDERFLAGS mask, FOLDERFLAGS flags, FOLDERVIEWMODE mode, const SHELLVIEWID *view_id, const RECT *prcView, HWND *hwnd)
|
||||
{
|
||||
OLEMENUGROUPWIDTHS omw = { { 0, 0, 0, 0, 0, 0 } };
|
||||
const UINT SUPPORTED_SV3CVW3 = SV3CVW3_FORCEVIEWMODE | SV3CVW3_FORCEFOLDERFLAGS;
|
||||
const UINT IGNORE_FWF = FWF_OWNERDATA; // FIXME: Support this
|
||||
|
||||
*hwnd = NULL;
|
||||
|
||||
|
@ -3433,13 +3674,16 @@ HRESULT STDMETHODCALLTYPE CDefView::CreateViewWindow3(IShellBrowser *psb, IShell
|
|||
if (psb == NULL || m_hWnd)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (view_flags != SV3CVW3_DEFAULT)
|
||||
FIXME("unsupported view flags 0x%08x\n", view_flags);
|
||||
if (view_flags & ~SUPPORTED_SV3CVW3)
|
||||
FIXME("unsupported view flags 0x%08x\n", view_flags & ~SUPPORTED_SV3CVW3);
|
||||
|
||||
if (mode == FVM_AUTO)
|
||||
mode = GetDefaultViewMode();
|
||||
|
||||
/* Set up the member variables */
|
||||
m_pShellBrowser = psb;
|
||||
m_FolderSettings.ViewMode = mode;
|
||||
m_FolderSettings.fFlags = mask & flags;
|
||||
m_FolderSettings.fFlags = (mask & flags) & ~IGNORE_FWF;
|
||||
|
||||
if (view_id)
|
||||
{
|
||||
|
@ -3460,6 +3704,7 @@ HRESULT STDMETHODCALLTYPE CDefView::CreateViewWindow3(IShellBrowser *psb, IShell
|
|||
else
|
||||
FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id));
|
||||
}
|
||||
const UINT requestedViewMode = m_FolderSettings.ViewMode;
|
||||
|
||||
/* Get our parent window */
|
||||
m_pShellBrowser->GetWindow(&m_hWndParent);
|
||||
|
@ -3471,6 +3716,12 @@ HRESULT STDMETHODCALLTYPE CDefView::CreateViewWindow3(IShellBrowser *psb, IShell
|
|||
TRACE("-- CommDlgBrowser\n");
|
||||
}
|
||||
|
||||
LoadViewState();
|
||||
if (view_flags & SV3CVW3_FORCEVIEWMODE)
|
||||
m_FolderSettings.ViewMode = requestedViewMode;
|
||||
if (view_flags & SV3CVW3_FORCEFOLDERFLAGS)
|
||||
m_FolderSettings.fFlags = (mask & flags) & ~IGNORE_FWF;
|
||||
|
||||
RECT rcView = *prcView;
|
||||
Create(m_hWndParent, rcView, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_TABSTOP, 0, 0U);
|
||||
if (m_hWnd == NULL)
|
||||
|
@ -3800,17 +4051,20 @@ HRESULT WINAPI CDefView::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCm
|
|||
|
||||
if (IsEqualIID(*pguidCmdGroup, CGID_DefView))
|
||||
{
|
||||
CComPtr<IStream> pStream;
|
||||
WCHAR SubKey[MAX_PATH];
|
||||
switch (nCmdID)
|
||||
{
|
||||
case DVCMDID_SET_DEFAULTFOLDER_SETTINGS:
|
||||
SHDeleteKey(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\ShellNoRoam\\Bags");
|
||||
FIXME("Save current as default\n");
|
||||
if (SUCCEEDED(GetDefaultViewStream(STGM_WRITE, &pStream)))
|
||||
SaveViewState(pStream);
|
||||
break;
|
||||
case DVCMDID_RESET_DEFAULTFOLDER_SETTINGS:
|
||||
wsprintfW(SubKey, L"%s\\%s", REGSTR_PATH_EXPLORER, L"Streams\\Default");
|
||||
SHDeleteKey(HKEY_CURRENT_USER, SubKey);
|
||||
SHDeleteKey(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\ShellNoRoam\\Bags");
|
||||
m_FolderSettings.fFlags |= FWF_NOBROWSERVIEWSTATE; // Don't let this folder save itself
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -528,11 +528,11 @@ CFSFolder::~CFSFolder()
|
|||
}
|
||||
|
||||
static const shvheader GenericSFHeader[] = {
|
||||
{IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
|
||||
{IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 18},
|
||||
{IDS_SHV_COLUMN_SIZE, SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
|
||||
{IDS_SHV_COLUMN_TYPE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
|
||||
{IDS_SHV_COLUMN_MODIFIED, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
|
||||
{IDS_SHV_COLUMN_ATTRIBUTES, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
|
||||
{IDS_SHV_COLUMN_ATTRIBUTES, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 8},
|
||||
{IDS_SHV_COLUMN_COMMENTS, SHCOLSTATE_TYPE_STR | SHCOLSTATE_SLOW, LVCFMT_LEFT, 10}, // We don't currently support comments but CRegFolder does
|
||||
};
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ class CDesktopBrowser :
|
|||
public CWindowImpl<CDesktopBrowser, CWindow, CFrameWinTraits>,
|
||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
public IShellBrowser,
|
||||
public IShellBrowserService,
|
||||
public IServiceProvider
|
||||
{
|
||||
private:
|
||||
|
@ -76,6 +77,9 @@ public:
|
|||
STDMETHOD(OnViewWindowActive)(struct IShellView *ppshv) override;
|
||||
STDMETHOD(SetToolbarItems)(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags) override;
|
||||
|
||||
// *** IShellBrowserService methods ***
|
||||
STDMETHOD(GetPropertyBag)(long flags, REFIID riid, void **ppv) override;
|
||||
|
||||
// *** IBrowserService2 methods (fake for now) ***
|
||||
inline void SetTopBrowser() const {}
|
||||
|
||||
|
@ -93,6 +97,7 @@ public:
|
|||
LRESULT OnGetChangeNotifyServer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnDeviceChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnShowOptionsDlg(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
LRESULT OnSaveState(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
|
||||
DECLARE_WND_CLASS_EX(szProgmanClassName, CS_DBLCLKS, COLOR_DESKTOP)
|
||||
|
||||
|
@ -108,11 +113,13 @@ BEGIN_MSG_MAP(CBaseBar)
|
|||
MESSAGE_HANDLER(WM_DESKTOP_GET_CNOTIFY_SERVER, OnGetChangeNotifyServer)
|
||||
MESSAGE_HANDLER(WM_DEVICECHANGE, OnDeviceChange)
|
||||
MESSAGE_HANDLER(WM_PROGMAN_OPENSHELLSETTINGS, OnShowOptionsDlg)
|
||||
MESSAGE_HANDLER(WM_PROGMAN_SAVESTATE, OnSaveState)
|
||||
END_MSG_MAP()
|
||||
|
||||
BEGIN_COM_MAP(CDesktopBrowser)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IShellBrowser, IShellBrowser)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IShellBrowserService, IShellBrowserService)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
|
||||
END_COM_MAP()
|
||||
};
|
||||
|
@ -228,10 +235,12 @@ HRESULT CDesktopBrowser::Initialize(IShellDesktopTray *ShellDesk)
|
|||
if (FAILED_UNEXPECTEDLY(hRet))
|
||||
return hRet;
|
||||
|
||||
BOOL fHideIcons = SHELL_GetSetting(SSF_HIDEICONS, fHideIcons);
|
||||
FOLDERSETTINGS fs;
|
||||
RECT rcShellView = {0,0,0,0};
|
||||
fs.ViewMode = FVM_ICON;
|
||||
fs.fFlags = FWF_DESKTOP | FWF_NOCLIENTEDGE | FWF_NOSCROLL | FWF_TRANSPARENT;
|
||||
fs.fFlags = FWF_DESKTOP | FWF_NOCLIENTEDGE | FWF_NOSCROLL | FWF_TRANSPARENT |
|
||||
FWF_AUTOARRANGE | (fHideIcons ? FWF_NOICONS : 0);
|
||||
hRet = m_ShellView->CreateViewWindow(NULL, &fs, (IShellBrowser *)this, &rcShellView, &m_hWndShellView);
|
||||
if (FAILED_UNEXPECTEDLY(hRet))
|
||||
return hRet;
|
||||
|
@ -349,9 +358,15 @@ HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetToolbarItems(LPTBBUTTON lpButtons,
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetPropertyBag(long flags, REFIID riid, void **ppv)
|
||||
{
|
||||
ITEMIDLIST deskpidl = {};
|
||||
return SHGetViewStatePropertyBag(&deskpidl, L"Desktop", flags | SHGVSPB_ROAM, riid, ppv);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryService(REFGUID guidService, REFIID riid, PVOID *ppv)
|
||||
{
|
||||
/* FIXME - handle guidService */
|
||||
/* FIXME - handle guidService (SID_STopLevelBrowser for IShellBrowserService etc) */
|
||||
return QueryInterface(riid, ppv);
|
||||
}
|
||||
|
||||
|
@ -517,6 +532,13 @@ LRESULT CDesktopBrowser::OnShowOptionsDlg(UINT uMsg, WPARAM wParam, LPARAM lPara
|
|||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CDesktopBrowser::OnSaveState(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
||||
{
|
||||
if (m_ShellView && !SHRestricted(REST_NOSAVESET))
|
||||
m_ShellView->SaveViewState();
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CDesktopBrowser_CreateInstance(IShellDesktopTray *Tray, REFIID riid, void **ppv)
|
||||
{
|
||||
return ShellObjectCreatorInit<CDesktopBrowser, IShellDesktopTray*>(Tray, riid, ppv);
|
||||
|
|
|
@ -1802,6 +1802,7 @@ BOOL WINAPI ReadCabinetState(CABINETSTATE *cs, int length)
|
|||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD type, r;
|
||||
C_ASSERT(sizeof(*cs) == FIELD_OFFSET(CABINETSTATE, fMenuEnumFilter) + sizeof(UINT));
|
||||
|
||||
TRACE("%p %d\n", cs, length);
|
||||
|
||||
|
@ -1822,6 +1823,10 @@ BOOL WINAPI ReadCabinetState(CABINETSTATE *cs, int length)
|
|||
if ( (r != ERROR_SUCCESS) || (cs->cLength < sizeof(*cs)) ||
|
||||
(cs->cLength != length) )
|
||||
{
|
||||
SHELLSTATE shellstate;
|
||||
shellstate.fWin95Classic = FALSE;
|
||||
SHGetSetSettings(&shellstate, SSF_WIN95CLASSIC, FALSE);
|
||||
|
||||
TRACE("Initializing shell cabinet settings\n");
|
||||
memset(cs, 0, sizeof(*cs));
|
||||
cs->cLength = sizeof(*cs);
|
||||
|
@ -1831,11 +1836,11 @@ BOOL WINAPI ReadCabinetState(CABINETSTATE *cs, int length)
|
|||
cs->fNotShell = FALSE;
|
||||
cs->fSimpleDefault = TRUE;
|
||||
cs->fDontShowDescBar = FALSE;
|
||||
cs->fNewWindowMode = FALSE;
|
||||
cs->fNewWindowMode = shellstate.fWin95Classic;
|
||||
cs->fShowCompColor = FALSE;
|
||||
cs->fDontPrettyNames = FALSE;
|
||||
cs->fAdminsCreateCommonGroups = TRUE;
|
||||
cs->fMenuEnumFilter = 96;
|
||||
cs->fMenuEnumFilter = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -1463,7 +1463,7 @@ CViewStatePropertyBag::_GetMRUSlots(
|
|||
return hr;
|
||||
|
||||
hr = pMruList->QueryPidl(pidl, cSlots, puSlots, pcSlots);
|
||||
if (hr == S_OK && MODE_CAN_WRITE(dwMode))
|
||||
if (hr == S_OK || MODE_CAN_WRITE(dwMode)) // FIXME: HACK! (Without this, a new pidl can never be saved)
|
||||
hr = pMruList->UsePidl(pidl, puSlots);
|
||||
else if (cSlots == 1)
|
||||
hr = E_FAIL;
|
||||
|
@ -1917,13 +1917,9 @@ SHGetViewStatePropertyBag(
|
|||
::LeaveCriticalSection(&g_csBagCacheLock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
g_pCachedBag.Attach(pBag);
|
||||
|
||||
hr = g_pCachedBag->QueryInterface(riid, ppv);
|
||||
|
||||
g_pCachedBag = pBag;
|
||||
::LeaveCriticalSection(&g_csBagCacheLock);
|
||||
return hr;
|
||||
return pBag->QueryInterface(riid, ppv);
|
||||
}
|
||||
|
||||
EXTERN_C VOID FreeViewStatePropertyBagCache(VOID)
|
||||
|
|
|
@ -204,6 +204,13 @@ SHCreatePropertyBagOnProfileSection(
|
|||
_In_ REFIID riid,
|
||||
_Out_ void **ppvObj);
|
||||
|
||||
EXTERN_C HRESULT WINAPI
|
||||
IUnknown_QueryServicePropertyBag(
|
||||
_In_ IUnknown *punk,
|
||||
_In_ long flags,
|
||||
_In_ REFIID riid,
|
||||
_Outptr_ void **ppvObj);
|
||||
|
||||
HWND WINAPI SHCreateWorkerWindowA(WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle,
|
||||
DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra);
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ typedef struct _TRAYNOTIFYDATAW
|
|||
* ProgMan messages
|
||||
*/
|
||||
#define WM_PROGMAN_OPENSHELLSETTINGS (WM_USER + 22) /* wParam specifies the dialog (and tab page) */
|
||||
#define WM_PROGMAN_SAVESTATE (WM_USER + 77)
|
||||
|
||||
/****************************************************************************
|
||||
* IDList Functions
|
||||
|
|
Loading…
Reference in a new issue