An Original Idea

because all great software begins with an original idea

Archive for the ‘.net Framework’ Category

Enabling callto (Skype) in your application

Posted by anoriginalidea on September 30, 2009

image image

You may have noticed that Skype seems to embed itself into Internet Explorer, Firefox and Chrome.  It recognises contacts and phone numbers in the page and provides the ability to call them.

I believe people will expect this kind of functionality in conventional windows applications also.  To assist with this I created a little class that will not only allow calls, but allows a check for the existence of a skype and give the ability to extract the calling applications icon.

Sample Project

The sample winforms project includes the CallTo class and a simple Winforms test form:

image

The form has a textbox and button.   One load, the call button is enabled and give an image.  The button makes the call.

 

Public Class Form1

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim loCallTo As New CallTo
        cmdCall.Image = loCallTo.Image
        cmdCall.Enabled = loCallTo.Enabled
    End Sub
    Private Sub cmdCall_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdCall.Click
        Dim loCallTo As New CallTo
        loCallTo.DoCall(txtPhoneNumber.Text)
    End Sub

End Class

 

 

Heres the source of CallTo.vb:

 

Imports Microsoft.Win32
Imports System.Runtime
Imports System.Runtime.InteropServices

''' <summary>
''' This class allows for making callto calls
''' </summary>
Public Class CallTo

    ''' <summary>
    ''' Gets the image.
    ''' </summary>
    ''' <value>The image.</value>
    Public ReadOnly Property Image() As Image
        Get
            If Not Enabled Then Return Nothing

            Dim lsValue As String
            With Registry.ClassesRoot.OpenSubKey("callto\DefaultIcon")
                lsValue = .GetValue("")
            End With

            If lsValue.Contains(",") Then
                Dim lsBits() As String = lsValue.Split(","c)
                Dim lsFilename As String = lsBits(0).Trim(New Char() {""""c})
                Dim liPosition As Integer = Val(lsBits(1))
                Return moGetIconFromExeOrDll(lsFilename, liPosition)
            Else
                Return Nothing
            End If

        End Get
    End Property
    Private Declare Auto Function ExtractIcon Lib "shell32" ( _
ByVal hInstance As IntPtr, ByVal lpszExeFileName As String, _
ByVal nIconIndex As Integer) As IntPtr
    Private Function moGetIconFromExeOrDll(ByVal filename As String, ByVal position As Integer) As Image
        Dim hInstance As IntPtr = Marshal.GetHINSTANCE( _
           System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0))
        Dim hIcon As IntPtr = ExtractIcon(hInstance, filename, position)
        Dim loBitmap As Bitmap = Bitmap.FromHicon(hIcon)
        Dim loReturn As Image = loBitmap.GetThumbnailImage(16, 16, Nothing, Nothing)

        loBitmap.Dispose()
        Return loReturn

    End Function

    ''' <summary>
    ''' Gets a value indicating whether this CallTo is enabled.
    ''' </summar
    ''' <value><c>true</c> if enabled; otherwise, <c>false</c>.</value>
    Public ReadOnly Property Enabled() As Boolean
        Get
            Try
                Dim loReg As RegistryKey = Registry.ClassesRoot.OpenSubKey("callto", False)
                loReg.Close()
            Catch
                Return False
            End Try
            Return True
        End Get
    End Property
    ''' <summary>
    ''' Does the call.
    ''' </summary>
    ''' <param name="destination">The destination.</param>
    Public Sub DoCall(ByVal destination As String)

        If Not Enabled Then Throw New ApplicationException("Callto is not enabled")
        Process.Start("callto://" & destination)

    End Sub

End Class

 

Download Sample

Posted in .net Framework, Code, Software Development | Tagged: , , , , | Leave a Comment »

Sketchflow – “Duplicate” Bug

Posted by anoriginalidea on August 27, 2009

 

image

 

The Problem

At the moment I’m trialling Sketchflow for Expression Blend.  There’s an annoying bug that happens when you use the “Duplicate” action on a node:

image

If you use this action, sooner or later you’ll end up with this error:

‘InitializeComponent’ is not a member of ‘xxxxxxxxxx.xxxxxxxxxxxxxx’

This can be very frustrating if you are trying to advocate Sketchflow as a prototyping tool for non wpf savvy analysts.

The Workaround

The simplest workaround is to delete the code-behind file.  To do this, go to the project pane and choose “Delete”.

image

 

At first I tried hard to ensure that the xaml filenames and classnames were correct.  This just causes a cascading comedy of errors.

Upgrading Sketchflow prototype projects to real code is a pipe-dream at the moment.

If you know of a better way of handling this situation (and fixing the errors) more quickly, feel free to comment.  I just want get on with the prototyping.

Posted in .net Framework, Expression Blend, Silverlight, Sketchflow, Windows Presentation Foundation | 2 Comments »

Serialize and Deserialize objects as Xml using generic types in VB.Net

Posted by anoriginalidea on August 10, 2009

image

In his blog post Serialize and deserialize objects as xml using generic types in C# 2.0 , Paul Whitaker creates some ubiquitous functions for doing Xml Serialization with generics.

 

To serialize:

Dim lsXml As String = GenericXmlSerializer.SerializeObject(of MyObjectType)(myObject)

 

To deserialize:

Dim myObject As MyObjectType = GenericXmlSerializer.DeserializeObject(of MyObjectType)(lsXml)

 

Here’s the code

Imports System.Collections.Generic
Imports System.Text
Imports System.Xml
Imports System.IO
Imports System.Xml.Serialization

Class GenericXmlSerializer
    ''' <summary>
    ''' To convert a Byte Array of Unicode values (UTF-8 encoded) to a complete String.
    ''' </summary>
    ''' <param name="characters">Unicode Byte Array to be converted to String</param>
    ''' <returns>String converted from Unicode Byte Array</returns>
    Public Shared Function UTF8ByteArrayToString(ByVal characters As Byte()) As String

        Dim encoding As New UTF8Encoding
        Dim constructedString As String = encoding.GetString(characters)
        Return constructedString

    End Function

    ''' <summary>
    ''' Converts the String to UTF8 Byte array and is used in De serialization
    ''' </summary>
    ''' <param name="pXmlString"></param>
    ''' <returns></returns>
    Public Shared Function StringToUTF8ByteArray(ByVal pXmlString As String) As Byte()

        Dim encoding As New UTF8Encoding()
        Dim byteArray As Byte() = encoding.GetBytes(pXmlString)
        Return byteArray
    End Function

    ''' <summary>
    ''' Serialize an object into an XML string
    ''' </summary>
    ''' <typeparam name="T"></typeparam>
    ''' <param name="obj"></param>
    ''' <returns></returns>
    Public Shared Function SerializeObject(Of T)(ByVal obj As T) As String

        Try
            Dim xmlString As String = Nothing

            Dim memoryStream As New MemoryStream()
            Dim xs As New XmlSerializer(GetType(T))
            Dim xmlTextWriter As New XmlTextWriter(memoryStream, Encoding.UTF8)
            xs.Serialize(xmlTextWriter, obj)
            memoryStream = CType(xmlTextWriter.BaseStream, MemoryStream)
            xmlString = UTF8ByteArrayToString(memoryStream.ToArray())
            memoryStream.Dispose()

            Return xmlString
        Catch

            Return String.Empty
        End Try
    End Function

    ''' <summary>
    ''' Reconstruct an object from an XML string
    ''' </summary>
    ''' <param name="xml"></param>
    ''' <returns></returns>
    Public Shared Function DeserializeObject(Of T)(ByVal xml As String) As T

        Dim xs As New XmlSerializer(GetType(T))
        Dim memoryStream As New MemoryStream(StringToUTF8ByteArray(xml))
        Dim xmlTextWriter As New XmlTextWriter(memoryStream, Encoding.UTF8)

        Dim theObject As T = CType(xs.Deserialize(memoryStream), T)
        memoryStream.Dispose()
        Return theObject

    End Function

