Matriz de plantillas de fábrica
[La característica asociada a esta página, DirectShow, es una característica heredada. Se ha reemplazado por MediaPlayer, IMFMediaEngine y Captura de audio/vídeo en Media Foundation. Esas características se han optimizado para Windows 10 y Windows 11. Microsoft recomienda encarecidamente que el nuevo código use MediaPlayer, IMFMediaEngine y Audio/Video Capture en Media Foundation en lugar de DirectShow, siempre que sea posible. Microsoft sugiere que el código existente que usa las API heredadas se reescriba para usar las nuevas API si es posible.
La plantilla de fábrica contiene las siguientes variables miembro públicas:
const WCHAR * m_Name; // Name
const CLSID * m_ClsID; // CLSID
LPFNNewCOMObject m_lpfnNew; // Function to create an instance
// of the component
LPFNInitRoutine m_lpfnInit; // Initialization function (optional)
const AMOVIESETUP_FILTER * m_pAMovieSetup_Filter; // Set-up information (for filters)
Los dos punteros de función, m_lpfnNew y m_lpfnInit, usan las siguientes definiciones de tipo:
typedef CUnknown *(CALLBACK *LPFNNewCOMObject)(LPUNKNOWN pUnkOuter, HRESULT *phr);
typedef void (CALLBACK *LPFNInitRoutine)(BOOL bLoading, const CLSID *rclsid);
La primera es la función de creación de instancias del componente. El segundo es una función de inicialización opcional. Si proporciona una función de inicialización, se llama desde dentro de la función de punto de entrada dll. (La función de punto de entrada dll se describe más adelante en este artículo).
Supongamos que va a crear un archivo DLL que contenga un componente denominado CMyComponent, que hereda de CUnknown. Debe proporcionar los siguientes elementos en el archivo DLL:
- La función de inicialización, un método público que devuelve una nueva instancia de CMyComponent.
- Matriz global de plantillas de fábrica, denominada g_Templates. Esta matriz contiene la plantilla de fábrica para CMyComponent.
- Variable global denominada g_cTemplates que especifica el tamaño de la matriz.
En el ejemplo siguiente se muestra cómo declarar estos elementos:
// Public method that returns a new instance.
CUnknown * WINAPI CMyComponent::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr)
{
CMyComponent *pNewObject = new CMyComponent(NAME("My Component"), pUnk, pHr );
if (pNewObject == NULL) {
*pHr = E_OUTOFMEMORY;
}
return pNewObject;
}
CFactoryTemplate g_Templates[1] =
{
{
L"My Component", // Name
&CLSID_MyComponent, // CLSID
CMyComponent::CreateInstance, // Method to create an instance of MyComponent
NULL, // Initialization function
NULL // Set-up information (for filters)
}
};
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
El CreateInstance
método llama al constructor de clase y devuelve un puntero a la nueva instancia de clase. El parámetro pUnk es un puntero a la agregación de IUnknown. Simplemente puede pasar este parámetro al constructor de clase. El parámetro pHr es un puntero a un valor HRESULT. El constructor de clase establece este valor en un valor adecuado, pero si se produce un error en el constructor, establezca el valor en E_OUTOFMEMORY.
La macro NAME genera una cadena en compilaciones de depuración, pero se resuelve en NULL en compilaciones comerciales. Se usa en este ejemplo para asignar al componente un nombre que aparece en los registros de depuración, pero no ocupa memoria en la versión final.
El CreateInstance
método puede tener cualquier nombre, ya que el generador de clases hace referencia al puntero de función de la plantilla de fábrica. Sin embargo, g_Templates y g_cTemplates son variables globales que el generador de clases espera encontrar, por lo que deben tener exactamente esos nombres.
Temas relacionados