MFC library offers a series of wrapper classes over Direct2D and DirectWrite interfaces (see CRenderTarget and CD2D classes). That’s pretty cool because allows to easily load and render images and draw texts, without care too much of direct dealing with COM interfaces.
However, let’s say we have to implemented something different so we need to start creating Direct2D or DirectWrite factories. Of course, we can call D2D1CreateFactory or DWriteCreateFactory functions, but a little bit handier is to use the factories instances created and kept by the MFC framework.
Getting Direct2D, DirectWrite and WIC factories in Visual Studio 2010
In MFC framework shipped with Visual Studio 2010, the instances of ID2D1Factory and IDWriteFactory are created and kept in a global AFX_GLOBAL_DATA structure named afxGlobalData. So, we have to do something like this:
ID2D1Factory* pDirect2dFactory = afxGlobalData.GetDirect2dFactory(); IDWriteFactory* pDirectWriteFactory = afxGlobalData.GetWriteFactory(); IWICImagingFactory* pImagingFactory = afxGlobalData.GetWICFactory(); // ...
Getting Direct2D, DirectWrite and WIC factories in Visual Studio 2012 – 2015
In Visual Studio 2012, these factory instances have been moved in a D2D-specific structure of type _AFX_D2D_STATE that can be accessed by calling AfxGetD2DState.
_AFX_D2D_STATE* pD2DState = AfxGetD2DState(); ID2D1Factory* pDirect2dFactory = pD2DState->GetDirect2dFactory(); IDWriteFactory* pDirectWriteFactory = pD2DState->GetWriteFactory(); IWICImagingFactory* pImagingFactory = pD2DState->GetWICFactory(); // ...
Now, we can note that MFC framework keeps also an instance of IWICImagingFactory which is internally used by CD2D classes. That’s also pretty cool; we’ll use it in the following example.
An example of getting and using IWICImagingFactory
Here is a brief example of getting IWICImagingFactory to further read metadata stored in JPEG, TIFF and other image formats.
void CWhateverMFCClass::ListImageFileMetadata(LPCWSTR wzFilePath) { // get IWICImagingFactory from global _AFX_D2D_STATE structure _AFX_D2D_STATE* pD2DState = AfxGetD2DState(); IWICImagingFactory* pImagingFactory = pD2DState->GetWICFactory(); ATLASSERT(pImagingFactory); try { // create bitmap decoder based on the given file CComPtr<IWICBitmapDecoder> spBitmapDecoder; HRESULT hr = pImagingFactory->CreateDecoderFromFilename(wzFilePath, NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &spBitmapDecoder); ATLENSURE_SUCCEEDED(hr); // get first image frame CComPtr<IWICBitmapFrameDecode> spBitmapFrameDecode; hr = spBitmapDecoder->GetFrame(0, &spBitmapFrameDecode); ATLENSURE_SUCCEEDED(hr); // get metadata reader CComPtr<IWICMetadataQueryReader> spMetadataQueryReader; hr = spBitmapFrameDecode->GetMetadataQueryReader(&spMetadataQueryReader); ATLENSURE_SUCCEEDED(hr); // further, just a little sweat to read metadata :) // ... } catch (CException* e) { e->ReportError(); e->Delete(); } }
References and related articles
- MSDN: IWICImagingFactory interface
- MSDN: Breaking Changes in Visual C++ 2012
- Codexpert blog: MFC Support for DirectWrite – Part 5: Typography