An Original Idea

because all great software begins with an original idea

Archive for the ‘Code’ 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 »

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 »

Automatically stretching a Silverlight 2 control on a webpage

Posted by anoriginalidea on June 3, 2008

image

A couple of fun hours were spent trying to get my Silverlight content to resize when the user resized the browser. 

I mean, what’s the point of having your Silverlight content replace HTML if it wont flow and resize when the user resizes the browser? I want my Silverlight content to take up the whole browser frame.

The Html Code

You’d think this would be the default behaviour for an asp.net tag definition like this:

<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/TechnologyOneCrm.xap" Version="2.0" Width="100%" Height="100%" />

 

Sadly this is not enough.  Your silverlight sits there in a dumb un-resizeable box.

The Xaml

When you create a Silverlight 2 control in Visual Studio 2008 or blend, the UserControl typically has Height and Width properties set, something like this:

<UserControl x:Class="Daphne.WorkplaceHome"
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Width="900" Height="400" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
    <Grid x:Name="LayoutRoot" Background="White" >
    </Grid>
</UserControl>

 

The Elusive Auto

Hence the reason why your content is not resizable.

One solution is to remove the Width and Height property.   Another is to set them to “Auto”, like so:

<UserControl x:Class="Daphne.WorkplaceHome"
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Width="Auto" Height="Auto" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
    <Grid x:Name="LayoutRoot" Background="White" >
    </Grid>
</UserControl>

 

If you run the project, it will start resizing.  Unfortunately this causes the designer in Blend and VS2008 look like rubbish.  (or more rubbish than usual anyway).

The trick is to set the Width and Height properties to “Auto” after the the screen has been rendered.

 

In WPF (apparently) you can use code like this:

Partial Public Class Page
    Inherits UserControl
    Public Sub New()
        InitializeComponent()

        Me.Height = new System.Windows.LengthConverter().ConvertFromString("Auto")
        Me.Width =  new System.Windows.LengthConverter().ConvertFromString("Auto")
    End Sub

...

 

Sadly, in another twist of fate, “LengthConverter” does not exist in Silverlight.

The Silverlight Solution – Who’s your Nan?

 

image

 

Fortunately, browsing the type library showed me that setting the property value of Height or Width to “System.Double.Nan” has the same effect as “Auto”.

So, in the intialise of your Silverlight control, put this:

 

Partial Public Class Page
    Inherits UserControl
    Public Sub New()
        InitializeComponent()

        Me.Height = System.Double.NaN
        Me.Width = System.Double.NaN
    End Sub

 

I am not sure if Microsoft intend to support LengthConverter (or TypeDescriptor.GetConverter!) in a future Silverlight version, but I’m guessing not.

Links

 


Share this post :

Posted in Code, Silverlight, Software Development | Tagged: , , , | 5 Comments »

Weird Science – Defining Winforms in XAML

Posted by anoriginalidea on December 13, 2007

image

I like to think of XAML as an “object instantiation script”.  According the to the main books on the subject it should be possible to utilise XAML to create any kind of .net object. 

Practical examples include WWF (Windows Workflow Foundation) , which allows the storage of definition in XAML, which is nothing to do WPF.  WPF (Windows Presentation Foundation) was the original reason XAML was created, but XAML was designed to be independent.

So I was thinking, why not see if I can define a traditional “Winform” in XAML.    Why would I want to?   I thought it might be fun.   As it turns out, it may actually be useful in some scenarios.  (With a great stretch of the imagination)

So does it work?  Oh yes it works and it works well.   “Well” means that VS2008 provides full intellisense for tags within the Xaml designer, as well as “code behind”.  Now that, my friends, is cool.  Imagine being able to create form layouts using XML tags instead of that oh-so-last year winforms designer!  The result is surprisingly WPF like, which I find intriguing.

To create the example below, I created a WPF project, then removed the default WPF “Window1.xaml” and replaced it with my own “Form1.xaml”:

<Form Name="Form1" x:Class="Form1"  Text="Hello" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
        >
    <Form.Controls>
        <FlowLayoutPanel>
            <FlowLayoutPanel.Controls>
                <TextBox Name="txtName" x:Name="txtName" />
                <Button Name="cmdSayHello" Text="Say Hello" Click="Button_Click" /> 
            </FlowLayoutPanel.Controls>
        </FlowLayoutPanel>
    </Form.Controls>
</Form>

