Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
5.6 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #include "prevwnd.h"
  4. #include <shpriv.h>
  5. DWORD g_dwThreadID = 0;
  6. class CAutoplayForSlideShow : public IHWEventHandler,
  7. public IDropTarget,
  8. public NonATLObject
  9. {
  10. public:
  11. CAutoplayForSlideShow() : _cRef(1) {}
  12. // IUnknown
  13. STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
  14. STDMETHOD_(ULONG, AddRef)();
  15. STDMETHOD_(ULONG, Release)();
  16. // IHWEventHandler
  17. STDMETHOD(Initialize)(LPCWSTR pszParams);
  18. STDMETHOD(HandleEvent)(LPCWSTR pszDeviceID, LPCWSTR pszAltDeviceID,
  19. LPCWSTR pszEventType);
  20. STDMETHOD(HandleEventWithContent)(LPCWSTR pszDeviceID,
  21. LPCWSTR pszAltDeviceID, LPCWSTR pszEventType,
  22. LPCWSTR pszContentTypeHandler, IDataObject* pdtobj);
  23. // IDropTarget ***
  24. STDMETHODIMP DragEnter(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
  25. STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
  26. STDMETHODIMP DragLeave(void);
  27. STDMETHODIMP Drop(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
  28. private:
  29. LONG _cRef;
  30. };
  31. STDMETHODIMP CAutoplayForSlideShow::QueryInterface(REFIID riid, void **ppv)
  32. {
  33. static const QITAB qit[] =
  34. {
  35. QITABENT(CAutoplayForSlideShow, IHWEventHandler),
  36. QITABENT(CAutoplayForSlideShow, IDropTarget),
  37. { 0 },
  38. };
  39. return QISearch(this, qit, riid, ppv);
  40. }
  41. STDMETHODIMP_(ULONG) CAutoplayForSlideShow::AddRef()
  42. {
  43. return InterlockedIncrement(&_cRef);
  44. }
  45. STDMETHODIMP_(ULONG) CAutoplayForSlideShow::Release()
  46. {
  47. if (InterlockedDecrement(&_cRef))
  48. return _cRef;
  49. delete this;
  50. return 0;
  51. }
  52. STDAPI CAutoplayForSlideShow_CreateInstance(IUnknown* pUnkOuter, IUnknown** ppunk, LPCOBJECTINFO poi)
  53. {
  54. CAutoplayForSlideShow* pass = new CAutoplayForSlideShow();
  55. if (!pass)
  56. {
  57. *ppunk = NULL; // incase of failure
  58. return E_OUTOFMEMORY;
  59. }
  60. HRESULT hr = pass->QueryInterface(IID_PPV_ARG(IUnknown, ppunk));
  61. pass->Release();
  62. return hr;
  63. }
  64. STDMETHODIMP CAutoplayForSlideShow::Initialize(LPCWSTR)
  65. {
  66. // We don't care about params a this point
  67. return S_OK;
  68. }
  69. STDMETHODIMP CAutoplayForSlideShow::HandleEvent(LPCWSTR pszDeviceID,
  70. LPCWSTR pszAltDeviceID, LPCWSTR pszEventType)
  71. {
  72. return E_NOTIMPL;
  73. }
  74. DWORD WINAPI SlideShowThread(void* pv)
  75. {
  76. IStream *pstm = (IStream *)pv;
  77. IDataObject* pdtobj;
  78. HRESULT hr = CoGetInterfaceAndReleaseStream(pstm, IID_PPV_ARG(IDataObject, &pdtobj));
  79. if (SUCCEEDED(hr))
  80. {
  81. CPreviewWnd cwndPreview;
  82. hr = cwndPreview.Initialize(NULL, SLIDESHOW_MODE, TRUE);
  83. if (SUCCEEDED(hr))
  84. {
  85. // 4 is the walk depth, make sure we pick up pictures
  86. if (cwndPreview.CreateSlideshowWindow(4))
  87. {
  88. hr = cwndPreview.StartSlideShow(pdtobj);
  89. if (SUCCEEDED(hr))
  90. {
  91. MSG msg;
  92. while (GetMessage(&msg, NULL, 0, 0))
  93. {
  94. TranslateMessage(&msg);
  95. DispatchMessage(&msg);
  96. }
  97. ::PostThreadMessage(g_dwThreadID, WM_QUIT, 0, 0);
  98. }
  99. }
  100. else
  101. {
  102. hr = E_FAIL;
  103. }
  104. }
  105. pdtobj->Release();
  106. }
  107. return hr;
  108. }
  109. HRESULT _StartSlideShowThread(IDataObject *pdo)
  110. {
  111. IStream *pstm;
  112. HRESULT hr = CoMarshalInterThreadInterfaceInStream(IID_IDataObject, pdo, &pstm);
  113. if (SUCCEEDED(hr))
  114. {
  115. // maybe do threadref?
  116. if (!SHCreateThread(SlideShowThread, pstm, CTF_COINIT, NULL))
  117. {
  118. pstm->Release();
  119. hr = E_FAIL;
  120. }
  121. }
  122. return hr;
  123. }
  124. STDMETHODIMP CAutoplayForSlideShow::HandleEventWithContent(
  125. LPCWSTR pszDeviceID, LPCWSTR pszAltDeviceID, LPCWSTR pszEventType,
  126. LPCWSTR pszContentTypeHandler, IDataObject* pdtobj)
  127. {
  128. return _StartSlideShowThread(pdtobj);
  129. }
  130. // IDropTarget::DragEnter
  131. HRESULT CAutoplayForSlideShow::DragEnter(IDataObject *pdtobj, DWORD grfKeyState, POINTL ptl, DWORD *pdwEffect)
  132. {
  133. *pdwEffect = DROPEFFECT_COPY;
  134. return S_OK;;
  135. }
  136. // IDropTarget::DragOver
  137. HRESULT CAutoplayForSlideShow::DragOver(DWORD grfKeyState, POINTL ptl, DWORD *pdwEffect)
  138. {
  139. *pdwEffect = DROPEFFECT_COPY;
  140. return S_OK;;
  141. }
  142. // IDropTarget::DragLeave
  143. HRESULT CAutoplayForSlideShow::DragLeave(void)
  144. {
  145. return S_OK;
  146. }
  147. // IDropTarget::DragDrop
  148. HRESULT CAutoplayForSlideShow::Drop(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
  149. {
  150. *pdwEffect = DROPEFFECT_COPY;
  151. return _StartSlideShowThread(pdtobj);
  152. }
  153. void WINAPI ImageView_COMServer(HWND hwnd, HINSTANCE hAppInstance, LPTSTR pszCmdLine, int nCmdShow)
  154. {
  155. HRESULT hrOle = SHCoInitialize();
  156. if (SUCCEEDED(hrOle))
  157. {
  158. g_dwThreadID = GetCurrentThreadId();
  159. IUnknown* punkFact;
  160. // the preview window will init GDI+
  161. HRESULT hr = DllGetClassObject(CLSID_AutoplayForSlideShow, IID_PPV_ARG(IUnknown, &punkFact));
  162. if (SUCCEEDED(hr))
  163. {
  164. DWORD dwROC;
  165. hr = CoRegisterClassObject(CLSID_AutoplayForSlideShow, punkFact, CLSCTX_LOCAL_SERVER,
  166. REGCLS_SINGLEUSE, &dwROC);
  167. if (SUCCEEDED(hr))
  168. {
  169. MSG msg;
  170. while (GetMessage(&msg, NULL, 0, 0))
  171. {
  172. TranslateMessage(&msg);
  173. DispatchMessage(&msg);
  174. }
  175. CoRevokeClassObject(dwROC);
  176. }
  177. punkFact->Release();
  178. }
  179. SHCoUninitialize(hrOle);
  180. }
  181. }