1*e639d7c1SWhindmar Saksit /*
2*e639d7c1SWhindmar Saksit * PROJECT: shell32
3*e639d7c1SWhindmar Saksit * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
4*e639d7c1SWhindmar Saksit * PURPOSE: DefView utility functions
5*e639d7c1SWhindmar Saksit * COPYRIGHT: Copyright 2024 Whindmar Saksit <whindsaks@proton.me>
6*e639d7c1SWhindmar Saksit */
7*e639d7c1SWhindmar Saksit
8*e639d7c1SWhindmar Saksit #include "precomp.h"
9*e639d7c1SWhindmar Saksit
10*e639d7c1SWhindmar Saksit WINE_DEFAULT_DEBUG_CHANNEL(shell);
11*e639d7c1SWhindmar Saksit
12*e639d7c1SWhindmar Saksit class CObjectWithSiteBase :
13*e639d7c1SWhindmar Saksit public IObjectWithSite
14*e639d7c1SWhindmar Saksit {
15*e639d7c1SWhindmar Saksit public:
16*e639d7c1SWhindmar Saksit IUnknown* m_pUnkSite;
17*e639d7c1SWhindmar Saksit
CObjectWithSiteBase()18*e639d7c1SWhindmar Saksit CObjectWithSiteBase() : m_pUnkSite(NULL) {}
~CObjectWithSiteBase()19*e639d7c1SWhindmar Saksit virtual ~CObjectWithSiteBase() { SetSite(NULL); }
20*e639d7c1SWhindmar Saksit
21*e639d7c1SWhindmar Saksit // IObjectWithSite
SetSite(IUnknown * pUnkSite)22*e639d7c1SWhindmar Saksit STDMETHODIMP SetSite(IUnknown *pUnkSite) override
23*e639d7c1SWhindmar Saksit {
24*e639d7c1SWhindmar Saksit IUnknown_Set(&m_pUnkSite, pUnkSite);
25*e639d7c1SWhindmar Saksit return S_OK;
26*e639d7c1SWhindmar Saksit }
GetSite(REFIID riid,void ** ppvSite)27*e639d7c1SWhindmar Saksit STDMETHODIMP GetSite(REFIID riid, void **ppvSite) override
28*e639d7c1SWhindmar Saksit {
29*e639d7c1SWhindmar Saksit *ppvSite = NULL;
30*e639d7c1SWhindmar Saksit return m_pUnkSite ? m_pUnkSite->QueryInterface(riid, ppvSite) : E_FAIL;
31*e639d7c1SWhindmar Saksit }
32*e639d7c1SWhindmar Saksit };
33*e639d7c1SWhindmar Saksit
34*e639d7c1SWhindmar Saksit // This class adapts the legacy function callback to work as an IShellFolderViewCB
35*e639d7c1SWhindmar Saksit class CShellFolderViewCBWrapper :
36*e639d7c1SWhindmar Saksit public CComObjectRootEx<CComMultiThreadModelNoCS>,
37*e639d7c1SWhindmar Saksit public IShellFolderViewCB,
38*e639d7c1SWhindmar Saksit public CObjectWithSiteBase
39*e639d7c1SWhindmar Saksit {
40*e639d7c1SWhindmar Saksit protected:
41*e639d7c1SWhindmar Saksit HWND m_hWndMain;
42*e639d7c1SWhindmar Saksit PIDLIST_ABSOLUTE m_Pidl;
43*e639d7c1SWhindmar Saksit CComPtr<IShellFolder> m_psf;
44*e639d7c1SWhindmar Saksit CComPtr<IShellView> m_psvOuter;
45*e639d7c1SWhindmar Saksit LPFNVIEWCALLBACK m_Callback;
46*e639d7c1SWhindmar Saksit FOLDERVIEWMODE m_FVM;
47*e639d7c1SWhindmar Saksit LONG m_Events;
48*e639d7c1SWhindmar Saksit
49*e639d7c1SWhindmar Saksit public:
CShellFolderViewCBWrapper()50*e639d7c1SWhindmar Saksit CShellFolderViewCBWrapper() : m_hWndMain(NULL), m_Pidl(NULL) {}
51*e639d7c1SWhindmar Saksit
~CShellFolderViewCBWrapper()52*e639d7c1SWhindmar Saksit virtual ~CShellFolderViewCBWrapper()
53*e639d7c1SWhindmar Saksit {
54*e639d7c1SWhindmar Saksit ILFree(m_Pidl);
55*e639d7c1SWhindmar Saksit }
56*e639d7c1SWhindmar Saksit
Initialize(LPCSFV psvcbi)57*e639d7c1SWhindmar Saksit HRESULT WINAPI Initialize(LPCSFV psvcbi)
58*e639d7c1SWhindmar Saksit {
59*e639d7c1SWhindmar Saksit m_psf = psvcbi->pshf;
60*e639d7c1SWhindmar Saksit m_psvOuter = psvcbi->psvOuter;
61*e639d7c1SWhindmar Saksit m_Pidl = psvcbi->pidl ? ILClone(psvcbi->pidl) : NULL;
62*e639d7c1SWhindmar Saksit m_Callback = psvcbi->pfnCallback;
63*e639d7c1SWhindmar Saksit m_FVM = psvcbi->fvm;
64*e639d7c1SWhindmar Saksit m_Events = psvcbi->lEvents;
65*e639d7c1SWhindmar Saksit return S_OK;
66*e639d7c1SWhindmar Saksit }
67*e639d7c1SWhindmar Saksit
68*e639d7c1SWhindmar Saksit // IShellFolderViewCB
MessageSFVCB(UINT uMsg,WPARAM wParam,LPARAM lParam)69*e639d7c1SWhindmar Saksit STDMETHODIMP MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) override
70*e639d7c1SWhindmar Saksit {
71*e639d7c1SWhindmar Saksit switch (uMsg)
72*e639d7c1SWhindmar Saksit {
73*e639d7c1SWhindmar Saksit case SFVM_HWNDMAIN:
74*e639d7c1SWhindmar Saksit m_hWndMain = (HWND)lParam;
75*e639d7c1SWhindmar Saksit break;
76*e639d7c1SWhindmar Saksit
77*e639d7c1SWhindmar Saksit case SFVM_DEFVIEWMODE:
78*e639d7c1SWhindmar Saksit if (m_FVM)
79*e639d7c1SWhindmar Saksit *(FOLDERVIEWMODE*)lParam = m_FVM;
80*e639d7c1SWhindmar Saksit break;
81*e639d7c1SWhindmar Saksit }
82*e639d7c1SWhindmar Saksit
83*e639d7c1SWhindmar Saksit HRESULT hr = m_Callback(m_psvOuter, m_psf, m_hWndMain, uMsg, wParam, lParam);
84*e639d7c1SWhindmar Saksit if (SUCCEEDED(hr))
85*e639d7c1SWhindmar Saksit return hr;
86*e639d7c1SWhindmar Saksit
87*e639d7c1SWhindmar Saksit switch (uMsg)
88*e639d7c1SWhindmar Saksit {
89*e639d7c1SWhindmar Saksit case SFVM_GETNOTIFY:
90*e639d7c1SWhindmar Saksit *(LPITEMIDLIST*)wParam = m_Pidl;
91*e639d7c1SWhindmar Saksit *(LONG*)lParam = m_Events;
92*e639d7c1SWhindmar Saksit return S_OK;
93*e639d7c1SWhindmar Saksit }
94*e639d7c1SWhindmar Saksit return hr;
95*e639d7c1SWhindmar Saksit }
96*e639d7c1SWhindmar Saksit
97*e639d7c1SWhindmar Saksit // IObjectWithSite
SetSite(IUnknown * pUnkSite)98*e639d7c1SWhindmar Saksit STDMETHODIMP SetSite(IUnknown *pUnkSite) override
99*e639d7c1SWhindmar Saksit {
100*e639d7c1SWhindmar Saksit // learn.microsoft.com/en-us/windows/win32/shell/sfvm-setisfv
101*e639d7c1SWhindmar Saksit HRESULT hr = CObjectWithSiteBase::SetSite(pUnkSite);
102*e639d7c1SWhindmar Saksit MessageSFVCB(SFVM_SETISFV, 0, (LPARAM)pUnkSite);
103*e639d7c1SWhindmar Saksit return hr;
104*e639d7c1SWhindmar Saksit }
105*e639d7c1SWhindmar Saksit
106*e639d7c1SWhindmar Saksit DECLARE_NO_REGISTRY()
107*e639d7c1SWhindmar Saksit DECLARE_NOT_AGGREGATABLE(CShellFolderViewCBWrapper)
108*e639d7c1SWhindmar Saksit BEGIN_COM_MAP(CShellFolderViewCBWrapper)
109*e639d7c1SWhindmar Saksit COM_INTERFACE_ENTRY_IID(IID_IShellFolderViewCB, IShellFolderViewCB)
110*e639d7c1SWhindmar Saksit COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
111*e639d7c1SWhindmar Saksit END_COM_MAP()
112*e639d7c1SWhindmar Saksit };
113*e639d7c1SWhindmar Saksit
114*e639d7c1SWhindmar Saksit /*************************************************************************
115*e639d7c1SWhindmar Saksit * SHCreateShellFolderViewEx [SHELL32.174] (Win95+)
116*e639d7c1SWhindmar Saksit */
117*e639d7c1SWhindmar Saksit EXTERN_C HRESULT WINAPI
SHCreateShellFolderViewEx(_In_ LPCSFV pcsfv,_Out_ IShellView ** ppsv)118*e639d7c1SWhindmar Saksit SHCreateShellFolderViewEx(_In_ LPCSFV pcsfv, _Out_ IShellView **ppsv)
119*e639d7c1SWhindmar Saksit {
120*e639d7c1SWhindmar Saksit if (!ppsv)
121*e639d7c1SWhindmar Saksit return E_INVALIDARG;
122*e639d7c1SWhindmar Saksit *ppsv = NULL;
123*e639d7c1SWhindmar Saksit
124*e639d7c1SWhindmar Saksit TRACE("sf=%p pidl=%p cb=%p mode=0x%08x outer=%p\n",
125*e639d7c1SWhindmar Saksit pcsfv->pshf, pcsfv->pidl, pcsfv->pfnCallback,
126*e639d7c1SWhindmar Saksit pcsfv->fvm, pcsfv->psvOuter);
127*e639d7c1SWhindmar Saksit
128*e639d7c1SWhindmar Saksit CComPtr<IShellFolderViewCB> psfvcb;
129*e639d7c1SWhindmar Saksit SFV_CREATE create = { sizeof(create), pcsfv->pshf, pcsfv->psvOuter };
130*e639d7c1SWhindmar Saksit
131*e639d7c1SWhindmar Saksit if (pcsfv->pfnCallback)
132*e639d7c1SWhindmar Saksit {
133*e639d7c1SWhindmar Saksit HRESULT hr = ShellObjectCreatorInit<CShellFolderViewCBWrapper>(pcsfv,
134*e639d7c1SWhindmar Saksit IID_PPV_ARG(IShellFolderViewCB, &psfvcb));
135*e639d7c1SWhindmar Saksit if (FAILED(hr))
136*e639d7c1SWhindmar Saksit return hr;
137*e639d7c1SWhindmar Saksit create.psfvcb = psfvcb;
138*e639d7c1SWhindmar Saksit }
139*e639d7c1SWhindmar Saksit return SHCreateShellFolderView(&create, ppsv);
140*e639d7c1SWhindmar Saksit }
141