Esempio n. 1
0
        private bool CreateLayeredWindowFromImgBuffer(IntPtr pImgBuffer, long cImgBufferLen, bool topMost)
        {
            bool bSuccess = false;
            IntPtr pImagingFactory = IntPtr.Zero;
            IntPtr pDecoder = IntPtr.Zero;
            IntPtr pIStream = IntPtr.Zero;
            IntPtr pDecodedFrame = IntPtr.Zero;
            IntPtr pBitmapSourceFormatConverter = IntPtr.Zero;
            IntPtr pBitmapFlipRotator = IntPtr.Zero;

            try
            {
                UnsafeNativeMethods.HRESULT.Check(
                    UnsafeNativeMethods.WIC.CreateImagingFactory(UnsafeNativeMethods.WIC.WINCODEC_SDK_VERSION, out pImagingFactory));

                // Use the WIC stream class to wrap the unmanaged pointer
                UnsafeNativeMethods.HRESULT.Check(
                    UnsafeNativeMethods.WIC.CreateStream(pImagingFactory, out pIStream));

                UnsafeNativeMethods.HRESULT.Check(
                    UnsafeNativeMethods.WIC.InitializeStreamFromMemory(pIStream, pImgBuffer, (uint)cImgBufferLen));

                // Create an object that will decode the encoded image
                Guid vendor = Guid.Empty;
                UnsafeNativeMethods.HRESULT.Check(
                    UnsafeNativeMethods.WIC.CreateDecoderFromStream(pImagingFactory, pIStream,
                                                                    ref vendor, 0, out pDecoder));

                // Get the frame from the decoder. Most image formats have only a single frame, in the case
                // of animated gifs we are ok with only displaying the first frame of the animation.
                UnsafeNativeMethods.HRESULT.Check(
                    UnsafeNativeMethods.WIC.GetFrame(pDecoder, 0, out pDecodedFrame));

                UnsafeNativeMethods.HRESULT.Check(
                    UnsafeNativeMethods.WIC.CreateFormatConverter(pImagingFactory, out pBitmapSourceFormatConverter));

                // Convert the image from whatever format it is in to 32bpp premultiplied alpha BGRA
                Guid pixelFormat = UnsafeNativeMethods.WIC.WICPixelFormat32bppPBGRA;
                UnsafeNativeMethods.HRESULT.Check(
                    UnsafeNativeMethods.WIC.InitializeFormatConverter(pBitmapSourceFormatConverter, pDecodedFrame,
                                                                      ref pixelFormat, 0 /*DitherTypeNone*/, IntPtr.Zero,
                                                                      0, UnsafeNativeMethods.WIC.WICPaletteType.WICPaletteTypeCustom));
                // Reorient the image
                UnsafeNativeMethods.HRESULT.Check(
                    UnsafeNativeMethods.WIC.CreateBitmapFlipRotator(pImagingFactory, out pBitmapFlipRotator));

                UnsafeNativeMethods.HRESULT.Check(
                    UnsafeNativeMethods.WIC.InitializeBitmapFlipRotator(pBitmapFlipRotator, pBitmapSourceFormatConverter,
                                                                        UnsafeNativeMethods.WIC.WICBitmapTransformOptions.WICBitmapTransformFlipVertical));
                Int32 width, height;
                UnsafeNativeMethods.HRESULT.Check(
                    UnsafeNativeMethods.WIC.GetBitmapSize(pBitmapFlipRotator, out width, out height));

                Int32 stride = width * 4;

                // initialize the bitmap header
                MS.Win32.NativeMethods.BITMAPINFO bmInfo = new MS.Win32.NativeMethods.BITMAPINFO(width, height, 32 /*bpp*/);
                bmInfo.bmiHeader_biCompression = MS.Win32.NativeMethods.BI_RGB;
                bmInfo.bmiHeader_biSizeImage = (int)(stride * height);

                // Create a 32bpp DIB.  This DIB must have an alpha channel for UpdateLayeredWindow to succeed.
                IntPtr pBitmapBits = IntPtr.Zero;
                _hBitmap = UnsafeNativeMethods.CreateDIBSection(new HandleRef(), ref bmInfo, 0 /* DIB_RGB_COLORS*/, ref pBitmapBits, null, 0);

                // Copy the decoded image to the new buffer which backs the HBITMAP
                Int32Rect rect = new Int32Rect(0, 0, width, height);
                UnsafeNativeMethods.HRESULT.Check(
                    UnsafeNativeMethods.WIC.CopyPixels(pBitmapFlipRotator, ref rect, stride, stride * height, pBitmapBits));

                _hwnd = CreateWindow(_hBitmap, width, height, topMost);

                bSuccess = true;
            }
            finally
            {
                if (pImagingFactory != IntPtr.Zero)
                {
                    Marshal.Release(pImagingFactory);
                }
                if (pDecoder != IntPtr.Zero)
                {
                    Marshal.Release(pDecoder);
                }
                if (pIStream != IntPtr.Zero)
                {
                    Marshal.Release(pIStream);
                }
                if (pDecodedFrame != IntPtr.Zero)
                {
                    Marshal.Release(pDecodedFrame);
                }
                if (pBitmapSourceFormatConverter != IntPtr.Zero)
                {
                    Marshal.Release(pBitmapSourceFormatConverter);
                }
                if (pBitmapFlipRotator != IntPtr.Zero)
                {
                    Marshal.Release(pBitmapFlipRotator);
                }

                if (bSuccess == false)
                {
                    DestroyResources(); // cleans up _hwnd and _hBitmap
                }
            }

            return bSuccess;
        }
Esempio n. 2
0
 private void DestroyResources()
 {
     if (_dt != null)
     {
         _dt.Stop();
         _dt = null;
     }
     if (_hwnd != IntPtr.Zero)
     {
         HandleRef hwnd = new HandleRef(null, _hwnd);
         if (UnsafeNativeMethods.IsWindow(hwnd))
         {
             UnsafeNativeMethods.IntDestroyWindow(hwnd);
         }
         _hwnd = IntPtr.Zero;
     }
     if (_hBitmap != null && !_hBitmap.IsClosed)
     {
         UnsafeNativeMethods.DeleteObject(_hBitmap.MakeHandleRef(null).Handle);
         _hBitmap.Close();
         _hBitmap = null;
     }
     if (_wndClass != 0)
     {
         // Attempt to unregister the window class.  If the application has a second
         // splash screen which is still open this call will fail.  That's OK.
         if (UnsafeNativeMethods.IntUnregisterClass(new IntPtr(_wndClass), _hInstance) != 0)
         {
             _defWndProc = null; // Can safely release the wndproc delegate when there are no more splash screen instances
         }
         _wndClass = 0;
     }
     if (_resourceManager != null)
     {
         _resourceManager.ReleaseAllResources();
     }
 }