Exemple de DLL de plug-in d’unité d’extension
Important
Le contenu et l’exemple de code de cette rubrique sont obsolètes et actuellement non pris en charge. Il peut ne pas fonctionner avec la chaîne d’outils de développement de pilote actuelle.
Cette rubrique contient un exemple de code pour une DLL de plug-in d’unité d’extension qui expose une API COM au-dessus d’un jeu de propriétés KS.
L’exemple définit une classe appelée CExtension, qui dérive de CNodeControl. L’implémentation de la classe CNodeControl est également fournie ultérieurement. CNodeControl dérive de l’interface IKsNodeControl fournie par Microsoft, qui est définie dans Vidcap.h.
Vidcap.ax utilise IKsNodeControl pour informer le plug-in de l’ID du nœud d’extension et lui fournir une instance d’IKsControl. Plus précisément, le plug-in reçoit ces informations par le biais d’appels à CExtension::p ut_NodeId et CExtension::p ut_KsControl. Vous trouverez les implémentations possibles de ces méthodes plus loin dans cette rubrique pour la classe parente CNodeControl.
Vidcap.h apparaît dans le Kit de développement logiciel (SDK) DirectX d’été 2004 via le Kit de développement logiciel (SDK) DirectX de février 2005. Lors de l’installation de ces packages, vous devez installer les extras pour obtenir Vidcap.h.
Dans Windows Vista et les versions ultérieures, Vidcap.h est inclus dans le Microsoft Windows SDK.
Incluez le code suivant dans le fichier d’en-tête de classe, nommé arbitrairement 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)
Implémentez les deux méthodes virtuelles de IKsNodeControl dans CNodeControl. Ces méthodes sont ensuite héritées par les instances de la classe CExtension .
Le code suivant se trouve dans un fichier source nommé arbitrairement 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;
}
Incluez également des implémentations des méthodes de CExtension dans le même fichier Xuproxy.cpp :
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;
}