Beispiel-Erweiterungseinheit-Plug-In-DLL
Wichtig
Der Inhalt und der Beispielcode in diesem Thema sind veraltet und werden derzeit nicht unterstützt. Dies funktioniert möglicherweise nicht mit der aktuellen Toolkette für die Treiberentwicklung.
Dieses Thema enthält Beispielcode für eine Erweiterungseinheit-Plug-In-DLL, die eine COM-API zusätzlich zu einem KS-Eigenschaftensatz verfügbar macht.
Im Beispiel wird eine Klasse namens CExtension definiert, die von CNodeControl abgeleitet wird. Die Implementierung der CNodeControl-Klasse wird später ebenfalls bereitgestellt. CNodeControl wird von der von Microsoft bereitgestellten IKsNodeControl-Schnittstelle abgeleitet, die in Vidcap.h definiert ist.
Vidcap.ax verwendet IKsNodeControl, um das Plug-In über die Erweiterungsknoten-ID zu informieren und eine instance von IKsControl bereitzustellen. Insbesondere empfängt das Plug-In diese Informationen durch Aufrufe von CExtension::p ut_NodeId und CExtension::p ut_KsControl. Mögliche Implementierungen dieser Methoden finden Sie weiter unten in diesem Thema für die übergeordnete Klasse CNodeControl.
Vidcap.h wird im DirectX SDK im Sommer 2004 bis zum DirectX SDK vom Februar 2005 angezeigt. Wenn Sie diese Pakete installieren, müssen Sie die Extras installieren, um Vidcap.h zu erhalten.
In Windows Vista und höheren Versionen ist Vidcap.h als Teil der Microsoft Windows SDK enthalten.
Fügen Sie den folgenden Code in die Klassenheaderdatei ein, mit dem Namen Xuproxy.h:
#include <ks.h>
#include <ksproxy.h>
#include <C:\Program Files\Microsoft DirectX 9.0 SDK (February 2005)\Extras\DirectShow\Include\vidcap.h>
#include <C:\Program Files\Microsoft DirectX 9.0 SDK (February 2005)\Extras\DirectShow\Include\ksmedia.h>
DEFINE_GUID(CLSID_ExtensionUnit, 0xzzzzzzzz, 0xzzzz, 0xzzzz, 0xzz, 0xzz, 0xzz, 0xzz, 0xzz, 0xzz, 0xzz, 0xzz);
class CNodeControl :
public IKsNodeControl
{
public:
STDMETHOD(put_NodeId) (DWORD dwNodeId);
STDMETHOD(put_KsControl) (PVOID pKsControl);
DWORD m_dwNodeId;
CComPtr<IKsControl> m_pKsControl;
};
class CExtension :
public IExtensionUnit,
public CComObjectRootEx<CComObjectThreadModel>,
public CComCoClass<CExtension, &CLSID_ExtensionUnit>,
public CNodeControl
{
public:
CExtension();
STDMETHOD(FinalConstruct)();
BEGIN_COM_MAP(CExtension)
COM_INTERFACE_ENTRY(IKsNodeControl)
COM_INTERFACE_ENTRY(IExtensionUnit)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
DECLARE_NO_REGISTRY()
DECLARE_ONLY_AGGREGATABLE(CExtension)
// IExtensionUnit
public:
STDMETHOD (get_Info)(
ULONG ulSize,
BYTE pInfo[]);
STDMETHOD (get_InfoSize)(
ULONG *pulSize);
STDMETHOD (get_PropertySize)(
ULONG PropertyId,
ULONG *pulSize);
STDMETHOD (get_Property)(
ULONG PropertyId,
ULONG ulSize,
BYTE pValue[]);
STDMETHOD (put_Property)(
ULONG PropertyId,
ULONG ulSize,
BYTE pValue[]);
STDMETHOD (get_PropertyRange)(
ULONG PropertyId,
ULONG ulSize,
BYTE pMin[],
BYTE pMax[],
BYTE pSteppingDelta[],
BYTE pDefault[]);
};
#define STATIC_PROPSETID_VIDCAP_EXTENSION_UNIT \
0xXXXXXXXX,0xXXXX,0xXXXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX,0xXX
DEFINE_GUIDSTRUCT("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", \
PROPSETID_VIDCAP_EXTENSION_UNIT);
#define PROPSETID_VIDCAP_EXTENSION_UNIT \
DEFINE_GUIDNAMED(PROPSETID_VIDCAP_EXTENSION_UNIT)
Implementieren Sie die beiden virtuellen Methoden aus IKsNodeControl in CNodeControl. Diese Methoden werden dann von Instanzen der CExtension-Klasse geerbt.
Der folgende Code befindet sich in einer Quelldatei mit dem Namen Xuproxy.cpp:
STDMETHODIMP
CNodeControl::put_NodeId(
DWORD dwNodeId)
{
m_dwNodeId = dwNodeId;
return S_OK;
}
STDMETHODIMP
CNodeControl::put_KsControl(
PVOID pKsControl)
{
HRESULT hr = S_OK;
IKsControl *pIKsControl;
if (!pKsControl) return E_POINTER;
pIKsControl = (IKsControl *) pKsControl;
if (m_pKsControl) m_pKsControl.Release();
hr = pIKsControl->QueryInterface(__uuidof(IKsControl),
(void **) &m_pKsControl);
return hr;
}
Schließen Sie auch Implementierungen der CExtension-Methoden in derselben Xuproxy.cpp-Datei ein:
CExtension::CExtension()
{
m_pKsControl = NULL;
}
STDMETHODIMP
CExtension::FinalConstruct()
{
if (m_pOuterUnknown == NULL ) return E_FAIL;
return S_OK;
}
STDMETHODIMP
CExtension::get_InfoSize(
ULONG *pulSize)
{
HRESULT hr = S_OK;
ULONG ulBytesReturned;
KSP_NODE ExtensionProp;
if (!pulSize) return E_POINTER;
ExtensionProp.Property.Set = PROPSETID_VIDCAP_EXTENSION_UNIT;
ExtensionProp.Property.Id = KSPROPERTY_EXTENSION_UNIT_INFO;
ExtensionProp.Property.Flags = KSPROPERTY_TYPE_GET |
KSPROPERTY_TYPE_TOPOLOGY;
ExtensionProp.NodeId = m_dwNodeId;
hr = m_pKsControl->KsProperty(
(PKSPROPERTY) &ExtensionProp,
sizeof(ExtensionProp),
NULL,
0,
&ulBytesReturned);
if (hr == HRESULT_FROM_WIN32(ERROR_MORE_DATA))
{
*pulSize = ulBytesReturned;
hr = S_OK;
}
return hr;
}
STDMETHODIMP
CExtension::get_Info(
ULONG ulSize,
BYTE pInfo[])
{
HRESULT hr = S_OK;
KSP_NODE ExtensionProp;
ULONG ulBytesReturned;
ExtensionProp.Property.Set = PROPSETID_VIDCAP_EXTENSION_UNIT;
ExtensionProp.Property.Id = KSPROPERTY_EXTENSION_UNIT_INFO;
ExtensionProp.Property.Flags = KSPROPERTY_TYPE_GET |
KSPROPERTY_TYPE_TOPOLOGY;
ExtensionProp.NodeId = m_dwNodeId;
hr = m_pKsControl->KsProperty(
(PKSPROPERTY) &ExtensionProp,
sizeof(ExtensionProp),
(PVOID) pInfo,
ulSize,
&ulBytesReturned);
return hr;
}
STDMETHODIMP
CExtension::get_PropertySize(
ULONG PropertyId,
ULONG *pulSize)
{
HRESULT hr = S_OK;
ULONG ulBytesReturned;
KSP_NODE ExtensionProp;
if (!pulSize) return E_POINTER;
ExtensionProp.Property.Set = PROPSETID_VIDCAP_EXTENSION_UNIT;
ExtensionProp.Property.Id = PropertyId;
ExtensionProp.Property.Flags = KSPROPERTY_TYPE_GET |
KSPROPERTY_TYPE_TOPOLOGY;
ExtensionProp.NodeId = m_dwNodeId;
hr = m_pKsControl->KsProperty(
(PKSPROPERTY) &ExtensionProp,
sizeof(ExtensionProp),
NULL,
0,
&ulBytesReturned);
if (hr == HRESULT_FROM_WIN32(ERROR_MORE_DATA))
{
*pulSize = ulBytesReturned;
hr = S_OK;
}
return hr;
}
STDMETHODIMP
CExtension::get_Property(
ULONG PropertyId,
ULONG ulSize,
BYTE pValue[])
{
HRESULT hr = S_OK;
KSP_NODE ExtensionProp;
ULONG ulBytesReturned;
ExtensionProp.Property.Set = PROPSETID_VIDCAP_EXTENSION_UNIT;
ExtensionProp.Property.Id = PropertyId;
ExtensionProp.Property.Flags = KSPROPERTY_TYPE_GET |
KSPROPERTY_TYPE_TOPOLOGY;
ExtensionProp.NodeId = m_dwNodeId;
hr = m_pKsControl->KsProperty(
(PKSPROPERTY) &ExtensionProp,
sizeof(ExtensionProp),
(PVOID) pValue,
ulSize,
&ulBytesReturned);
return hr;
}
STDMETHODIMP
CExtension::put_Property(
ULONG PropertyId,
ULONG ulSize,
BYTE pValue[])
{
HRESULT hr = S_OK;
KSP_NODE ExtensionProp;
ULONG ulBytesReturned;
ExtensionProp.Property.Set = PROPSETID_VIDCAP_EXTENSION_UNIT;
ExtensionProp.Property.Id = PropertyId;
ExtensionProp.Property.Flags = KSPROPERTY_TYPE_SET |
KSPROPERTY_TYPE_TOPOLOGY;
ExtensionProp.NodeId = m_dwNodeId;
hr = m_pKsControl->KsProperty(
(PKSPROPERTY) &ExtensionProp,
sizeof(ExtensionProp),
(PVOID) pValue,
ulSize,
&ulBytesReturned);
return hr;
}
STDMETHODIMP
CExtension::get_PropertyRange(
ULONG PropertyId,
ULONG ulSize,
BYTE pMin[ ],
BYTE pMax[ ],
BYTE pSteppingDelta[ ],
BYTE pDefault[ ])
{
// IHV may add code here, current stub just returns S_OK
HRESULT hr = S_OK;
return hr;
}
CExtension::CExtension()
{
m_pKsControl = NULL;
}
STDMETHODIMP
CExtension::FinalConstruct()
{
if (m_pOuterUnknown == NULL) return E_FAIL;
return S_OK;
}