コード例 #1
0
        /// <summary>
        /// Changes the current bitmap shown in the form with a custom opacity level and alpha blending.  Here is where all happens!
        /// The size of the bitmap drawn is equal to the size of the given "bitmap".
        /// This is a private method. Use the other managed methods to perform the bitmap setting operations.
        /// </summary>
        /// <param name="bitmap">The bitmap must be 32ppp with alpha-channel.</param>
        /// <param name="opacity">0-255</param>
        private void SetBitmap(ref Bitmap bitmap, byte opacity, bool SetNewPos, int NewLeftPos, int NewTopPos)
        {
            if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
            {
                throw new ApplicationException("The bitmap must be 32ppp with alpha-channel.");
            }

            // The idea of this is very simple,
            // 1. Create a compatible DC with screen;
            // 2. Select the bitmap with 32bpp with alpha-channel in the compatible DC;
            // 3. Call the UpdateLayeredWindow.

            IntPtr screenDc  = Win32.GetDC(IntPtr.Zero);
            IntPtr memDc     = Win32.CreateCompatibleDC(screenDc);
            IntPtr hBitmap   = IntPtr.Zero;
            IntPtr oldBitmap = IntPtr.Zero;

            try
            {
                hBitmap   = bitmap.GetHbitmap(Color.FromArgb(0)); // grab a GDI handle from this GDI+ bitmap
                oldBitmap = Win32.SelectObject(memDc, hBitmap);

                Win32.Size  size        = new Win32.Size(bitmap.Width, bitmap.Height);
                Win32.Point pointSource = new Win32.Point(0, 0);
                Win32.Point topPos;
                if (SetNewPos == true)
                {
                    topPos = new Win32.Point(NewLeftPos, NewTopPos);

                    //Very important to update the Location because UpdateLayeredWindow doesn't do it correctly.
                    this.Location = new Point(NewLeftPos, NewTopPos);
                }
                else
                {
                    topPos        = new Win32.Point(Left, Top);
                    this.Location = new Point(Left, Top);
                }

                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.UpdateLayeredWindow(Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, Win32.ULW_ALPHA);
            }
            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);
            }
        }
コード例 #2
0
        private void SetBitmap(ref Bitmap bitmap, byte opacity, bool SetNewPos, int NewLeftPos, int NewTopPos)
        {
            IntPtr dC      = Win32.GetDC(IntPtr.Zero);
            IntPtr intPtr  = Win32.CreateCompatibleDC(dC);
            IntPtr intPtr2 = IntPtr.Zero;
            IntPtr hObject = IntPtr.Zero;

            try
            {
                intPtr2 = bitmap.GetHbitmap(Color.FromArgb(0));
                hObject = Win32.SelectObject(intPtr, intPtr2);
                Win32.Size  size  = new Win32.Size(bitmap.Width, bitmap.Height);
                Win32.Point point = new Win32.Point(0, 0);
                Win32.Point point2;
                if (SetNewPos)
                {
                    point2        = new Win32.Point(NewLeftPos, NewTopPos);
                    base.Location = new Point(NewLeftPos, NewTopPos);
                }
                else
                {
                    point2        = new Win32.Point(base.Left, base.Top);
                    base.Location = new Point(base.Left, base.Top);
                }
                Win32.BLENDFUNCTION bLENDFUNCTION = default(Win32.BLENDFUNCTION);
                bLENDFUNCTION.BlendOp             = 0;
                bLENDFUNCTION.BlendFlags          = 0;
                bLENDFUNCTION.SourceConstantAlpha = opacity;
                bLENDFUNCTION.AlphaFormat         = 1;
                Win32.UpdateLayeredWindow(base.Handle, dC, ref point2, ref size, intPtr, ref point, 0, ref bLENDFUNCTION, 2);
            }
            catch (Exception)
            {
            }
            finally
            {
                Win32.ReleaseDC(IntPtr.Zero, dC);
                if (intPtr2 != IntPtr.Zero)
                {
                    Win32.SelectObject(intPtr, hObject);
                    Win32.DeleteObject(intPtr2);
                }
                Win32.DeleteDC(intPtr);
            }
        }
コード例 #3
0
ファイル: Win32.cs プロジェクト: WiiPlayer2/CircleDock
 public static extern Win32.Bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Win32.Point pptDst, ref Win32.Size psize, IntPtr hdcSrc, ref Win32.Point pprSrc, int crKey, ref Win32.BLENDFUNCTION pblend, int dwFlags);