Please note that features such as code behind (partial classes), event hooks and most things in the “x” namespace work fine.

Creating XAML from an existing Winform

For even more fun and games, you can feed a running instance of a Winform into XAML Writer and get XAML source.  Sadly winforms incorporates read-only properties, so without massaging the Xml you’re not going to be able to clone a Winform using XAML serialization just yet.

The code would look something like this:

Dim loWinform As Form = Me ' Some Winform
Dim lsWinformXaml As String = XamlWriter.Save(loWinForm)
Dim loClonedForm As Form = XamlReader.Load(new XmlTextReader(new StringReader(xaml)))

 

See this Mike Hillberg’s object cloning article for more information.

 

So where from here?

What’s the use of it?  Well for me it proved that Xaml can be used to create any sort of object graph.  

Possible uses for this:

  • Embedding Winforms instantiation code within a WPF XAML document (something I haven’t tried)
  • Streaming Winforms form definitions from a server down to a client (effectively allowing a WebServer to render Winforms just like it renders HTML pages)
  • Providing a good interim step in creating a Winforms to WPF Converter

 

Any Comments?

If you find this topic interesting, ask questions or download a sample project, write some comments on the blog.  If I can see interest in the topic I may develop it further.


Share this post :

kick it on DotNetKicks.com

Posted in .net Framework, Code, Software Development, VB.Net, Windows Forms, Windows Presentation Foundation | Tagged: , , , , , | 2 Comments »

Visual Basic 9 for the Insane – Extension Methods

Posted by anoriginalidea on December 7, 2007

 

image

Am I the only one who found “Shared” (aka Static) methods disturbing?  Loving true Object Oriented programming, when reviewing .net 1.0 Beta 1 I was aghast (similar to being agog) in that I knew my less sophisticated software developing brethren would use this as a way of avoiding using OO.  (also don’t get me started on the Module keyword in VB)   I was  not disappointed.

As much as I tried to encourage these simple souls to inherit, override and extend, they happily pointed out the cursed “NotInheritable” (sealed) classes.  My dreams of adding my own methods to existing classes such as “String” were dashed.  The “subroutine” brigade merrily created their “Utils” modules and using OO for “everything” appeared to be unattainable.

Fortunately the situation has been approved.  I give you the new VB9 feature of “Extension Methods”.  These are cool methods that can be effectively added to any class, whether “NotInheritable” or not.

A feature of the string class I really like is the “StartsWith” and “EndsWith” methods.  They allow me to check if a string has certain characters at the beginning or end of a target string.

What if I wanted to check if there was a string anywhere within a target string?  No easy boolean operator there.  (There is “IndexOf” but returns a -1 if not found. Yuk!)

Now if I was one of the simple Shared method lovers I may create a module like this:

Module Utils
    Public Function ContainsString(ByVal targ As String, ByVal toFind As String) As Boolean
        Return tar.IndexOf(toFind) <> -1
    End Function

End Module

To do the check, you’d have code that looked like this:

Dim lsString = "The red sun set in the west"

    If Utils.ContainsString(lsString, "red") Then
        MsgBox("Contains Red")
    End If

To some this may be beautiful.  To me it is not. 

I prefer this syntax:

Dim lsString = "The red sun set in the west"

If lsString.ContainsString("red") Then
           MsgBox("Contains Red")
End If

To make this happen, simple add the *<Extension()> attribute:

Imports System.Runtime.CompilerServices
Module Utils
    <Extension()> Public Function ContainsString(ByVal targetString As String, ByVal stringToFind As String) As Boolean
        Return targetString.IndexOf(stringToFind) <> -1
    End Function

End Module

Pretty cool eh?  I’m quite excited at the possibilities.  It honours the accessor keywords (Public,Friend,Private) so you can use it within assemblies safely without having to have debates.

Extension methods even work for generic types, such as “List(Of T)”, so they really are without limits. 

Note: Sadly this requires targeting .Net Framework 3.5 and doesn’t appear to work on the Compact Framework.

 

 

 

 

End Module

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

Visual Basic 9 for the Insane – A class with no name – Anonymous Types

Posted by anoriginalidea on December 6, 2007

image

Now we’re starting enter strange territory.  I give you a syntax that allows you to create classes “on the fly” :

Dim loClasslessSmurf = New With {.Name = "Brainy", .AnnoyingTrait = "Whiny Voice"}

This syntax creates a “temporary” class with the properties you specify.  This is known as an “anonymous type”.  (Or a type with no name)  This is the equivalent of:

