Skip to main content

Signature Capture for windows mobile 6

This is about capturing signature in windows mobile 6 application. This is part of my last project I think it will help you
  • Visual studio 2008
  • Windows Mobile 6 professional SDK

Design the user interface as following  



Use a Panel to draw the signature and make sure according to my code its size should be 234, 154

Add following code to the form...

Code:
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlServerCe;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using signatureD;
using System.IO;
using System.Reflection;
using System.Drawing.Imaging;
using System.Collections;
using System.Runtime.InteropServices;
using System.Web;

namespace StoneWheelTestPOD
{
    public partial class signatureD : Form
    {
        string Img;


        private string AppPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
        private Signature cSignature;

        public signatureD(string code)
        {
            InitializeComponent();
            cSignature = new Signature();
            cSignature.Location = SignPanel.Location;
            cSignature.Size = SignPanel.Size;
            this.Controls.Add(cSignature);
            cSignature.Clear(true);
            Cursor.Current = Cursors.Default;

            cSignature.Focus();            
        }
  
        private void ClearBtn_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;

            //Reset the Signature Component and load with a WHITE picture
            cSignature.Clear(true);
            Cursor.Current = Cursors.Default;
        }

        private void acceptBtn_Click(object sender, EventArgs e)
        {           
            Cursor.Current = Cursors.WaitCursor;          
            //Save to a File            
            cSignature.Save(Path.Combine(AppPath, "signature.bmp"));
            //Reset the Signature Component and load with a WHITE picture after saving. Remove if dont want to reset.
            cSignature.Clear(false);
            Cursor.Current = Cursors.Default;
        }


        private void cancelBtn_Click(object sender, EventArgs e)
        {
            this.Dispose();
            //try
            //{
            //    Cursor.Current = Cursors.WaitCursor;

            //    //Load any existing file of same size 
            //    //Here we are jsut loading the old saved file.
            //    cSignature.LoadImage(Path.Combine(AppPath, "signature.bmp"));

            //    Cursor.Current = Cursors.Default;
            //}
            //catch (Exception ex) { return; }

        }              
    }
}
Create a class call Signature and add following code

Code:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Data.SqlServerCe;
using System.Runtime.InteropServices;
using System.Data.SqlTypes;

namespace signatureD
{
    public class Signature : Control
    {
    private string AppPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
        private ArrayList Points = new ArrayList();
        private Bitmap BackGroundImage;
        private Graphics GraphicsHandle;
        private Pen SignaturePen = new Pen(Color.Black);
        private Point LastMouseCoordinates = new Point(0, 0);
        private bool CaptureMouseCoordinates = false;

        const int XPelsPerMeter = 0xb12;
        const int YPelsPerMeter = 0xb12;
        const int GPTR = 0x40;
        const int SRCCOPY = 0x00CC0020;

