Index: /trunk/DirectShowSpy/DirectShowSpy.idl
===================================================================
--- /trunk/DirectShowSpy/DirectShowSpy.idl (revision 289)
+++ /trunk/DirectShowSpy/DirectShowSpy.idl (revision 290)
@@ -219,3 +219,24 @@
[default] interface IUnknown; //IPropertyPage;
};
-};
+ [
+ object,
+ uuid(DA0D924F-1AC0-496D-AE44-CC2BD8CE7CFA),
+ nonextensible,
+ helpstring("IRunEventAware Interface"),
+ pointer_default(unique)
+ ]
+ interface IRunEventAware : IDispatch
+ {
+ [propget, id(DISPID_VALUE)] HRESULT Value([out, retval] VARIANT* pvValue);
+ [propget, id(1)] HRESULT Capture([out, retval] VARIANT_BOOL* pbCapture);
+ [propput, id(1)] HRESULT Capture([in] VARIANT_BOOL bCapture);
+ };
+ [
+ uuid(AD0E84E9-DE25-4C1A-85A5-47406604E144),
+ helpstring("RunEventPropertyPage Class")
+ ]
+ coclass RunEventPropertyPage
+ {
+ [default] interface IUnknown; //IPropertyPage;
+ };
+};
Index: /trunk/DirectShowSpy/DirectShowSpy.rc
===================================================================
--- /trunk/DirectShowSpy/DirectShowSpy.rc (revision 289)
+++ /trunk/DirectShowSpy/DirectShowSpy.rc (revision 290)
@@ -60,5 +60,5 @@
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1, 0, 0, 1483
+ FILEVERSION 1, 0, 0, 1515
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
@@ -79,5 +79,5 @@
VALUE "CompanyName", "Roman Ryltsov"
VALUE "FileDescription", "Alax.Info DirectShow Spy Module"
- VALUE "FileVersion", "1, 0, 0, 1483\0"
+ VALUE "FileVersion", "1, 0, 0, 1515\0"
VALUE "InternalName", "DirectShowSpy.dll"
VALUE "LegalCopyright", "Copyright © Alax.Info, Roman Ryltsov, 2008-2014"
@@ -106,5 +106,6 @@
IDR_SYSTEMDEVICEENUMERATORSPY REGISTRY "GenericClass.rgs"
IDR_FILTERGRAPHHELPER REGISTRY "GenericClass.rgs"
-IDR_GENERIC_RUNPROPERTYBAGPROPERTYPAGE REGISTRY "GenericPropertyPage.rgs"
+IDR_GENERIC_RUNPROPERTYBAG_PROPERTYPAGE REGISTRY "GenericPropertyPage.rgs"
+IDR_GENERIC_RUNEVENT_PROPERTYPAGE REGISTRY "GenericPropertyPage.rgs"
/////////////////////////////////////////////////////////////////////////////
@@ -322,4 +323,15 @@
+IDD_GENERIC_RUNEVENT DIALOGEX 0, 0, 227, 200
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x0
+BEGIN
+ CONTROL "&Capture runtime events",IDC_GENERIC_RUNEVENT_CAPTURE,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,6,210,10
+ EDITTEXT IDC_GENERIC_RUNEVENT_TEXT,6,24,215,150,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL
+ PUSHBUTTON "&Refresh",IDC_GENERIC_RUNEVENT_REFRESH,6,180,50,14
+END
+
+
/////////////////////////////////////////////////////////////////////////////
//
@@ -445,11 +457,14 @@
STRINGTABLE
BEGIN
- IDR_GENERIC_RUNPROPERTYBAGPROPERTYPAGE
+ IDR_GENERIC_RUNPROPERTYBAG_PROPERTYPAGE
"\n\nAlax.Info DirectShow Spy Runtime Property Bag Property Page\n"
-END
-
-STRINGTABLE
-BEGIN
- IDD_GENERIC_RUNPROPERTYBAG "Runtime"
+ IDR_GENERIC_RUNEVENT_PROPERTYPAGE
+ "\n\nAlax.Info DirectShow Spy Runtime Event Property Page\n"
+END
+
+STRINGTABLE
+BEGIN
+ IDD_GENERIC_RUNPROPERTYBAG "Runtime Properties"
+ IDD_GENERIC_RUNEVENT "Runtime Events"
END
Index: /trunk/DirectShowSpy/DirectShowSpy.vcxproj
===================================================================
--- /trunk/DirectShowSpy/DirectShowSpy.vcxproj (revision 289)
+++ /trunk/DirectShowSpy/DirectShowSpy.vcxproj (revision 290)
@@ -473,6 +473,7 @@
-
+
+
Index: /trunk/DirectShowSpy/DirectShowSpy.vcxproj.filters
===================================================================
--- /trunk/DirectShowSpy/DirectShowSpy.vcxproj.filters (revision 289)
+++ /trunk/DirectShowSpy/DirectShowSpy.vcxproj.filters (revision 290)
@@ -113,5 +113,8 @@
Header Files
-
+
+ Header Files
+
+
Header Files
Index: /trunk/DirectShowSpy/DirectShowSpy_i.c
===================================================================
--- /trunk/DirectShowSpy/DirectShowSpy_i.c (revision 289)
+++ /trunk/DirectShowSpy/DirectShowSpy_i.c (revision 290)
@@ -7,5 +7,5 @@
/* File created by MIDL compiler version 7.00.0555 */
-/* at Wed May 07 14:27:04 2014
+/* at Wed May 28 01:18:35 2014
*/
/* Compiler settings for DirectShowSpy.idl:
@@ -118,4 +118,10 @@
MIDL_DEFINE_GUID(CLSID, CLSID_RunPropertyBagPropertyPage,0x76127943,0xD22E,0x4C4E,0x9D,0x9B,0x17,0x3C,0x22,0x4D,0x0E,0xE4);
+
+MIDL_DEFINE_GUID(IID, IID_IRunEventAware,0xDA0D924F,0x1AC0,0x496D,0xAE,0x44,0xCC,0x2B,0xD8,0xCE,0x7C,0xFA);
+
+
+MIDL_DEFINE_GUID(CLSID, CLSID_RunEventPropertyPage,0xAD0E84E9,0xDE25,0x4C1A,0x85,0xA5,0x47,0x40,0x66,0x04,0xE1,0x44);
+
#undef MIDL_DEFINE_GUID
Index: /trunk/DirectShowSpy/DirectShowSpy_i.h
===================================================================
--- /trunk/DirectShowSpy/DirectShowSpy_i.h (revision 289)
+++ /trunk/DirectShowSpy/DirectShowSpy_i.h (revision 290)
@@ -5,5 +5,5 @@
/* File created by MIDL compiler version 7.00.0555 */
-/* at Wed May 07 14:27:04 2014
+/* at Wed May 28 01:18:35 2014
*/
/* Compiler settings for DirectShowSpy.idl:
@@ -178,4 +178,22 @@
+#ifndef __IRunEventAware_FWD_DEFINED__
+#define __IRunEventAware_FWD_DEFINED__
+typedef interface IRunEventAware IRunEventAware;
+#endif /* __IRunEventAware_FWD_DEFINED__ */
+
+
+#ifndef __RunEventPropertyPage_FWD_DEFINED__
+#define __RunEventPropertyPage_FWD_DEFINED__
+
+#ifdef __cplusplus
+typedef class RunEventPropertyPage RunEventPropertyPage;
+#else
+typedef struct RunEventPropertyPage RunEventPropertyPage;
+#endif /* __cplusplus */
+
+#endif /* __RunEventPropertyPage_FWD_DEFINED__ */
+
+
/* header files for imported files */
#include "oaidl.h"
@@ -1584,4 +1602,153 @@
RunPropertyBagPropertyPage;
#endif
+
+#ifndef __IRunEventAware_INTERFACE_DEFINED__
+#define __IRunEventAware_INTERFACE_DEFINED__
+
+/* interface IRunEventAware */
+/* [unique][helpstring][nonextensible][uuid][object] */
+
+
+EXTERN_C const IID IID_IRunEventAware;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("DA0D924F-1AC0-496D-AE44-CC2BD8CE7CFA")
+ IRunEventAware : public IDispatch
+ {
+ public:
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_Value(
+ /* [retval][out] */ VARIANT *pvValue) = 0;
+
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_Capture(
+ /* [retval][out] */ VARIANT_BOOL *pbCapture) = 0;
+
+ virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_Capture(
+ /* [in] */ VARIANT_BOOL bCapture) = 0;
+
+ };
+
+#else /* C style interface */
+
+ typedef struct IRunEventAwareVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ IRunEventAware * This,
+ /* [in] */ REFIID riid,
+ /* [annotation][iid_is][out] */
+ __RPC__deref_out void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ IRunEventAware * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ IRunEventAware * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
+ IRunEventAware * This,
+ /* [out] */ UINT *pctinfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
+ IRunEventAware * This,
+ /* [in] */ UINT iTInfo,
+ /* [in] */ LCID lcid,
+ /* [out] */ ITypeInfo **ppTInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
+ IRunEventAware * This,
+ /* [in] */ REFIID riid,
+ /* [size_is][in] */ LPOLESTR *rgszNames,
+ /* [range][in] */ UINT cNames,
+ /* [in] */ LCID lcid,
+ /* [size_is][out] */ DISPID *rgDispId);
+
+ /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
+ IRunEventAware * This,
+ /* [in] */ DISPID dispIdMember,
+ /* [in] */ REFIID riid,
+ /* [in] */ LCID lcid,
+ /* [in] */ WORD wFlags,
+ /* [out][in] */ DISPPARAMS *pDispParams,
+ /* [out] */ VARIANT *pVarResult,
+ /* [out] */ EXCEPINFO *pExcepInfo,
+ /* [out] */ UINT *puArgErr);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Value )(
+ IRunEventAware * This,
+ /* [retval][out] */ VARIANT *pvValue);
+
+ /* [id][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Capture )(
+ IRunEventAware * This,
+ /* [retval][out] */ VARIANT_BOOL *pbCapture);
+
+ /* [id][propput] */ HRESULT ( STDMETHODCALLTYPE *put_Capture )(
+ IRunEventAware * This,
+ /* [in] */ VARIANT_BOOL bCapture);
+
+ END_INTERFACE
+ } IRunEventAwareVtbl;
+
+ interface IRunEventAware
+ {
+ CONST_VTBL struct IRunEventAwareVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define IRunEventAware_QueryInterface(This,riid,ppvObject) \
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define IRunEventAware_AddRef(This) \
+ ( (This)->lpVtbl -> AddRef(This) )
+
+#define IRunEventAware_Release(This) \
+ ( (This)->lpVtbl -> Release(This) )
+
+
+#define IRunEventAware_GetTypeInfoCount(This,pctinfo) \
+ ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) )
+
+#define IRunEventAware_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+ ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) )
+
+#define IRunEventAware_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
+ ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) )
+
+#define IRunEventAware_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+ ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) )
+
+
+#define IRunEventAware_get_Value(This,pvValue) \
+ ( (This)->lpVtbl -> get_Value(This,pvValue) )
+
+#define IRunEventAware_get_Capture(This,pbCapture) \
+ ( (This)->lpVtbl -> get_Capture(This,pbCapture) )
+
+#define IRunEventAware_put_Capture(This,bCapture) \
+ ( (This)->lpVtbl -> put_Capture(This,bCapture) )
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+
+#endif /* __IRunEventAware_INTERFACE_DEFINED__ */
+
+
+EXTERN_C const CLSID CLSID_RunEventPropertyPage;
+
+#ifdef __cplusplus
+
+class DECLSPEC_UUID("AD0E84E9-DE25-4C1A-85A5-47406604E144")
+RunEventPropertyPage;
+#endif
#endif /* __AlaxInfoDirectShowSpy_LIBRARY_DEFINED__ */
Index: /trunk/DirectShowSpy/DirectShowSpy_p.c
===================================================================
--- /trunk/DirectShowSpy/DirectShowSpy_p.c (revision 289)
+++ /trunk/DirectShowSpy/DirectShowSpy_p.c (revision 290)
@@ -5,5 +5,5 @@
/* File created by MIDL compiler version 7.00.0555 */
-/* at Wed May 07 14:27:04 2014
+/* at Wed May 28 01:18:35 2014
*/
/* Compiler settings for DirectShowSpy.idl:
Index: /trunk/DirectShowSpy/FilterGraphHelper.h
===================================================================
--- /trunk/DirectShowSpy/FilterGraphHelper.h (revision 289)
+++ /trunk/DirectShowSpy/FilterGraphHelper.h (revision 290)
@@ -20,5 +20,6 @@
#include "DirectShowSpy_i.h"
#include "Common.h"
-#include "PropertyBag.h"
+#include "RunPropertyBag.h"
+#include "RunEvent.h"
#include "AboutDialog.h"
#include "..\..\Repository-Private\Utilities\EmailTools\Message.h"
@@ -32,7 +33,4 @@
HRESULT FilterGraphHelper_OpenGraphStudioNext(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult);
HRESULT FilterGraphHelper_OpenGraphEdit(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult);
-
-////////////////////////////////////////////////////////////
-// CFilterGraphHelper
////////////////////////////////////////////////////////////
@@ -46,5 +44,5 @@
{
public:
- enum { IDR = IDR_GENERIC_RUNPROPERTYBAGPROPERTYPAGE };
+ enum { IDR = IDR_GENERIC_RUNPROPERTYBAG_PROPERTYPAGE };
enum { IDD = IDD_GENERIC_RUNPROPERTYBAG };
@@ -88,9 +86,9 @@
CRunPropertyBagPropertyPage()
{
- _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
+ _Z4_THIS();
}
~CRunPropertyBagPropertyPage()
{
- _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
+ _Z4_THIS();
}
VOID UpdateControls()
@@ -101,5 +99,5 @@
CString sText;
_A(GetObjectCount() == 1);
- m_TextEdit.SetValue(CPropertyBagHelper::GetPropertyBagText(GetObject(0)));
+ m_TextEdit.SetValue(CRunPropertyBagHelper::GetPropertyBagText(GetObject(0)));
}
@@ -169,4 +167,186 @@
OBJECT_ENTRY_AUTO(__uuidof(RunPropertyBagPropertyPage), CRunPropertyBagPropertyPage)
+
+////////////////////////////////////////////////////////////
+// CRunEventPropertyPage
+
+class ATL_NO_VTABLE CRunEventPropertyPage :
+ public CComObjectRootEx,
+ public CComCoClass,
+ public COlePropertyPageT,
+ public CDialogResize
+{
+public:
+ enum { IDR = IDR_GENERIC_RUNEVENT_PROPERTYPAGE };
+ enum { IDD = IDD_GENERIC_RUNEVENT };
+
+BEGIN_COM_MAP(CRunEventPropertyPage)
+ COM_INTERFACE_ENTRY(IPropertyPage2)
+ COM_INTERFACE_ENTRY(IPropertyPage)
+END_COM_MAP()
+
+BEGIN_MSG_MAP_EX(CRunEventPropertyPage)
+ CHAIN_MSG_MAP(COlePropertyPage)
+ CHAIN_MSG_MAP(CDialogResize)
+ MSG_WM_INITDIALOG(OnInitDialog)
+ MSG_WM_DESTROY(OnDestroy)
+ COMMAND_HANDLER_EX(IDC_GENERIC_RUNEVENT_CAPTURE, BN_CLICKED, OnCaptureButtonClicked)
+ COMMAND_ID_HANDLER_EX(IDC_GENERIC_RUNEVENT_REFRESH, OnRefresh)
+ REFLECT_NOTIFICATIONS()
+END_MSG_MAP()
+
+BEGIN_DLGRESIZE_MAP(CRunEventPropertyPage)
+ DLGRESIZE_CONTROL(IDC_GENERIC_RUNEVENT_CAPTURE, DLSZ_SIZE_X)
+ DLGRESIZE_CONTROL(IDC_GENERIC_RUNEVENT_TEXT, DLSZ_SIZE_X | DLSZ_SIZE_Y)
+ DLGRESIZE_CONTROL(IDC_GENERIC_RUNEVENT_REFRESH, DLSZ_MOVE_Y)
+END_DLGRESIZE_MAP()
+
+public:
+
+private:
+ BOOL m_bActivating;
+ CButton m_CaptureButton;
+ CRoEdit m_TextEdit;
+ CButton m_RefreshButton;
+ CRoMapT m_ChangeMap;
+
+public:
+// CRunEventPropertyPage
+ static CString GetObjectFriendlyName()
+ {
+ return _StringHelper::GetLine(IDR, 2);
+ }
+ static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
+ {
+ _Z2(atlTraceRegistrar, 2, _T("bRegister %d\n"), bRegister);
+ return DefaultUpdateRegistry(bRegister);
+ }
+ CRunEventPropertyPage()
+ {
+ _Z4_THIS();
+ }
+ ~CRunEventPropertyPage()
+ {
+ _Z4_THIS();
+ }
+ VOID UpdateControls()
+ {
+ const BOOL bCapture = m_CaptureButton.GetCheck();
+ //m_TextEdit.EnableWindow(bCapture);
+ m_RefreshButton.EnableWindow(bCapture);
+ }
+ VOID Refresh()
+ {
+ const CComQIPtr pRunEventAware = GetObject(0);
+ if(!pRunEventAware)
+ return;
+ CComVariantArray vValue;
+ __C(pRunEventAware->get_Value(&vValue));
+ CString sText;
+ _ATLTRY
+ {
+ if(vValue.vt > VT_NULL)
+ {
+ CRoArrayT Array;
+ vValue.ToElementArray(Array);
+ for(SIZE_T nIndex = 0; nIndex < Array.GetCount(); nIndex++)
+ {
+ CRunEventHelper::CEvents::CItem Item;
+ if(!Item.SetAsVariant(Array[nIndex]))
+ continue;
+ sText.AppendFormat(_T("%d") _T("\t") _T("%hs"), (LONG) (Item.m_nTime / 10000i64), Item.m_pszText);
+ sText.Append(_T("\r\n"));
+ }
+ }
+ }
+ _ATLCATCHALL()
+ {
+ _Z_EXCEPTION();
+ }
+ m_TextEdit.SetValue(sText);
+ }
+
+// Window message handlers
+ LRESULT OnInitDialog(HWND, LPARAM)
+ {
+ m_bActivating = TRUE;
+ _ATLTRY
+ {
+ m_CaptureButton = GetDlgItem(IDC_GENERIC_RUNEVENT_CAPTURE);
+ m_TextEdit = GetDlgItem(IDC_GENERIC_RUNEVENT_TEXT);
+ m_RefreshButton = GetDlgItem(IDC_GENERIC_RUNEVENT_REFRESH);
+ DlgResize_Init(FALSE);
+ //m_OutputSampleTimeEdit = GetDlgItem(IDC_SUSPENSIONFILTER_SAMPLE_OUTPUTTIME);
+ _A(GetObjectCount() >= 1);
+ const CComQIPtr pRunEventAware = GetObject(0);
+ __D(pRunEventAware, E_NOINTERFACE);
+ VARIANT_BOOL bCapture = ATL_VARIANT_FALSE;
+ __C(pRunEventAware->get_Capture(&bCapture));
+ m_CaptureButton.SetCheck(bCapture != ATL_VARIANT_FALSE);
+ if(bCapture != ATL_VARIANT_FALSE)
+ Refresh();
+ UpdateControls();
+ m_ChangeMap.RemoveAll();
+ m_bActivating = FALSE;
+ }
+ _ATLCATCH(Exception)
+ {
+ AtlExceptionMessageBox(m_hWnd, Exception);
+ for(CWindow Window = GetWindow(GW_CHILD); Window.IsWindow(); Window = Window.GetWindow(GW_HWNDNEXT))
+ Window.EnableWindow(FALSE);
+ }
+ return TRUE;
+ }
+ LRESULT OnDestroy()
+ {
+ return 0;
+ }
+ LRESULT OnCaptureButtonClicked(UINT, INT, HWND)
+ {
+ CWaitCursor WaitCursor;
+ const CComQIPtr pRunEventAware = GetObject(0);
+ if(pRunEventAware)
+ _ATLTRY
+ {
+ const BOOL bCapture = m_CaptureButton.GetCheck();
+ __C(pRunEventAware->put_Capture(bCapture ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE));
+ }
+ _ATLCATCHALL()
+ {
+ _Z_EXCEPTION();
+ }
+ UpdateControls();
+ return 0;
+ }
+ LRESULT OnRefresh(UINT, INT, HWND)
+ {
+ CWaitCursor WaitCursor;
+ Refresh();
+ UpdateControls();
+ return 0;
+ }
+
+// COlePropertyPageT, IRoPropertyPageT, IPropertyPage2, IPropertyPage
+ STDMETHOD(Apply)()
+ {
+ _Z4(atlTraceCOM, 4, _T("...\n"));
+ _ATLTRY
+ {
+ //if(!m_ChangeMap.IsEmpty())
+ {
+ //CWaitCursor WaitCursor;
+ //m_ChangeMap.RemoveAll();
+ SetDirty(FALSE);
+ }
+ }
+ _ATLCATCH(Exception)
+ {
+ _C(Exception);
+ }
+ return S_OK;
+ }
+};
+
+OBJECT_ENTRY_AUTO(__uuidof(RunEventPropertyPage), CRunEventPropertyPage)
////////////////////////////////////////////////////////////
@@ -1739,5 +1919,5 @@
_ATLTRY
{
- const CString sPropertyBagText = CPropertyBagHelper::GetPropertyBagText(Data.m_pBaseFilter, CComQIPtr(m_Owner.m_pFilterGraph));
+ const CString sPropertyBagText = CRunPropertyBagHelper::GetPropertyBagText(Data.m_pBaseFilter, CComQIPtr(m_Owner.m_pFilterGraph));
if(!sPropertyBagText.IsEmpty())
{
@@ -1915,9 +2095,9 @@
CFilterGraphHelper()
{
- _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
+ _Z4_THIS();
}
~CFilterGraphHelper()
{
- _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
+ _Z4_THIS();
}
static CString FormatIdentifier(LPCSTR pszValue)
@@ -2685,5 +2865,5 @@
const CComPtr& pBaseFilter = FilterArray[nIndex];
//_Z4(atlTraceGeneral, 4, _T("pBaseFilter 0x%p \"%ls\"\n"), pBaseFilter, _FilterGraphHelper::GetFilterName(pBaseFilter));
- const CString sPropertyBagText = CPropertyBagHelper::GetPropertyBagText(pBaseFilter, pSpy);
+ const CString sPropertyBagText = CRunPropertyBagHelper::GetPropertyBagText(pBaseFilter, pSpy);
if(sPropertyBagText.IsEmpty())
continue;
Index: /trunk/DirectShowSpy/FilterGraphSpy.h
===================================================================
--- /trunk/DirectShowSpy/FilterGraphSpy.h (revision 289)
+++ /trunk/DirectShowSpy/FilterGraphSpy.h (revision 290)
@@ -19,5 +19,5 @@
#include "DirectShowSpy_i.h"
#include "Common.h"
-#include "PropertyBag.h"
+#include "RunPropertyBag.h"
HRESULT FilterGraphHelper_OpenGraphStudioNext(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult);
@@ -790,5 +790,5 @@
__D(pvValue, E_POINTER);
VariantInit(pvValue);
- _V(CPropertyBagHelper::ReadRunPropertyBag(pBaseFilterUnknown, bAllowExtension != ATL_VARIANT_FALSE).Detach(pvValue));
+ _V(CRunPropertyBagHelper::ReadRunPropertyBag(pBaseFilterUnknown, bAllowExtension != ATL_VARIANT_FALSE).Detach(pvValue));
}
_ATLCATCHALL()
Index: unk/DirectShowSpy/PropertyBag.h
===================================================================
--- /trunk/DirectShowSpy/PropertyBag.h (revision 289)
+++ (revision )
@@ -1,298 +1,0 @@
-////////////////////////////////////////////////////////////
-// Copyright (C) Roman Ryltsov, 2008-2014
-// Created by Roman Ryltsov roman@alax.info, http://alax.info
-//
-// This source code is published to complement DirectShowSpy developer powertoy
-// and demonstrate the internal use of APIs and tricks powering the tool. It is
-// allowed to freely re-use the portions of the code in other projects, commercial
-// or otherwise (provided that you dont pretend that you wrote the original tool).
-//
-// Please keep in mind that DirectShowSpy is a developer tool, it is strongly recommended
-// that it is not shipped with release grade software. It is allowed to distribute
-// DirectShowSpy if only it is not registered with Windows by default and either
-// used privately, or registered on specific throubleshooting request. The advice applies
-// to hooking methods used by DirectShowSpy in general as well.
-
-#pragma once
-
-#include "DirectShowSpy_i.h"
-#include "Common.h"
-
-////////////////////////////////////////////////////////////
-//
-
-class CPropertyBagHelper
-{
-public:
-
- ////////////////////////////////////////////////////////
- // CSimpleSortTraitsT
-
- class CNameSortTraits :
- public CSimpleSortTraitsT
- {
- public:
- // CNameSortTraits
- static INT_PTR CompareElements(const CString& sElementA, const CString& sElementB, PARAMETERARGUMENT Parameter)
- {
- return _tcsicmp(sElementA, sElementB);
- }
- };
-
-protected:
- static CObjectPtr& PropertyBagNeeded(CObjectPtr& pPropertyBag)
- {
- if(!pPropertyBag)
- pPropertyBag.Construct();
- return pPropertyBag;
- }
-
-public:
-// CPropertyBagHelper
- static CComVariantArray ReadRunPropertyBag(IUnknown* pBaseFilterUnknown, BOOL bAllowExtension = TRUE)
- {
- CComVariantArray vValue;
- CRoArrayT Array;
- const CComQIPtr pRunPropertyBagAware = pBaseFilterUnknown;
- CComQIPtr pPropertyBag2;
- #pragma region Extension
- if(!pRunPropertyBagAware && bAllowExtension)
- {
- CObjectPtr pPropertyBag;
- #pragma region IQualProp
- const CComQIPtr pQualProp = pBaseFilterUnknown;
- if(pQualProp)
- _ATLTRY
- {
- INT nFramesDroppedInRenderer, nFramesDrawn, nAvgFrameRate, nJitter, nAvgSyncOffset, nDevSyncOffset;
- __C(pQualProp->get_FramesDroppedInRenderer(&nFramesDroppedInRenderer));
- __C(pQualProp->get_FramesDrawn(&nFramesDrawn));
- __C(pQualProp->get_AvgFrameRate(&nAvgFrameRate));
- __C(pQualProp->get_Jitter(&nJitter));
- __C(pQualProp->get_AvgSyncOffset(&nAvgSyncOffset));
- __C(pQualProp->get_DevSyncOffset(&nDevSyncOffset));
- PropertyBagNeeded(pPropertyBag);
- pPropertyBag->WriteValue(_T("FramesDroppedInRenderer"), CComVariant((LONG) nFramesDroppedInRenderer));
- pPropertyBag->WriteValue(_T("FramesDrawn"), CComVariant((LONG) nFramesDrawn));
- pPropertyBag->WriteValue(_T("AvgFrameRate"), CComVariant((DOUBLE) nAvgFrameRate / 100));
- pPropertyBag->WriteValue(_T("Jitter"), CComVariant((LONG) nJitter));
- pPropertyBag->WriteValue(_T("AvgSyncOffset"), CComVariant((LONG) nAvgSyncOffset));
- pPropertyBag->WriteValue(_T("DevSyncOffset"), CComVariant((LONG) nDevSyncOffset));
- }
- _ATLCATCHALL()
- {
- _Z_EXCEPTION();
- }
- #pragma endregion
- #pragma region IAMAudioRendererStats
- const CComQIPtr pAmAudioRendererStats = pBaseFilterUnknown;
- if(pAmAudioRendererStats)
- _ATLTRY
- {
- DWORD nDummy;
- DWORD nBreakCount, nSlaveMode, nSilenceDuration, nLastBufferDuration, nDiscontinuityCount, nSlaveRate, nDropWriteDuration;
- DWORD nHighestSlaveError, nLowestSlaveError, nLastHighSlaveError, nLastLowSlaveError;
- DWORD nAccumulatedError, nBufferFullness;
- //DWORD nJitter;
- __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_BREAK_COUNT, &nBreakCount, &nDummy));
- __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_SLAVE_MODE, &nSlaveMode, &nDummy));
- __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_SILENCE_DUR, &nSilenceDuration, &nDummy));
- __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_LAST_BUFFER_DUR, &nLastBufferDuration, &nDummy));
- __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_DISCONTINUITIES, &nDiscontinuityCount, &nDummy));
- if(nSlaveMode)
- {
- __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_SLAVE_RATE, &nSlaveRate, &nDummy));
- __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_SLAVE_DROPWRITE_DUR, &nDropWriteDuration, &nDummy));
- __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_SLAVE_HIGHLOWERROR, &nHighestSlaveError, &nLowestSlaveError));
- __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_SLAVE_LASTHIGHLOWERROR, &nLastHighSlaveError, &nLastLowSlaveError));
- __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_SLAVE_ACCUMERROR, &nAccumulatedError, &nDummy));
- }
- __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_BUFFERFULLNESS, &nBufferFullness, &nDummy));
- //__C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_JITTER, &nJitter, &nDummy));
- PropertyBagNeeded(pPropertyBag);
- pPropertyBag->WriteValue(_T("BreakCount"), CComVariant((LONG) nBreakCount));
- pPropertyBag->WriteValue(_T("SlaveMode"), CComVariant((LONG) nSlaveMode));
- pPropertyBag->WriteValue(_T("SilenceDuration"), CComVariant((LONG) nSilenceDuration));
- pPropertyBag->WriteValue(_T("LastBufferDuration"), CComVariant((LONG) nLastBufferDuration));
- pPropertyBag->WriteValue(_T("DiscontinuityCount"), CComVariant((LONG) nDiscontinuityCount));
- if(nSlaveMode)
- {
- pPropertyBag->WriteValue(_T("SlaveRate"), CComVariant((LONG) nSlaveRate));
- pPropertyBag->WriteValue(_T("DropWriteDuration"), CComVariant((LONG) nDropWriteDuration));
- pPropertyBag->WriteValue(_T("HighestSlaveError"), CComVariant((LONG) nHighestSlaveError));
- pPropertyBag->WriteValue(_T("LowestSlaveError"), CComVariant((LONG) nLowestSlaveError));
- pPropertyBag->WriteValue(_T("LastHighSlaveError"), CComVariant((LONG) nLastHighSlaveError));
- pPropertyBag->WriteValue(_T("LastLowSlaveError"), CComVariant((LONG) nLastLowSlaveError));
- pPropertyBag->WriteValue(_T("AccumulatedError"), CComVariant((LONG) nAccumulatedError));
- }
- pPropertyBag->WriteValue(_T("BufferFullness"), CComVariant((LONG) nBufferFullness));
- //pPropertyBag->WriteValue(_T("Jitter"), CComVariant((LONG) nJitter));
- }
- _ATLCATCHALL()
- {
- _Z_EXCEPTION();
- }
- #pragma endregion
- if(pPropertyBag)
- pPropertyBag2 = pPropertyBag;
- }
- #pragma endregion
- if(!pPropertyBag2 && pRunPropertyBagAware)
- {
- CComPtr pPropertyBagUnknown;
- __C(pRunPropertyBagAware->get_Value(&pPropertyBagUnknown));
- pPropertyBag2 = pPropertyBagUnknown;
- }
- if(pPropertyBag2)
- {
- ULONG nPropertyCount = 0;
- __C(pPropertyBag2->CountProperties(&nPropertyCount));
- _Z4(atlTraceGeneral, 4, _T("nPropertyCount %d\n"), nPropertyCount);
- if(nPropertyCount)
- {
- CTempBufferT pPropBags(nPropertyCount);
- ZeroMemory((PROPBAG2*) pPropBags, nPropertyCount * sizeof *pPropBags);
- ULONG nPropBagCount = 0;
- __C(pPropertyBag2->GetPropertyInfo(0, nPropertyCount, pPropBags, &nPropBagCount));
- _Z4(atlTraceGeneral, 4, _T("nPropBagCount %d\n"), nPropBagCount);
- CRoListT> NameList;
- for(ULONG nIndex = 0; nIndex < nPropBagCount; nIndex++)
- NameList.GetAt(NameList.AddTail()).Attach(pPropBags[nIndex].pstrName);
- CRoArrayT ValueArray;
- __D(ValueArray.SetCount(nPropBagCount), E_OUTOFMEMORY);
- CTempBufferT pnResults(nPropBagCount);
- __C(pPropertyBag2->Read(nPropBagCount, pPropBags, NULL, ValueArray.GetData(), pnResults));
- for(ULONG nIndex = 0; nIndex < nPropBagCount; nIndex++)
- if(SUCCEEDED(pnResults[nIndex]))
- {
- CString sName(pPropBags[nIndex].pstrName);
- _Z4(atlTraceGeneral, 4, _T("sName \"%s\"\n"), sName);
- CComVariantArray vPropertyValue;
- Array.Add(vPropertyValue.FromElements(2, CComVariant(sName), ValueArray[nIndex]));
- }
- vValue.FromElementArray(Array);
- }
- }
- return vValue;
- }
- static CString GetPropertyBagText(CRoArrayT& NameArray, CRoMapT& Map)
- {
- CString sText;
- _SortHelper::QuickSort(NameArray);
- // SUGG: Nicer similar names, taking prefix at dot separator, also changing Foo-A-B into Foo (A; B)
- for(SIZE_T nIndex = 0; nIndex < NameArray.GetCount(); nIndex++)
- {
- const CString& sName = NameArray[nIndex];
- _Z4(atlTraceGeneral, 4, _T("sName \"%s\"\n"), sName);
- CString sValue;
- CComVariantArray vValue;
- if(!Map.Lookup(sName, vValue))
- continue;
- CString sComment;
- #pragma region Friendly Comment
- switch(vValue.vt)
- {
- #pragma region VT_I4
- case VT_I4:
- if(vValue.lVal < -999 || vValue.lVal > 999)
- sComment = _StringHelper::FormatNumber(vValue.lVal);
- break;
- #pragma endregion
- #pragma region VT_R8
- case VT_R8:
- if(vValue.dblVal > -0.001 || vValue.dblVal < 0.001)
- sComment = _StringHelper::FormatNumber(vValue.dblVal, 6);
- else
- if(vValue.lVal < -999.0 || vValue.lVal > 999.0)
- sComment = _StringHelper::FormatNumber(vValue.dblVal, 1);
- break;
- #pragma endregion
- }
- #pragma endregion
- const HRESULT nChangeTypeResult = vValue.ChangeType(VT_BSTR);
- _Z45_HRESULT(nChangeTypeResult);
- if(FAILED(nChangeTypeResult))
- continue;
- sText.AppendFormat(_T(" * ") _T("`%s`: `%s`"), sName, CString(vValue.bstrVal));
- if(!sComment.IsEmpty())
- sText.AppendFormat(_T(" // %s"), sComment);
- sText.Append(_T("\r\n"));
- }
- return sText;
- }
- static ATL_DEPRECATED("Convert IPropertyBag2 into VARIANT using ISpy or CSpy instead") CString GetPropertyBagText(IPropertyBag2* pPropertyBag2)
- {
- _A(pPropertyBag2);
- CString sText;
- ULONG nPropertyCount = 0;
- __C(pPropertyBag2->CountProperties(&nPropertyCount));
- _Z4(atlTraceGeneral, 4, _T("nPropertyCount %d\n"), nPropertyCount);
- if(!nPropertyCount)
- return sText;
- #pragma region Read
- CTempBufferT pPropBags(nPropertyCount);
- ZeroMemory((PROPBAG2*) pPropBags, nPropertyCount * sizeof *pPropBags);
- ULONG nPropBagCount = 0;
- __C(pPropertyBag2->GetPropertyInfo(0, nPropertyCount, pPropBags, &nPropBagCount));
- _Z4(atlTraceGeneral, 4, _T("nPropBagCount %d\n"), nPropBagCount);
- CRoListT> NameList;
- for(ULONG nIndex = 0; nIndex < nPropBagCount; nIndex++)
- NameList.GetAt(NameList.AddTail()).Attach(pPropBags[nIndex].pstrName);
- CRoArrayT ValueArray;
- __D(ValueArray.SetCount(nPropBagCount), E_OUTOFMEMORY);
- CTempBufferT pnResults(nPropBagCount);
- __C(pPropertyBag2->Read(nPropBagCount, pPropBags, NULL, ValueArray.GetData(), pnResults));
- #pragma endregion
- CRoMapT Map;
- CRoArrayT NameArray;
- for(ULONG nIndex = 0; nIndex < nPropBagCount; nIndex++)
- if(SUCCEEDED(pnResults[nIndex]))
- {
- CString sName(pPropBags[nIndex].pstrName);
- _Z4(atlTraceGeneral, 4, _T("sName \"%s\"\n"), sName);
- NameArray.Add(sName);
- _W(Map.SetAt(sName, ValueArray[nIndex]));
- }
- return GetPropertyBagText(NameArray, Map);
- }
- static CString GetPropertyBagText(CComVariantArray& vValue)
- {
- if(vValue.vt <= VT_NULL)
- return _T("");
- CRoArrayT Array;
- vValue.ToElementArray(Array);
- CRoMapT Map;
- CRoArrayT NameArray;
- for(SIZE_T nIndex = 0; nIndex < Array.GetCount(); nIndex++)
- {
- CComVariantArray vPropertyName, vPropertyValue;
- Array[nIndex].ToElements(2, &vPropertyName, &vPropertyValue);
- __C(vPropertyName.ChangeType(VT_BSTR));
- CString sName(vPropertyName.bstrVal);
- _Z4(atlTraceGeneral, 4, _T("sName \"%s\"\n"), sName);
- NameArray.Add(sName);
- _W(Map.SetAt(sName, vPropertyValue));
- }
- return GetPropertyBagText(NameArray, Map);
- }
- static CString GetPropertyBagText(VARIANT vValue)
- {
- return GetPropertyBagText(reinterpret_cast(vValue));
- }
- static CString GetPropertyBagText(IUnknown* pBaseFilterUnknown, ISpy* pSpy = NULL)
- {
- const CComQIPtr pRunPropertyBagAware = pBaseFilterUnknown;
- CComQIPtr pEffectiveSpy = pSpy;
- if(!pEffectiveSpy && pRunPropertyBagAware)
- pEffectiveSpy = _FilterGraphHelper::GetFilterGraph(CComQIPtr(pBaseFilterUnknown));
- if(pEffectiveSpy)
- {
- CComVariantArray vValue;
- __C(pEffectiveSpy->ReadRunPropertyBag(pBaseFilterUnknown, ATL_VARIANT_TRUE, &vValue));
- return GetPropertyBagText(vValue);
- }
- if(!pRunPropertyBagAware)
- return _T("");
- return GetPropertyBagText(ReadRunPropertyBag(pRunPropertyBagAware));
- }
-};
Index: /trunk/DirectShowSpy/RunEvent.h
===================================================================
--- /trunk/DirectShowSpy/RunEvent.h (revision 290)
+++ /trunk/DirectShowSpy/RunEvent.h (revision 290)
@@ -0,0 +1,201 @@
+////////////////////////////////////////////////////////////
+// Copyright (C) Roman Ryltsov, 2008-2014
+// Created by Roman Ryltsov roman@alax.info, http://alax.info
+//
+// This source code is published to complement DirectShowSpy developer powertoy
+// and demonstrate the internal use of APIs and tricks powering the tool. It is
+// allowed to freely re-use the portions of the code in other projects, commercial
+// or otherwise (provided that you dont pretend that you wrote the original tool).
+//
+// Please keep in mind that DirectShowSpy is a developer tool, it is strongly recommended
+// that it is not shipped with release grade software. It is allowed to distribute
+// DirectShowSpy if only it is not registered with Windows by default and either
+// used privately, or registered on specific throubleshooting request. The advice applies
+// to hooking methods used by DirectShowSpy in general as well.
+
+#pragma once
+
+#include "DirectShowSpy_i.h"
+
+////////////////////////////////////////////////////////////
+// CRunEventHelper
+
+class CRunEventHelper
+{
+public:
+
+ ////////////////////////////////////////////////////////
+ // CEventsT, CEvents
+
+ template
+ class CEventsT
+ {
+ public:
+
+ ////////////////////////////////////////////////////
+ // CItem
+
+ class CItem
+ {
+ public:
+ ULONGLONG m_nTime;
+ CHAR m_pszText[t_nItemTextLength];
+
+ public:
+ // CItem
+ CComVariantArray GetAsVariant(ULONGLONG nTime) const
+ {
+ CComVariantArray vValue;
+ vValue.FromElements(2, CComVariant((LONG) (nTime - m_nTime) / 10000), CComVariant(m_pszText));
+ return vValue;
+ }
+ BOOL SetAsVariant(CComVariantArray& vValue)
+ {
+ if(vValue.vt != (VT_ARRAY | VT_VARIANT))
+ return FALSE;
+ _A(vValue.GetDimensionCount() == 1);
+ CRoArrayT Array;
+ vValue.ToElementArray(Array);
+ if(Array.GetCount() < 2)
+ return FALSE;
+ m_nTime = Array[0].GetAsType(VT_I4).lVal * 10000;
+ strncpy_s(m_pszText, CW2A(Array[1].GetAsType(VT_BSTR).bstrVal), _TRUNCATE);
+ return TRUE;
+ }
+ BOOL SetAsVariant(VARIANT vValue)
+ {
+ return SetAsVariant(reinterpret_cast(vValue));
+ }
+ CString GetText(ULONGLONG nTime) const
+ {
+ CString sText;
+ sText.AppendFormat(_T("%Id"), (LONG) (nTime - m_nTime));
+ sText.AppendChar(_T('\t'));
+ sText.Append(CA2CT(m_pszText));
+ return sText;
+ }
+ };
+
+ private:
+ mutable CRoLightCriticalSection m_DataCriticalSection;
+ BOOL m_bCapture;
+ CItem m_pItems[t_nItemCapacity];
+ SIZE_T m_nItemIndex;
+ SIZE_T m_nItemCount;
+ BOOL m_bTrace;
+ SIZE_T m_nTraceItemCount;
+
+ public:
+ // CEventsT
+ CEventsT() :
+ m_bCapture(FALSE),
+ m_bTrace(FALSE)
+ {
+ }
+ static SIZE_T GetCapacity()
+ {
+ return t_nItemCapacity;
+ }
+ BOOL IsCapture() const
+ {
+ CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
+ return m_bCapture;
+ }
+ VOID SetCapture(BOOL bCapture)
+ {
+ CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
+ if(m_bCapture == bCapture)
+ return;
+ m_bCapture = bCapture;
+ if(bCapture)
+ {
+ m_nItemIndex = 0;
+ m_nItemCount = 0;
+ }
+ }
+ VOID AddItemV(ULONGLONG nTime, LPCSTR pszFormat, va_list Arguments)
+ {
+ CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
+ if(!m_bCapture)
+ return;
+ CItem& Item = m_pItems[m_nItemIndex];
+ Item.m_nTime = nTime;
+ vsprintf_s(Item.m_pszText, pszFormat, Arguments);
+ if(m_nItemCount < t_nItemCapacity)
+ m_nItemCount++;
+ ++m_nItemIndex %= t_nItemCapacity;
+ if(m_bTrace && m_nTraceItemCount)
+ m_nTraceItemCount--;
+ }
+ VOID AddItem(ULONGLONG nTime, LPCSTR pszFormat, ...)
+ {
+ va_list Arguments;
+ va_start(Arguments, pszFormat);
+ AddItemV(pszFormat, Arguments);
+ va_end(Arguments);
+ }
+ VOID AddItem(LPCSTR pszFormat, ...)
+ {
+ va_list Arguments;
+ va_start(Arguments, pszFormat);
+ AddItemV(CMsAccurateFileTime::GetTime(), pszFormat, Arguments);
+ va_end(Arguments);
+ }
+ CComVariantArray GetAsVariant() const
+ {
+ CComVariantArray vValue;
+ CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
+ if(m_bCapture && m_nItemCount)
+ {
+ const ULONGLONG nTime = CMsAccurateFileTime::GetTime();
+ CRoArrayT Array;
+ Array.SetCount(0, (INT) m_nItemCount);
+ for(SIZE_T nItemIndex = 0; nItemIndex < m_nItemCount; nItemIndex++)
+ {
+ const CItem& Item = m_pItems[((m_nItemIndex - 1) - nItemIndex + t_nItemCapacity) % t_nItemCapacity];
+ Array.Add(Item.GetAsVariant(nTime));
+ }
+ vValue.FromElementArray(Array);
+ }
+ return vValue;
+ }
+ SIZE_T GetText(CRoArrayT& Array) const
+ {
+ _A(Array.IsEmpty());
+ CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
+ if(m_bCapture && m_nItemCount)
+ {
+ const ULONGLONG nTime = CMsAccurateFileTime::GetTime();
+ Array.SetCount(0, (INT) m_nItemCount);
+ for(SIZE_T nItemIndex = 0; nItemIndex < m_nItemCount; nItemIndex++)
+ {
+ const CItem& Item = m_pItems[((m_nItemIndex - 1) - nItemIndex + t_nItemCapacity) % t_nItemCapacity];
+ Array.Add(Item.GetText(nTime));
+ }
+ }
+ return Array.GetCount();
+ }
+ BOOL IsTrace() const
+ {
+ CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
+ return m_bTrace && !m_nTraceItemCount;
+ }
+ VOID SetTrace(BOOL bTrace, SIZE_T nTraceItemCount = 0)
+ {
+ CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
+ if(bTrace)
+ {
+ if(m_bTrace)
+ return; // Stick to Existing Schedule
+ m_bTrace = TRUE;
+ m_nTraceItemCount = nTraceItemCount;
+ } else
+ m_bTrace = FALSE;
+ }
+ };
+
+ typedef CEventsT<> CEvents;
+
+public:
+// CRunEventHelper
+};
Index: /trunk/DirectShowSpy/RunPropertyBag.h
===================================================================
--- /trunk/DirectShowSpy/RunPropertyBag.h (revision 290)
+++ /trunk/DirectShowSpy/RunPropertyBag.h (revision 290)
@@ -0,0 +1,298 @@
+////////////////////////////////////////////////////////////
+// Copyright (C) Roman Ryltsov, 2008-2014
+// Created by Roman Ryltsov roman@alax.info, http://alax.info
+//
+// This source code is published to complement DirectShowSpy developer powertoy
+// and demonstrate the internal use of APIs and tricks powering the tool. It is
+// allowed to freely re-use the portions of the code in other projects, commercial
+// or otherwise (provided that you dont pretend that you wrote the original tool).
+//
+// Please keep in mind that DirectShowSpy is a developer tool, it is strongly recommended
+// that it is not shipped with release grade software. It is allowed to distribute
+// DirectShowSpy if only it is not registered with Windows by default and either
+// used privately, or registered on specific throubleshooting request. The advice applies
+// to hooking methods used by DirectShowSpy in general as well.
+
+#pragma once
+
+#include "DirectShowSpy_i.h"
+#include "Common.h"
+
+////////////////////////////////////////////////////////////
+// CRunPropertyBagHelper
+
+class CRunPropertyBagHelper
+{
+public:
+
+ ////////////////////////////////////////////////////////
+ // CSimpleSortTraitsT
+
+ class CNameSortTraits :
+ public CSimpleSortTraitsT
+ {
+ public:
+ // CNameSortTraits
+ static INT_PTR CompareElements(const CString& sElementA, const CString& sElementB, PARAMETERARGUMENT Parameter)
+ {
+ return _tcsicmp(sElementA, sElementB);
+ }
+ };
+
+protected:
+ static CObjectPtr& PropertyBagNeeded(CObjectPtr& pPropertyBag)
+ {
+ if(!pPropertyBag)
+ pPropertyBag.Construct();
+ return pPropertyBag;
+ }
+
+public:
+// CRunPropertyBagHelper
+ static CComVariantArray ReadRunPropertyBag(IUnknown* pBaseFilterUnknown, BOOL bAllowExtension = TRUE)
+ {
+ CComVariantArray vValue;
+ CRoArrayT Array;
+ const CComQIPtr pRunPropertyBagAware = pBaseFilterUnknown;
+ CComQIPtr pPropertyBag2;
+ #pragma region Extension
+ if(!pRunPropertyBagAware && bAllowExtension)
+ {
+ CObjectPtr pPropertyBag;
+ #pragma region IQualProp
+ const CComQIPtr pQualProp = pBaseFilterUnknown;
+ if(pQualProp)
+ _ATLTRY
+ {
+ INT nFramesDroppedInRenderer, nFramesDrawn, nAvgFrameRate, nJitter, nAvgSyncOffset, nDevSyncOffset;
+ __C(pQualProp->get_FramesDroppedInRenderer(&nFramesDroppedInRenderer));
+ __C(pQualProp->get_FramesDrawn(&nFramesDrawn));
+ __C(pQualProp->get_AvgFrameRate(&nAvgFrameRate));
+ __C(pQualProp->get_Jitter(&nJitter));
+ __C(pQualProp->get_AvgSyncOffset(&nAvgSyncOffset));
+ __C(pQualProp->get_DevSyncOffset(&nDevSyncOffset));
+ PropertyBagNeeded(pPropertyBag);
+ pPropertyBag->WriteValue(_T("FramesDroppedInRenderer"), CComVariant((LONG) nFramesDroppedInRenderer));
+ pPropertyBag->WriteValue(_T("FramesDrawn"), CComVariant((LONG) nFramesDrawn));
+ pPropertyBag->WriteValue(_T("AvgFrameRate"), CComVariant((DOUBLE) nAvgFrameRate / 100));
+ pPropertyBag->WriteValue(_T("Jitter"), CComVariant((LONG) nJitter));
+ pPropertyBag->WriteValue(_T("AvgSyncOffset"), CComVariant((LONG) nAvgSyncOffset));
+ pPropertyBag->WriteValue(_T("DevSyncOffset"), CComVariant((LONG) nDevSyncOffset));
+ }
+ _ATLCATCHALL()
+ {
+ _Z_EXCEPTION();
+ }
+ #pragma endregion
+ #pragma region IAMAudioRendererStats
+ const CComQIPtr pAmAudioRendererStats = pBaseFilterUnknown;
+ if(pAmAudioRendererStats)
+ _ATLTRY
+ {
+ DWORD nDummy;
+ DWORD nBreakCount, nSlaveMode, nSilenceDuration, nLastBufferDuration, nDiscontinuityCount, nSlaveRate, nDropWriteDuration;
+ DWORD nHighestSlaveError, nLowestSlaveError, nLastHighSlaveError, nLastLowSlaveError;
+ DWORD nAccumulatedError, nBufferFullness;
+ //DWORD nJitter;
+ __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_BREAK_COUNT, &nBreakCount, &nDummy));
+ __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_SLAVE_MODE, &nSlaveMode, &nDummy));
+ __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_SILENCE_DUR, &nSilenceDuration, &nDummy));
+ __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_LAST_BUFFER_DUR, &nLastBufferDuration, &nDummy));
+ __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_DISCONTINUITIES, &nDiscontinuityCount, &nDummy));
+ if(nSlaveMode)
+ {
+ __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_SLAVE_RATE, &nSlaveRate, &nDummy));
+ __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_SLAVE_DROPWRITE_DUR, &nDropWriteDuration, &nDummy));
+ __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_SLAVE_HIGHLOWERROR, &nHighestSlaveError, &nLowestSlaveError));
+ __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_SLAVE_LASTHIGHLOWERROR, &nLastHighSlaveError, &nLastLowSlaveError));
+ __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_SLAVE_ACCUMERROR, &nAccumulatedError, &nDummy));
+ }
+ __C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_BUFFERFULLNESS, &nBufferFullness, &nDummy));
+ //__C(pAmAudioRendererStats->GetStatParam(AM_AUDREND_STAT_PARAM_JITTER, &nJitter, &nDummy));
+ PropertyBagNeeded(pPropertyBag);
+ pPropertyBag->WriteValue(_T("BreakCount"), CComVariant((LONG) nBreakCount));
+ pPropertyBag->WriteValue(_T("SlaveMode"), CComVariant((LONG) nSlaveMode));
+ pPropertyBag->WriteValue(_T("SilenceDuration"), CComVariant((LONG) nSilenceDuration));
+ pPropertyBag->WriteValue(_T("LastBufferDuration"), CComVariant((LONG) nLastBufferDuration));
+ pPropertyBag->WriteValue(_T("DiscontinuityCount"), CComVariant((LONG) nDiscontinuityCount));
+ if(nSlaveMode)
+ {
+ pPropertyBag->WriteValue(_T("SlaveRate"), CComVariant((LONG) nSlaveRate));
+ pPropertyBag->WriteValue(_T("DropWriteDuration"), CComVariant((LONG) nDropWriteDuration));
+ pPropertyBag->WriteValue(_T("HighestSlaveError"), CComVariant((LONG) nHighestSlaveError));
+ pPropertyBag->WriteValue(_T("LowestSlaveError"), CComVariant((LONG) nLowestSlaveError));
+ pPropertyBag->WriteValue(_T("LastHighSlaveError"), CComVariant((LONG) nLastHighSlaveError));
+ pPropertyBag->WriteValue(_T("LastLowSlaveError"), CComVariant((LONG) nLastLowSlaveError));
+ pPropertyBag->WriteValue(_T("AccumulatedError"), CComVariant((LONG) nAccumulatedError));
+ }
+ pPropertyBag->WriteValue(_T("BufferFullness"), CComVariant((LONG) nBufferFullness));
+ //pPropertyBag->WriteValue(_T("Jitter"), CComVariant((LONG) nJitter));
+ }
+ _ATLCATCHALL()
+ {
+ _Z_EXCEPTION();
+ }
+ #pragma endregion
+ if(pPropertyBag)
+ pPropertyBag2 = pPropertyBag;
+ }
+ #pragma endregion
+ if(!pPropertyBag2 && pRunPropertyBagAware)
+ {
+ CComPtr pPropertyBagUnknown;
+ __C(pRunPropertyBagAware->get_Value(&pPropertyBagUnknown));
+ pPropertyBag2 = pPropertyBagUnknown;
+ }
+ if(pPropertyBag2)
+ {
+ ULONG nPropertyCount = 0;
+ __C(pPropertyBag2->CountProperties(&nPropertyCount));
+ _Z4(atlTraceGeneral, 4, _T("nPropertyCount %d\n"), nPropertyCount);
+ if(nPropertyCount)
+ {
+ CTempBufferT pPropBags(nPropertyCount);
+ ZeroMemory((PROPBAG2*) pPropBags, nPropertyCount * sizeof *pPropBags);
+ ULONG nPropBagCount = 0;
+ __C(pPropertyBag2->GetPropertyInfo(0, nPropertyCount, pPropBags, &nPropBagCount));
+ _Z4(atlTraceGeneral, 4, _T("nPropBagCount %d\n"), nPropBagCount);
+ CRoListT> NameList;
+ for(ULONG nIndex = 0; nIndex < nPropBagCount; nIndex++)
+ NameList.GetAt(NameList.AddTail()).Attach(pPropBags[nIndex].pstrName);
+ CRoArrayT ValueArray;
+ __D(ValueArray.SetCount(nPropBagCount), E_OUTOFMEMORY);
+ CTempBufferT pnResults(nPropBagCount);
+ __C(pPropertyBag2->Read(nPropBagCount, pPropBags, NULL, ValueArray.GetData(), pnResults));
+ for(ULONG nIndex = 0; nIndex < nPropBagCount; nIndex++)
+ if(SUCCEEDED(pnResults[nIndex]))
+ {
+ CString sName(pPropBags[nIndex].pstrName);
+ _Z4(atlTraceGeneral, 4, _T("sName \"%s\"\n"), sName);
+ CComVariantArray vPropertyValue;
+ Array.Add(vPropertyValue.FromElements(2, CComVariant(sName), ValueArray[nIndex]));
+ }
+ vValue.FromElementArray(Array);
+ }
+ }
+ return vValue;
+ }
+ static CString GetPropertyBagText(CRoArrayT& NameArray, CRoMapT& Map)
+ {
+ CString sText;
+ _SortHelper::QuickSort(NameArray);
+ // SUGG: Nicer similar names, taking prefix at dot separator, also changing Foo-A-B into Foo (A; B)
+ for(SIZE_T nIndex = 0; nIndex < NameArray.GetCount(); nIndex++)
+ {
+ const CString& sName = NameArray[nIndex];
+ _Z4(atlTraceGeneral, 4, _T("sName \"%s\"\n"), sName);
+ CString sValue;
+ CComVariantArray vValue;
+ if(!Map.Lookup(sName, vValue))
+ continue;
+ CString sComment;
+ #pragma region Friendly Comment
+ switch(vValue.vt)
+ {
+ #pragma region VT_I4
+ case VT_I4:
+ if(vValue.lVal < -999 || vValue.lVal > 999)
+ sComment = _StringHelper::FormatNumber(vValue.lVal);
+ break;
+ #pragma endregion
+ #pragma region VT_R8
+ case VT_R8:
+ if(vValue.dblVal > -0.001 || vValue.dblVal < 0.001)
+ sComment = _StringHelper::FormatNumber(vValue.dblVal, 6);
+ else
+ if(vValue.lVal < -999.0 || vValue.lVal > 999.0)
+ sComment = _StringHelper::FormatNumber(vValue.dblVal, 1);
+ break;
+ #pragma endregion
+ }
+ #pragma endregion
+ const HRESULT nChangeTypeResult = vValue.ChangeType(VT_BSTR);
+ _Z45_HRESULT(nChangeTypeResult);
+ if(FAILED(nChangeTypeResult))
+ continue;
+ sText.AppendFormat(_T(" * ") _T("`%s`: `%s`"), sName, CString(vValue.bstrVal));
+ if(!sComment.IsEmpty())
+ sText.AppendFormat(_T(" // %s"), sComment);
+ sText.Append(_T("\r\n"));
+ }
+ return sText;
+ }
+ static ATL_DEPRECATED("Convert IPropertyBag2 into VARIANT using ISpy or CSpy instead") CString GetPropertyBagText(IPropertyBag2* pPropertyBag2)
+ {
+ _A(pPropertyBag2);
+ CString sText;
+ ULONG nPropertyCount = 0;
+ __C(pPropertyBag2->CountProperties(&nPropertyCount));
+ _Z4(atlTraceGeneral, 4, _T("nPropertyCount %d\n"), nPropertyCount);
+ if(!nPropertyCount)
+ return sText;
+ #pragma region Read
+ CTempBufferT pPropBags(nPropertyCount);
+ ZeroMemory((PROPBAG2*) pPropBags, nPropertyCount * sizeof *pPropBags);
+ ULONG nPropBagCount = 0;
+ __C(pPropertyBag2->GetPropertyInfo(0, nPropertyCount, pPropBags, &nPropBagCount));
+ _Z4(atlTraceGeneral, 4, _T("nPropBagCount %d\n"), nPropBagCount);
+ CRoListT> NameList;
+ for(ULONG nIndex = 0; nIndex < nPropBagCount; nIndex++)
+ NameList.GetAt(NameList.AddTail()).Attach(pPropBags[nIndex].pstrName);
+ CRoArrayT ValueArray;
+ __D(ValueArray.SetCount(nPropBagCount), E_OUTOFMEMORY);
+ CTempBufferT pnResults(nPropBagCount);
+ __C(pPropertyBag2->Read(nPropBagCount, pPropBags, NULL, ValueArray.GetData(), pnResults));
+ #pragma endregion
+ CRoMapT Map;
+ CRoArrayT NameArray;
+ for(ULONG nIndex = 0; nIndex < nPropBagCount; nIndex++)
+ if(SUCCEEDED(pnResults[nIndex]))
+ {
+ CString sName(pPropBags[nIndex].pstrName);
+ _Z4(atlTraceGeneral, 4, _T("sName \"%s\"\n"), sName);
+ NameArray.Add(sName);
+ _W(Map.SetAt(sName, ValueArray[nIndex]));
+ }
+ return GetPropertyBagText(NameArray, Map);
+ }
+ static CString GetPropertyBagText(CComVariantArray& vValue)
+ {
+ if(vValue.vt <= VT_NULL)
+ return _T("");
+ CRoArrayT Array;
+ vValue.ToElementArray(Array);
+ CRoMapT Map;
+ CRoArrayT NameArray;
+ for(SIZE_T nIndex = 0; nIndex < Array.GetCount(); nIndex++)
+ {
+ CComVariantArray vPropertyName, vPropertyValue;
+ Array[nIndex].ToElements(2, &vPropertyName, &vPropertyValue);
+ __C(vPropertyName.ChangeType(VT_BSTR));
+ CString sName(vPropertyName.bstrVal);
+ _Z4(atlTraceGeneral, 4, _T("sName \"%s\"\n"), sName);
+ NameArray.Add(sName);
+ _W(Map.SetAt(sName, vPropertyValue));
+ }
+ return GetPropertyBagText(NameArray, Map);
+ }
+ static CString GetPropertyBagText(VARIANT vValue)
+ {
+ return GetPropertyBagText(reinterpret_cast(vValue));
+ }
+ static CString GetPropertyBagText(IUnknown* pBaseFilterUnknown, ISpy* pSpy = NULL)
+ {
+ const CComQIPtr pRunPropertyBagAware = pBaseFilterUnknown;
+ CComQIPtr pEffectiveSpy = pSpy;
+ if(!pEffectiveSpy && pRunPropertyBagAware)
+ pEffectiveSpy = _FilterGraphHelper::GetFilterGraph(CComQIPtr(pBaseFilterUnknown));
+ if(pEffectiveSpy)
+ {
+ CComVariantArray vValue;
+ __C(pEffectiveSpy->ReadRunPropertyBag(pBaseFilterUnknown, ATL_VARIANT_TRUE, &vValue));
+ return GetPropertyBagText(vValue);
+ }
+ if(!pRunPropertyBagAware)
+ return _T("");
+ return GetPropertyBagText(ReadRunPropertyBag(pRunPropertyBagAware));
+ }
+};
Index: /trunk/DirectShowSpy/resource.h
===================================================================
--- /trunk/DirectShowSpy/resource.h (revision 289)
+++ /trunk/DirectShowSpy/resource.h (revision 290)
@@ -101,9 +101,15 @@
#define IDC_FILTERGRAPHHELPER_EMAIL_LOG_DELETETITLE 1812
#define IDC_FILTERGRAPHHELPER_EMAIL_LOG_DELETE 1813
-#define IDR_GENERIC_RUNPROPERTYBAGPROPERTYPAGE 1900
+#define IDR_GENERIC_RUNPROPERTYBAG_PROPERTYPAGE 1900
#define IDD_GENERIC_RUNPROPERTYBAG 1910
-#define IDC_GENERIC_RUNPROPERTYBAG_INTRODUCTION 1911
-#define IDC_GENERIC_RUNPROPERTYBAG_TEXT 1912
-#define IDC_GENERIC_RUNPROPERTYBAG_REFRESH 1913
+#define IDC_GENERIC_RUNPROPERTYBAG_INTRODUCTION 1915
+#define IDC_GENERIC_RUNPROPERTYBAG_TEXT 1916
+#define IDC_GENERIC_RUNPROPERTYBAG_REFRESH 1917
+#define IDR_GENERIC_RUNEVENT_PROPERTYPAGE 1950
+#define IDD_GENERIC_RUNEVENT 1960
+#define IDC_GENERIC_RUNEVENT_CAPTURE 1965
+#define IDC_GENERIC_RUNEVENT_TEXT 1966
+#define IDC_GENERIC_RUNEVENT_REFRESH 1967
+
#define IDR_FILTERGRAPHSPY 25000
#define IDR_NOTHREADFILTERGRAPHSPY 25001