Public NotInheritable Class XXXX
  Public Name As String
  Public AnnoyingTrait As String
End Class

These classes do not have methods on them.  They are intended as useful temporary data holders for inline processing.  They were created for the LINQ language feature to allow results to be returned without having to create result container classes.

Differences between Cousins

It appears that the behaviour between VB9 and CSharp3.0 differs when creating an anonymous types.  If you create one in CSharp, the properties are read-only.  If you create them in VB9 the properties are writeable.

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

Visual Basic 9 for the Insane – Constructors for Free

Posted by anoriginalidea on December 5, 2007

image

There are some activities, such as searching for an attendant at a hardware store, watching television commercials, waiting for a TFS build server to come free or buying a bus ticket, bore me. 

Writing Constructors also bores me to tears.  I know it makes things easier for others that use your classes, but creating then just disrupts my “flow”.  In the world of mocking it’s a good idea to expose your dependencies via alternate constructors, which I do.  A new syntax may free me from this burden.

“Object Intializers” (This is an American product so in this case the “z” spelling) are another name for a feature I call “constructors for free”.

Take a boring class that represents a smurf like this:

Public Class Smurf

  Public AnnoyingTrait As String
  Public Name As String

End Class

If you want to create an instance of this class and want to set some defaults, the usual way of doing this is:

Dim loSmurf As New Smurf
loSmurf.AnnoyingTrait = "Whiny voice and Glasses"
loSmurf.Name = "Brainy"

Three lines of code!  The usual thing to do would be to create a constructor (Public Sub New), but this just moves the 3 lines of code elsewhere.  A far cooler thing to do is to use the new “Object Initializer” syntax:

Dim loSmurf As New Smurf With { .AnnoyingTrait = "Whiny voice", .Name="Brainy"}

Cool eh?  Additionally you can include these in array intializers so that you can create arrays with pre-intialized values:

Dim loSmurfs() = New Smurf() { _
     New Smurf With {.AnnoyingTrait = "Whiny voice", .Name = "Brainy"}, _
     New Smurf With {.AnnoyingTrait = "Unrealistic Beard", .Name = "Papa"}, _
     New Smurf With {.AnnoyingTrait = "Isn't a smurf", .Name = "Dopey"} _
     }

(Because of the “Implicit Types” feature you can also leave out the “New Smurf()” bit if you wanted to)

I pleased to report all this works fine in Compact Framework 2.0 (with VS2008).

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

Visual Basic 9 for the Insane – The rise and fall of "As" – Implicit Types

Posted by anoriginalidea on December 4, 2007

Posted in .net Framework, Code, Software Development, VB.Net | 1 Comment »

Visual Basic 9 for the Insane – An Introduction

Posted by anoriginalidea on December 4, 2007

image

Now don’t misunderstand me.  I am not implying that people who use VB.Net are crazy.  Far from it.   Some of the most grounded lunatics I’ve met use VB.Net regularly.  Some even use a computer at the same time.   I use VB.Net and every conversation I’ve had with myself so far has been erudite, interesting and mostly coherent. 

The truth of that matter is I wanted a catchy title for my series of articles on Visual Studio 2008.    Currently I’m attending a course in sunny Melbourne (or at least a it was a few minutes ago…now it’s raining….oh no it isn’t….) to learn about the new features of Visual Studio.  This is training in easy bite sized chunks, not insanity.

Temporary frustration at seeing yet another series of articles on VB9, soon to be replaced with rapture

As part of my learning process I thought I’d share my impressions and provide some tutorials on the functionality.    I intend to enlighten you with my account of LINQ to everything, anonymous types,  lambda’s and other strange animals. 

“Wait a minute!” you may say, “haven’t other people covered this information already?”

“Well yes” I reply, “there are some good overviews available (*This guy seems to be pretty good at it).  I intend however to provide concise examples in VB9!”

“I thought the VB Team published this in *their blog already” you say unconvinced.

“Well yes, that is true, but my examples will be even simpler!  I hereby announce my intent to provide the simplest, most drop-dead examples of the new VB9 language features in Visual Basic anywhere!”

“Well I have seen it all before” you say

“….and…and…and I’m going to do it all only using technologies available in .Net Compact Framework 2.0, using the retargetting feature of VS2008!”

“Really! That’s just swell!” you exclaim. 

You are now utterly convinced and start posting links to this blog everywhere. 

