2

I created an application in C# that gets icon images from window handles using user32.dll like this:

[DllImport("user32.dll", EntryPoint = "GetClassLong")]
private static extern int GetClassLongPtr32(IntPtr hWnd, int nIndex);

public static IntPtr GetAppIcon(IntPtr hwnd)
{
    return WI.GetClassLongPtr32(hwnd, WI.ICON_SMALL);
}

And I want to create a BitmapSource from this icon pointer. Usually for WPF I would use

Imaging.CreateBitmapSourceFromHIcon(handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

But since I need the BitmapSource to draw it in a Direct2D render target I would need to use DirectX's BitmapSource

Microsoft.WindowsAPICodePack.DirectX.WindowImagingComponent.BitmapSource

How can I create this kind of BitmapSource using the icon handle or can I transfer one BitmapSource type to the other?

Dominic Lacaille
  • 220
  • 1
  • 10

1 Answers1

2

The ID2D1DeviceContext has a method CreateBitmapFromWicBitmap.

With its help you can create an ID2D1Bitmap. The only thing you have to do is to create an IWICBitmap from your HICON and then create an IWICFormatConverter, so you can keep the alpha channel. You can do it this way (The snippet from below is a delphi one but in C# should be very similar):

procedure iconToD2D1Bitmap;
var
  hIcon: HICON;
  wicBitmap: IWICBitmap;
  wicConverter: IWICFormatConverter;
  wicFactory: IWICImagingFactory;  
  bitmapProps: D2D1_BITMAP_PROPERTIES1;
  bitmap: ID2D1Bitmap1;
begin
  // get a HICON
  hIcon := SendMessage(Handle, WM_GETICON, ICON_BIG, 0);
  try  
    // create wic imaging factory
    CoCreateInstance(CLSID_WICImagingFactory, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IUnknown, wicFactory);

    wicFactory.CreateBitmapFromHICON(hIcon, wicBitmap);
    wicFactory.CreateFormatConverter(wicConverter);

    wicConverter.Initialize(wicBitmap, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nil, 0, WICBitmapPaletteTypeMedianCut);

    bitmapProps.bitmapOptions := D2D1_BITMAP_OPTIONS_NONE;
    bitmapProps.pixelFormat.format := DXGI_FORMAT_B8G8R8A8_UNORM;
    bitmapProps.pixelFormat.alphaMode := D2D1_ALPHA_MODE_PREMULTIPLIED;
    bitmapProps.dpiX := 96;
    bitmapProps.dpiY := 96;
    bitmapProps.colorContext := nil;    

    // deviceContext should be a valid D2D1DeviceContext
    deviceContext.CreateBitmapFromWicBitmap(wicConverter, @bitmapProps, bitmap);

    // the bitmap variable contains your icon

  except
    //
  end;
end;
Peter Kostov
  • 941
  • 1
  • 6
  • 15
  • Unfortunately the ImagingFactory that WindowsAPICodePack provides does not contain the method CreateBitmapFromHICON. I think I will try using SharpDX instead, since it provides the methods you are using. – Dominic Lacaille Dec 16 '14 at 23:59
  • I don't know what `WindowsAPICodePack` exactly contains, but the `CreateBitmapFromHICON` is a `IWICImagingFactory` interface method, part of the [Wincodec library](http://goo.gl/sDFvjN) – Peter Kostov Dec 17 '14 at 06:19
  • I know, but I did not have access to this method without importing the interfaces since they were not included in the WindowsAPICodePack. I accepted your answer anyway because it was the right method and you helped me to find it in SharpDX. Thank you! – Dominic Lacaille Dec 17 '14 at 20:38