.
In Depth Banner
Skip Navigation Links

Select your preferred language

Non-client mouse operations

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());

    }

 

  }

}

 

Return to the article.

Copyright © Bob Powell 2000-.  All rights reserved.