End Class

 

Rather than be original, I converted most of his code verbatim and have found the functions useful. 

I offer them to you warranty free, unadorned and hopefully useful.

 

 


Share this post :

Posted in .net Framework, VB.Net | Leave a Comment »

A Simple Scroll Controller for Winforms

Posted by anoriginalidea on February 20, 2009

 image

I am currently researching “flick” scrolling for Windows XP and over.  As part of this I need the ability to scroll controls in code.

To do this I have created a wrapper around the scrolling apis to assist with this.

Here’s how to use it for an autoscrolling panel:

 

Dim loScrollIt As New ScrollController(Panel1)

loScrollIt.VerticalScroll(20)

 

Here’s the code:

Imports System.Runtime.InteropServices
Public Class ScrollController

    ' Scrollbar direction
    '
    Const SBS_HORZ = 0
    Const SBS_VERT = 1

    ' Windows Messages
    '
    Const WM_VSCROLL = &H115
    Const WM_HSCROLL = &H114
    Const SB_THUMBPOSITION = 4

    Private Declare Function GetScrollPos Lib "user32.dll" ( _
        ByVal hWnd As IntPtr, _
        ByVal nBar As Integer) As Integer

    'Example: position = GetScrollPos(textbox1.handle, SBS_HORZ)
    Private Declare Function SetScrollPos Lib "user32.dll" ( _
        ByVal hWnd As IntPtr, _
        ByVal nBar As Integer, _
        ByVal nPos As Integer, _
        ByVal bRedraw As Boolean) As Integer

    'Example: SetScrollPos(hWnd, SBS_HORZ, position, True

    Private Declare Function PostMessageA Lib "user32.dll" ( _
        ByVal hwnd As IntPtr, _
        ByVal wMsg As Integer, _
        ByVal wParam As Integer, _
        ByVal lParam As Integer) As Boolean

    'Example: PostMessageA(hWnd, WM_HSCROLL, SB_THUMBPOSITION _
    '                         + &H10000 * position, Nothing)

    Private moControl As Control

    Public Sub New(ByVal controlToScroll As Control)

        moControl = controlToScroll
    End Sub
    Public Sub VerticalScroll(ByVal amount As Integer)
        Dim liHwnd As IntPtr = moControl.Handle
        Dim Position = GetScrollPos(liHwnd, SBS_VERT) + amount

        If (SetScrollPos(liHwnd, SBS_VERT, Position, True) <> -1) Then

            PostMessageA(liHwnd, WM_VSCROLL, SB_THUMBPOSITION + _
                                       &H10000 * Position, Nothing)
        End If

    End Sub

