예제 #1
0
        //dirtyRect是绝对坐标(在多屏的情况下)
        public virtual void SetHBitmap(IntPtr hBitmap, Rectangle newWindowBounds, Point drawAt, Rectangle dirtyRect,byte opacity)
        {
           // IntPtr screenDc = Win32.GDI32.GetDC(IntPtr.Zero);

            IntPtr memDc = Win32.GDI32.CreateCompatibleDC(IntPtr.Zero);
            IntPtr oldBitmap = IntPtr.Zero;

            try
            {
                oldBitmap = Win32.GDI32.SelectObject(memDc, hBitmap);

                var winSize = new Native.Size(newWindowBounds.Width, newWindowBounds.Height);
                var winPos = new Native.Point(newWindowBounds.X, newWindowBounds.Y);

                var drawBmpAt = new Native.Point(drawAt.X, drawAt.Y);
                var blend = new Native.BLENDFUNCTION { BlendOp = GDI32.AC_SRC_OVER, BlendFlags = 0, SourceConstantAlpha = opacity, AlphaFormat = GDI32.AC_SRC_ALPHA };

                var updateInfo = new Native.UPDATELAYEREDWINDOWINFO();
                updateInfo.cbSize = (uint) Marshal.SizeOf(typeof (Native.UPDATELAYEREDWINDOWINFO));
                updateInfo.dwFlags = GDI32.ULW_ALPHA;
                updateInfo.hdcDst = IntPtr.Zero;//Native.GetDC(IntPtr.Zero);//IntPtr.Zero; //ScreenDC
                updateInfo.hdcSrc = memDc;

               // dirtyRect.X -= _bounds.X;
               // dirtyRect.Y -= _bounds.Y;
                    
                //dirtyRect.Offset(-_bounds.X, -_bounds.Y);
                var dirRect = new GDI32.RECT(dirtyRect.X,dirtyRect.Y,dirtyRect.Right,dirtyRect.Bottom);
                
                unsafe
                {
                    updateInfo.pblend = &blend;
                    updateInfo.pptDst = &winPos;
                    updateInfo.psize = &winSize;
                    updateInfo.pptSrc = &drawBmpAt;
                    updateInfo.prcDirty = &dirRect;
                }

                Native.UpdateLayeredWindowIndirect(Handle, ref updateInfo);
               // Debug.Assert(Native.GetLastError() == 0);

                //Native.UpdateLayeredWindow(Handle, IntPtr.Zero, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, GDI32.ULW_ALPHA);

            }
            finally
            {

                //GDI32.ReleaseDC(IntPtr.Zero, screenDc);
                if (hBitmap != IntPtr.Zero)
                {
                    GDI32.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);
                }
                GDI32.DeleteDC(memDc);
            }
        }