using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;

[assembly:TagPrefix("SignNameCustomControl", "relay")]
namespace SignNameCustomControl
{
 /// <summary>
 /// Summary description for SignNameControl.
 /// </summary>
 [DefaultProperty("Text"),
  ToolboxData("<{0}:SignNameControl runat=server></{0}:SignNameControl>")]  
 public class SignNameControl : System.Web.UI.WebControls.WebControl
 {
      #region Const fields     
      private const int MM_ANISOTROPIC = 8;
      #endregion

      #region Enumerations
     
      public enum PenSizeEnum
      {
         /// <summary>
         /// ??????
         /// </summary>
         Fine = 1,

         /// <summary>
         /// ????
         /// </summary>
         Bold = 2
      }

      /// <summary>
      /// ????(?????)
      /// </summary>
      public enum DisplayModeEnum
      {
         Edit = 1,
         View = 2
      }

      /// <summary>
      /// ????????
      /// </summary>
      private enum EmfToWmfBitsFlags
      {
         /// <summary>
         ///Use the default conversion
         /// </summary>
         EmfToWmfBitsFlagsDefault = 0x00000000,
        
         /// <summary>
         /// Embedded the source of the EMF metafiel within the resulting WMF metafile
         /// </summary>
         EmfToWmfBitsFlagsEmbedEmf = 0x00000001,

         /// <summary>
         /// Place a 22-byte header in the resulting WMF file.  The header is required for the metafile to be considered placeable.
         /// </summary>
         EmfToWmfBitsFlagsIncludePlaceable = 0x00000002,

         /// <summary>
         /// Don't simulate clipping by using the XOR operator.
         /// </summary>
         EmfToWmfBitsFlagsNoXORClip = 0x00000004
      }
      #endregion

      #region Private Variables
      private string _signatureHex = string.Empty;
      private string _signatureCoordinate = string.Empty;
      private int _signatureWidth = 400;
      private int _signatureHeight = 120;
      private PenSizeEnum _penSize = PenSizeEnum.Fine;
      private DisplayModeEnum _mode = DisplayModeEnum.View; 
      #endregion

      #region Public properties
      /// <summary>
      /// ????????????,?????: "x1~y1:x2~y2"
      /// </summary>
      public string SignatureCoordinate
      {
         get{return txtCoords.Text.ToString();}
         set{txtCoords.Text = value;}
      }

      /// <summary>
      /// ????
      /// </summary>
      public int SignatureWidth
      {
         get{return _signatureWidth;}
         set{_signatureWidth = value;}
      }
     
      /// <summary>
      /// ????
      /// </summary>
      public int SignatureHeight
      {
         get{return _signatureHeight;}
         set{_signatureHeight = value;}
      }

      /// <summary>
      /// ???????
      /// </summary>
      public PenSizeEnum PenSize
      {
         get{return _penSize;}
         set{_penSize = value;}
      }

      /// <summary>
      /// ?????16????
      /// </summary>
      public string signatureHex
      {
         get{return convertCoordinatesToHex();}
         set{_signatureHex = value;}
      }

      /// <summary>
      /// ????????
      /// </summary>
      public DisplayModeEnum DisplayMode
      {
         get{return _mode;}
         set{_mode = value;}
      }
      #endregion

      #region Member Variables
      private TextBox txtCoords;
      #endregion

      #region Private Methods
     