End Class

Posted in .net Framework, Code, Software Development, VB.Net | 2 Comments »

More VSTO fun : WindowActivate in Outlook/Word 2007 does not fire for Wordmail more than once

Posted by anoriginalidea on February 9, 2009

image

Welcome to the horrible world of creating Outlook addins that work for both 2003 and 2007.

People have commented that wordmail has a horrible side effect in Word 2003, where toolbars used in Outlook inspectors show up in Word.  See the this Kevin Slovak’s discussion of the problem in the links section.

Anyway, the workaround mentioned in the article doesn’t work (of course) in Outlook 2007.  It is therefore necessary to check the version of Word (which doesn’t have toolbars) for the code to work for both versions.

It makes me wish Microsoft would hand out free office upgrades.

Anyway, here’s the complete code:

 

' Listen for inspector activate
Private WithEvents moWord As Microsoft.Office.Interop.Word.Application
Private moInspector As Inspector
Private Sub moWord_WindowActivate(ByVal Doc As Microsoft.Office.Interop.Word.Document, ByVal Wn As Microsoft.Office.Interop.Word.Window) Handles moWord.WindowActivate

     If Wn.EnvelopeVisible AndAlso moInspector IsNot Nothing Then
         mShowInspector(moInspector)
         moInspector = Nothing
         moWord = Nothing
         If Doc.AttachedTemplate IsNot Nothing Then Doc.AttachedTemplate.Saved = True
     End If