After doing this you start searching the main blog page searching for the PayPal “donate now” button repeatedly.  (You are insane after all)

Proof I am creating an insane sample project to justify my insane claims

Seriously though, I think it’s really cool that you can create Apps for your current target .net Framework version (ie 2.0, 3.0 or 3.5) and still take advantage of some of the languages.  Please send me a note if a feature I mention doesn’t work with 2.0 and I’ll be sure to annotate the article.

* I have the rare ability to be able to speak in hyperlinks

Go on to read the first article in the series:

Visual Basic 9 for the Insane – The rise and fall of “As” – Implicit Types

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

A way of detecting if an Outlook Contact has been updated since last synced with the server

Posted by anoriginalidea on October 17, 2007

This entry concerns a common problem in the world of occasionally connected clients and synchronising changes.  I thought I’d document my solution as it uses less known Outlook attributes.  Those doing similar things might find it useful.   It assumes a knowledge of VSTO, Visual Studio 2005 and VB.NET. 

At the moment I’m working on a process to synchronise Outlook contacts items with contacts stored in a database on the Server.

There’s always a question of which updates take priority (Outlook or Server?), and how to detect if things are updated.

The Rules

I’ve devised a couple of rules that determine which updates are the master:

  • If the Server record has been updated since we last synced, overwrite the local record
  • If the local record has been modified since the last server update, don’t overwrite it

Implementation

When translating a server record to a client contact, I save the following properties to the Outlook Contact:

loNewContact.SetUserProperty("ServerContactId", ServerRecord.Id)
loNewContact.SetUserProperty("ServerTimestamp", ServerRecord.Vers)
loNewContact.SetUserProperty("ServerLastUpdateDateTime", Now.AddSeconds(20))

loNewContact.Save

 

ServerContactId : Associates the client record with the server record

ServerTimestamp: Is the value of a field used on the server to indicate when the server record is updated.  In this case it’s an integer. 

ServerLastUpdateDateTime : This indicates when this record is synced.  It is compared with Outlook’s Local LastModificationTime property in order to determine if the local record has been updated since last sync.  The adding of 20 seconds to the ServerLastUpdate property is because calling “Save” on the contact will update the LastModificationTime property to a later value.

 

The “SetUserProperty” routine is a quick way of setting user properties. ie:  

Public Sub SetUserProperty(ByVal name As String, ByVal value As String)  

       With CType(moOutlookItem.UserProperties, UserProperties)
           Dim loProp As UserProperty = .Find(name)
           If loProp Is Nothing Then
               loProp = .Add(name, OlUserPropertyType.olText)
           End If
           loProp.Value = value
       End With
End Sub

 

The synchronisation logic contains a loop that goes through the server items, checking if they are already local (using the ServerContactId user property.

For items that already exist, I use this piece of code to determine whether to update or not:

 

If mbTheServerRecordHasBeenModifiedSinceLastUpdate(loServerContact, loPimContact) Then

       ' Update the local record
        ....

Else
      ' If the contact has been updated since the last server sync
      If mbThePimContactHasBeenUpdated(loPimContact) Then

                      ' Issue an update request to the server
                    

       End If
End If

 

The routines look like this:

 

Private Function mbTheServerRecordHasBeenModifiedSinceLastUpdate(ByVal serverContact As ContactDetail, ByVal pimContact As IPimContactItem) As Boolean
    Dim lsServerVers As String = pimContact.GetUserProperty("ServerTimestamp")
    If IsNumeric(lsServerVers) Then

        ' If the server has been updated since the last update
        ' of this record
        Return (CInt(lsServerVers) <> serverContact.Vers)

    End If
 
    Return False
End Function

Private Function mbThePimContactHasBeenUpdated(ByVal pimContact As IPimContactItem) As Boolean
    Dim lsLastServerUpdateDateTime As String = pimContact.GetUserProperty("ServerLastUpdateDateTime")
    Dim loPimContactLastModificationDateTime As Date = pimContact.LastModificationDateTime
    If IsDate(lsLastServerUpdateDateTime) Then

        Return CDate(lsLastServerUpdateDateTime) < loPimContactLastModificationDateTime

    End If
 
    Return False
End Function

 

I’m sorry to say I do not have a downloadable code sample you can use, as it tends to be quite specific to the associated server process.    If you have any interest or comments about this code, please post a comment.

Posted in Code, Software Development | 2 Comments »