Click here to Skip to main content
15,897,181 members
Articles / Programming Languages / C#

A .NET Wizard control

Rate me:
Please Sign up or sign in to vote.
4.86/5 (89 votes)
24 Apr 2003CPOL7 min read 668.2K   8.7K   216  
A .NET Wizard control for the VS.IDE and client apps
#region Using directives
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Text;
using System.Data;
using System.Windows.Forms;
using System.Diagnostics;
using UtilityLibrary.General;
#endregion

namespace UtilityLibrary.WinControls
{
  /// <summary>
  /// Summary description for VSNetButton.
  /// </summary>
  public class ButtonEx : System.Windows.Forms.Button
  {
    #region Class members
    private bool mouseDown = false;
    private bool mouseEnter = false;

    private StringFormat m_format = new StringFormat();
    #endregion
    
    #region Class Initialize/Finalize methods
    public ButtonEx()
    {
      SetStyle( ControlStyles.AllPaintingInWmPaint |
        ControlStyles.Opaque |
        ControlStyles.UserPaint |
        ControlStyles.DoubleBuffer, true );

      m_format.Trimming     = StringTrimming.None;
      m_format.FormatFlags  = StringFormatFlags.LineLimit;
      m_format.HotkeyPrefix = HotkeyPrefix.Show;

      base.ImageAlign = ContentAlignment.MiddleLeft;
    }
    #endregion

    #region Class Overrides
    protected override void OnMouseEnter(EventArgs e)
    {
      mouseEnter = true;
      base.OnMouseEnter(e);
      Invalidate();
    
    }

    protected override void OnMouseLeave(EventArgs e)
    {
      mouseEnter = false;
      base.OnMouseLeave(e);
      Invalidate();
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
      base.OnMouseDown(e);
      mouseDown = true;
      Invalidate();
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
      base.OnMouseUp(e);
      mouseDown = false;
      Invalidate();
    }

    protected override void OnGotFocus(EventArgs e)
    {
      base.OnGotFocus(e);
      Invalidate();
    }
        
    protected override void OnLostFocus(EventArgs e)
    {
      base.OnLostFocus(e);
      Invalidate();
    }
    #endregion
    
    #region Class Drawing methods
    private StringAlignment GetHorizontalAlign( ContentAlignment align )
    {
      StringAlignment retValue = StringAlignment.Near;

      switch( align )
      {
        case ContentAlignment.BottomRight:
        case ContentAlignment.MiddleRight:
        case ContentAlignment.TopRight:
          retValue = StringAlignment.Far;
          break;

        case ContentAlignment.BottomCenter:
        case ContentAlignment.MiddleCenter:
        case ContentAlignment.TopCenter:
          retValue = StringAlignment.Center;
          break;

        case ContentAlignment.BottomLeft:
        case ContentAlignment.MiddleLeft:
        case ContentAlignment.TopLeft:
        default:
          retValue = StringAlignment.Near;
          break;
      }

      return retValue;
    }

    private StringAlignment GetVerticalAlign( ContentAlignment align )
    {
      StringAlignment retValue = StringAlignment.Near;

      switch( align )
      {
        case ContentAlignment.BottomRight:
        case ContentAlignment.BottomCenter:
        case ContentAlignment.BottomLeft:
          retValue = StringAlignment.Far;
          break;

        case ContentAlignment.MiddleRight:
        case ContentAlignment.MiddleCenter:
        case ContentAlignment.MiddleLeft:
          retValue = StringAlignment.Center;
          break;

        case ContentAlignment.TopRight:
        case ContentAlignment.TopLeft:
        case ContentAlignment.TopCenter:
        default:
          retValue = StringAlignment.Near;
          break;
      }

      return retValue;
    }


    protected override void OnPaint( PaintEventArgs pe )
    {
      //base.OnPaint(pe);
      Graphics g = pe.Graphics;

      bool gotFocus = Focused;

      if( mouseDown && Enabled )
      {
        DrawButtonState( g, DrawState.Pressed );
        return;
      }
      else if( ( gotFocus || mouseEnter ) && Enabled ) 
      {
        DrawButtonState( g, DrawState.Hot );
        return;
      }
      else
      {
        DrawButtonState( g, ( Enabled ) ? DrawState.Normal : DrawState.Disable );
      }
    }