End Sub
Private Sub moInspectors_NewInspector(ByVal Inspector As Microsoft.Office.Interop.Outlook.Inspector) Handles moInspectors.NewInspector

     Dim lbRaiseEvents As Boolean = True

     If Inspector.IsWordMail Then
         ' HACK: Wordmail does not work in the same way in
         ' Word 2008 as it does in 2003.  I think this
         ' may be because of the lack of real toolbars
         ' in Word 2007.
         If Val(Inspector.WordEditor.Application.Version) < 12 Then
             moInspector = Inspector
             moWord = Inspector.WordEditor.Application
             lbRaiseEvents = False
         End If
     End If
     If lbRaiseEvents Then mShowInspector(Inspector)

End Sub

 

This code is provided in case some poor soul out there gets the problem as well. 

 

Links

Problem with Inspector CommandBars and MS Word [WiredBox.Net - Office Newsgroups]

Inspector Wrapper for Wordmail VSTO and vb.net

Posted in .net Framework, Outlook, VSTO | Tagged: , , | Leave a Comment »

Musings about the memory usage of WPF and Winforms Applications

Posted by anoriginalidea on November 23, 2008

Newcomers to Winforms and WPF .net applications are sometimes alarmed about the amount of memory they are shown to use in Task Manager.  

When these applications run in a Terminal Server environment (or Citrix) the memory consumption seems to add up.  I have heard of products that somehow reduce the memory consumption of processes in this environment.   The makers of these products claimed to be able to fit more processes on the one server. I made it my mission to find out how these applications may work.

Minimizing as a Lifestyle

A hint as to how they may work is the behaviour of the application when it’s minimised.  Memory usage definitiely goes down.  When the application is normalised, memory consumption goes back up, but not as much.

For example, with a WPF application with a single window and no controls, according to Task Manager uses 27388K.  On minimise of the application, memory consumption goes down to 3128K.  Normalising the application, the memory consumption goes back to 8306K.

Apparently minimizing the application makes a call to the Win32 api call SetWorkingSet, this is what causes the apparent memory reduction.  Looking at the history of Windows, this behaviour makes sense.  In the Windows 3.1 user interface, minimizing applications was the way a user typically indicated to Windows they were switching to something else.

Something I wonder about is whether this is still appropriate?  Since Windows 95 introduced the Task Switcher, do people still minimise?    Another question.  In the Terminal Server environment, is the call being made when a user becomes idle?  Should it be?

SetWorkingSet(-1,-1)

Microsoft’s documentation of the call indicates that application calls to SetWorkingSet are not necessary, as the operating system will manage the memory as required.   Is this automatic memory management assuming the Windows 3.1 usage pattern? 

Two years ago I created a prototype that called SetWorkingSet when an application had become idle for a certain amount of time.  It seemed to work well, but I had no evidence it helped system performance particularly.

I apologise for the inconclusive nature of this post, but I thought I would put my musing out there in case others had anything to comment.

 

Links

Reducing WinForm Memory Footprint with SetWorkingSet

How much memory does my .NET application use?

WPF Memory Usage

 


Share this post :

Posted in .net Framework, Software Development | Tagged: , , , | 1 Comment »

iPhone

Posted by anoriginalidea on November 15, 2008

“In more bad news for Windows Mobile, Apple shipped more iPhones in the quarter than the total of all handsets based on the Microsoft system, even though their numbers actually increased by 42%.” (See article Apple and RIM tussle for Q4 prizes as smartphones boom)

I’m really sorry, but I don’t think Windows Mobile 6.5 or 7 is going to make any difference, it seems that Microsoft is not going to be able to produce anything compelling enough, soon enough.   I don’t think there’s going to be a “comeback”.

