using
System;
using
System.Drawing;
using
System.Collections;
using
System.ComponentModel;
using
System.Windows.Forms;
using
System.Data;
using
System.Runtime.InteropServices;
namespace
ShortButComplete
{
///
<summary>
/// Creates a simple
form, nothing is done in the client area at initialization
/// but in the
nonclient area there is a slider that controls the opacity of the window
///
</summary>
public class
Form1 : System.Windows.Forms.Form
{
///
<summary>
///
Required designer variable.
///
</summary>
///
private
System.ComponentModel.Container components = null;
//Interop
declarations
[DllImport("user32.dll")]
public
static extern
IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
public
static extern
IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll")]
public
static extern
int ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("user32.dll")]
public
static extern
int SendMessage(IntPtr hWnd,
int message, int
wParam, IntPtr lParam);
//Message
constants from winuser.h
//constant
for event that redwaws the window form
public
const int
WM_NCPAINT = 0x0085;
//.....left/right
button down/up, mouse move... all of the following...
private
const int
WM_NCHITTEST = 0x84;
private
const int
WM_NCMOUSEMOVE = 0x00A0;
private
const int
WM_NCLBUTTONDOWN = 0x00A1;
private
const int
WM_NCLBUTTONUP = 0x00A2;
private
const int
WM_NCLBUTTONDBLCLK = 0x00A3;
private
const int
WM_NCRBUTTONDOWN = 0x00A4;
private
const int
WM_NCRBUTTONUP = 0x00A5;
private
const int
WM_NCRBUTTONDBLCLK = 0x00A6;
private
const int
WM_NCMBUTTONDOWN = 0x00A7;
private
const int
WM_NCMBUTTONUP = 0x00A8;
private
const int
WM_NCMBUTTONDBLCLK = 0x00A9;
//variables
bool
leftBtnPressed = false;
//test if mouse is pressed
int
Y=6; //pixels from top to do the drawing
int
_sliderValue=0;
int
_ptOffset; //the offset of the pointer within
the slider button
Rectangle
_sliderRect; //The rectangle for the scale
Rectangle
_sliderButton; //Position and size of the button
public
Form1()
{
//
//
Required for Windows Form Designer support
//
InitializeComponent();
//
//
TODO: Add any constructor code after InitializeComponent call
//
}
///
<summary>
///
Clean up any resources being used.
///
</summary>
protected
override void
Dispose( bool disposing )
{
if(
disposing )
{
if
(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
///
<summary>
///
Repaints the NC area
///
</summary>
void
NCInvalidate()
{
SendMessage(this.Handle, WM_NCPAINT, 1,
IntPtr.Zero);
}
///
<summary>
///
Checks to see if the mouse pointer is in the slider button
///
</summary>
///
<remarks>
///
NC mouse values are returned in screen coordinates so for a form
///
we just need to subtract the form's location to obtain values that are
///
relative to the non-client area.
///
///
PointToClient can deliver negative values that are no good
///
</remarks>
///
<param name="pt">The
point to test</param>
///
<returns>True
if the point is in the slider button</returns>
bool
InSlider(Point pt)
{
Rectangle rc=_sliderButton;
pt.Offset(-Location.X,-Location.Y);
if(rc.Contains(pt))
return
true;
return
false;
}
//Override
the Winproc function.
protected
override void
WndProc(ref Message m)
{
//intercept
the messages
switch
(m.Msg)
{
case
WM_NCPAINT:
{
base.WndProc
(ref m); //do the
default behaviour
Paint_NC_(m.HWnd); //then paint the slider
}
break;
//get
the leftbutton down message
case
WM_NCLBUTTONDOWN:
{
Point pt = new Point( m.LParam.ToInt32()
) ;
if(InSlider(pt))
{
_ptOffset=(pt.X-this.Location.X)-_sliderButton.Left;
leftBtnPressed = true;
NCInvalidate();
m.Result=IntPtr.Zero;
}
else
base.WndProc(ref
m);
}
break;
case
WM_NCMOUSEMOVE:
{
Point pt = new Point( m.LParam.ToInt32()
);
if(leftBtnPressed)
{
//calculate
the position of the slider and then the value 0-100
pt.Offset(-(Location.X+_ptOffset),-Location.Y);
_sliderValue = (int)(0.5f+(100f/(_sliderRect.Width-_sliderButton.Width)*(pt.X-this.Width/2)));
_sliderValue = _sliderValue < 0 ? 0 : _sliderValue > 100 ? 100 :
_sliderValue;
this.SetTransparency(_sliderValue);
NCInvalidate();
m.Result=IntPtr.Zero;
}
else
base.WndProc(ref
m);
}
break;
case
WM_NCLBUTTONUP:
if(leftBtnPressed)
{
leftBtnPressed=false;
m.Result=IntPtr.Zero;
NCInvalidate();
}
base.WndProc(ref
m);
break;
default
:
base.WndProc(ref
m);
break;
}
}
protected
void Paint_NC_(System.IntPtr hWnd)
{
IntPtr
hDC = GetWindowDC(hWnd); //(create handler) - get
window device context - whole are, including NonClient
Graphics g = Graphics.FromHdc(hDC); //create
graphics object to draw with form handler
_sliderRect=new Rectangle(this.Width/2,
6,
this.Width/2-(2*SystemInformation.IconSize.Width),
14);
//Drawing
the slider according to the mouse position
//draw
the scale lines
g.DrawLine(Pens.DarkGray,
_sliderRect.Left,
_sliderRect.Top+_sliderRect.Height/2,
_sliderRect.Right,
_sliderRect.Top+_sliderRect.Height/2);
g.DrawLine(Pens.LightGray,
_sliderRect.Left,
_sliderRect.Top+_sliderRect.Height/2-1,
_sliderRect.Right,
_sliderRect.Top+_sliderRect.Height/2-1);
for(int
x=0;x<11;x++)
{
int
w=_sliderRect.Width;
g.DrawLine(Pens.DarkGray,
_sliderRect.Left+(x*w/10),
_sliderRect.Top+4,
_sliderRect.Left+(x*w/10),
_sliderRect.Bottom-5);
g.DrawLine(Pens.LightGray,
_sliderRect.Left+(x*w/10)-1,
_sliderRect.Top+4,
_sliderRect.Left+(x*w/10)-1,
_sliderRect.Bottom-5);
}
ButtonState bs=ButtonState.Normal;
if(leftBtnPressed)
bs=ButtonState.Pushed;
//draw
the button
_sliderButton=new Rectangle(this.Width/2+
(int)((_sliderValue/100f)*(_sliderRect.Width-10)),
Y,
10,
14);
ControlPaint.DrawButton(g,_sliderButton,bs);
//Dispose
of the graphics.
g.Dispose();
ReleaseDC(hWnd, hDC);
}
public
void SetTransparency(int
XPosition)
{
float
op = _sliderValue;
op /=
100; //grows from 0.01 to 1 , by 0.01 step
this.Opacity
= 1 - 0.5 * op;
}
protected
override void
OnSizeChanged(EventArgs e)
{
this.NCInvalidate();
base.OnSizeChanged
(e);
}
#region
Windows Form Designer generated code
///
<summary>
///
Required method for Designer support - do not modify
///
the contents of this method with the code editor.
///
</summary>
private
void InitializeComponent()
{
//
//
Form1
//
this.AutoScaleBaseSize
= new System.Drawing.Size(5, 13);
this.ClientSize
= new System.Drawing.Size(322, 295);
this.Name
= "Form1";
this.Text
= "Opacity Slider";
//this.Load
+= new System.EventHandler(this.Form1_Load);
}
#endregion
///
<summary>
///
The main entry point for the application.
///
</summary>
[STAThread]
static
void Main()
{
Application.Run(new
Form1());
}
}
}