Using Direct2D conditionally

In the Windows 7 Developer training I learned that we should not test the OS version in order to check which new features can be used. We now shall test each feature individually (I think today it’s so confusing that you can’t determine which OS service pack implements which extension).

When I asked to show some examples how the test for individual features can be done I got no answer.

Today I had the problem to implement a C++ DLL that should use Direct2D if it was available. My first idea was to just use delay-load for my D2D1.DLL import. But this would not work under XP because the late load of d2d1.dll would fail.

So I decided to dynamically load Direct2D. The architecture of Direct2D comes to my aid because D2D uses the factory pattern to construct all objects. That leads to the consequence that the D2D1.DLL has few exports. Ideally it only had the D2D1CreateFactory export so it would be very easy to get it’s proc address and forget about it. Direct2D adds some helper functions that ease the handling of frequently-used structures (like D2D1InvertMatrix). In my case I was lucky because I didn’t need them so I just needed to call GetProcAddress once for D2D1CreateFactory.

I declared a global smart pointer for the factory and a HMODULE variable for the D2D1.DLL handle and then I inserted the following code into my DllMain in the DLL_PROCESS_ATTACH branch. It was a bit tricky to find the correct function prototype for D2D1CreateFactory because the docs state four different variants and the sample code uses another one.

if (NULL != (hD2D1Lib = AfxLoadLibrary("D2D1.DLL")))
  {
  typedef HRESULT(STDAPICALLTYPE* FPCF)(D2D1_FACTORY_TYPE, REFIID, CONST D2D1_FACTORY_OPTIONS *, void**);
   FPCF pfn = (FPCF) GetProcAddress(hD2D1Lib, "D2D1CreateFactory");
   if (pfn == NULL || FAILED(pfn(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory), NULL, (void**)&g_spFactory)))
  {
      g_spFactory = NULL;
      AfxFreeLibrary(hD2D1Lib);
      hD2D1Lib = NULL;
      }
   }

What’s left is not to forget to call AfxFreeLibrary again in the DLL_PROCESS_DETACH branch.

In my implementation I can now simply test the g_spFactory pointer to decide if I can use Direct2D features.

Comments are closed.