In case you think that the iPhone is all hype and marketing, I have a question for you.  Have you ever tried using one?  I have yet to meet anyone who has had less than a “revelatory” experience using an iPhone. 

I’ve had a great experience developing for the platform (I think the Compact Framework is excellent).

I believe the future of mobile computing is and is going to be huge, but I’m afraid Windows Mobile isn’t going to play a significant role anymore. 

Future handset operating systems will be various, including of course the iPhone and Android.

Other mobile devices such as tablet computers and netbooks will probably continue to run Windows, so I think Microsoft should concentrate their efforts on continuing to ensure relevance on this form factor.

For developers I think the news is all good.  There are great opportunities out their in mobility, if we are willing to “move on” in our choice of development technologies. 

 

Links

Permanent Link to IE6 for Windows Mobile – Better, but not brilliant

The Mobile Spoon: What happens when a Windows Mobile Addict breaks his vow and buys an iPhone?

Apple and RIM tussle for Q4 prizes as smartphones boom

 


Share this post :

Posted in .net Framework, Pocket PC Development, Software Development | Leave a Comment »

Estranged Siblings – Silverlight Mobile and the Compact Framework CLR

Posted by anoriginalidea on November 1, 2008

An illustration that contemplates the cojoined nature of Silverlight and the Compact Framework

 

At PDC 2008 in the session Microsoft Silverlight 2 for Mobile- Developing for Mobile Devices, Amit Chopra revealed some interesting details about Silverlight Mobile that I haven’t seen written elsewhere.

The presentation mainly consists of “here’s Silverlight running on Windows Mobile”.   The interesting bits are at the end.  I dear reader, present these to you here.

 

Compact Framework, small but mighty

The compact framework, is small yet mighty.  (Some may say mighty ugly...by default)

The Compact Framework provides a great deal of rich device integration and sheer programmability. It is a pleasure to create software for.  I even think that Compact Framework based applications have been a reason for customers, particularly in the Mobile Fieldworker areas to adopt Windows Mobile devices.

If you’re a Compact Framework developer like me, you may have been frustrated by the default “yesterday” appearance of the System.Windows.Forms forms engine.  It takes a great deal of work to make forms look good. 

Silverlight, a Framework Apart?

Two frameworks, Silverlight and Compact Framework, so alike, yet so different.

I for one was very excited last year at the thought of a Silverlight (ie WPF) graphics engine being available for Mobile Device development.  I was then saddened to learn that the Silverlight runtime would not be extending the Compact Framework, but would exist in addition to Compact Framework.

This is disappointing news. (I am now showing my disappointed face….beware!) It appears that Microsoft (at the moment) seem determined to give Silverlight minimal access to the device.  This is aligned with the idea that Silverlight is only a competitor to traditional Flash app that runs from a Web page. 

Although this may be acceptable for certain kinds of desktop oriented Silverlight applications, I doubt this is a believable use case for mobile developers.  The power of mobility is not only the ability to access data anywhere, but the ability to talk to the features of the device.

In the presentation mentioned at the outset, there was declaration of the intention to support Webcams, accelerometer and other device features in the future, depending on the support for this on other platforms (eg Windows and Mac). 

So, we are restricted to the lowest common denominator.  You may believe this is for technical reasons.  It isn’t. Because….

Silverlight Uses the Compact Framework!

Diagram of Silverlight Architecture on Windows Mobile

Amit said that the Silverlight runtime for Windows Mobile may be smaller because it may omit certain codecs and it also shares the Compact Framework Clr.    He went on to say that the Compact Framework would be a prerequisite to installing the Silverlight runtime.

A new and nobler purpose for Silverlight Mobile

I give you....Silver-Knight

It’s Microsoft’s belief that targeting Windows Mobile 6.? (Sorry about that WM2003 and 5) and Nokia phones will mean Web users will eschew DHTML and Flash websites for Silverlight ones.  

With the proliferation of device operating systems (particularly that pesky iPhone) I don’t think this is a likely scenario.  Do you?  Well do you?

