//dirtyRect是绝对坐标(在多屏的情况下) private void SetHBitmap(IntPtr hBitmap, Rectangle newWindowBounds, Point drawAt, Rectangle dirtyRect, byte opacity) { // IntPtr screenDc = Win32.GDI32.GetDC(IntPtr.Zero); IntPtr memDc = NativeMethods.CreateCompatibleDC(IntPtr.Zero); IntPtr oldBitmap = IntPtr.Zero; try { oldBitmap = NativeMethods.SelectObject(memDc, hBitmap); var winSize = new NativeMethods.Size(newWindowBounds.Width, newWindowBounds.Height); var winPos = new NativeMethods.Point(newWindowBounds.X, newWindowBounds.Y); var drawBmpAt = new NativeMethods.Point(drawAt.X, drawAt.Y); var blend = new NativeMethods.BLENDFUNCTION { BlendOp = AC_SRC_OVER, BlendFlags = 0, SourceConstantAlpha = opacity, AlphaFormat = AC_SRC_ALPHA }; var updateInfo = new NativeMethods.UPDATELAYEREDWINDOWINFO { cbSize = (uint)Marshal.SizeOf(typeof(NativeMethods.UPDATELAYEREDWINDOWINFO)), dwFlags = ULW_ALPHA, hdcDst = IntPtr.Zero, hdcSrc = memDc }; //NativeMethods.GetDC(IntPtr.Zero);//IntPtr.Zero; //ScreenDC // dirtyRect.X -= _bounds.X; // dirtyRect.Y -= _bounds.Y; //dirtyRect.Offset(-_bounds.X, -_bounds.Y); var dirRect = new NativeMethods.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; } NativeMethods.UpdateLayeredWindowIndirect(Handle, ref updateInfo); // Debug.Assert(NativeMethods.GetLastError() == 0); //NativeMethods.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) { NativeMethods.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); } NativeMethods.DeleteDC(memDc); } }
protected virtual void UpdateLayeredWindow(byte alpha) { var bitmap = (Bitmap)BackgroundImage; IntPtr hdcScreen = NativeMethods.GetDC(new HandleRef(this, IntPtr.Zero)); IntPtr hdcMemory = NativeMethods.CreateCompatibleDC(new HandleRef(this, hdcScreen)); IntPtr hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); IntPtr hOldBitmap = NativeMethods.SelectObject(new HandleRef(this, hdcMemory), new HandleRef(this, hBitmap)); var size = new NativeMethods.SIZESTRUCT(bitmap.Width, bitmap.Height); var pointSource = new NativeMethods.POINTSTRUCT(0, 0); var topPos = new NativeMethods.POINTSTRUCT(Left, Top); var blend = new NativeMethods.BLENDFUNCTION(); blend.BlendOp = 0; blend.BlendFlags = 0; blend.SourceConstantAlpha = alpha; blend.AlphaFormat = 1; NativeMethods.UpdateLayeredWindow(handle, hdcScreen, ref topPos, ref size, hdcMemory, ref pointSource, 0, ref blend, 0x00000002); NativeMethods.ReleaseDC(new HandleRef(this, IntPtr.Zero), new HandleRef(this, hdcScreen)); if (hBitmap != IntPtr.Zero) { NativeMethods.SelectObject(new HandleRef(this, hdcMemory), new HandleRef(this, hOldBitmap)); NativeMethods.DeleteObject(new HandleRef(this, hBitmap)); } NativeMethods.DeleteDC(new HandleRef(this, hdcMemory)); }
public void SetBits() { //绘制绘图层背景 Bitmap bitmap = new Bitmap(Main.Width + Main.ShadowWidth * 2, Main.Height + Main.ShadowWidth * 2); //Rectangle _BacklightLTRB = new Rectangle(20, 20, 20, 20);//窗体光泽重绘边界 Graphics g = Graphics.FromImage(bitmap); g.SmoothingMode = SmoothingMode.HighQuality; //高质量 g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移质量 DrawShadow(g); //ImageDrawRect.DrawRect(g, Properties.Resources.main_light_bkg_top123, ClientRectangle, Rectangle.FromLTRB(_BacklightLTRB.X, _BacklightLTRB.Y, _BacklightLTRB.Width, _BacklightLTRB.Height), 1, 1); if (!Bitmap.IsCanonicalPixelFormat(bitmap.PixelFormat) || !Bitmap.IsAlphaPixelFormat(bitmap.PixelFormat)) { throw new ApplicationException("图片必须是32位带Alhpa通道的图片。"); } IntPtr oldBits = IntPtr.Zero; IntPtr screenDC = NativeMethods.GetDC(IntPtr.Zero); IntPtr hBitmap = IntPtr.Zero; IntPtr memDc = NativeMethods.CreateCompatibleDC(screenDC); try { NativeMethods.Point topLoc = new NativeMethods.Point(Left, Top); NativeMethods.Size bitMapSize = new NativeMethods.Size(Width, Height); NativeMethods.BLENDFUNCTION blendFunc = new NativeMethods.BLENDFUNCTION(); NativeMethods.Point srcLoc = new NativeMethods.Point(0, 0); hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); oldBits = NativeMethods.SelectObject(memDc, hBitmap); blendFunc.BlendOp = AC.AC_SRC_OVER; blendFunc.SourceConstantAlpha = Byte.Parse("255"); blendFunc.AlphaFormat = AC.AC_SRC_ALPHA; blendFunc.BlendFlags = 0; NativeMethods.UpdateLayeredWindow(Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, NativeMethods.ULW_ALPHA); } finally { if (hBitmap != IntPtr.Zero) { NativeMethods.SelectObject(memDc, oldBits); NativeMethods.DeleteObject(hBitmap); } NativeMethods.ReleaseDC(IntPtr.Zero, screenDC); NativeMethods.DeleteDC(memDc); } }
private void PaintNative(Bitmap bitmap, byte opacity) { IntPtr hdcDestination = NativeMethods.GetDC(IntPtr.Zero); IntPtr hdcSource = NativeMethods.CreateCompatibleDC(hdcDestination); IntPtr hdcBitmap = IntPtr.Zero; IntPtr previousBitmap = IntPtr.Zero; try { hdcBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); previousBitmap = NativeMethods.SelectObject(hdcSource, hdcBitmap); NativeMethods.SIZE size = new NativeMethods.SIZE(bitmap.Width, bitmap.Height); NativeMethods.POINT source = new NativeMethods.POINT(0, 0); NativeMethods.POINT destination = new NativeMethods.POINT(Left, Top); NativeMethods.BLENDFUNCTION blend = new NativeMethods.BLENDFUNCTION(); blend.BlendOp = NativeMethods.AC_SRC_OVER; blend.BlendFlags = 0; blend.SourceConstantAlpha = opacity; blend.AlphaFormat = NativeMethods.AC_SRC_ALPHA; NativeMethods.UpdateLayeredWindow( Handle, hdcDestination, ref destination, ref size, hdcSource, ref source, 0, ref blend, 2); } catch (Exception) { return; } finally { NativeMethods.ReleaseDC(IntPtr.Zero, hdcDestination); if (hdcBitmap != IntPtr.Zero) { NativeMethods.SelectObject(hdcSource, previousBitmap); NativeMethods.DeleteObject(hdcBitmap); } NativeMethods.DeleteDC(hdcSource); } }
protected void DrawBitmap(Bitmap bitmap, int opacity) { IntPtr screenDc = UnsafeNativeMethods.GetDC(IntPtr.Zero); IntPtr memDc = UnsafeNativeMethods.CreateCompatibleDC(screenDc); IntPtr hBitmap = IntPtr.Zero; IntPtr hOldBitmap = IntPtr.Zero; try { hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); hOldBitmap = UnsafeNativeMethods.SelectObject(memDc, hBitmap); var newSize = new Size(bitmap.Width, bitmap.Height); var sourceLocation = new Point(0, 0); var newLocation = new Point(this.Left, this.Top); var blend = new NativeMethods.BLENDFUNCTION() { BlendOp = AC_SRC_OVER, BlendFlags = 0, SourceConstantAlpha = (byte)opacity, AlphaFormat = AC_SRC_ALPHA }; UnsafeNativeMethods.UpdateLayeredWindow( this.Handle, screenDc, ref newLocation, ref newSize, memDc, ref sourceLocation, 0, ref blend, ULW_ALPHA); } finally { UnsafeNativeMethods.ReleaseDC(IntPtr.Zero, screenDc); if (hBitmap != IntPtr.Zero) { UnsafeNativeMethods.SelectObject(memDc, hOldBitmap); UnsafeNativeMethods.DeleteObject(hBitmap); } UnsafeNativeMethods.DeleteDC(memDc); } }
public void SetBitmap(Bitmap bitmap, byte opacity = 255) { if (bitmap.PixelFormat != PixelFormat.Format32bppArgb) { throw new ApplicationException("The bitmap must be 32ppp with alpha-channel."); } // The ideia 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 = NativeMethods.GetDC(IntPtr.Zero); IntPtr memDc = NativeMethods.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 = NativeMethods.SelectObject(memDc, hBitmap); var size = new NativeMethods.Size(bitmap.Width, bitmap.Height); var pointSource = new NativeMethods.Point(0, 0); var topPos = new NativeMethods.Point(Left, Top); var blend = new NativeMethods.BLENDFUNCTION(); blend.BlendOp = NativeMethods.AC_SRC_OVER; blend.BlendFlags = 0; blend.SourceConstantAlpha = opacity; blend.AlphaFormat = NativeMethods.AC_SRC_ALPHA; NativeMethods.UpdateLayeredWindow(Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, NativeMethods.ULW_ALPHA); } finally { NativeMethods.ReleaseDC(IntPtr.Zero, screenDc); if (hBitmap != IntPtr.Zero) { NativeMethods.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. NativeMethods.DeleteObject(hBitmap); } NativeMethods.DeleteDC(memDc); } }
public void SetBits() { Bitmap image = new Bitmap(this.m_HostForm.Width + (m_Config.ShadowWidth * 2), this.m_HostForm.Height + (m_Config.ShadowWidth * 2)); Graphics g = Graphics.FromImage(image); g.SmoothingMode = SmoothingMode.HighQuality; g.PixelOffsetMode = PixelOffsetMode.HighQuality; this.DrawShadow(g); if (Image.IsCanonicalPixelFormat(image.PixelFormat) && Image.IsAlphaPixelFormat(image.PixelFormat)) { IntPtr zero = IntPtr.Zero; //diff //IntPtr dC = NativeMethods.GetDC(new HandleRef(null, IntPtr.Zero)); IntPtr dC = NativeMethods.GetDC(IntPtr.Zero); IntPtr hgdiobj = IntPtr.Zero; //diff //IntPtr hdc = NativeMethods.CreateCompatibleDC(new HandleRef(null, dC)); IntPtr hdc = NativeMethods.CreateCompatibleDC(dC); try { NativeMethods.POINTSTRUCT pptDst = new NativeMethods.POINTSTRUCT(base.Left, base.Top); NativeMethods.SIZESTRUCT psize = new NativeMethods.SIZESTRUCT(base.Width, base.Height); NativeMethods.BLENDFUNCTION pblend = new NativeMethods.BLENDFUNCTION(); NativeMethods.POINTSTRUCT pprSrc = new NativeMethods.POINTSTRUCT(0, 0); hgdiobj = image.GetHbitmap(Color.FromArgb(0)); zero = NativeMethods.SelectObject(hdc, hgdiobj); pblend.BlendOp = 0; pblend.SourceConstantAlpha = byte.Parse("255"); pblend.AlphaFormat = 1; pblend.BlendFlags = 0; NativeMethods.UpdateLayeredWindow(base.Handle, dC, ref pptDst, ref psize, hdc, ref pprSrc, 0, ref pblend, 2); return; } finally { if (hgdiobj != IntPtr.Zero) { NativeMethods.SelectObject(hdc, zero); NativeMethods.DeleteObject(hgdiobj); } NativeMethods.ReleaseDC(IntPtr.Zero, dC); NativeMethods.DeleteDC(hdc); } } throw new ApplicationException("图片必须是32位带Alhpa通道的图片。"); }
public void SetBits() { if (BackgroundImage != null) { //绘制绘图层背景 Bitmap bitmap = new Bitmap(BackgroundImage, base.Width, base.Height); if (!Bitmap.IsCanonicalPixelFormat(bitmap.PixelFormat) || !Bitmap.IsAlphaPixelFormat(bitmap.PixelFormat)) { throw new ApplicationException("图片必须是32位带Alhpa通道的图片。"); } IntPtr oldBits = IntPtr.Zero; IntPtr screenDC = NativeMethods.GetDC(IntPtr.Zero); IntPtr hBitmap = IntPtr.Zero; IntPtr memDc = NativeMethods.CreateCompatibleDC(screenDC); try { NativeMethods.Point topLoc = new NativeMethods.Point(Left, Top); NativeMethods.Size bitMapSize = new NativeMethods.Size(Width, Height); NativeMethods.BLENDFUNCTION blendFunc = new NativeMethods.BLENDFUNCTION(); NativeMethods.Point srcLoc = new NativeMethods.Point(0, 0); hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); oldBits = NativeMethods.SelectObject(memDc, hBitmap); blendFunc.BlendOp = AC.AC_SRC_OVER; blendFunc.SourceConstantAlpha = Byte.Parse("255"); blendFunc.AlphaFormat = AC.AC_SRC_ALPHA; blendFunc.BlendFlags = 0; NativeMethods.UpdateLayeredWindow(Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, NativeMethods.ULW_ALPHA); } finally { if (hBitmap != IntPtr.Zero) { NativeMethods.SelectObject(memDc, oldBits); NativeMethods.DeleteObject(hBitmap); } NativeMethods.ReleaseDC(IntPtr.Zero, screenDC); NativeMethods.DeleteDC(memDc); } } }
private IntPtr CreateWindow(NativeMethods.BitmapHandle hBitmap, int width, int height, bool topMost) { if (_defWndProc == null) { _defWndProc = new MS.Win32.NativeMethods.WndProc(UnsafeNativeMethods.DefWindowProc); } MS.Win32.NativeMethods.WNDCLASSEX_D wndClass = new MS.Win32.NativeMethods.WNDCLASSEX_D(); wndClass.cbSize = Marshal.SizeOf(typeof(MS.Win32.NativeMethods.WNDCLASSEX_D)); wndClass.style = 3; /* CS_HREDRAW | CS_VREDRAW */ wndClass.lpfnWndProc = null; wndClass.hInstance = _hInstance; wndClass.hCursor = IntPtr.Zero; wndClass.lpszClassName = CLASSNAME; wndClass.lpszMenuName = string.Empty; wndClass.lpfnWndProc = _defWndProc; // We chose to ignore re-registration errors in RegisterClassEx on the off chance that the user // wants to open multiple splash screens. _wndClass = MS.Win32.UnsafeNativeMethods.IntRegisterClassEx(wndClass); if (_wndClass == 0) { if (Marshal.GetLastWin32Error() != 0x582) /* class already registered */ throw new Win32Exception(); } int screenWidth = MS.Win32.UnsafeNativeMethods.GetSystemMetrics(SM.CXSCREEN); int screenHeight = MS.Win32.UnsafeNativeMethods.GetSystemMetrics(SM.CYSCREEN); int x = (screenWidth - width) / 2; int y = (screenHeight - height) / 2; HandleRef nullHandle = new HandleRef(null, IntPtr.Zero); int windowCreateFlags = (int) NativeMethods.WS_EX_WINDOWEDGE | NativeMethods.WS_EX_TOOLWINDOW | NativeMethods.WS_EX_LAYERED | (topMost ? NativeMethods.WS_EX_TOPMOST : 0); // CreateWindowEx will either succeed or throw IntPtr hWnd = MS.Win32.UnsafeNativeMethods.CreateWindowEx( windowCreateFlags, CLASSNAME, SR.Get(SRID.SplashScreenIsLoading), MS.Win32.NativeMethods.WS_POPUP | MS.Win32.NativeMethods.WS_VISIBLE, x, y, width, height, nullHandle, nullHandle, new HandleRef(null, _hInstance), IntPtr.Zero); // Display the image on the window IntPtr hScreenDC = UnsafeNativeMethods.GetDC(new HandleRef()); IntPtr memDC = UnsafeNativeMethods.CreateCompatibleDC(new HandleRef(null, hScreenDC)); IntPtr hOldBitmap = UnsafeNativeMethods.SelectObject(new HandleRef(null, memDC), hBitmap.MakeHandleRef(null).Handle); NativeMethods.POINT newSize = new NativeMethods.POINT(width, height); NativeMethods.POINT newLocation = new NativeMethods.POINT(x, y); NativeMethods.POINT sourceLocation = new NativeMethods.POINT(0, 0); _blendFunc = new NativeMethods.BLENDFUNCTION(); _blendFunc.BlendOp = NativeMethods.AC_SRC_OVER; _blendFunc.BlendFlags = 0; _blendFunc.SourceConstantAlpha = 255; _blendFunc.AlphaFormat = 1; /*AC_SRC_ALPHA*/ bool result = UnsafeNativeMethods.UpdateLayeredWindow(hWnd, hScreenDC, newLocation, newSize, memDC, sourceLocation, 0, ref _blendFunc, NativeMethods.ULW_ALPHA); UnsafeNativeMethods.SelectObject(new HandleRef(null, memDC), hOldBitmap); UnsafeNativeMethods.ReleaseDC(new HandleRef(), new HandleRef(null, memDC)); UnsafeNativeMethods.ReleaseDC(new HandleRef(), new HandleRef(null, hScreenDC)); if (result == false) { UnsafeNativeMethods.HRESULT.Check(Marshal.GetHRForLastWin32Error()); } return hWnd; }
protected override void OnPaint(PaintEventArgs e) { var outerBounds = new Rectangle(0, 0, Width, Height); using (var target = new Bitmap(outerBounds.Width, outerBounds.Height, PixelFormat.Format32bppArgb)) { using (var targetGraphics = Graphics.FromImage(target)) { // The top and bottom borders extend over the sides of the window. // The left and right borders do no. This means that we need to // update the bounds to make it seem like the left and right // borders do extend outside of the window. if (Border == DropShadowBorder.Left || Border == DropShadowBorder.Right) { outerBounds = new Rectangle( outerBounds.Left, outerBounds.Top - _borderWidth, outerBounds.Width, outerBounds.Height + _borderWidth * 2 ); } if (Border == DropShadowBorder.Left || Border == DropShadowBorder.Top) { DrawImage( targetGraphics, _imageCache.CornerNW, new Point( outerBounds.Left, outerBounds.Top ) ); } if (Border == DropShadowBorder.Right || Border == DropShadowBorder.Top) { DrawImage( targetGraphics, _imageCache.CornerNE, new Point( outerBounds.Right - _cornerSize, outerBounds.Top ) ); } if (Border == DropShadowBorder.Bottom || Border == DropShadowBorder.Left) { DrawImage( targetGraphics, _imageCache.CornerSW, new Point( outerBounds.Left, outerBounds.Bottom - _cornerSize ) ); } if (Border == DropShadowBorder.Bottom || Border == DropShadowBorder.Right) { DrawImage( targetGraphics, _imageCache.CornerSE, new Point( outerBounds.Right - _cornerSize, outerBounds.Bottom - _cornerSize ) ); } if (Border == DropShadowBorder.Top) { DrawBorder( targetGraphics, _imageCache.BorderN, new Rectangle( outerBounds.Left + _cornerSize, outerBounds.Top, outerBounds.Width - _cornerSize * 2, _borderWidth ) ); } if (Border == DropShadowBorder.Bottom) { DrawBorder( targetGraphics, _imageCache.BorderS, new Rectangle( outerBounds.Left + _cornerSize, outerBounds.Bottom - _borderWidth, outerBounds.Width - _cornerSize * 2, _borderWidth ) ); } if (Border == DropShadowBorder.Left) { DrawBorder( targetGraphics, _imageCache.BorderW, new Rectangle( outerBounds.Left, outerBounds.Top + _cornerSize, _borderWidth, outerBounds.Height - _cornerSize * 2 ) ); } if (Border == DropShadowBorder.Right) { DrawBorder( targetGraphics, _imageCache.BorderE, new Rectangle( outerBounds.Right - _borderWidth, outerBounds.Top + _cornerSize, _borderWidth, outerBounds.Height - _cornerSize * 2 ) ); } } // Get device contexts var screenDc = NativeMethods.GetDC(IntPtr.Zero); var memDc = NativeMethods.CreateCompatibleDC(screenDc); var hBitmap = IntPtr.Zero; var hOldBitmap = IntPtr.Zero; try { // Get handle to the new bitmap and select it into the current device context hBitmap = target.GetHbitmap(Color.FromArgb(0)); hOldBitmap = NativeMethods.SelectObject(memDc, hBitmap); // Set parameters for layered window update var newSize = new NativeMethods.SIZE(target.Size); // Size window to match bitmap var sourceLocation = new NativeMethods.POINT(Point.Empty); var newLocation = new NativeMethods.POINT(Location); // Same as this window var blend = new NativeMethods.BLENDFUNCTION { BlendOp = NativeMethods.AC_SRC_OVER, // Only works with a 32bpp bitmap BlendFlags = 0, // Always 0 SourceConstantAlpha = 255, // Set to 255 for per-pixel alpha values AlphaFormat = NativeMethods.AC_SRC_ALPHA // Only works when the bitmap contains an alpha channel }; // Update the window NativeMethods.UpdateLayeredWindow( Handle, screenDc, ref newLocation, ref newSize, memDc, ref sourceLocation, 0, ref blend, NativeMethods.ULW_ALPHA ); } finally { // Release device context NativeMethods.ReleaseDC(IntPtr.Zero, screenDc); if (hBitmap != IntPtr.Zero) { NativeMethods.SelectObject(memDc, hOldBitmap); NativeMethods.DeleteObject(hBitmap); // Remove bitmap resources } NativeMethods.DeleteDC(memDc); } } }
public void SetBits() { //绘制绘图层背景 Bitmap bitmap = new Bitmap(Main.Width + Main.ShadowWidth * 2, Main.Height + Main.ShadowWidth * 2); //Rectangle _BacklightLTRB = new Rectangle(20, 20, 20, 20);//窗体光泽重绘边界 Graphics g = Graphics.FromImage(bitmap); g.SmoothingMode = SmoothingMode.HighQuality; //高质量 g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移质量 DrawShadow(g); //ImageDrawRect.DrawRect(g, Properties.Resources.main_light_bkg_top123, ClientRectangle, Rectangle.FromLTRB(_BacklightLTRB.X, _BacklightLTRB.Y, _BacklightLTRB.Width, _BacklightLTRB.Height), 1, 1); if (!Bitmap.IsCanonicalPixelFormat(bitmap.PixelFormat) || !Bitmap.IsAlphaPixelFormat(bitmap.PixelFormat)) throw new ApplicationException("图片必须是32位带Alhpa通道的图片。"); IntPtr oldBits = IntPtr.Zero; IntPtr screenDC = NativeMethods.GetDC(IntPtr.Zero); IntPtr hBitmap = IntPtr.Zero; IntPtr memDc = NativeMethods.CreateCompatibleDC(screenDC); try { NativeMethods.Point topLoc = new NativeMethods.Point(Left, Top); NativeMethods.Size bitMapSize = new NativeMethods.Size(Width, Height); NativeMethods.BLENDFUNCTION blendFunc = new NativeMethods.BLENDFUNCTION(); NativeMethods.Point srcLoc = new NativeMethods.Point(0, 0); hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); oldBits = NativeMethods.SelectObject(memDc, hBitmap); blendFunc.BlendOp = AC.AC_SRC_OVER; blendFunc.SourceConstantAlpha = Byte.Parse("255"); blendFunc.AlphaFormat = AC.AC_SRC_ALPHA; blendFunc.BlendFlags = 0; NativeMethods.UpdateLayeredWindow(Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, NativeMethods.ULW_ALPHA); } finally { if (hBitmap != IntPtr.Zero) { NativeMethods.SelectObject(memDc, oldBits); NativeMethods.DeleteObject(hBitmap); } NativeMethods.ReleaseDC(IntPtr.Zero, screenDC); NativeMethods.DeleteDC(memDc); } }
public void SetBits() { if (shadow_rect.Width > 0 && shadow_rect.Height > 0) { using (Bitmap bitmap = new Bitmap(shadow_rect.Width, shadow_rect.Height)) { using (Graphics g = Graphics.FromImage(bitmap)) { g.SmoothingMode = SmoothingMode.AntiAlias; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.CompositingQuality = CompositingQuality.HighQuality; g.PixelOffsetMode = PixelOffsetMode.HighQuality; //高像素偏移质量 using (GraphicsPath path = rect.CreateRoundedRectanglePath(Main.Radius, Main.RoundStyle)) { g.FillPath(Main.ShadowColor, path); bitmap.StackBlur(Main.ShadowWidth); g.CompositingMode = CompositingMode.SourceCopy; g.FillPath(TransparentsolidBrush, path); } } //绘制绘图层背景 //if (!Bitmap.IsCanonicalPixelFormat(bitmap.PixelFormat) || !Bitmap.IsAlphaPixelFormat(bitmap.PixelFormat)) // throw new ApplicationException("图片必须是32位带Alhpa通道的图片。"); IntPtr oldBits = IntPtr.Zero; IntPtr screenDC = NativeMethods.GetDC(IntPtr.Zero); IntPtr hBitmap = IntPtr.Zero; IntPtr memDc = NativeMethods.CreateCompatibleDC(screenDC); try { NativeMethods.Point topLoc = new NativeMethods.Point(Left, Top); NativeMethods.Size bitMapSize = new NativeMethods.Size(Width, Height); NativeMethods.BLENDFUNCTION blendFunc = new NativeMethods.BLENDFUNCTION(); NativeMethods.Point srcLoc = new NativeMethods.Point(0, 0); hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); oldBits = NativeMethods.SelectObject(memDc, hBitmap); blendFunc.BlendOp = AC.AC_SRC_OVER; blendFunc.SourceConstantAlpha = Byte.Parse("255"); blendFunc.AlphaFormat = AC.AC_SRC_ALPHA; blendFunc.BlendFlags = 0; NativeMethods.UpdateLayeredWindow(Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, NativeMethods.ULW_ALPHA); } finally { if (hBitmap != IntPtr.Zero) { NativeMethods.SelectObject(memDc, oldBits); NativeMethods.DeleteObject(hBitmap); } NativeMethods.ReleaseDC(IntPtr.Zero, screenDC); NativeMethods.DeleteDC(memDc); } } } }
private void PaintNative(Bitmap bitmap, byte opacity) { Debug.WriteLine("PaintNative"); IntPtr hdcDestination = NativeMethods.GetDC(IntPtr.Zero); IntPtr hdcSource = NativeMethods.CreateCompatibleDC(hdcDestination); IntPtr hdcBitmap = IntPtr.Zero; IntPtr previousBitmap = IntPtr.Zero; try { hdcBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); previousBitmap = NativeMethods.SelectObject(hdcSource, hdcBitmap); NativeMethods.SIZE size = new NativeMethods.SIZE(bitmap.Width, bitmap.Height); NativeMethods.POINT source = new NativeMethods.POINT(0, 0); NativeMethods.POINT destination = new NativeMethods.POINT(Left, Top); NativeMethods.BLENDFUNCTION blend = new NativeMethods.BLENDFUNCTION(); blend.BlendOp = NativeMethods.AC_SRC_OVER; blend.BlendFlags = 0; blend.SourceConstantAlpha = opacity; blend.AlphaFormat = NativeMethods.AC_SRC_ALPHA; NativeMethods.UpdateLayeredWindow( Handle, hdcDestination, ref destination, ref size, hdcSource, ref source, 0, ref blend, 2); } catch (Exception) { return; } finally { NativeMethods.ReleaseDC(IntPtr.Zero, hdcDestination); if (hdcBitmap != IntPtr.Zero) { NativeMethods.SelectObject(hdcSource, previousBitmap); NativeMethods.DeleteObject(hdcBitmap); } NativeMethods.DeleteDC(hdcSource); } }
public void SetBits() { if (BackgroundImage != null) { //绘制绘图层背景 Bitmap bitmap = new Bitmap(BackgroundImage, base.Width, base.Height); if (!Bitmap.IsCanonicalPixelFormat(bitmap.PixelFormat) || !Bitmap.IsAlphaPixelFormat(bitmap.PixelFormat)) throw new ApplicationException("图片必须是32位带Alhpa通道的图片。"); IntPtr oldBits = IntPtr.Zero; IntPtr screenDC = NativeMethods.GetDC(IntPtr.Zero); IntPtr hBitmap = IntPtr.Zero; IntPtr memDc = NativeMethods.CreateCompatibleDC(screenDC); try { NativeMethods.Point topLoc = new NativeMethods.Point(Left, Top); NativeMethods.Size bitMapSize = new NativeMethods.Size(Width, Height); NativeMethods.BLENDFUNCTION blendFunc = new NativeMethods.BLENDFUNCTION(); NativeMethods.Point srcLoc = new NativeMethods.Point(0, 0); hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); oldBits = NativeMethods.SelectObject(memDc, hBitmap); blendFunc.BlendOp = AC.AC_SRC_OVER; blendFunc.SourceConstantAlpha = Byte.Parse("255"); blendFunc.AlphaFormat = AC.AC_SRC_ALPHA; blendFunc.BlendFlags = 0; NativeMethods.UpdateLayeredWindow(Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, NativeMethods.ULW_ALPHA); } finally { if (hBitmap != IntPtr.Zero) { NativeMethods.SelectObject(memDc, oldBits); NativeMethods.DeleteObject(hBitmap); } NativeMethods.ReleaseDC(IntPtr.Zero, screenDC); NativeMethods.DeleteDC(memDc); } } }
private void UpdateWindowSettings(bool enableRenderTarget, DUCE.ChannelSet? channelSet) { MediaContext mctx = MediaContext.From(Dispatcher); // It's possible that this method could be called multiple times in a row // with the same enableRenderTarget value and we'd like to minimize the // number of flushes on the OOB channel by only flushing when transitioning // rather than ever time we get a disable. bool firstTimeRenderTargetDisabled = false; bool firstTimeRenderTargetEnabled = false; if (_isRenderTargetEnabled != enableRenderTarget) { _isRenderTargetEnabled = enableRenderTarget; firstTimeRenderTargetDisabled = !enableRenderTarget; firstTimeRenderTargetEnabled = enableRenderTarget; // Basic idea: the render thread and the UI thread have a // race condition when the UI thread wants to modify // HWND data and the render thread is using it. The render // thread can paint garbage on the screen, and it can also // cause the old data to be set again (ULW issue, hence ULWEx). // // So we tell the render thread to stop rendering and then we // wait for them to stop when disabling the render target by // issuing the UpdateWindowSettings command synchronously on // an out-of-band channel. } // if we are disconnected we are done. if (!_compositionTarget.IsOnAnyChannel) { return; } // // Calculate the client rectangle in screen coordinates. // GetWindowRectsInScreenCoordinates(); Int32 style = UnsafeNativeMethods.GetWindowLong(_hWnd.MakeHandleRef(this), NativeMethods.GWL_STYLE); Int32 exStyle = UnsafeNativeMethods.GetWindowLong(_hWnd.MakeHandleRef(this), NativeMethods.GWL_EXSTYLE); bool isLayered = (exStyle & NativeMethods.WS_EX_LAYERED) != 0; bool isChild = (style & NativeMethods.WS_CHILD) != 0; bool isRTL = (exStyle & NativeMethods.WS_EX_LAYOUTRTL) != 0; int width = _hwndClientRectInScreenCoords.right - _hwndClientRectInScreenCoords.left; int height = _hwndClientRectInScreenCoords.bottom - _hwndClientRectInScreenCoords.top; MILTransparencyFlags flags = MILTransparencyFlags.Opaque; // if (!DoubleUtil.AreClose(_opacity, 1.0)) // { // flags |= MILTransparencyFlags.ConstantAlpha; // } // if (_colorKey.HasValue) // { // flags |= MILTransparencyFlags.ColorKey; // } if (_usesPerPixelOpacity) { flags |= MILTransparencyFlags.PerPixelAlpha; } if (!isLayered && flags != MILTransparencyFlags.Opaque) { // The window is not layered, but it should be -- set the layered flag. UnsafeNativeMethods.SetWindowLong(_hWnd.MakeHandleRef(this), NativeMethods.GWL_EXSTYLE, new IntPtr(exStyle | NativeMethods.WS_EX_LAYERED)); } else if (isLayered && flags == MILTransparencyFlags.Opaque) { // The window is layered but should not be -- unset the layered flag. UnsafeNativeMethods.SetWindowLong(_hWnd.MakeHandleRef(this), NativeMethods.GWL_EXSTYLE, new IntPtr(exStyle & ~NativeMethods.WS_EX_LAYERED)); } else if(isLayered && flags != MILTransparencyFlags.Opaque && _isRenderTargetEnabled && (width == 0 || height == 0)) { // The window is already layered, and it should be. But we are enabling a window // that is has a 0-size dimension. This may cause us to leave the last sprite // on the screen. The best way to get rid of this is to just make the entire // sprite transparent. NativeMethods.BLENDFUNCTION blend = new NativeMethods.BLENDFUNCTION(); blend.BlendOp = NativeMethods.AC_SRC_OVER; blend.SourceConstantAlpha = 0; // transparent UnsafeNativeMethods.UpdateLayeredWindow(_hWnd.h, IntPtr.Zero, null, null, IntPtr.Zero, null, 0, ref blend, NativeMethods.ULW_ALPHA); } isLayered = (flags != MILTransparencyFlags.Opaque); if (channelSet == null) { channelSet = mctx.GetChannels(); } // If this is the first time going from disabled -> enabled, flush // the out of band to make sure all disable packets have been // processed before sending the enable later below. Otherwise, // the enable could be ignored if the disable cookie doesn't match DUCE.Channel outOfBandChannel = channelSet.Value.OutOfBandChannel; if (firstTimeRenderTargetEnabled) { outOfBandChannel.Commit(); outOfBandChannel.SyncFlush(); } // Every UpdateWindowSettings command that disables the render target is // assigned a new cookie. Every UpdateWindowSettings command that enables // the render target uses the most recent cookie. This allows the // compositor to ignore UpdateWindowSettings(enable) commands that come // out of order due to us disabling out-of-band and enabling in-band. if (!_isRenderTargetEnabled) { _disableCookie++; } // // When enabling the render target, stay in-band. This allows any // client-side rendering instructions to be included in the same packet. // Otherwise pass in the OutOfBand handle. // DUCE.Channel channel = channelSet.Value.Channel; DUCE.CompositionTarget.UpdateWindowSettings( _isRenderTargetEnabled ? _compositionTarget.GetHandle(channel) : _compositionTarget.GetHandle(outOfBandChannel), _hwndClientRectInScreenCoords, Colors.Transparent, // _colorKey.GetValueOrDefault(Colors.Black), 1.0f, // (float)_opacity, isLayered ? (_usesPerPixelOpacity ? MILWindowLayerType.ApplicationManagedLayer : MILWindowLayerType.SystemManagedLayer) : MILWindowLayerType.NotLayered, flags, isChild, isRTL, _isRenderTargetEnabled, _disableCookie, _isRenderTargetEnabled ? channel : outOfBandChannel); if (_isRenderTargetEnabled) { // // Re-render the visual tree. // mctx.PostRender(); } else { if (firstTimeRenderTargetDisabled) { outOfBandChannel.CloseBatch(); outOfBandChannel.Commit(); // // Wait for the command to be processed -- [....] flush will take care // of that while being safe w.r.t. zombie partitions. // outOfBandChannel.SyncFlush(); } // If we disabled the render target, we run the risk of leaving it disabled. // One such example is when a window is programatically sized, but then // GetMinMaxInfo denies the change. We do not receive any message that would // allow us to re-enable the render targer. To cover these odd cases, we // post ourselves a message to possible re-enable the render target when // we are done with the current message processing. UnsafeNativeMethods.PostMessage(new HandleRef(this, _hWnd), s_updateWindowSettings, IntPtr.Zero, IntPtr.Zero); } }
private IntPtr CreateWindow(NativeMethods.BitmapHandle hBitmap, int width, int height, bool topMost) { if (_defWndProc == null) { _defWndProc = new MS.Win32.NativeMethods.WndProc(UnsafeNativeMethods.DefWindowProc); } MS.Win32.NativeMethods.WNDCLASSEX_D wndClass = new MS.Win32.NativeMethods.WNDCLASSEX_D(); wndClass.cbSize = Marshal.SizeOf(typeof(MS.Win32.NativeMethods.WNDCLASSEX_D)); wndClass.style = 3; /* CS_HREDRAW | CS_VREDRAW */ wndClass.lpfnWndProc = null; wndClass.hInstance = _hInstance; wndClass.hCursor = IntPtr.Zero; wndClass.lpszClassName = CLASSNAME; wndClass.lpszMenuName = string.Empty; wndClass.lpfnWndProc = _defWndProc; // We chose to ignore re-registration errors in RegisterClassEx on the off chance that the user // wants to open multiple splash screens. _wndClass = MS.Win32.UnsafeNativeMethods.IntRegisterClassEx(wndClass); if (_wndClass == 0) { if (Marshal.GetLastWin32Error() != 0x582) /* class already registered */ { throw new Win32Exception(); } } int screenWidth = MS.Win32.UnsafeNativeMethods.GetSystemMetrics(SM.CXSCREEN); int screenHeight = MS.Win32.UnsafeNativeMethods.GetSystemMetrics(SM.CYSCREEN); int x = (screenWidth - width) / 2; int y = (screenHeight - height) / 2; HandleRef nullHandle = new HandleRef(null, IntPtr.Zero); int windowCreateFlags = (int)NativeMethods.WS_EX_WINDOWEDGE | NativeMethods.WS_EX_TOOLWINDOW | NativeMethods.WS_EX_LAYERED | (topMost ? NativeMethods.WS_EX_TOPMOST : 0); // CreateWindowEx will either succeed or throw IntPtr hWnd = MS.Win32.UnsafeNativeMethods.CreateWindowEx( windowCreateFlags, CLASSNAME, SR.Get(SRID.SplashScreenIsLoading), MS.Win32.NativeMethods.WS_POPUP | MS.Win32.NativeMethods.WS_VISIBLE, x, y, width, height, nullHandle, nullHandle, new HandleRef(null, _hInstance), IntPtr.Zero); // Display the image on the window IntPtr hScreenDC = UnsafeNativeMethods.GetDC(new HandleRef()); IntPtr memDC = UnsafeNativeMethods.CreateCompatibleDC(new HandleRef(null, hScreenDC)); IntPtr hOldBitmap = UnsafeNativeMethods.SelectObject(new HandleRef(null, memDC), hBitmap.MakeHandleRef(null).Handle); NativeMethods.POINT newSize = new NativeMethods.POINT(width, height); NativeMethods.POINT newLocation = new NativeMethods.POINT(x, y); NativeMethods.POINT sourceLocation = new NativeMethods.POINT(0, 0); _blendFunc = new NativeMethods.BLENDFUNCTION(); _blendFunc.BlendOp = NativeMethods.AC_SRC_OVER; _blendFunc.BlendFlags = 0; _blendFunc.SourceConstantAlpha = 255; _blendFunc.AlphaFormat = 1; /*AC_SRC_ALPHA*/ bool result = UnsafeNativeMethods.UpdateLayeredWindow(hWnd, hScreenDC, newLocation, newSize, memDC, sourceLocation, 0, ref _blendFunc, NativeMethods.ULW_ALPHA); UnsafeNativeMethods.SelectObject(new HandleRef(null, memDC), hOldBitmap); UnsafeNativeMethods.ReleaseDC(new HandleRef(), new HandleRef(null, memDC)); UnsafeNativeMethods.ReleaseDC(new HandleRef(), new HandleRef(null, hScreenDC)); if (result == false) { UnsafeNativeMethods.HRESULT.Check(Marshal.GetHRForLastWin32Error()); } return(hWnd); }
/// <summary> /// Updates the position, size, shape, content, and translucency of a layered window. /// </summary> /// <param name="hwnd"> /// A handle to a layered window. A layered window is created by specifying WS_EX_LAYERED when creating the /// window with the CreateWindowEx function. /// </param> /// <param name="hdcDst"> /// A handle to a DC for the screen. This handle is obtained by specifying NULL when calling the function. /// It is used for palette color matching when the window contents are updated. If hdcDst isNULL, the default /// palette will be used. If hdcSrc is NULL, hdcDst must be NULL. /// </param> /// <param name="pptDst"> /// A pointer to a structure that specifies the new screen position of the layered window. If the current /// position is not changing, pptDst can be NULL. /// </param> /// <param name="psize"> /// A pointer to a structure that specifies the new size of the layered window. If the size of the window /// is not changing, psize can be NULL. If hdcSrc is NULL, psize must be NULL. /// </param> /// <param name="hdcSrc"> /// A handle to a DC for the surface that defines the layered window. This handle can be obtained by calling /// the CreateCompatibleDC function. If the shape and visual context of the window are not changing, hdcSrc /// can be NULL. /// </param> /// <param name="pprSrc"> /// A pointer to a structure that specifies the location of the layer in the device context. /// If hdcSrc is NULL, pptSrc should be NULL. /// </param> /// <param name="crKey"> /// A structure that specifies the color key to be used when composing the layered window. /// To generate a COLORREF, use the RGB macro. /// </param> /// <param name="pblend"> /// A pointer to a structure that specifies the transparency value to be used when composing the layered window. /// </param> /// <param name="dwFlags"> /// This parameter can be one of the following values. /// </param> /// <returns> /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. /// To get extended error information, call GetLastError. /// </returns> public static bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, Int32 crKey, ref NativeMethods.BLENDFUNCTION pblend, Int32 dwFlags) { return(NativeMethods.UpdateLayeredWindow(hwnd, hdcDst, ref pptDst, ref psize, hdcSrc, ref pprSrc, crKey, ref pblend, dwFlags)); }
public void UpdateWindow() { if (this.IsDisposed || this.Width <= 0 || this.Height <= 0) return; using (Bitmap backBuffer = new Bitmap(this.Width, this.Height, PixelFormat.Format32bppPArgb)) { using (Graphics gr = Graphics.FromImage(backBuffer)) { gr.SmoothingMode = SmoothingMode.AntiAlias; Point pt = this.PointToScreen(Point.Empty); pt.Offset(-this.Left, -this.Top); Rectangle rc = this.RectangleToScreen(this.ClientRectangle); rc.Offset(-this.Left, -this.Top); if (this.ClientSize.Width > 0 && this.ClientSize.Height > 0) { //Paint the ClientArea gr.FillRectangle(backBrush, rc); //Allow for AutoScroll behaviour using (Bitmap clientBuffer = new Bitmap(this.DisplayRectangle.Width, this.DisplayRectangle.Height, PixelFormat.Format32bppPArgb)) { Point pos = this.AutoScrollPosition; //Paint the Controls foreach (Control ctl in this.Controls) { Rectangle rcCtl = ctl.Bounds; rcCtl.Offset(-pos.X, -pos.Y); ctl.DrawToBitmap(clientBuffer, rcCtl); } gr.DrawImage(clientBuffer, new Rectangle(rc.Location, this.ClientSize), new Rectangle(new Point(-pos.X, -pos.Y), this.ClientSize), GraphicsUnit.Pixel); } } //Paint the NonClientArea gr.SetClip(rc, CombineMode.Exclude); gr.FillPath(backBrush, this.CreateFormShape()); if (this.WindowState != FormWindowState.Minimized) { using (Font scrollFont = new Font("Marlett", SystemInformation.VerticalScrollBarArrowHeight, FontStyle.Regular, GraphicsUnit.Pixel)) { using (StringFormat sf = new StringFormat()) { sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; //Paint any scrollbars if (this.HScroll) { Rectangle hScrollRect = this.RectangleToScreen(new Rectangle(0, this.ClientSize.Height, this.ClientSize.Width, SystemInformation.HorizontalScrollBarHeight)); hScrollRect.Offset(-this.Left, -this.Top); gr.FillRectangle(Brushes.Aqua, hScrollRect); Rectangle thumbRect = new Rectangle(hScrollRect.X, hScrollRect.Y, hScrollRect.Height, hScrollRect.Height); gr.FillRectangle(Brushes.Green, thumbRect); gr.DrawString("3", scrollFont, Brushes.White, thumbRect); NativeMethods.SCROLLBARINFO sbi = new NativeMethods.SCROLLBARINFO(); sbi.cbSize = Marshal.SizeOf(sbi); bool rslt = NativeMethods.GetScrollBarInfo(this.Handle, NativeMethods.OBJID_HSCROLL, ref sbi); thumbRect = this.RectangleToScreen(Rectangle.FromLTRB(sbi.xyThumbTop, this.ClientRectangle.Bottom + 1, sbi.xyThumbBottom, this.ClientRectangle.Bottom + hScrollRect.Height + 1)); thumbRect.Offset(-this.Left, -this.Top); gr.FillRectangle(Brushes.Red, thumbRect); thumbRect = new Rectangle(hScrollRect.Right - hScrollRect.Height, hScrollRect.Y, hScrollRect.Height, hScrollRect.Height); gr.FillRectangle(Brushes.Green, thumbRect); gr.DrawString("4", scrollFont, Brushes.White, thumbRect); } if (this.VScroll) { Rectangle vScrollRect = this.RectangleToScreen(new Rectangle(this.ClientSize.Width, 0, SystemInformation.VerticalScrollBarWidth, this.ClientSize.Height)); vScrollRect.Offset(-this.Left, -this.Top); gr.FillRectangle(Brushes.Aqua, vScrollRect); Rectangle thumbRect = new Rectangle(vScrollRect.X, vScrollRect.Y, vScrollRect.Width, vScrollRect.Width); gr.FillRectangle(Brushes.Green, thumbRect); gr.DrawString("5", scrollFont, Brushes.White, thumbRect); NativeMethods.SCROLLBARINFO sbi = new NativeMethods.SCROLLBARINFO(); sbi.cbSize = Marshal.SizeOf(sbi); bool rslt = NativeMethods.GetScrollBarInfo(this.Handle, NativeMethods.OBJID_VSCROLL, ref sbi); thumbRect = this.RectangleToScreen(Rectangle.FromLTRB(this.ClientRectangle.Right + 1, sbi.xyThumbTop, this.ClientRectangle.Right + vScrollRect.Width + 1, sbi.xyThumbBottom)); thumbRect.Offset(-this.Left, -this.Top); gr.FillRectangle(Brushes.Red, thumbRect); thumbRect = new Rectangle(vScrollRect.X, vScrollRect.Bottom - vScrollRect.Width, vScrollRect.Width, vScrollRect.Width); gr.FillRectangle(Brushes.Green, thumbRect); gr.DrawString("6", scrollFont, Brushes.White, thumbRect); } //Paint the borders Size hBorderSize = new Size(this.Width, 2); Size vBorderSize = new Size(2, this.Height); Rectangle borderRect = new Rectangle(new Point(0, 0), hBorderSize); gr.FillRectangle(borderBrush, borderRect); borderRect = new Rectangle(new Point(0, 17), hBorderSize); gr.FillRectangle(Brushes.Aqua, borderRect); borderRect = new Rectangle(new Point(0, this.Height - 2), hBorderSize); gr.FillRectangle(Brushes.Aqua, borderRect); borderRect = new Rectangle(new Point(0, 0), vBorderSize); gr.FillRectangle(Brushes.Aqua, borderRect); borderRect = new Rectangle(new Point(this.Width - 2, 0), vBorderSize); gr.FillRectangle(Brushes.Aqua, borderRect); //Paint title bar Size titleSize = new Size(this.Width-4, 15); Rectangle titleRect = new Rectangle(new Point(2, 2), titleSize); //Paint the Caption String sf.Alignment = StringAlignment.Near; sf.Trimming = StringTrimming.EllipsisCharacter; gr.DrawString(this.Text, this.Font, Brushes.White, 4, 4, sf); } } gr.ResetClip(); } } //Use Interop to transfer the bitmap to the screen. IntPtr screenDC = NativeMethods.GetDC(IntPtr.Zero); IntPtr memDC = NativeMethods.CreateCompatibleDC(screenDC); IntPtr hBitmap = backBuffer.GetHbitmap(Color.FromArgb(0)); IntPtr oldBitmap = NativeMethods.SelectObject(memDC, hBitmap); NativeMethods.BLENDFUNCTION blend = new NativeMethods.BLENDFUNCTION(255); Point ptDst = this.Location; Size szDst = backBuffer.Size; Point ptSrc = Point.Empty; NativeMethods.UpdateLayeredWindow(this.Handle, screenDC, ref ptDst, ref szDst, memDC, ref ptSrc, 0, ref blend, NativeMethods.ULW_ALPHA); NativeMethods.SelectObject(memDC, oldBitmap); NativeMethods.DeleteObject(hBitmap); NativeMethods.DeleteDC(memDC); NativeMethods.DeleteDC(screenDC); } }