#ifndef _DCOMPFACTORY_H_
#define _DCOMPFACTORY_H_
#ifdef _WIN32
#include <Unknwnbase.h>
namespace D2DRENDER
{
// COM接口化
// {E1818A78-D4DD-4234-ACA1-15BFD37E80CB}
// IMPLEMENT_OLECREATE(<< class >> , << external_name >> ,
// 0xe1818a78, 0xd4dd, 0x4234, 0xac, 0xa1, 0x15, 0xbf, 0xd3, 0x7e, 0x80, 0xcb);
MIDL_INTERFACE("E1818A78-D4DD-4234-ACA1-15BFD37E80CB")
IDcompFactory :public IUnknown
{
STDMETHOD_(HRESULT, QueryInterface)(REFIID riid, void** ppvObject)PURE;
STDMETHOD_(ULONG, AddRef)()PURE;
STDMETHOD_(ULONG, Release)()PURE;
STDMETHOD(DCompositionCreateDevice)(IUnknown* dxgiDevice, REFIID iid, void** device)PURE;
};
// {CE28B6E9-665D-464F-A613-43A46830BBBF}
// IMPLEMENT_OLECREATE(<< class >> , << external_name >> ,
// 0xce28b6e9, 0x665d, 0x464f, 0xa6, 0x13, 0x43, 0xa4, 0x68, 0x30, 0xbb, 0xbf);
MIDL_INTERFACE("CE28B6E9-665D-464F-A613-43A46830BBBF")
IDcompFactory1 :public IDcompFactory
{
STDMETHOD(DCompositionCreateDevice2)(IUnknown* d2dDevice, REFIID iid, void** device)PURE;
};
IDcompFactory* CoCreateDcompFactory();
}
#endif //_WIN32
#endif // !_DCOMPFACTORY_H_
#include "DcompFactory.h"
#include "SystemDetector.h"
#include <dxgi.h>
#include <d2d1_1.h>
using namespace D2DRENDER;
// 匹配 dcomp.h 中的 DCompositionCreateDevice 函数原型
typedef HRESULT(WINAPI* fDCompositionCreateDevice)(
IDXGIDevice* dxgiDevice,
REFIID riid,
void** ppv
);
// 匹配 dcomp.h 中的 DCompositionCreateDevice2 函数原型
typedef HRESULT(WINAPI* fDCompositionCreateDevice2)(
IUnknown* renderingDevice,
REFIID riid,
void** ppv
);
class CDcompFactory1;
class CDcompFactory : public IDcompFactory
{
friend class CDcompFactory1;
public:
CDcompFactory();
~CDcompFactory();
STDMETHOD_(HRESULT, QueryInterface)(REFIID riid, void** ppvObject);
STDMETHOD_(ULONG, AddRef)();
STDMETHOD_(ULONG, Release)();
STDMETHOD(DCompositionCreateDevice)(IUnknown* dxgiDevice, REFIID riid, void** ppv);
private:
DWORD m_dwRefCount;
HMODULE m_hModule;
fDCompositionCreateDevice m_pfDCompositionCreateDevice;
};
CDcompFactory::CDcompFactory():
m_dwRefCount(0),
m_hModule(nullptr),
m_pfDCompositionCreateDevice(nullptr)
{
m_hModule = LoadLibrary("dcomp.dll");
if (m_hModule)
{
m_pfDCompositionCreateDevice = (fDCompositionCreateDevice)GetProcAddress(m_hModule, "DCompositionCreateDevice");
}
//else 当前系统小于win8
}
CDcompFactory::~CDcompFactory()
{
if(m_hModule)FreeLibrary(m_hModule);
}
STDMETHODIMP CDcompFactory::QueryInterface(REFIID riid, void** ppvObject)
{
if (riid == __uuidof(IDcompFactory))
{
*ppvObject = this;
AddRef();
return S_OK;
}
else
{
*ppvObject = nullptr;
return E_NOINTERFACE;
}
}
STDMETHODIMP_(ULONG) CDcompFactory::AddRef()
{
return InterlockedIncrement(&m_dwRefCount);
}
STDMETHODIMP_(ULONG) CDcompFactory::Release()
{
ULONG ulCount = InterlockedDecrement(&m_dwRefCount);
if (ulCount == 0)
{
delete this;
}
return ulCount;
}
STDMETHODIMP CDcompFactory::DCompositionCreateDevice(IUnknown* dxgiDevice, REFIID riid, void** ppv)
{
IDXGIDevice* pDXGIDevice = nullptr;
if ( !dxgiDevice || FAILED(dxgiDevice->QueryInterface(IID_PPV_ARGS(&pDXGIDevice))) )
{
return E_INVALIDARG;
}
if (m_pfDCompositionCreateDevice == nullptr)
{
pDXGIDevice->Release();
return E_NOINTERFACE;
}
HRESULT hr = m_pfDCompositionCreateDevice(pDXGIDevice, riid, ppv);
pDXGIDevice->Release();
return hr;
}
/***************************************************************************************************************************************************/
class CDcompFactory1 : public IDcompFactory1
{
public:
CDcompFactory1():
m_dwRefCount(0),
m_pfDCompositionCreateDevice2(nullptr)
{
if (m_dcompFactory.m_hModule)//检测模块是否已经加载
{
m_pfDCompositionCreateDevice2 = (fDCompositionCreateDevice2)GetProcAddress(m_dcompFactory.m_hModule, "DCompositionCreateDevice2");
}
//else 当前系统小于win8
}
STDMETHOD_(HRESULT, QueryInterface)(REFIID riid, void** ppvObject)
{
if (riid == __uuidof(IDcompFactory))
{
*ppvObject = &m_dcompFactory;
m_dcompFactory.AddRef();
return S_OK;
}
if (riid == __uuidof(IDcompFactory1))
{
*ppvObject = this;
AddRef();
return S_OK;
}
else
{
*ppvObject = nullptr;
return E_NOINTERFACE;
}
}
STDMETHOD_(ULONG, AddRef)()
{
return InterlockedIncrement(&m_dwRefCount);
}
STDMETHOD_(ULONG, Release)()
{
ULONG ulCount = InterlockedDecrement(&m_dwRefCount);
if (ulCount == 0)
{
delete this;
}
return ulCount;
}
STDMETHOD(DCompositionCreateDevice)(IUnknown* dxgiDevice, REFIID riid, void** ppv)
{
return m_dcompFactory.DCompositionCreateDevice(dxgiDevice, riid, ppv);
}
STDMETHOD(DCompositionCreateDevice2)(IUnknown* d2dDevice, REFIID iid, void** device)
{
ID2D1Device* pD2DDevice = nullptr;
if (!d2dDevice || FAILED(d2dDevice->QueryInterface(IID_PPV_ARGS(&pD2DDevice))))
{
return E_INVALIDARG;
}
if (m_pfDCompositionCreateDevice2 == nullptr)
{
return E_NOINTERFACE;
}
HRESULT hr = m_pfDCompositionCreateDevice2(pD2DDevice, iid, device);
pD2DDevice->Release();
return hr;
}
private:
DWORD m_dwRefCount;
CDcompFactory m_dcompFactory;
fDCompositionCreateDevice2 m_pfDCompositionCreateDevice2;
};
IDcompFactory* D2DRENDER::CoCreateDcompFactory()
{
IDcompFactory1* Factory = new CDcompFactory1;
Factory->AddRef();
return Factory;
}
改成接口聚合模式
最新发布