I’ve I got an idea!  As it’s unlikely Microsoft will backtrack on their “one platform everywhere” philosophy for Silverlight, why not, in addition enable Silverlight as a cutdown WPF for the Compact Framework on Windows Mobile? Microsoft, I know you can!  Doing this would earn the gratitude of all Compact Developers and provide a side benefit to their current Silverlight efforts on Mobile.

Call to Action

If you agree, please add a comment or bookmark this article using the links below, blog about this yourself or email the people at Microsoft.   Amit said they wanted feedback, lets give it!

(BTW Any physical resemblance between Amit and myself is entirely coincidental, so don’t say it)

 

Links

Microsoft Silverlight 2 for Mobile- Developing for Mobile Devices

Amit Chopra’s Blog (Email) – WIndows Mobile Program Mananger

Giorgio Sardo’s Blog (Email: gisardo @ microsoft  com) – Evangelist for Windows Mobile

 


Share this post :

Posted in .net Framework, Pocket PC Development, Silverlight, Software Development | Tagged: , , , , | 3 Comments »

Twittering using the Compact Framework

Posted by anoriginalidea on May 19, 2008

 image

My twitter updates are done using a variety of code.  At the moment I use the Curl command line  in conjunction with SlickRun.  In the past I did this with Outlook (see the article Twittering from Outlook Using VBA).  In the past I’ve found this pretty easy to do using the Twitter Api.

 

I also like to do updates from my Pocket PC, but am not keen on SMS charges.  The solution of course is to create my own client, which I’ll be posting about shortly.

For my client program I intend to use TwitterLib library.  Sadly this does not work for the compact framework unaltered.  I am currently working on porting it to the compact framework.

 

In the interim I want to share with you a simple code sample for submitting tweets to Twitter. 

The example is simple enough to be used by people who want to do HTTP posts to similar services.

 

    Dim lsParams As String = "status=" & Uri.EscapeDataString(tweetText)

    Dim loRequest As HttpWebRequest = CType(HttpWebRequest.Create("http://twitter.com/statuses/update.xml"), HttpWebRequest)
           With loRequest
               .Proxy = System.Net.GlobalProxySelection.GetEmptyWebProxy()

               .Timeout = 10000
               .AllowAutoRedirect = True
               .AllowWriteStreamBuffering = True

               .Method = "POST"

               .ContentType = "application/x-www-form-urlencoded"
               .ContentLength = Len(lsParams)

               Dim loCred As New System.Net.NetworkCredential("someusername", "somepassword")
               .Credentials = loCred

               ' Write the request paramater
               Dim stOut As New StreamWriter(.GetRequestStream(), System.Text.Encoding.ASCII)
               stOut.Write(lsParams)
               stOut.Flush()
               stOut.Close()

               Dim loResp = .GetResponse
               With loResp

                   .Close()
               End With

           End With

 

The most important difference with the full .net framework is the “GetEmptyWebProxy” and “AllowWriteStreamBuffering” lines.  It won’t work without it.


Share this post :

Posted in .net Framework, Pocket PC Development, VB.Net | Tagged: , , , , | 4 Comments »

Easy InkCanvas in Winforms for capturing signatures

Posted by anoriginalidea on April 18, 2008

image

In WPF there’s an interesting control called “InkCanvas” that can be used to capture signatures and the like in Tablet PC applications.

Recently I created a prototype for a windows forms application.  I did consider using WPF, but the overhead seemed unnecessary considering the simplicity of the requirement.

I am aware there’s a specific SDK for Tablet PC that provides winforms controls for the requirement, but I thought it might be fun to create my own.  As it turns out, it was pretty easy.

The requirement was to have a signature panel which could be used to collect a bitmap that would be attached to an entity to act as an authorisation.

Signature Panel

In the prototype I decided to create the signature panel as a standalone usercontrol called it, strangely enough “SignaturePanel”.

It uses Mousedown and MouseUp events to determine stylus pressure and mousemove for drawing.  Like the WPF control it keeps a collection of strokes internally.

