Leaked source code of windows server 2003
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.

1235 lines
39 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // VidCtl.h : Declaration of the CVidCtl
  3. // Copyright (c) Microsoft Corporation 1999-2001.
  4. #pragma once
  5. #ifndef __VidCtl_H_
  6. #define __VidCtl_H_
  7. #include <msvidctl.h>
  8. #include "devices.h"
  9. #include "composition.h"
  10. #include "surface.h"
  11. #include "topwin.h"
  12. #include <objectwithsiteimplsec.h>
  13. #include "msvidcp.h"
  14. #include "perfcntr.h"
  15. typedef CComQIPtr<IMSVidGraphSegmentUserInput, &__uuidof(IMSVidGraphSegmentUserInput)> PQGraphSegmentUserInput;
  16. #define OCR_ARROW_DEFAULT_SYSCUR 100 // Default Windows OEM arrow system cursor
  17. // if source size isn't known default to 480P since its most common
  18. const int DEFAULT_SIZE_X = 640;
  19. const int DEFAULT_SIZE_Y = 480;
  20. #ifdef ASYNC_VR_NOTIFY
  21. #define SURFACESTATECHANGED() \ // post message to self
  22. if (m_CurrentSurface.IsDirty() { \
  23. ::PostMessage(self registered msg,???); \
  24. }
  25. #endif
  26. const OLE_COLOR NO_DEVICE_COLOR = 0x0; //black if no device set(Default Background Color)
  27. const OLE_COLOR DEFAULT_COLOR_KEY_COLOR = 0xff00ff; // magenta
  28. const int DEFAULT_TIMER_ID = 42;
  29. const int DEFAULT_WINDOW_SYNCH_TIMER_TIME = 1000; //ms
  30. #define WM_MEDIAEVENT (WM_USER+101)
  31. const CRect crect0(0, 0, 0, 0);
  32. const LPCRECT pcrect0 = &crect0;
  33. class CTopWin;
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CVidCtl
  36. class ATL_NO_VTABLE CVidCtl :
  37. public CComObjectRootEx<CComSingleThreadModel>,
  38. public CComControl<CVidCtl>,
  39. public CStockPropImpl<CVidCtl, IMSVidCtl, &IID_IMSVidCtl, &LIBID_MSVidCtlLib>,
  40. public IPersistStreamInitImpl<CVidCtl>,
  41. public IOleControlImpl<CVidCtl>,
  42. public IOleObjectImpl<CVidCtl>,
  43. public IOleInPlaceActiveObjectImpl<CVidCtl>,
  44. public IViewObjectExImpl<CVidCtl>,
  45. public IOleInPlaceObjectWindowlessImpl<CVidCtl>,
  46. public ISupportErrorInfo,
  47. public IConnectionPointContainerImpl<CVidCtl>,
  48. public IPersistStorageImpl<CVidCtl>,
  49. public IPersistPropertyBagImpl<CVidCtl>,
  50. public ISpecifyPropertyPagesImpl<CVidCtl>,
  51. public IQuickActivateImpl<CVidCtl>,
  52. public IDataObjectImpl<CVidCtl>,
  53. public IProvideClassInfo2Impl<&CLSID_MSVidCtl, &DIID__IMSVidCtlEvents, &LIBID_MSVidCtlLib>,
  54. public IPropertyNotifySinkCP<CVidCtl>,
  55. public IObjectSafetyImpl<CVidCtl, INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA>,
  56. public IMSVidGraphSegmentContainer,
  57. public CComCoClass<CVidCtl, &CLSID_MSVidCtl>,
  58. public CProxy_IMSVidCtlEvents< CVidCtl >,
  59. public IServiceProvider,
  60. public IObjectWithSiteImplSec<CVidCtl>,
  61. public IPointerInactiveImpl<CVidCtl>
  62. {
  63. private:
  64. // can't find this catid in any system header so we're defining our own
  65. struct __declspec(uuid("1D06B600-3AE3-11cf-87B9-00AA006C8166")) CATID_WindowlessObject;
  66. friend CTopWin;
  67. public:
  68. CVidCtl() :
  69. m_fInit(false),
  70. m_fGraphDirty(true),
  71. m_TimerID(DEFAULT_TIMER_ID),
  72. m_WindowSynchTime(DEFAULT_WINDOW_SYNCH_TIMER_TIME),
  73. m_fTimerOn(false),
  74. m_fNotificationSet(false),
  75. m_pComposites(VWSegmentList()),
  76. m_iCompose_Input_Video(-1),
  77. m_iCompose_Input_Audio(-1),
  78. m_clrBackColor(NO_DEVICE_COLOR),
  79. m_clrColorKey(DEFAULT_COLOR_KEY_COLOR),
  80. m_iDblClkState(0),
  81. m_usButtonState(0),
  82. m_usShiftState(0),
  83. m_bPendingUIActivation(false),
  84. m_fMaintainAspectRatio(VARIANT_FALSE),
  85. m_pTopWin(NULL),
  86. m_hCursor(NULL),
  87. m_dwROTCookie(0),
  88. m_videoSetNull(false),
  89. m_dslDisplaySize(dslDefaultSize),
  90. m_audioSetNull(false)
  91. // undone: default displaystyle to source size
  92. {
  93. m_State = STATE_UNBUILT;
  94. m_bAutoSize = false; // default to autosized
  95. m_bRecomposeOnResize = true;
  96. if (!VideoTypes.size()) {
  97. VideoTypes.push_back(MEDIATYPE_Video);
  98. VideoTypes.push_back(MEDIATYPE_AnalogVideo);
  99. }
  100. if (!AudioTypes.size()) {
  101. AudioTypes.push_back(MEDIATYPE_Audio);
  102. AudioTypes.push_back(MEDIATYPE_AnalogAudio);
  103. }
  104. #ifndef ENABLE_WINDOWLESS_SUPPORT
  105. m_bWindowOnly = true;
  106. #endif
  107. }
  108. virtual ~CVidCtl();
  109. // IMPORTANT: no matter how tempting don't add OLEMISC_IGNOREACTIVATEWHENVISIBLE
  110. // to the registration of this control. it breaks the case where we return
  111. // a running vidctl from the tv: pluggable protocol. we never get activated.
  112. REGISTER_FULL_CONTROL(IDS_PROJNAME,
  113. IDS_REG_VIDCTL_PROGID,
  114. IDS_REG_VIDCTL_DESC,
  115. LIBID_MSVidCtlLib,
  116. CLSID_MSVidCtl, 1, 0,
  117. OLEMISC_ACTIVATEWHENVISIBLE |
  118. OLEMISC_RECOMPOSEONRESIZE | OLEMISC_CANTLINKINSIDE |
  119. OLEMISC_INSIDEOUT);
  120. DECLARE_PROTECT_FINAL_CONSTRUCT()
  121. BEGIN_CATEGORY_MAP(CVidCtl)
  122. IMPLEMENTED_CATEGORY(CATID_Control)
  123. IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
  124. IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)
  125. IMPLEMENTED_CATEGORY(CATID_Programmable)
  126. IMPLEMENTED_CATEGORY(CATID_PersistsToPropertyBag)
  127. IMPLEMENTED_CATEGORY(CATID_PersistsToStorage)
  128. #ifdef ENABLE_WINDOWLESS_SUPPORT
  129. IMPLEMENTED_CATEGORY(__uuidof(CATID_WindowlessObject))
  130. #endif
  131. END_CATEGORY_MAP()
  132. BEGIN_COM_MAP(CVidCtl)
  133. COM_INTERFACE_ENTRY(IMSVidCtl)
  134. COM_INTERFACE_ENTRY(IDispatch)
  135. COM_INTERFACE_ENTRY(IViewObjectEx)
  136. COM_INTERFACE_ENTRY(IViewObject2)
  137. COM_INTERFACE_ENTRY(IViewObject)
  138. #ifdef ENABLE_WINDOWLESS_SUPPORT
  139. COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
  140. COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
  141. #endif
  142. COM_INTERFACE_ENTRY(IOleInPlaceObject)
  143. COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
  144. COM_INTERFACE_ENTRY(IOleControl)
  145. COM_INTERFACE_ENTRY(IOleObject)
  146. COM_INTERFACE_ENTRY(IPersistStreamInit)
  147. COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
  148. COM_INTERFACE_ENTRY(ISupportErrorInfo)
  149. COM_INTERFACE_ENTRY(IConnectionPointContainer)
  150. COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
  151. COM_INTERFACE_ENTRY(IQuickActivate)
  152. COM_INTERFACE_ENTRY(IPersistStorage)
  153. COM_INTERFACE_ENTRY(IPersistPropertyBag)
  154. COM_INTERFACE_ENTRY(IDataObject)
  155. COM_INTERFACE_ENTRY(IProvideClassInfo)
  156. COM_INTERFACE_ENTRY(IProvideClassInfo2)
  157. COM_INTERFACE_ENTRY(IObjectSafety)
  158. COM_INTERFACE_ENTRY(IMSVidGraphSegmentContainer)
  159. COM_INTERFACE_ENTRY(IPointerInactive)
  160. COM_INTERFACE_ENTRY(IServiceProvider)
  161. COM_INTERFACE_ENTRY(IObjectWithSite)
  162. END_COM_MAP()
  163. BEGIN_PROP_MAP(CVidCtl)
  164. PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
  165. PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
  166. PROP_ENTRY("AutoSize", DISPID_AUTOSIZE, CLSID_NULL)
  167. PROP_ENTRY("Enabled", DISPID_ENABLED, CLSID_NULL)
  168. PROP_ENTRY("TabStop", DISPID_TABSTOP, CLSID_NULL)
  169. PROP_ENTRY("BackColor", DISPID_BACKCOLOR, CLSID_NULL)
  170. END_PROP_MAP()
  171. BEGIN_CONNECTION_POINT_MAP(CVidCtl)
  172. CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink)
  173. CONNECTION_POINT_ENTRY(DIID__IMSVidCtlEvents)
  174. END_CONNECTION_POINT_MAP()
  175. void ComputeAspectRatioAdjustedRects(const CRect& rctSrc, const CRect& rctOuterDst, CRect& rctInnerDst, CRect& rctTLBorder, CRect& rctlBRBorder);
  176. HRESULT OnDrawAdvanced(ATL_DRAWINFO& di);
  177. static MediaMajorTypeList VideoTypes;
  178. static MediaMajorTypeList AudioTypes;
  179. SurfaceState m_CurrentSurface;
  180. CTopWin* m_pTopWin;
  181. UINT m_iDblClkState;
  182. bool m_bPendingUIActivation;
  183. USHORT m_usButtonState; // stock oa event bit positions
  184. USHORT m_usShiftState;
  185. HCURSOR m_hCursor; // mouse cursor to use over our window when overlay active to prevent colorkey bleed through
  186. DWORD m_dwROTCookie;
  187. void OnButtonDown(USHORT nButton, UINT nFlags, CPoint point);
  188. void OnButtonUp(USHORT nButton, UINT nFlags, CPoint point);
  189. void OnButtonDblClk(USHORT nButton, UINT nFlags, CPoint point);
  190. #define MSG_FUNC(func) LRESULT func(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  191. MSG_FUNC(OnShowWindow);
  192. MSG_FUNC(OnMoveWindow);
  193. MSG_FUNC(OnSizeWindow);
  194. inline MSG_FUNC(OnSurfaceStateChanged) {
  195. RefreshVRSurfaceState();
  196. return 0;
  197. }
  198. MSG_FUNC(OnWindowPosChanged);
  199. MSG_FUNC(OnTerminate);
  200. MSG_FUNC(OnTimer);
  201. MSG_FUNC(OnMediaEvent);
  202. MSG_FUNC(OnDisplayChange);
  203. MSG_FUNC(OnPower);
  204. MSG_FUNC(OnPNP);
  205. MSG_FUNC(OnSetCursor);
  206. MSG_FUNC(OnChar);
  207. MSG_FUNC(OnKeyDown);
  208. MSG_FUNC(OnKeyUp);
  209. #if 0 // undone:
  210. MSG_FUNC(OnSysKeyDown);
  211. MSG_FUNC(OnSysKeyUp);
  212. #endif
  213. MSG_FUNC(OnCancelMode);
  214. MSG_FUNC(OnMouseActivate);
  215. MSG_FUNC(OnMouseMove);
  216. MSG_FUNC(OnLButtonDown);
  217. MSG_FUNC(OnLButtonUp);
  218. MSG_FUNC(OnLButtonDblClk);
  219. MSG_FUNC(OnMButtonDown);
  220. MSG_FUNC(OnMButtonUp);
  221. MSG_FUNC(OnMButtonDblClk);
  222. MSG_FUNC(OnRButtonDown);
  223. MSG_FUNC(OnRButtonUp);
  224. MSG_FUNC(OnRButtonDblClk);
  225. MSG_FUNC(OnXButtonDown);
  226. MSG_FUNC(OnXButtonUp);
  227. MSG_FUNC(OnXButtonDblClk);
  228. #if 0 // undone:
  229. MSG_FUNC(OnMouseWheel);
  230. #endif
  231. // undone: make sure we call onterminate for windowless close functions
  232. // Handler prototypes:
  233. // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  234. // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  235. // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
  236. BEGIN_MSG_MAP(CVidCtl)
  237. MESSAGE_HANDLER(WM_SHOWWINDOW, OnShowWindow)
  238. MESSAGE_HANDLER(WM_MOVE, OnMoveWindow)
  239. MESSAGE_HANDLER(WM_SIZE, OnSizeWindow)
  240. MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnWindowPosChanged)
  241. MESSAGE_HANDLER(WM_CLOSE, OnTerminate)
  242. MESSAGE_HANDLER(WM_NCDESTROY, OnTerminate)
  243. MESSAGE_HANDLER(WM_DESTROY, OnTerminate)
  244. MESSAGE_HANDLER(WM_TIMER, OnTimer)
  245. MESSAGE_HANDLER(WM_MEDIAEVENT, OnMediaEvent)
  246. MESSAGE_HANDLER(WM_DISPLAYCHANGE, OnDisplayChange)
  247. MESSAGE_HANDLER(WM_POWERBROADCAST, OnPower)
  248. MESSAGE_HANDLER(WM_DEVICECHANGE, OnPNP)
  249. MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
  250. // undone: decide if we also need to do something with the following:
  251. // WM_ENDSESSION
  252. // WM_QUERYENDSESSION
  253. // WM_QUERYPOWERBROADCAST
  254. // WM_DEVMODECHANGE
  255. #if 0
  256. MESSAGE_HANDLER(WM_NCHITTEST, )
  257. MESSAGE_HANDLER(WM_NCLBUTTONDOWN, )
  258. #endif
  259. MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
  260. MESSAGE_HANDLER(WM_KEYUP, OnKeyUp)
  261. MESSAGE_HANDLER(WM_CHAR, OnChar)
  262. #if 0 // undone:
  263. MESSAGE_HANDLER(WM_SYSKEYDOWN, OnSysKeyDown)
  264. MESSAGE_HANDLER(WM_SYSKEYUP, OnSysKeyUp)
  265. #endif
  266. // Stock Events
  267. MESSAGE_HANDLER(WM_CANCELMODE, OnCancelMode)
  268. MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
  269. MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
  270. MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
  271. MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
  272. MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk)
  273. MESSAGE_HANDLER(WM_MBUTTONDOWN, OnMButtonDown)
  274. MESSAGE_HANDLER(WM_MBUTTONUP, OnMButtonUp)
  275. MESSAGE_HANDLER(WM_MBUTTONDBLCLK, OnMButtonDblClk)
  276. MESSAGE_HANDLER(WM_RBUTTONDOWN, OnRButtonDown)
  277. MESSAGE_HANDLER(WM_RBUTTONUP, OnRButtonUp)
  278. MESSAGE_HANDLER(WM_RBUTTONDBLCLK, OnRButtonDblClk)
  279. MESSAGE_HANDLER(WM_XBUTTONDOWN, OnXButtonDown)
  280. MESSAGE_HANDLER(WM_XBUTTONUP, OnXButtonUp)
  281. MESSAGE_HANDLER(WM_XBUTTONDBLCLK, OnXButtonDblClk)
  282. #if 0 // undone:
  283. MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
  284. #endif
  285. // also xbutton and wheel
  286. // async: update MESSAGE_HANDLER(Register message, OnSurfaceStateChanged)
  287. CHAIN_MSG_MAP(CComControl<CVidCtl>)
  288. DEFAULT_REFLECTION_HANDLER()
  289. END_MSG_MAP()
  290. int m_TimerID;
  291. bool m_fTimerOn;
  292. int m_WindowSynchTime;
  293. bool m_fNotificationSet;
  294. USHORT GetShiftState() {
  295. BOOL bShift = (GetKeyState(VK_SHIFT) < 0);
  296. BOOL bCtrl = (GetKeyState(VK_CONTROL) < 0);
  297. BOOL bAlt = (GetKeyState(VK_MENU) < 0);
  298. return (short)(bShift + (bCtrl << 1) + (bAlt << 2));
  299. }
  300. // ISupportsErrorInfo
  301. STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
  302. // IViewObjectEx
  303. DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)
  304. // Helpers
  305. public:
  306. // IMSVidCtl
  307. public:
  308. MSVidCtlStateList m_State;
  309. DSGraph m_pGraph;
  310. PQCreateDevEnum m_pSystemEnum;
  311. PQFilterMapper m_pFilterMapper;
  312. // available collections
  313. VWInputDevices m_pInputs;
  314. PQGraphSegmentUserInput m_pInputNotify;
  315. VWOutputDevices m_pOutputs;
  316. VWFeatures m_pFeatures;
  317. VWVideoRendererDevices m_pVRs; // video renderers
  318. VWAudioRendererDevices m_pARs; // audio renderers
  319. // chosen devices&features
  320. PQInputDevice m_pInput;
  321. VWOutputDevices m_pOutputsInUse;
  322. PQVRGraphSegment m_pVideoRenderer;
  323. PQAudioRenderer m_pAudioRenderer;
  324. VWFeatures m_pFeaturesInUse;
  325. // Composition Segments
  326. VWSegmentList m_pComposites;
  327. int m_iCompose_Input_Video;
  328. int m_iCompose_Input_Audio;
  329. // undone: vector of these for features and outputs
  330. // REV2: ultimately we probably want streams to be a core dshow facility
  331. // but for now they're a list of xbar input/output point pairs just like in
  332. // win98 gold.
  333. VWStreamList m_Streams;
  334. // stock properties
  335. OLE_COLOR m_clrBackColor;
  336. BOOL m_bEnabled;
  337. BOOL m_bTabStop;
  338. BOOL m_bValid;
  339. STDMETHOD(get_State)(MSVidCtlStateList *lState);
  340. OLE_COLOR m_clrColorKey;
  341. DisplaySizeList m_dslDisplaySize;
  342. VARIANT_BOOL m_fMaintainAspectRatio;
  343. GUID2 m_InputsCatGuid;
  344. GUID2 m_CurViewCatGuid;
  345. CComVariant m_CurView;
  346. // Event handler
  347. HRESULT OnPreEventNotify(LONG lEvent, LONG_PTR LParam1, LONG_PTR LParam2);
  348. HRESULT OnPostEventNotify(LONG lEvent, LONG_PTR LParam1, LONG_PTR LParam2);
  349. protected:
  350. bool m_fInit;
  351. bool m_fGraphDirty;
  352. void Init(void);
  353. bool m_audioSetNull;
  354. bool m_videoSetNull;
  355. CComPtr<IUnknown> punkCert;
  356. HRESULT GetInputs(const GUID2& CategoryGuid, VWInputDevices& pInputs);
  357. HRESULT GetOutputs(const GUID2& CategoryGuid);
  358. HRESULT GetVideoRenderers(void);
  359. HRESULT GetAudioRenderers(void);
  360. HRESULT GetFeatures(void);
  361. HRESULT SelectView(VARIANT *pv, bool fNext);
  362. HRESULT SelectViewFromSegmentList(CComVariant &v, VWInputDevices& list, PQInputDevice& m_pInput);
  363. HRESULT LoadDefaultVR(void);
  364. HRESULT LoadDefaultAR(void);
  365. HRESULT Compose(VWGraphSegment &Up, VWGraphSegment &Down, int &NewIdx);
  366. HRESULT BuildGraph(void);
  367. HRESULT RunGraph(void);
  368. HRESULT DecomposeSegment(VWGraphSegment& pSegment);
  369. HRESULT DecomposeAll();
  370. HRESULT RouteStreams(void);
  371. void SetMediaEventNotification();
  372. protected:
  373. HRESULT SetControlCapture(bool bCapture) {
  374. if (m_bInPlaceActive && (m_bUIActive || m_bPendingUIActivation)) {
  375. if (!m_bWndLess) {
  376. if (bCapture) {
  377. if (m_hWnd) {
  378. HWND h;
  379. h = ::SetCapture(m_hWnd);
  380. return (h = m_hWnd) ? NOERROR : E_FAIL;
  381. }
  382. } else {
  383. BOOL rc = ::ReleaseCapture();
  384. if (!rc) {
  385. return HRESULT_FROM_WIN32(::GetLastError());
  386. }
  387. }
  388. } else {
  389. return m_spInPlaceSite->SetFocus(bCapture);
  390. }
  391. }
  392. return NOERROR;
  393. }
  394. bool CheckSurfaceStateChanged(CScalingRect& pos) {
  395. TRACELSM(TRACE_PAINT, (dbgDump << "CVidctrl::CheckSurfaceStateChanged() pos = " << pos), "");
  396. m_CurrentSurface = pos;
  397. ValidateSurfaceState();
  398. return RefreshVRSurfaceState();
  399. }
  400. void CheckTopWin() {
  401. if (m_pTopWin) {
  402. return;
  403. }
  404. m_pTopWin = new CTopWin(this);
  405. m_pTopWin->Init();
  406. }
  407. UINT SetTimer() {
  408. if (!m_fTimerOn) {
  409. CheckTopWin();
  410. m_fTimerOn = true;
  411. return m_pTopWin->SetTimer(m_TimerID, m_WindowSynchTime);
  412. }
  413. return 0;
  414. }
  415. void KillTimer() {
  416. if (m_pTopWin) {
  417. if (m_fTimerOn) {
  418. m_pTopWin->KillTimer(42);
  419. }
  420. } else if (m_fTimerOn) {
  421. CComControl<CVidCtl>::KillTimer(42);
  422. }
  423. }
  424. bool RefreshVRSurfaceState();
  425. void SetExtents() {
  426. TRACELM(TRACE_PAINT, "CVidCtl::SetExtents()");
  427. CSize prevNat(m_sizeNatural), prevSize(m_sizeExtent);
  428. CSize newsize(0, 0);
  429. if (m_pVideoRenderer) {
  430. CRect r;
  431. HRESULT hr = m_pVideoRenderer->get_Source(r);
  432. if (FAILED(hr)) {
  433. GetSourceSize(m_sizeNatural);
  434. } else {
  435. m_sizeNatural.cx = r.Width();
  436. m_sizeNatural.cy = r.Height();
  437. }
  438. }
  439. if (m_bAutoSize) {
  440. ComputeDisplaySize();
  441. if (prevNat != m_sizeNatural ||
  442. prevSize != m_sizeExtent) {
  443. FireOnSizeChange();
  444. }
  445. }
  446. }
  447. void FireOnSizeChange() {
  448. TRACELM(TRACE_PAINT, "CVidCtl::FireOnSizeChange()");
  449. if (m_CurrentSurface != m_rcPos) {
  450. if (m_pTopWin) {
  451. TRACELM(TRACE_PAINT, "CVidCtl::FireOnSizeChange() firing");
  452. m_pTopWin->PostMessage(WM_USER + CTopWin::WMUSER_SITE_RECT_WRONG, 0, 0);
  453. }
  454. }
  455. }
  456. void OnSizeChange() {
  457. // if we've already negotiated a site then
  458. // notify our container that our rect size has changed
  459. // this can be because the source changed(such as broadcast show boundary)
  460. CScalingRect r(m_rcPos);
  461. CSize s;
  462. AtlHiMetricToPixel(&m_sizeExtent, &s);
  463. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidctrl::OnSizeChange() new sz = " << s), "" );
  464. r.top = m_rcPos.top;
  465. r.left = m_rcPos.left;
  466. r.right = m_rcPos.left + s.cx;
  467. r.bottom = m_rcPos.top + s.cy;
  468. if (m_spInPlaceSite && r != m_rcPos && m_bAutoSize) {
  469. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidctrl::OnSizeChange() changing to " << r << " from " << m_rcPos), "" );
  470. HRESULT hr = m_spInPlaceSite->OnPosRectChange(r);
  471. if (FAILED(hr)) {
  472. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidctrl::OnSizeChange() site notify failed. hr = " << hexdump(hr)), "" );
  473. return;
  474. }
  475. }
  476. return;
  477. }
  478. AspectRatio SourceAspect() {
  479. AspectRatio ar(4, 3);
  480. if (m_pGraph) {
  481. if (m_pVideoRenderer) {
  482. CSize p, a;
  483. HRESULT hr = m_pVideoRenderer->get_NativeSize(&p, &a);
  484. if (SUCCEEDED(hr)) {
  485. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidctrl::SourceAspect() ar = " << a), "");
  486. if (a.cx && a.cy) {
  487. ar = a;
  488. }
  489. }
  490. }
  491. }
  492. return ar; // default
  493. }
  494. void GetSourceSize(SIZE& s) {
  495. CSize a;
  496. if (m_pVideoRenderer) {
  497. HRESULT hr = m_pVideoRenderer->get_NativeSize(&s, &a);
  498. if (FAILED(hr) || !s.cx || !s.cy) {
  499. s.cx = DEFAULT_SIZE_X;
  500. s.cy = DEFAULT_SIZE_Y;
  501. }
  502. } else {
  503. s.cx = DEFAULT_SIZE_X;
  504. s.cy = DEFAULT_SIZE_Y;
  505. }
  506. TRACELSM(TRACE_PAINT, (dbgDump << "CVidCtl::GetSourceSize() sz = " << s), "");
  507. }
  508. bool ValidateSurfaceState() {
  509. #if 0
  510. TRACELSM(TRACE_PAINT, (dbgDump << "CVidCtl::ValidateSurfaceState() m_bAutoSize = " << m_bAutoSize << " fMaintain " << m_fMaintainAspectRatio << " cursurf " << m_CurrentSurface << " objrct = " << m_rcPos), "");
  511. if (m_fMaintainAspectRatio) {
  512. AspectRatio src;
  513. src = SourceAspect();
  514. AspectRatio surf;
  515. surf = m_CurrentSurface.Aspect();
  516. if (!!surf && !!src && surf != src) {
  517. TRACELM(TRACE_PAINT, "CVidctrl::ValidateSurfaceState() aspect wrong");
  518. if (m_CurrentSurface.Round(src)) {
  519. ASSERT(src == m_CurrentSurface.Aspect());
  520. } else {
  521. // aspect ratios don't match and Round didn't fix it.
  522. _ASSERT(false);
  523. }
  524. }
  525. }
  526. #endif
  527. return true;
  528. }
  529. void ComputeDisplaySize() {
  530. CSize s;
  531. TRACELSM(TRACE_PAINT, (dbgDump << "CVidCtl::ComputeDisplaySize() dsl = " << m_dslDisplaySize), "");
  532. switch (m_dslDisplaySize) {
  533. case dslSourceSize:
  534. GetSourceSize(s);
  535. break;
  536. case dslHalfSourceSize:
  537. GetSourceSize(s);
  538. s.cx >>= 1;
  539. s.cy >>= 1;
  540. break;
  541. case dslDoubleSourceSize:
  542. GetSourceSize(s);
  543. s.cx <<= 1;
  544. s.cy <<= 1;
  545. break;
  546. case dslFullScreen: {
  547. CRect rcdesk;
  548. ::GetWindowRect(::GetDesktopWindow(), &rcdesk);
  549. s.cx = rcdesk.Width();
  550. s.cy = rcdesk.Height();
  551. break;
  552. }
  553. case dslHalfScreen: {
  554. CScalingRect rcdesk;
  555. rcdesk.Owner(::GetDesktopWindow());
  556. ::GetWindowRect(rcdesk.Owner(), &rcdesk);
  557. rcdesk.Owner(m_CurrentSurface.Owner());
  558. s.cx = rcdesk.Width() * 3 / 4;
  559. s.cy = rcdesk.Height() * 3 / 4;
  560. break;
  561. }
  562. case dslQuarterScreen: {
  563. CScalingRect rcdesk;
  564. rcdesk.Owner(::GetDesktopWindow());
  565. ::GetWindowRect(rcdesk.Owner(), &rcdesk);
  566. rcdesk.Owner(m_CurrentSurface.Owner());
  567. s.cx = rcdesk.Width() / 2;
  568. s.cy = rcdesk.Height() / 2;
  569. break;
  570. }
  571. case dslSixteenthScreen: {
  572. CScalingRect rcdesk;
  573. rcdesk.Owner(::GetDesktopWindow());
  574. ::GetWindowRect(rcdesk.Owner(), &rcdesk);
  575. rcdesk.Owner(m_CurrentSurface.Owner());
  576. s.cx = rcdesk.Width() / 4;
  577. s.cy = rcdesk.Height() / 4;
  578. break;
  579. }}
  580. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidctrl::ComputeDisplaySize() sz = " << s), "");
  581. AtlPixelToHiMetric(&s, &m_sizeExtent);
  582. OnSizeChange();
  583. }
  584. #if 0
  585. CString GetMonitorName(HMONITOR hm);
  586. bool WindowHasHWOverlay(HWND hWnd);
  587. bool MonitorHasHWOverlay(HMONITOR hm);
  588. HRESULT GetCapsForMonitor(HMONITOR hm, LPDDCAPS pDDCaps);
  589. HRESULT GetDDrawNameForMonitor(HMONITOR hm, VMRGUID& guid);
  590. #endif
  591. public:
  592. STDMETHOD(SetObjectRects)(LPCRECT prcPos,LPCRECT prcClip) {
  593. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidCtl::SetObjectRects() pos = " << *prcPos << " clip = " << *prcClip), "");
  594. if (prcPos == NULL || prcClip == NULL)
  595. return E_POINTER;
  596. bool bRectChange = !::EqualRect(prcPos, &m_rcPos);
  597. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidCtl::SetObjectRects() bRectChange = " << bRectChange), "");
  598. HRESULT hr = IOleInPlaceObjectWindowlessImpl<CVidCtl>::SetObjectRects(prcPos, prcClip);
  599. if (FAILED(hr)) {
  600. return hr;
  601. }
  602. if (bRectChange) {
  603. FireViewChange();
  604. }
  605. return NOERROR;
  606. }
  607. HRESULT OnPostVerbShow() {
  608. SetTimer();
  609. m_CurrentSurface.Visible(true);
  610. RefreshVRSurfaceState();
  611. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidctrl::OnPostVerbShow() visible = " << m_CurrentSurface.IsVisible() << " rect = " << CRect(m_CurrentSurface)), "" );
  612. return NOERROR;
  613. }
  614. HRESULT OnPostVerbUIActivate() {
  615. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidctrl::OnPostVerbUIActivate() visible = " << m_CurrentSurface.IsVisible()), "" );
  616. return OnPostVerbInPlaceActivate();
  617. }
  618. HRESULT OnPostVerbInPlaceActivate() {
  619. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidctrl::OnPostVerbInPlaceActivate() visible = " << m_CurrentSurface.IsVisible()), "" );
  620. HRESULT hr = OnPostVerbShow();
  621. if (FAILED(hr)) {
  622. return hr;
  623. }
  624. if (m_bWndLess) {
  625. m_CurrentSurface.Site(PQSiteWindowless(m_spInPlaceSite));
  626. } else {
  627. m_CurrentSurface.Owner(m_hWnd);
  628. }
  629. RefreshVRSurfaceState();
  630. return NOERROR;
  631. }
  632. HRESULT OnPreVerbHide() {
  633. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidctrl::OnPreVerbHide() visible = " << m_CurrentSurface.IsVisible()), "" );
  634. HRESULT hr = OnInPlaceDeactivate();
  635. m_CurrentSurface.Visible(false);
  636. KillTimer();
  637. RefreshVRSurfaceState();
  638. return hr;
  639. }
  640. HRESULT OnInPlaceDeactivate() {
  641. TRACELM(TRACE_DETAIL, "CVidctrl::OnInPlaceDeactivate()");
  642. HRESULT hr = OnUIDeactivate();
  643. if((long)m_State > 0){
  644. Stop();
  645. }
  646. m_CurrentSurface.Owner(INVALID_HWND);
  647. RefreshVRSurfaceState();
  648. return hr;
  649. }
  650. HRESULT OnUIDeactivate() {
  651. SetControlCapture(false);
  652. m_bPendingUIActivation = false;
  653. return NOERROR;
  654. }
  655. HRESULT InPlaceActivate(LONG iVerb, const RECT* prcPosRect = NULL) {
  656. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidctrl::InPlaceActivate() iverb = " << iVerb), "");
  657. HRESULT hr = CComControlBase::InPlaceActivate(iVerb, prcPosRect);
  658. if (SUCCEEDED(hr)) {
  659. if (DoesVerbUIActivate(iVerb)) {
  660. hr = OnPostVerbUIActivate();
  661. } else {
  662. hr = OnPostVerbInPlaceActivate();
  663. if (FAILED(hr)) {
  664. return hr;
  665. }
  666. }
  667. }
  668. return hr;
  669. }
  670. #if 0
  671. STDMETHOD(DoVerb)(LONG iVerb, LPMSG pMsg, IOleClientSite *pActiveSite, LONG lIndex, HWND hParent, const RECT* prcPosRect) {
  672. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidctrl::DoVerb() iverb = " << iVerb), "");
  673. HRESULT hr = IOleObjectImpl<CVidCtl>::DoVerb(iVerb, pMsg, pActiveSite, lIndex, hParent, prcPosRect);
  674. return hr;
  675. }
  676. #endif
  677. void DoSetCursor() {
  678. if (!m_hCursor) {
  679. // Create a default arrow cursor
  680. m_hCursor = (HCURSOR) LoadImage((HINSTANCE) NULL,
  681. MAKEINTRESOURCE(OCR_ARROW_DEFAULT_SYSCUR),
  682. IMAGE_CURSOR,0,0,0);
  683. }
  684. ::SetCursor(m_hCursor);
  685. }
  686. LRESULT CheckMouseCursor(BOOL& bHandled) {
  687. try{
  688. // we can be running but not inplaceactive yet if we got started from a pluggable protocol
  689. if (m_pGraph && m_pGraph.IsPlaying() && m_pVideoRenderer && m_bInPlaceActive) {
  690. CComQIPtr<IMSVidVideoRenderer2> sp_VidVid(m_pVideoRenderer);
  691. if(sp_VidVid){
  692. VARIANT_BOOL effects;
  693. HRESULT hr = sp_VidVid->get_SuppressEffects(&effects);
  694. if(SUCCEEDED(hr) && effects == VARIANT_TRUE){
  695. DoSetCursor(); // note: we do this regardless of overlay status
  696. }
  697. }
  698. return 0;
  699. }
  700. bHandled = FALSE;
  701. return 0;
  702. }
  703. catch(...){
  704. return E_UNEXPECTED;
  705. }
  706. }
  707. #if 0
  708. // IOleObject::SetExtent
  709. STDMETHOD(SetExtent) {
  710. }
  711. #endif
  712. STDMETHOD(InPlaceDeactivate)(void) {
  713. try {
  714. OnInPlaceDeactivate();
  715. return IOleInPlaceObjectWindowlessImpl<CVidCtl>::InPlaceDeactivate();
  716. } catch(...) {
  717. return E_UNEXPECTED;
  718. }
  719. }
  720. STDMETHOD(UIDeactivate)(void) {
  721. try {
  722. OnUIDeactivate();
  723. return IOleInPlaceObjectWindowlessImpl<CVidCtl>::UIDeactivate();
  724. } catch(...) {
  725. return E_UNEXPECTED;
  726. }
  727. }
  728. STDMETHOD(GetActivationPolicy)(DWORD* pdwPolicy) {
  729. if (!pdwPolicy) {
  730. return E_POINTER;
  731. }
  732. try {
  733. *pdwPolicy = 0;
  734. return NOERROR;
  735. } catch(...) {
  736. return E_UNEXPECTED;
  737. }
  738. }
  739. // undone: do we need to process inactivemousemove?
  740. STDMETHOD(OnInactiveSetCursor)(LPCRECT pRectBounds, long x, long y, DWORD dwMouseMsg, BOOL fSetAlways)
  741. {
  742. try {
  743. if (fSetAlways) {
  744. DoSetCursor();
  745. } else {
  746. int temp;
  747. CheckMouseCursor(temp);
  748. }
  749. return NOERROR;
  750. } catch(...) {
  751. return E_UNEXPECTED;
  752. }
  753. }
  754. // IMSVidCtl
  755. STDMETHOD(put_ColorKey)(OLE_COLOR clr) {
  756. m_clrColorKey = clr;
  757. if (m_pVideoRenderer) {
  758. return m_pVideoRenderer->put_ColorKey(clr);
  759. }
  760. return NOERROR;
  761. }
  762. STDMETHOD(get_ColorKey)(OLE_COLOR* pclr) {
  763. try {
  764. if (!pclr) {
  765. return E_POINTER;
  766. }
  767. *pclr = m_clrColorKey;
  768. return NOERROR;
  769. } catch(...) {
  770. return E_POINTER;
  771. }
  772. }
  773. STDMETHOD(put_DisplaySize)(DisplaySizeList dslNewSize) {
  774. if (dslNewSize != m_dslDisplaySize) {
  775. m_dslDisplaySize = dslNewSize;
  776. if (m_bAutoSize) {
  777. ComputeDisplaySize();
  778. }
  779. }
  780. return NOERROR;
  781. }
  782. STDMETHOD(get_DisplaySize)(DisplaySizeList* pdsl) {
  783. try {
  784. if (!pdsl) {
  785. return E_POINTER;
  786. }
  787. *pdsl = m_dslDisplaySize;
  788. return NOERROR;
  789. } catch(...) {
  790. return E_POINTER;
  791. }
  792. }
  793. STDMETHOD(put_MaintainAspectRatio)(VARIANT_BOOL fNewSize) {
  794. m_fMaintainAspectRatio = fNewSize;
  795. return NOERROR;
  796. }
  797. STDMETHOD(get_MaintainAspectRatio)(VARIANT_BOOL* pf) {
  798. try {
  799. if (!pf) {
  800. return E_POINTER;
  801. }
  802. *pf = m_fMaintainAspectRatio;
  803. return NOERROR;
  804. } catch(...) {
  805. return E_POINTER;
  806. }
  807. }
  808. STDMETHOD(Refresh)();
  809. STDMETHOD(get_InputsAvailable)(BSTR CategoryGuid, IMSVidInputDevices * * pVal);
  810. STDMETHOD(get_OutputsAvailable)(BSTR CategoryGuid, IMSVidOutputDevices * * pVal);
  811. STDMETHOD(get__InputsAvailable)(LPCGUID CategoryGuid, IMSVidInputDevices * * pVal);
  812. STDMETHOD(get__OutputsAvailable)(LPCGUID CategoryGuid, IMSVidOutputDevices * * pVal);
  813. STDMETHOD(get_VideoRenderersAvailable)(IMSVidVideoRendererDevices * * pVal);
  814. STDMETHOD(get_AudioRenderersAvailable)(IMSVidAudioRendererDevices * * pVal);
  815. STDMETHOD(get_FeaturesAvailable)(IMSVidFeatures * * pVal);
  816. STDMETHOD(SetClientSite)(IOleClientSite *pClientSite);
  817. //STDMETHOD(DoVerb)(LONG iVerb, LPMSG pMsg, IOleClientSite* pActiveSite, LONG linddex,
  818. // HWND hwndParent, LPCRECT lprcPosRect);
  819. STDMETHOD(get_InputActive)(IMSVidInputDevice * * pVal) {
  820. try {
  821. return m_pInput.CopyTo(pVal);
  822. } catch(...) {
  823. return E_POINTER;
  824. }
  825. }
  826. STDMETHOD(put_InputActive)(IMSVidInputDevice * pVal) {
  827. if (pVal == NULL) {
  828. Decompose();
  829. if(m_pInput){
  830. PQGraphSegment(m_pInput)->put_Container(NULL);
  831. m_pInput.Release();
  832. }
  833. } else {
  834. try {
  835. if (m_pInput) {
  836. Decompose();
  837. PQGraphSegment(m_pInput)->put_Container(NULL);
  838. }
  839. m_pInput = pVal;
  840. m_pInputNotify = pVal; // if input device wants keyboard/mouse stuff(currently dvd only)
  841. m_fGraphDirty = true;
  842. } catch(...) {
  843. return E_POINTER;
  844. }
  845. }
  846. return NOERROR;
  847. }
  848. STDMETHOD(get_OutputsActive)(IMSVidOutputDevices * * pVal)
  849. {
  850. try {
  851. return m_pOutputsInUse.CopyTo(pVal);
  852. } catch(...) {
  853. return E_POINTER;
  854. }
  855. return NOERROR;
  856. }
  857. STDMETHOD(put_OutputsActive)(IMSVidOutputDevices * pVal)
  858. {
  859. if (pVal == NULL) {
  860. Decompose();
  861. m_pOutputsInUse.Release();
  862. } else {
  863. try {
  864. if (m_pOutputsInUse) {
  865. Decompose();
  866. }
  867. m_pOutputsInUse = pVal;
  868. m_fGraphDirty = true;
  869. } catch(...) {
  870. return E_POINTER;
  871. }
  872. }
  873. return NOERROR;
  874. }
  875. STDMETHOD(get_VideoRendererActive)(IMSVidVideoRenderer * * pVal)
  876. {
  877. try {
  878. PQVideoRenderer vr(m_pVideoRenderer);
  879. *pVal = vr.Detach();
  880. return NOERROR;
  881. } catch(...) {
  882. return E_POINTER;
  883. }
  884. }
  885. STDMETHOD(put_VideoRendererActive)(IMSVidVideoRenderer * pVal)
  886. {
  887. try {
  888. if (pVal == NULL) {
  889. m_videoSetNull = true;
  890. Decompose();
  891. m_pVideoRenderer.Release();
  892. } else {
  893. if (m_pVideoRenderer) {
  894. Decompose();
  895. }
  896. m_pVideoRenderer = pVal;
  897. }
  898. m_fGraphDirty = true;
  899. } catch(...) {
  900. return E_POINTER;
  901. }
  902. return NOERROR;
  903. }
  904. STDMETHOD(get_AudioRendererActive)(IMSVidAudioRenderer * * pVal)
  905. {
  906. try {
  907. return m_pAudioRenderer.CopyTo(pVal);
  908. } catch(...) {
  909. return E_POINTER;
  910. }
  911. return NOERROR;
  912. }
  913. STDMETHOD(put_AudioRendererActive)(IMSVidAudioRenderer * pVal)
  914. {
  915. try {
  916. if (pVal == NULL) {
  917. m_audioSetNull = true;
  918. Decompose();
  919. m_pAudioRenderer.Release();
  920. } else {
  921. if (m_pAudioRenderer) {
  922. Decompose();
  923. }
  924. m_pAudioRenderer = pVal;
  925. }
  926. m_fGraphDirty = true;
  927. } catch(...) {
  928. return E_POINTER;
  929. }
  930. return NOERROR;
  931. }
  932. STDMETHOD(get_FeaturesActive)(IMSVidFeatures * * pVal)
  933. {
  934. try {
  935. return m_pFeaturesInUse.CopyTo(pVal);
  936. } catch(...) {
  937. return E_POINTER;
  938. }
  939. return NOERROR;
  940. }
  941. STDMETHOD(put_FeaturesActive)(IMSVidFeatures * pVal){
  942. VIDPERF_FUNC;
  943. try {
  944. // Release the old list of active features
  945. if (m_pFeaturesInUse) {
  946. Decompose();
  947. }
  948. for (VWFeatures::iterator i = m_pFeaturesInUse.begin(); i != m_pFeaturesInUse.end(); ++i) {
  949. if ((*i).punkVal) {
  950. PQGraphSegment((*i).punkVal)->put_Container(NULL);
  951. }
  952. }
  953. m_pFeaturesInUse = pVal;
  954. m_fGraphDirty = true;
  955. } catch(...) {
  956. return E_POINTER;
  957. }
  958. return NOERROR;
  959. }
  960. STDMETHOD(View)(VARIANT* pItem) {
  961. VIDPERF_FUNC;
  962. try {
  963. return SelectView(pItem, false);
  964. } catch(ComException &e) {
  965. return e;
  966. } catch(...) {
  967. return E_UNEXPECTED;
  968. }
  969. }
  970. STDMETHOD(ViewNext)(VARIANT* pItem) {
  971. VIDPERF_FUNC;
  972. try {
  973. return SelectView(pItem, true);
  974. } catch(ComException &e) {
  975. return e;
  976. } catch(...) {
  977. return E_UNEXPECTED;
  978. }
  979. }
  980. STDMETHOD(Build)(void) {
  981. VIDPERF_FUNC;
  982. try {
  983. return BuildGraph();
  984. } catch(ComException &e) {
  985. return e;
  986. } catch(...) {
  987. return E_UNEXPECTED;
  988. }
  989. }
  990. STDMETHOD(Pause)(void);
  991. STDMETHOD(Run)(void) {
  992. VIDPERF_FUNC;
  993. try {
  994. return RunGraph();
  995. } catch(ComException &e) {
  996. return e;
  997. } catch(...) {
  998. return E_UNEXPECTED;
  999. }
  1000. }
  1001. STDMETHOD(Stop)(void);
  1002. STDMETHOD(Decompose)() {
  1003. VIDPERF_FUNC;
  1004. try {
  1005. return DecomposeAll();
  1006. } catch(ComException &e) {
  1007. return e;
  1008. } catch(...) {
  1009. return E_UNEXPECTED;
  1010. }
  1011. }
  1012. // ISegmentContainer
  1013. STDMETHOD(get_Graph)(IGraphBuilder **ppGraph) {
  1014. try {
  1015. return m_pGraph.CopyTo(ppGraph);
  1016. } catch(...) {
  1017. return E_POINTER;
  1018. }
  1019. }
  1020. STDMETHOD(get_Input)(IMSVidGraphSegment **ppInput) {
  1021. try {
  1022. return PQGraphSegment(m_pInput).CopyTo(ppInput);
  1023. } catch(...) {
  1024. return E_POINTER;
  1025. }
  1026. }
  1027. STDMETHOD(get_Outputs)(IEnumMSVidGraphSegment **ppOutputs) {
  1028. PQEnumSegment temp;
  1029. try {
  1030. temp = new CSegEnum(static_cast<COutputDevices *>(m_pOutputs.p)->m_Devices);
  1031. } catch(...) {
  1032. return E_OUTOFMEMORY;
  1033. }
  1034. try {
  1035. *ppOutputs = temp.Detach();
  1036. } catch(...) {
  1037. return E_POINTER;
  1038. }
  1039. return NOERROR;
  1040. }
  1041. STDMETHOD(get_VideoRenderer)(IMSVidGraphSegment **ppVR) {
  1042. try {
  1043. return PQGraphSegment(m_pVideoRenderer).CopyTo(ppVR);
  1044. } catch(...) {
  1045. return E_POINTER;
  1046. }
  1047. }
  1048. STDMETHOD(get_AudioRenderer)(IMSVidGraphSegment **ppAR) {
  1049. try {
  1050. return PQGraphSegment(m_pAudioRenderer).CopyTo(ppAR);
  1051. } catch(...) {
  1052. return E_POINTER;
  1053. }
  1054. }
  1055. STDMETHOD(get_Features)(IEnumMSVidGraphSegment **ppFeatures) {
  1056. PQEnumSegment temp;
  1057. try {
  1058. temp = new CSegEnum(static_cast<CFeatures *>(m_pFeatures.p)->m_Devices);
  1059. } catch(...) {
  1060. return E_OUTOFMEMORY;
  1061. }
  1062. try {
  1063. *ppFeatures = temp.Detach();
  1064. } catch(...) {
  1065. return E_POINTER;
  1066. }
  1067. return NOERROR;
  1068. }
  1069. STDMETHOD(get_Composites)(IEnumMSVidGraphSegment **ppComposites) {
  1070. PQEnumSegment temp;
  1071. try {
  1072. temp = new CSegEnum(m_pComposites);
  1073. } catch(...) {
  1074. return E_OUTOFMEMORY;
  1075. }
  1076. try {
  1077. *ppComposites = temp.Detach();
  1078. } catch(...) {
  1079. return E_POINTER;
  1080. }
  1081. return NOERROR;
  1082. }
  1083. STDMETHOD(get_ParentContainer)(IUnknown **ppUnk) {
  1084. try {
  1085. if (ppUnk) {
  1086. return E_POINTER;
  1087. }
  1088. if (!m_spClientSite) {
  1089. return E_NOINTERFACE;
  1090. }
  1091. m_spClientSite.CopyTo(ppUnk);
  1092. return NOERROR;
  1093. } catch(ComException &e) {
  1094. return e;
  1095. } catch(...) {
  1096. return E_UNEXPECTED;
  1097. }
  1098. }
  1099. STDMETHOD(Decompose)(IMSVidGraphSegment *pSegment) {
  1100. try {
  1101. return DecomposeSegment(VWGraphSegment(pSegment));
  1102. } catch(ComException &e) {
  1103. return e;
  1104. } catch(...) {
  1105. return E_UNEXPECTED;
  1106. }
  1107. }
  1108. STDMETHOD(DisableVideo)() {
  1109. return put_VideoRendererActive(NULL);
  1110. }
  1111. STDMETHOD(DisableAudio)() {
  1112. return put_AudioRendererActive(NULL);
  1113. }
  1114. STDMETHOD(IsWindowless)() {
  1115. return m_bWndLess ? NOERROR : S_FALSE;
  1116. }
  1117. STDMETHOD(GetFocus)() {
  1118. try {
  1119. if (!SetControlFocus(TRUE)) {
  1120. return E_FAIL;
  1121. }
  1122. return NOERROR;
  1123. } catch(...) {
  1124. return E_UNEXPECTED;
  1125. }
  1126. }
  1127. STDMETHOD(QueryService)(REFIID service, REFIID iface, LPVOID* ppv);
  1128. STDMETHOD(put_ServiceProvider)(/*[in]*/ IUnknown * pServiceP);
  1129. };
  1130. #endif //__VidCtl_H_