    protected void DrawButtonState( Graphics g, DrawState state )
    {
      DrawBackground( g, state );
      Rectangle rc = ClientRectangle;
      Rectangle rcText = Rectangle.Inflate( ClientRectangle, -1, -1 );

      // draw Image
      if( Image != null )
      {
        SizeF sizeF   = Image.PhysicalDimension;
        int imgWidth  = (int)sizeF.Width;
        int imgHeight = (int)sizeF.Height;
        
        StringAlignment imgVAlign = GetVerticalAlign( ImageAlign );
        StringAlignment imgHAlign = GetHorizontalAlign( ImageAlign );
        
        int minWid = Width - 2, minHg = Height - 2;
        
        minWid = Math.Min( minWid, imgWidth );
        minHg = Math.Min( minHg, imgHeight );

        int xPos = Math.Min( minHg, minWid ) + 2;

        Bitmap bmp = new Bitmap( Image, new Size( minWid, minHg ) );

        int y = 1; 

        if( imgVAlign == StringAlignment.Center )
        {
          y = ( Height - bmp.Height ) / 2;
        }
        else if( imgVAlign == StringAlignment.Far )
        {
          y = ( Height - bmp.Height - 1 );
        }

        switch( imgHAlign )
        {
          case StringAlignment.Near:
            rcText.X = xPos;  rcText.Width -= xPos;
            DrawImage( g, state, bmp, 2+(xPos-minWid)/2, y );
            break;

          case StringAlignment.Far:
            rcText.Width = rcText.Right - xPos;
            DrawImage( g, state, bmp, rcText.Right + (xPos-minWid)/2 - 2, y );
            break;
        }

        bmp.Dispose();
      }

      // draw Text
      DrawText( g, Text, state, rcText );
    }

    protected void DrawBackground( Graphics g, DrawState state )
    {
      Rectangle rc = ClientRectangle;
      
      // Draw background
      if( state == DrawState.Normal || state == DrawState.Disable )
      {
        g.FillRectangle( SystemBrushes.Control, rc );
        
        Pen p = ( state == DrawState.Disable ) ? SystemPens.ControlDark : SystemPens.ControlDarkDark;
        
        // Draw border rectangle
        g.DrawRectangle( p, rc.Left, rc.Top, rc.Width-1, rc.Height-1);

      }
      else if( state == DrawState.Hot || state == DrawState.Pressed  )
      {
        // Erase whaterver that was there before
        if ( state == DrawState.Hot )
          g.FillRectangle( ColorUtil.VSNetSelectionBrush, rc );
        else
          g.FillRectangle( ColorUtil.VSNetPressedBrush, rc );
        
        // Draw border rectangle
        g.DrawRectangle( SystemPens.Highlight, rc.Left, rc.Top, rc.Width-1, rc.Height-1 );
      }
    }

    protected void DrawImage( Graphics g, DrawState state, Image image, int x, int y )
    {
      SizeF sizeF = Image.PhysicalDimension;
      int imageWidth = (int)sizeF.Width;
      int imageHeight = (int)sizeF.Height;
      
      if( state == DrawState.Normal )
      {
        g.DrawImage(Image, x, y, imageWidth, imageHeight);
      }
      else if( state == DrawState.Disable )
      {
        ControlPaint.DrawImageDisabled(g, Image, x, y, SystemColors.Control);
      }
      else if( state == DrawState.Pressed || state == DrawState.Hot )
      {
        ControlPaint.DrawImageDisabled(g, Image, x+1, y, SystemColors.Control);
        g.DrawImage(Image, x, y-1, imageWidth, imageHeight);                 
      }
    }

    protected void DrawText( Graphics g, string Text, DrawState state, Rectangle rc )
    {
      m_format.Alignment = GetHorizontalAlign( TextAlign );
      m_format.LineAlignment = GetVerticalAlign( TextAlign );

      g.DrawString( Text, Font, 
        ( state == DrawState.Disable ) ? SystemBrushes.ControlDark : SystemBrushes.ControlText, 
        rc, m_format );
    }
    #endregion

    private void ResetFlags()
    {
      mouseDown = false;
      mouseEnter = false;
    }

    protected override void OnVisibleChanged(System.EventArgs e)
    {
      base.OnVisibleChanged( e );
      if( !Visible ) ResetFlags();
    }

    protected override void OnEnabledChanged(System.EventArgs e)
    {
      base.OnEnabledChanged( e );
      if( !Enabled ) ResetFlags();
    }
  }

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO ArtfulBits Inc.
Ukraine Ukraine
Name:Kucherenko Oleksandr

Born:September 20, 1979

Platforms: Win32, Linux; - well known and MS-DOS; Win16; OS/2 - old time not touched;

Hardware: IBM PC

Programming Languages: Assembler (for Intel 80386); Borland C/C++; Borland Pascal; Object Pascal; Borland C++Builder; Delphi; Perl; Java; Visual C++; Visual J++; UML; XML/XSL; C#; VB.NET; T-SQL; PL/SQL; and etc.

Development Environments: MS Visual Studio 2001-2008; MS Visual C++; Borland Delphi; Borland C++Builder; C/C++ any; Rational Rose; GDPro; Together and etc.

Libraries: STL, ATL, WTL, MFC, NuMega Driver Works, VCL; .NET 1.0, 1.1, 2.0, 3.5; and etc.

Technologies: Client/Server; COM; DirectX; DirectX Media; BDE; HTML/DHTML; ActiveX; Java Servlets; DCOM; COM+; ADO; CORBA; .NET; Windows Forms; GDI/GDI+; and etc.

Application Skills: Databases - design and maintain, support, programming; GUI Design; System Programming, Security; Business Software Development. Win/Web Services development and etc.

Comments and Discussions