Unlike the wpf control, I just decided to expose a “SignatureImage” property to allow a developer to retrieve a bitmap.  This is rendered from the strokes in realtime.

I assume it works for the Tablet PC, but I don’t know for sure.

Write your signature here

An additional feature of this control is a label which tells the user the last time the signature was last updated.  I thought the user may find this helpful.

If the user hasn’t written anything then it just reads “Write your signature here”.

The user control consists of a picturebox called “inkPanel” and a button for resetting the content:

 

What the control looks like in design time

Here’s the code:

 

Public Class SignaturePanel

    Private moCurrentWriting As New List(Of Point)
    Private moRememberInk As New List(Of List(Of Point))
    Private mbPenDown As Boolean = False
    Private Sub inkPanel_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles inkPanel.MouseDown
        mbPenDown = True
    End Sub

    Private Sub inkPanel_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles inkPanel.MouseMove
        If mbPenDown Then
            moCurrentWriting.Add(e.Location)
            mdLastSignatureUpdate = Now
            Me.Refresh()
        End If
    End Sub

    Private Sub inkPanel_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles inkPanel.MouseUp
        If moCurrentWriting.Count > 2 Then
            moRememberInk.Add(moCurrentWriting)
        End If

        moCurrentWriting = New List(Of Point)
        mbPenDown = False
    End Sub

    Private Sub inkPanel_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles inkPanel.Paint

        mRenderSignature(e.Graphics)

        Dim lsText As String = ""
        If Not Me.DesignMode Then
            If mdLastSignatureUpdate.HasValue Then
                lsText = "Signature last updated " & Me.LastSignatureUpdate.ToLongTimeString
            End If
            e.Graphics.DrawString(lsText, Me.Font, Brushes.Black, 5, inkPanel.Height - 20)
        Else
            lsText = "... Write your signature here ..."

            e.Graphics.DrawString(lsText, Me.Font, Brushes.Black, (inkPanel.Width / 2) - (e.Graphics.MeasureString(lsText, Me.Font).Width / 2), (inkPanel.Height / 2) - (e.Graphics.MeasureString(lsText, Me.Font).Height / 2))
        End If
    End Sub
    Private Sub mRenderSignature(ByVal g As Graphics)
        Using loPen As New Pen(Color.Black)
            loPen.Width = 2
            For Each loLines As List(Of Point) In moRememberInk
                g.DrawLines(loPen, loLines.ToArray)
            Next
            If moCurrentWriting.Count > 1 Then
                g.DrawLines(loPen, moCurrentWriting.ToArray)
            End If
        End Using
    End Sub
    Private Sub cmdClearInk_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdClearInk.Click
        moRememberInk.Clear()
        inkPanel.Refresh()
    End Sub
    Private mdLastSignatureUpdate As Nullable(Of Date) = Nothing
    <System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)> _
    Public Property LastSignatureUpdate() As Date
        Get
            Return mdLastSignatureUpdate
        End Get
        Set(ByVal value As Date)
            mdLastSignatureUpdate = value
        End Set
    End Property

    <System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)> _
    Public ReadOnly Property SignatureImage() As Image
        Get
            Dim loBitmap As New Bitmap(Me.Width, Me.Height)
            Using loGfx As Graphics = Graphics.FromImage(loBitmap)
                mRenderSignature(loGfx)
            End Using

            Return loBitmap
        End Get
    End Property

End Class

 

If anyone’s interested in a standalone sample project, post the request to this blog and I’ll see what I can do.

Possible Uses

It may be interesting to use this code as:

  • Signature recognition
  • “Mud map” style sketching for business applications
  • A basis for a drawing program ;)

Of course, if you’re using WPF, use InkPanel.  But if you don’t want the overhead, maybe this will be the foundation of a lightweight solution.

 


Share this post :

Posted in .net Framework, VB.Net, Windows Forms | Tagged: , , | 5 Comments »