217 lines
5.8 KiB
C++
217 lines
5.8 KiB
C++
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#include "prevwnd.h"
|
|
|
|
#include <shpriv.h>
|
|
|
|
DWORD g_dwThreadID = 0;
|
|
|
|
class CAutoplayForSlideShow : public IHWEventHandler,
|
|
public IDropTarget,
|
|
public NonATLObject
|
|
{
|
|
public:
|
|
CAutoplayForSlideShow() : _cRef(1) {}
|
|
|
|
// IUnknown
|
|
STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
|
|
STDMETHOD_(ULONG, AddRef)();
|
|
STDMETHOD_(ULONG, Release)();
|
|
|
|
// IHWEventHandler
|
|
STDMETHOD(Initialize)(LPCWSTR pszParams);
|
|
STDMETHOD(HandleEvent)(LPCWSTR pszDeviceID, LPCWSTR pszAltDeviceID,
|
|
LPCWSTR pszEventType);
|
|
STDMETHOD(HandleEventWithContent)(LPCWSTR pszDeviceID,
|
|
LPCWSTR pszAltDeviceID, LPCWSTR pszEventType,
|
|
LPCWSTR pszContentTypeHandler, IDataObject* pdtobj);
|
|
|
|
// IDropTarget ***
|
|
STDMETHODIMP DragEnter(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
|
STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
|
STDMETHODIMP DragLeave(void);
|
|
STDMETHODIMP Drop(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
|
|
|
private:
|
|
LONG _cRef;
|
|
};
|
|
|
|
|
|
STDMETHODIMP CAutoplayForSlideShow::QueryInterface(REFIID riid, void **ppv)
|
|
{
|
|
static const QITAB qit[] =
|
|
{
|
|
QITABENT(CAutoplayForSlideShow, IHWEventHandler),
|
|
QITABENT(CAutoplayForSlideShow, IDropTarget),
|
|
{ 0 },
|
|
};
|
|
return QISearch(this, qit, riid, ppv);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CAutoplayForSlideShow::AddRef()
|
|
{
|
|
return InterlockedIncrement(&_cRef);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CAutoplayForSlideShow::Release()
|
|
{
|
|
if (InterlockedDecrement(&_cRef))
|
|
return _cRef;
|
|
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
STDAPI CAutoplayForSlideShow_CreateInstance(IUnknown* pUnkOuter, IUnknown** ppunk, LPCOBJECTINFO poi)
|
|
{
|
|
CAutoplayForSlideShow* pass = new CAutoplayForSlideShow();
|
|
if (!pass)
|
|
{
|
|
*ppunk = NULL; // incase of failure
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
HRESULT hr = pass->QueryInterface(IID_PPV_ARG(IUnknown, ppunk));
|
|
pass->Release();
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CAutoplayForSlideShow::Initialize(LPCWSTR)
|
|
{
|
|
// We don't care about params a this point
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CAutoplayForSlideShow::HandleEvent(LPCWSTR pszDeviceID,
|
|
LPCWSTR pszAltDeviceID, LPCWSTR pszEventType)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
DWORD WINAPI SlideShowThread(void* pv)
|
|
{
|
|
IStream *pstm = (IStream *)pv;
|
|
IDataObject* pdtobj;
|
|
HRESULT hr = CoGetInterfaceAndReleaseStream(pstm, IID_PPV_ARG(IDataObject, &pdtobj));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CPreviewWnd cwndPreview;
|
|
hr = cwndPreview.Initialize(NULL, SLIDESHOW_MODE, TRUE);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// 4 is the walk depth, make sure we pick up pictures
|
|
if (cwndPreview.CreateSlideshowWindow(4))
|
|
{
|
|
hr = cwndPreview.StartSlideShow(pdtobj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
MSG msg;
|
|
|
|
while (GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
::PostThreadMessage(g_dwThreadID, WM_QUIT, 0, 0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
|
|
pdtobj->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT _StartSlideShowThread(IDataObject *pdo)
|
|
{
|
|
IStream *pstm;
|
|
HRESULT hr = CoMarshalInterThreadInterfaceInStream(IID_IDataObject, pdo, &pstm);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// maybe do threadref?
|
|
if (!SHCreateThread(SlideShowThread, pstm, CTF_COINIT, NULL))
|
|
{
|
|
pstm->Release();
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CAutoplayForSlideShow::HandleEventWithContent(
|
|
LPCWSTR pszDeviceID, LPCWSTR pszAltDeviceID, LPCWSTR pszEventType,
|
|
LPCWSTR pszContentTypeHandler, IDataObject* pdtobj)
|
|
{
|
|
return _StartSlideShowThread(pdtobj);
|
|
}
|
|
|
|
// IDropTarget::DragEnter
|
|
HRESULT CAutoplayForSlideShow::DragEnter(IDataObject *pdtobj, DWORD grfKeyState, POINTL ptl, DWORD *pdwEffect)
|
|
{
|
|
*pdwEffect = DROPEFFECT_COPY;
|
|
return S_OK;;
|
|
}
|
|
|
|
// IDropTarget::DragOver
|
|
HRESULT CAutoplayForSlideShow::DragOver(DWORD grfKeyState, POINTL ptl, DWORD *pdwEffect)
|
|
{
|
|
*pdwEffect = DROPEFFECT_COPY;
|
|
return S_OK;;
|
|
}
|
|
|
|
// IDropTarget::DragLeave
|
|
HRESULT CAutoplayForSlideShow::DragLeave(void)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
// IDropTarget::DragDrop
|
|
HRESULT CAutoplayForSlideShow::Drop(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
|
|
{
|
|
*pdwEffect = DROPEFFECT_COPY;
|
|
return _StartSlideShowThread(pdtobj);
|
|
}
|
|
|
|
void WINAPI ImageView_COMServer(HWND hwnd, HINSTANCE hAppInstance, LPTSTR pszCmdLine, int nCmdShow)
|
|
{
|
|
HRESULT hrOle = SHCoInitialize();
|
|
if (SUCCEEDED(hrOle))
|
|
{
|
|
g_dwThreadID = GetCurrentThreadId();
|
|
|
|
IUnknown* punkFact;
|
|
// the preview window will init GDI+
|
|
HRESULT hr = DllGetClassObject(CLSID_AutoplayForSlideShow, IID_PPV_ARG(IUnknown, &punkFact));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
DWORD dwROC;
|
|
hr = CoRegisterClassObject(CLSID_AutoplayForSlideShow, punkFact, CLSCTX_LOCAL_SERVER,
|
|
REGCLS_SINGLEUSE, &dwROC);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
MSG msg;
|
|
|
|
while (GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
CoRevokeClassObject(dwROC);
|
|
}
|
|
|
|
punkFact->Release();
|
|
}
|
|
|
|
SHCoUninitialize(hrOle);
|
|
}
|
|
}
|