      [DllImportAttribute("gdiplus.dll")]
      private static extern uint GdipEmfToWmfBits( IntPtr _hEmf, uint _bufferSize, byte[] _buffer, int _mappingMode, EmfToWmfBitsFlags _flags );

     
      private string convertCoordinatesToHex()
      {
         string signatureHex = string.Empty;

         if( SignatureCoordinate.Length > 0 )
         {
            StringBuilder signatureHexVaule = new StringBuilder();     
            MemoryStream memoryStream = new MemoryStream();
            System.Drawing.Image signatureTemplateImg = new System.Drawing.Bitmap( SignatureWidth, SignatureHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb );                 
            Graphics SignatureGraphs = Graphics.FromImage( signatureTemplateImg );     
            SignatureGraphs.FillRectangle( Brushes.White, 0, 0, signatureTemplateImg.Width, signatureTemplateImg.Height );           
           
            Metafile signatureMetaFile = null;                      
            IntPtr hdc;        
            try
            {              
               using( SignatureGraphs = Graphics.FromImage( signatureTemplateImg ) )
               {
                  hdc = SignatureGraphs.GetHdc();
                  signatureMetaFile = new Metafile( memoryStream, hdc );
                  SignatureGraphs.ReleaseHdc( hdc );
               }            
               using( SignatureGraphs = Graphics.FromImage( signatureMetaFile ) )
               {
                  SignatureGraphs.DrawImage( signatureTemplateImg, new System.Drawing.Rectangle( 0, 0, signatureTemplateImg.Width, signatureTemplateImg.Height ) );
                  SignatureGraphs.DrawRectangle(new Pen(Color.White, 1), 0, 0, SignatureWidth, SignatureHeight);

                  Pen pen = new Pen( Color.Black, 1 );
                  string []points = SignatureCoordinate.Split( ':' );
                  string []point = null;
               
                  for( int i = 0; i < points.Length - 1 ; i++ )
                  {
                     point = points[i].Split( '~' );
                     if( point.Length == 4 )
                     {
                        SignatureGraphs.DrawRectangle( pen, float.Parse( point[0] ), float.Parse( point[1] ), float.Parse( point[2] ), float.Parse( point[3] ) );
                     }
                  }
               }              
              
               IntPtr hEmf = signatureMetaFile.GetHenhmetafile();             
              
               uint bufferSize = GdipEmfToWmfBits( hEmf, 0, null, MM_ANISOTROPIC, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault );
               byte[] buffer = new byte[bufferSize];

               GdipEmfToWmfBits( hEmf, bufferSize, buffer, MM_ANISOTROPIC, EmfToWmfBitsFlags.EmfToWmfBitsFlagsDefault );              
              
               for( int i = 0; i < buffer.Length; ++i )
               {
                  signatureHexVaule.Append( String.Format( "{0:X2}", buffer[i] ) );
               }

               signatureHex = signatureHexVaule.ToString();
            }
            finally
            {
               if( SignatureGraphs != null )
               {
                  SignatureGraphs.Dispose();
               }

               if( signatureMetaFile != null )
               {
                  signatureMetaFile.Dispose();
               }

               if( memoryStream != null )
               {
                  memoryStream.Close();
               }
            }
         }

         return signatureHex;
      }
      #endregion

      #region Protected Members
      /// <summary>
      /// ??????TextBox???????
      /// </summary>
      /// <param name="e">EventArgs</param>
      protected override void OnInit( EventArgs e )
      {
         txtCoords = new TextBox();
         txtCoords.ID = "txtCoords";
         txtCoords.Style.Add( "display", "none" );
         Controls.Add( txtCoords );
         base.OnInit( e );
      }

      protected override void Render(HtmlTextWriter writer)
      {
         if( this._mode == DisplayModeEnum.Edit )
         {           
            writer.WriteLine( "<style type=\"text/css\">" );
            writer.WriteLine( ".point {position: absolute; background-color: black; color: black; width: 1px; height: 1px;font-size: "+ Convert.ToInt16( _penSize ) * 2 + "px}" );
            writer.WriteLine( "</style>" );
            writer.WriteLine( "<table border=\"1\" cellpadding=\"0\" cellspacing=\"10\" ID=\"Panel\">" );
            writer.WriteLine( "<tr>" );
            writer.WriteLine( "<td height=\"40\" width=\"120\">" );
            writer.WriteLine( "<div id=\"Canvas\" style=\"background-color: white; width: " + _signatureWidth +"px; height: " + _signatureHeight + "px\"></div>" );
            writer.WriteLine( "</td>" );
            writer.WriteLine( "</tr>" );
            writer.WriteLine( "</table>\n" );           
            string applicationDirectory = this.Page.Request.PhysicalApplicationPath;
            writer.WriteLine( "<script language='JavaScript' src='" + applicationDirectory + "JS/SignatureCapture.js'></script>" );

            writer.WriteLine( "<script language='JavaScript'>" );
            writer.WriteLine( "window.onload = initialize" );
            writer.WriteLine( "function initialize(){" );
            writer.WriteLine( " load('" + txtCoords.ClientID + "');}");
            writer.WriteLine( "</script>" );
         }
         else
         {           
            writer.WriteLine( "<img src ='DisplayImage.aspx'" + " width=" + _signatureWidth + " height=" + _signatureHeight + " />" );
         }
         base.Render ( writer );
      }
      #endregion
 }
}



在线签名