        [DllImport("coredll.dll")]
        private static extern IntPtr GetFocus();
        [DllImport("coredll.dll")]
        private static extern IntPtr LocalAlloc(uint flags, uint cb);
        [DllImport("coredll.dll")]
        private static extern IntPtr LocalFree(IntPtr hMem);
        [DllImport("coredll.dll")]
        private static extern IntPtr CreateDIBSection(IntPtr hdc, BITMAPINFOHEADER hdr, uint colors, ref IntPtr pBits, IntPtr hFile, uint offset);
        [DllImport("coredll.dll")]
        private static extern IntPtr CreateDIBSection(IntPtr hdc, IntPtr hdr, uint colors, ref IntPtr pBits, IntPtr hFile, uint offset);
        [DllImport("coredll.dll")]
        private static extern IntPtr GetDC(IntPtr hWnd);
        [DllImport("coredll.dll")]
        private static extern void ReleaseDC(IntPtr hDC);
        [DllImport("coredll.dll")]
        private static extern void DeleteDC(IntPtr hDC);
        [DllImport("coredll.dll")]
        private static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);
        [DllImport("coredll.dll")]
        private static extern IntPtr CreateCompatibleDC(IntPtr hdc);
        [DllImport("coredll.dll")]
        private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObj);
        [DllImport("coredll.dll")]
        private static extern void DeleteObject(IntPtr hObj);
        struct BITMAPINFOHEADER
        {
            public uint biSize;
            public int biWidth;
            public int biHeight;
            public ushort biPlanes;
            public ushort biBitCount;
            public uint biCompression;
            public uint biSizeImage;
            public int biXPelsPerMeter;
            public int biYPelsPerMeter;
            public uint biClrUsed;
            public uint biClrImportant;
        }
        struct BITMAPFILEHEADER
        {
            public ushort bfType;
            public uint bfSize;
            public ushort bfReserved1;
            public ushort bfReserved2;
            public uint bfOffBits;
        }
        private struct LineToDraw
        {
            public int StartX;
            public int StartY;
            public int EndX;
            public int EndY;
        }
        public Signature()
        {
            LoadBackgroundImage();
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            LoadBackgroundImageIfInvalid();
            e.Graphics.DrawImage(BackGroundImage, 0, 0);
        }
        protected override void OnPaintBackground(PaintEventArgs e)
        {

        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (CaptureMouseCoordinates) { return; }
            CaptureMouseCoordinates = true;
            LastMouseCoordinates.X = e.X;
            LastMouseCoordinates.Y = e.Y;
        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            CaptureMouseCoordinates = false;
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (!CaptureMouseCoordinates) { return; }
            LineToDraw l = new LineToDraw();
            l.StartX = LastMouseCoordinates.X;
            l.StartY = LastMouseCoordinates.Y;
            l.EndX = e.X;
            l.EndY = e.Y;
            Points.Add(l);
            GraphicsHandle.DrawLine(SignaturePen, l.StartX + 1, l.StartY, l.EndX + 1, l.EndY);
            GraphicsHandle.DrawLine(SignaturePen, l.StartX, l.StartY + 1, l.EndX, l.EndY + 1);
            GraphicsHandle.DrawLine(SignaturePen, l.StartX + 1, l.StartY + 1, l.EndX + 1, l.EndY + 1);
            GraphicsHandle.DrawLine(SignaturePen, l.StartX, l.StartY, l.EndX, l.EndY);
            LastMouseCoordinates.X = l.EndX;
            LastMouseCoordinates.Y = l.EndY;
            Invalidate();
        }
        public void Save(string FileName)
        {
            try
            {
                SaveToFile(this, FileName);

            }
            catch (Exception ex) 
            {
                MessageBox.Show("Exception");
               // throw;
            }
        }
        public void Clear(bool ClearCapturedLines)
        {
            try
            {
                LoadBackgroundImage();
                Invalidate();
                if (ClearCapturedLines == false) { return; }
                Points.Clear();
            }
            catch (Exception) { throw; }
        }
        private void LoadBackgroundImageIfInvalid()
        {
            try
            {
                if (BackGroundImage == null || BackGroundImage.Width != this.Width || BackGroundImage.Height != this.Height)
                {
                    LoadBackgroundImage();
                }
            }
            catch (Exception) { throw; }
        }
        private void LoadBackgroundImage()
        {
            try
            {
                BackGroundImage = new Bitmap(this.Width, this.Height);
                GraphicsHandle = Graphics.FromImage(BackGroundImage);
                GraphicsHandle.Clear(System.Drawing.Color.White);

            }
            catch (Exception) { throw; }
        }

        public byte[] ImageToByteArray(Image img)
        {
            MemoryStream ms = new MemoryStream();
            img.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
            return ms.ToArray();
        }
        public Image ByteArrayToImage(byte[] data)
        {
            MemoryStream ms = new MemoryStream(data);
            Image img = new Bitmap(ms);
            return img;
        }
    
   
        private void SaveToFile(Control ctl, string FileName)
        {
            IntPtr hDC;

            if (ctl != null)
            {
                ctl.Focus();
                IntPtr hReal = GetFocus();
                hDC = GetDC(hReal);
            }
            else
            {
                hDC = GetDC(IntPtr.Zero);
            }

            IntPtr hMemDC = CreateCompatibleDC(hDC);
            BITMAPINFOHEADER bi = new BITMAPINFOHEADER();
            bi.biSize = (uint)Marshal.SizeOf(bi);
            bi.biBitCount = 16;
            bi.biClrUsed = 0;
            bi.biClrImportant = 0;
            bi.biCompression = 0;
            bi.biHeight = ctl != null ? ctl.Height : Screen.PrimaryScreen.Bounds.Height;
            bi.biWidth = ctl != null ? ctl.Width : Screen.PrimaryScreen.Bounds.Width;
            bi.biPlanes = 1;
            int cb = (int)(bi.biHeight * bi.biWidth * bi.biBitCount / 8);
            bi.biSizeImage = (uint)cb;
            bi.biXPelsPerMeter = XPelsPerMeter;
            bi.biYPelsPerMeter = YPelsPerMeter;
            IntPtr pBits = IntPtr.Zero;
            IntPtr pBI = LocalAlloc(GPTR, bi.biSize);
            Marshal.StructureToPtr(bi, pBI, false);
            IntPtr hBmp = CreateDIBSection(hDC, pBI, 0, ref pBits, IntPtr.Zero, 0);
            BITMAPINFOHEADER biNew = (BITMAPINFOHEADER)Marshal.PtrToStructure(pBI, typeof(BITMAPINFOHEADER));
            IntPtr hOldBitmap = SelectObject(hMemDC, hBmp);
            int nRet = BitBlt(hMemDC, 0, 0, bi.biWidth, bi.biHeight, hDC, 0, 0, SRCCOPY);
            byte[] RealBits = new byte[cb];
            Marshal.Copy(pBits, RealBits, 0, cb);
            BITMAPFILEHEADER bfh = new BITMAPFILEHEADER();
            bfh.bfSize = (uint)cb + 0x36;
            bfh.bfType = 0x4d42;
            bfh.bfOffBits = 0x36;
            int HdrSize = 14;
            byte[] header = new byte[HdrSize];
            BitConverter.GetBytes(bfh.bfType).CopyTo(header, 0);
            BitConverter.GetBytes(bfh.bfSize).CopyTo(header, 2);
            BitConverter.GetBytes(bfh.bfOffBits).CopyTo(header, 10);
            byte[] data = new byte[cb + bfh.bfOffBits];
 


            header.CopyTo(data, 0);
            header = new byte[Marshal.SizeOf(bi)];
            IntPtr pHeader = LocalAlloc(GPTR, (uint)Marshal.SizeOf(bi));
            Marshal.StructureToPtr(biNew, pHeader, false);
            Marshal.Copy(pHeader, header, 0, Marshal.SizeOf(bi));
            LocalFree(pHeader);
            header.CopyTo(data, HdrSize);
            RealBits.CopyTo(data, (int)bfh.bfOffBits);
            FileStream fs = new FileStream(FileName, FileMode.Create);
            fs.Write(data, 0, data.Length);
          

          

            Image imm = ByteArrayToImage(data);
            imm.Save(Path.Combine(AppPath, "signature___________.bmp"), System.Drawing.Imaging.ImageFormat.Bmp);

            fs.Flush();
            fs.Close();               
            data = null;
            DeleteObject(SelectObject(hMemDC, hOldBitmap));
            DeleteDC(hMemDC);
            ReleaseDC(hDC);
           
           

        }
        public void SetPenColor(Color penColour)
        {
            SignaturePen = new Pen(penColour);
        }
        public void LoadImage(String ImageFileName)
        {
            try
            {
                BackGroundImage = new Bitmap(ImageFileName);
                GraphicsHandle = Graphics.FromImage(BackGroundImage);
                Invalidate();
            }
            catch (Exception) { throw; }
        }
    }

}


Now you can run the application …
image “bmp” will save on your device/ program/ form1 (your application name)

Thank you

Comments

Popular posts from this blog

Multithreading C# : Part 01

Multithreading with C# Think about old days, you have one central processing unit (CPU) in your pc which is capable of executing one operation at a time. If we have 5 operations to run then we have to wait till one operation is completed and then only other one can start. What will happen if the running operation has a bug and got stuck, then whole computer going to be freeze and useless unless we restart it. This is a huge problem. So if we can run multiple operation in the same time that would be great because it will solve this problem.

C# Character Escape Sequences

Character combinations consisting of a backslash ( \ ) followed by a letter or by a combination of digits are called "escape sequences." To represent a newline character, single quotation mark, or certain other characters in a character constant, you must use escape sequences. An escape sequence is regarded as a single character and is therefore valid as a character constant.

SQLite Database for Windows 8 App : Adding existing SQLite DB file

Hi Guys ... This Post is about adding an existing SQLite database file to the Windows Metro App project. As I think "using SQLite" is the best way to create local database for Windows Rt applications.Actually SQLite is very easy to learn but I really think if Microsoft SQL Server CE supports windows rt applications it will more fun. .Isnt it ?. :)