2017-01-16 20:59:50 +01:00
/ * Copyright ( c ) Citrix Systems , Inc .
2013-06-24 13:41:48 +02:00
* All rights reserved .
*
* Redistribution and use in source and binary forms ,
* with or without modification , are permitted provided
* that the following conditions are met :
*
* * Redistributions of source code must retain the above
* copyright notice , this list of conditions and the
* following disclaimer .
* * Redistributions in binary form must reproduce the above
* copyright notice , this list of conditions and the
* following disclaimer in the documentation and / or other
* materials provided with the distribution .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES ,
* INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING ,
* BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS
* INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY ,
* WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING
* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE .
* /
using System ;
using System.Drawing ;
using System.Drawing.Drawing2D ;
using System.Runtime.InteropServices ;
using System.Windows.Forms ;
using XenAdmin.Core ;
namespace XenAdmin.Controls
{
2018-03-20 14:23:00 +01:00
// Taken from http://209.85.165.104/search?q=cache:hnUUN2Zhi7YJ:www.developersdex.com/vb/message.asp%3Fp%3D2927%26r%3D5855234+NativeMethods.GetDCEx&hl=en&ct=clnk&cd=1&gl=uk&client=firefox-a
2013-06-24 13:41:48 +02:00
public class BlueBorderPanel : DoubleBufferedPanel
{
private Color borderColor = Drawing . XPBorderColor ;
public Color BorderColor
{
get { return borderColor ; }
set
{
if ( borderColor ! = value )
{
borderColor = value ;
NativeMethods . SendMessage ( this . Handle ,
NativeMethods . WM_NCPAINT ,
( IntPtr ) 1 , IntPtr . Zero ) ;
}
}
}
protected override void OnResize ( EventArgs e )
{
base . OnResize ( e ) ;
NativeMethods . SendMessage ( this . Handle ,
NativeMethods . WM_NCPAINT , ( IntPtr ) 1 , IntPtr . Zero ) ;
}
protected override void WndProc ( ref Message m )
{
if ( m . Msg = = NativeMethods . WM_NCPAINT )
{
if ( this . Parent ! = null )
{
NCPaint ( ) ;
m . WParam = GetHRegion ( ) ;
base . DefWndProc ( ref m ) ;
NativeMethods . DeleteObject ( m . WParam ) ;
m . Result = ( IntPtr ) 1 ;
}
}
base . WndProc ( ref m ) ;
}
private void NCPaint ( )
{
if ( this . Parent = = null )
return ;
if ( this . Width < = 0 | | this . Height < = 0 )
return ;
IntPtr windowDC = NativeMethods . GetDCEx ( this . Handle ,
IntPtr . Zero , NativeMethods . DCX_CACHE |
NativeMethods . DCX_WINDOW |
NativeMethods . DCX_CLIPSIBLINGS |
NativeMethods . DCX_LOCKWINDOWUPDATE ) ;
if ( windowDC . Equals ( IntPtr . Zero ) )
return ;
using ( Bitmap bm = new Bitmap ( this . Width , this . Height ,
System . Drawing . Imaging . PixelFormat . Format32bppPArgb ) )
{
using ( Graphics g = Graphics . FromImage ( bm ) )
{
Rectangle borderRect = new Rectangle ( 0 , 0 ,
Width - 1 , Height - 1 ) ;
using ( Pen borderPen = new Pen ( this . borderColor , 1 ) )
{
borderPen . Alignment = PenAlignment . Inset ;
g . DrawRectangle ( borderPen , borderRect ) ;
}
// Create and Apply a Clip Region to the WindowDC
using ( Region Rgn = new Region ( new
Rectangle ( 0 , 0 , Width , Height ) ) )
{
Rgn . Exclude ( new Rectangle ( 1 , 1 , Width - 2 , Height - 2 ) ) ;
IntPtr hRgn = Rgn . GetHrgn ( g ) ;
if ( ! hRgn . Equals ( IntPtr . Zero ) )
NativeMethods . SelectClipRgn ( windowDC , hRgn ) ;
IntPtr bmDC = g . GetHdc ( ) ;
IntPtr hBmp = bm . GetHbitmap ( ) ;
IntPtr oldDC = NativeMethods . SelectObject ( bmDC ,
hBmp ) ;
NativeMethods . BitBlt ( windowDC , 0 , 0 , bm . Width ,
bm . Height , bmDC , 0 , 0 , NativeMethods . SRCCOPY ) ;
NativeMethods . SelectClipRgn ( windowDC , IntPtr . Zero ) ;
NativeMethods . DeleteObject ( hRgn ) ;
g . ReleaseHdc ( bmDC ) ;
NativeMethods . SelectObject ( oldDC , hBmp ) ;
NativeMethods . DeleteObject ( hBmp ) ;
bm . Dispose ( ) ;
}
}
}
NativeMethods . ReleaseDC ( this . Handle , windowDC ) ;
}
private IntPtr GetHRegion ( )
{
//Define a Clip Region to pass back to WM_NCPAINTs wParam.
//Must be in Screen Coordinates.
IntPtr hRgn ;
Rectangle winRect = this . Parent . RectangleToScreen ( this . Bounds ) ;
Rectangle clientRect =
this . RectangleToScreen ( this . ClientRectangle ) ;
Region updateRegion = new Region ( winRect ) ;
updateRegion . Complement ( clientRect ) ;
using ( Graphics g = this . CreateGraphics ( ) )
hRgn = updateRegion . GetHrgn ( g ) ;
updateRegion . Dispose ( ) ;
return hRgn ;
}
}
internal class NativeMethods
{
[DllImport("user32.dll")]
public static extern IntPtr SendMessage ( IntPtr hWnd , int msg ,
IntPtr wParam ,
IntPtr lParam ) ;
[DllImport("gdi32.dll")]
public static extern int SelectClipRgn ( IntPtr hdc , IntPtr hrgn ) ;
[DllImport("gdi32.dll")]
public static extern IntPtr SelectObject ( IntPtr hdc ,
IntPtr hgdiobj ) ;
[DllImport("gdi32.dll")]
public static extern bool BitBlt ( IntPtr hdcDest ,
int nXDest , int nYDest ,
int nWidth , int nHeight ,
IntPtr hdcSrc ,
int nXSrc , int nYSrc , int dwRop ) ;
[DllImport("gdi32.dll")]
public static extern bool DeleteObject ( IntPtr hObject ) ;
[DllImport("user32.dll")]
public static extern IntPtr GetDCEx ( IntPtr hWnd , IntPtr hrgnClip ,
int flags ) ;
[DllImport("user32.dll")]
public static extern int ReleaseDC ( IntPtr hWnd , IntPtr hDC ) ;
public const int WM_NCPAINT = 0x85 ;
public const int DCX_WINDOW = 0x1 ;
public const int DCX_CACHE = 0x2 ;
public const int DCX_CLIPCHILDREN = 0x8 ;
public const int DCX_CLIPSIBLINGS = 0x10 ;
public const int DCX_LOCKWINDOWUPDATE = 0x400 ;
public const int SRCCOPY = 0xCC0020 ;
}
}