windows-nt/Source/XPSP1/NT/shell/ext/shscrap/scext.cpp
2020-09-26 16:20:57 +08:00

248 lines
5.9 KiB
C++

#include "shole.h"
#include "ids.h"
//===========================================================================
// CScrapExt : Class definition
//===========================================================================
class CScrapExt : public IShellExtInit, public IShellPropSheetExt
{
public:
CScrapExt();
~CScrapExt();
HRESULT GetFileName(LPTSTR pszPath);
// IUnKnown
virtual HRESULT __stdcall QueryInterface(REFIID,void **);
virtual ULONG __stdcall AddRef(void);
virtual ULONG __stdcall Release(void);
// IShellExtInit
virtual HRESULT __stdcall Initialize(LPCITEMIDLIST pidlFolder,
LPDATAOBJECT lpdobj, HKEY hkeyProgID);
// IShellPropSheetExt
virtual HRESULT __stdcall AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam);
virtual HRESULT __stdcall ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE lpfnReplaceWith, LPARAM lParam);
protected:
UINT _cRef;
IDataObject* _pdtobj;
};
HRESULT CScrapExt::GetFileName(LPTSTR pszPath)
{
STGMEDIUM medium;
FORMATETC fmte = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
HRESULT hres = E_FAIL;
if (_pdtobj)
{
hres = _pdtobj->GetData(&fmte, &medium);
if (hres == S_OK)
{
if (!DragQueryFile((HDROP)medium.hGlobal,0,pszPath,MAX_PATH))
hres = E_FAIL;
ReleaseStgMedium(&medium);
}
}
return hres;
}
HRESULT CScrapExt::QueryInterface(REFIID riid, LPVOID * ppvObj)
{
if (IsEqualIID(riid, IID_IShellExtInit) || IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = (IShellExtInit*)this;
_cRef++;
return S_OK;
}
else if (IsEqualIID(riid, IID_IShellPropSheetExt))
{
*ppvObj = (IShellPropSheetExt *)this;
_cRef++;
return S_OK;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
ULONG CScrapExt::AddRef()
{
_cRef++;
return _cRef;
}
ULONG CScrapExt::Release()
{
_cRef--;
if (_cRef > 0)
return _cRef;
delete this;
return 0;
}
CScrapExt::CScrapExt() : _cRef(1), _pdtobj(NULL)
{
g_cRefThisDll++;
OleInitialize(NULL);
}
CScrapExt::~CScrapExt()
{
if (_pdtobj) {
_pdtobj->Release();
}
OleUninitialize();
g_cRefThisDll--;
}
HRESULT CScrapExt::Initialize(LPCITEMIDLIST pidlFolder,
LPDATAOBJECT pdtobj, HKEY hkeyProgID)
{
DebugMsg(DM_TRACE, TEXT("sc TR - CScrapExt::Initialize called"));
if (pdtobj) {
_pdtobj = pdtobj;
pdtobj->AddRef();
return S_OK;
}
return E_FAIL;
}
//===========================================================================
// CScrapPropSheetPage: Class definition
//
// Notes: Notice that this class has no destructor. It has no destructor
// because the lifetime of the object itself does not mean anything
// -- full contents will be copied by the property sheet code.
// Instead, it has a _Release function which is explicitly called
// when the property sheet handle is destroyed.
//===========================================================================
class CScrapPropSheetPage : public PROPSHEETPAGE // spsp
{
public:
CScrapPropSheetPage(CScrapExt* psext);
protected:
static INT_PTR CALLBACK _DlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
static UINT CALLBACK _CallBack(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp);
void _Release();
CScrapExt* _psext;
HWND _hdlg;
IOleClientSite* _pcli;
};
CScrapPropSheetPage::CScrapPropSheetPage(CScrapExt* psext)
: _psext(psext), _hdlg(NULL), _pcli(NULL)
{
dwSize = sizeof(CScrapPropSheetPage);
dwFlags = PSP_DEFAULT|PSP_USECALLBACK;
hInstance = HINST_THISDLL;
pszTemplate = MAKEINTRESOURCE(IDD_VIEW);
// hIcon = NULL; // unused (PSP_USEICON is not set)
// pszTitle = NULL; // unused (PSP_USETITLE is not set)
pfnDlgProc = _DlgProc;
// lParam = 0; // unused
pfnCallback = _CallBack;
// pcRefParent = NULL;
_psext->AddRef();
CShClientSite_RegisterClass();
}
void CScrapPropSheetPage::_Release()
{
if (_psext) {
_psext->Release();
}
if (_pcli) {
CShClientSite_Release(_pcli);
}
};
INT_PTR CALLBACK CScrapPropSheetPage::_DlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HWND hwndView;
CScrapPropSheetPage* pspsp;
switch(uMsg)
{
case WM_INITDIALOG:
SetWindowLongPtr(hdlg, DWLP_USER, lParam);
pspsp = (CScrapPropSheetPage *)lParam;
pspsp->_hdlg = hdlg;
hwndView = GetDlgItem(hdlg, IDI_SCRAPVIEW);
if (hwndView) {
SetWindowText(hwndView, TEXT("Not Implemented Yet"));
// SetWindowLongPtr(hwndView, sizeof(LPVOID), (LPARAM)pspsp);
TCHAR szPath[MAX_PATH];
if (SUCCEEDED(pspsp->_psext->GetFileName(szPath)))
{
pspsp->_pcli = CShClientSite_Create(hwndView, szPath);
}
}
break;
}
return FALSE;
}
UINT CALLBACK CScrapPropSheetPage::_CallBack(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
{
CScrapPropSheetPage * pspsp = (CScrapPropSheetPage*)ppsp;
switch(uMsg)
{
case PSPCB_RELEASE:
DebugMsg(DM_TRACE, TEXT("sc - TR: _ScrapPageCallBack is releasing _psext"));
pspsp->_Release();
break;
}
return TRUE;
}
HRESULT CScrapExt::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
{
DebugMsg(DM_TRACE, TEXT("sc TR - CScrapExt::AddPage called"));
HPROPSHEETPAGE hpage;
HRESULT hres = S_OK;
CScrapPropSheetPage spsp(this);
hpage = CreatePropertySheetPage(&spsp);
if (hpage)
{
BOOL bResult = lpfnAddPage(hpage, lParam);
if (!bResult)
{
DestroyPropertySheetPage(hpage);
hres = E_FAIL;
}
}
return hres;
}
HRESULT CScrapExt::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE lpfnReplaceWith, LPARAM lParam)
{
return S_FALSE;
}
HRESULT CScrapExt_CreateInstance(LPUNKNOWN * ppunk)
{
DebugMsg(DM_TRACE, TEXT("sc TR - CScrapExt_CreateInstance called"));
CScrapExt* pscd = new CScrapExt();
if (pscd) {
*ppunk = (LPDATAOBJECT)pscd;
return S_OK;
}
return E_OUTOFMEMORY;
}