Recipe and best practice for accessing COM

Sean Cavanaugh WorksOnMyMachine at gmail.com
Sun Sep 9 05:57:17 PDT 2012


On 9/9/2012 7:30 AM, newToCOM wrote:
> Still struggling..
>
> test.d:
> -----------------------------------
> ( ... )  /* Other imports */
> import win32.directx.d2d1;
>
> alias win32.directx.d2d1.IID IID;
> IID IID_ID2D1Factory = { 0x06152247, 0x6F50, 0x465A, [0x92, 0x45, 0x11,
> 0x8B, 0xFD, 0x3B, 0x60, 0x07] };
>
> extern (Windows)
> int WinMain( ... )
> {
>      ( ... ) /* Boilerplate code */
> }
>
> int myWinMain( ... )
> {
>      ( ... ) /* Register class, Create window, show window, message loop */
> }
>
> LRESULT WndProc( ... )
> {
>      switch (message)
>      {
>          ( ... ) /* Default and case WM_DESTROY */
>
>          case WM_CREATE:
>
>              // arg2
>              REFIID pIID_ID2D1Factory;
>              pIID_ID2D1Factory = cast(REFIID)&IID_ID2D1Factory;
>
>              // arg3
>              D2D1_FACTORY_OPTIONS factoryOptions;
>                  factoryOptions.debugLevel = D2D1_DEBUG_LEVEL.INFORMATION;
>              const D2D1_FACTORY_OPTIONS* pfactoryOptions = &factoryOptions;
>
>              // arg4
>              void* pID2D1Factory;
>
>
>              HRESULT hr = D2D1CreateFactory(
>                      D2D1_FACTORY_TYPE.SINGLE_THREADED,
>                      pIID_ID2D1Factory,
>                      pfactoryOptions,
>                      pID2D1Factory
>                      );
>
>              writeln(hr);               // Prints 0
>              writeln(pID2D1Factory);    // Prints a non-null pointer
>
>              // Trying to use the interface
>              float dpiX, dpiY;
>              pID2D1Factory.GetDesktopDpi(dpiX, dpiY);
>              // !!! Error: undefined identifier 'GetDesktopDpi'
>              // I thought I had a pointer to the interface and could call
>              // its methods...
>
>              return 0;
>
> ------------------------------
>
> * Coffimplib was used to convert the d2d1.lib from Microsoft DirectX SDK
> (June 2010). The converted d2d1.dll was placed in C:\dcode\dlls
> * With test.d in C:\dcode, the file was compiled and linked in C:\dcode
> with:
> dmd test.d %cd%\dlls\d2d1.lib -I%cd%\dlls\ -version=DXSDK_JUNE_2010
>
>
> - Why is the method identifier undefined?
> - Are there any code examples showing the right use of the bindings?

In this example the pID2D1Factory is a void*, so it will need a cast to 
the proper type with a cast(ID2D1Factory) soemtime after the create call;

Since this particular API takes an out void* (since it is capable of 
creating multiple unrelated types), it would need to look something like 
this:

HRESULT hr = D2D1CreateFactory(
     D2D1_FACTORY_TYPE.SINGLE_THREADED,
     pIID_ID2D1Factory,
     pfactoryOptions,
     pID2D1Factory);

if (SUCCEEDED(hr))
{
	assert(pID2D1Factory !is null);
	ID2D1Factory factory = cast(ID2D1Factory)pID2D1Factory;
	factory.GetDesktopDpi(dpiX, dpiY);
}


I've been super busy at work so haven't had much time to respond to this 
thread.


Technically the API's fourth argument could be rewritten to be an 'out 
IUnknown', but then you are stuck calling QueryInterface, and back to 
having the exact same problem with the QueryInterface method.




More information about the Digitalmars-d-learn mailing list