views:

108

answers:

0

guys, have you tried using UpdateLayeredWindow API?

am not sure why it doesn't work. meaning.. just a blank layered window ..

public void MakeEXLAYERED(IntPtr hWnd)
{
 // add WS_EX_LAYERED and WS_EX_TRANSPARENT extended style in our form 
 int _initialexstyle = Win32.GetWindowLong(hWnd, Win32.GWL_EXSTYLE);
 Win32.SetWindowLong(hWnd, Win32.GWL_EXSTYLE, _initialexstyle | Win32.WS_EX_LAYERED | Win32.WS_EX_TANSPARENT);
}

public void SetBitmap(IntPtr hWnd, Point location, Bitmap bitmap, byte opacity)
{
 //if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
 //    throw new ApplicationException("The bitmap must be 32ppp with alpha-channel.");

 IntPtr screenDc = Win32.GetDC(IntPtr.Zero);
 System.Diagnostics.Debug.WriteLine("screenDc: " + screenDc);
 IntPtr memDc = Win32.CreateCompatibleDC(screenDc);
 System.Diagnostics.Debug.WriteLine("memDc: " + memDc);
 IntPtr hBitmap = IntPtr.Zero;
 IntPtr oldBitmap = IntPtr.Zero;

 try
 {
  hBitmap = bitmap.GetHbitmap();  // grab a GDI handle from this GDI+ bitmap
  System.Diagnostics.Debug.WriteLine("hBitmap: " + hBitmap);
  oldBitmap = Win32.SelectObject(memDc, hBitmap);
  System.Diagnostics.Debug.WriteLine("oldBitmap: " + oldBitmap);

  Win32.Size size = new Win32.Size(bitmap.Width, bitmap.Height);
  Win32.Point pointSource = new Win32.Point(0, 0);
  Win32.Point topPos = new Win32.Point(location.X, location.Y);

  Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION();
  blend.BlendOp = Win32.AC_SRC_OVER;
  blend.BlendFlags = 0;
  blend.SourceConstantAlpha = opacity;
  blend.AlphaFormat = Win32.AC_SRC_ALPHA;

  Win32.Bool success = Win32.UpdateLayeredWindow(hWnd, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, Win32.ULW_ALPHA);
  if(success == Win32.Bool.False) System.Diagnostics.Debug.WriteLine("failed to blend");
 }
 finally
 {
  Win32.ReleaseDC(IntPtr.Zero, screenDc);
  if (hBitmap != IntPtr.Zero)
  {
   Win32.SelectObject(memDc, oldBitmap);
   //Windows.DeleteObject(hBitmap); // The documentation says that we have to use the Windows.DeleteObject... but since there is no such method I use the normal DeleteObject from Win32 GDI and it's working fine without any resource leak.
   Win32.DeleteObject(hBitmap);
  }
  Win32.DeleteDC(memDc);
 }
}

Bitmap must be an PNG image with alphablend
alt text