Category Archives: Code

Backing up your files without file locks on Windows

Standard

Make perfect copies every time with Volume Shadow Copy

Do you have some files you want backed up but can’t afford the downtime?

As part of the eidy we have a shared game world for the team to experiment with running windows server.  Windows has a feature called “Volume Shadow Copy” that allows you to copy files while they are in use.

Shadow Copy is used in taking manual or automatic backup copies or snapshots of computer files or volumes, even when they are in use. It is implemented as a Windows service called the Volume Shadow Copy service. A software VSS provider service is also included as part of Windows to be used by Windows applications. Shadow Copy technology requires the file system to be NTFS to be able to create and store shadow copies. Shadow Copies can be created on local and external (removable or network) volumes by any Windows component that uses this technology, such as when creating a scheduled Windows Backup or automatic System Restore point. (From: https://en.wikipedia.org/wiki/Shadow_Copy)

I didn’t particularly want to use backup.  I just wanted to do a simple file copy.

The way this works is that you mount the folder you want to copy as a special drive letter, which you then copy the files from.  Weird eh?

I did this using a cool little program called “ShadowSpawn” that allows you to execute a command using a volume shadow copy mount.

Using Windows Scheduler I execute the following command:

shadowspawn C:\eidy Q: robocopy Q:\ D:\eidybackup /s

(The volume “Q:\” is a temporary driver letter, “D:\” is a cloud synced volume)

It’s easy to setup, and may help with your simplistic copying needs.

Optimising Winforms Dropdown list combos for touch

Standard

image

The optimisation of the iPhone and the iPad for touch has contributed to it’s success. 

One example of this kind of optimisation is “drop down combos”.  Rather than sticking with the traditional touch UI of a big combo with a fat scrollbar (that would mess up web pages), they do something completely different.  As shown above a neat “roller” control is shown which makes combos a pleasure to use.

On the iPad the experience is more like a traditional combo, but it is not the same.

In the creation of Windows 7 Tablet user interfaces I am sure our users would prefer this kind of experience.

In Winforms it turns out that it’s possible to improve the touch experience markedly using the “OwnerDrawVariable” style on comboboxes.

As you can see, when the combo box looks relatively normal, not taking up much screen real estate….

image

Yet when it’s clicked, the control becomes bigger, so the normal flick scrolling features of Windows 7 tablet can work better.

image

The following code sample is a class called TouchCombo that can be used to cause combos to take on the new style.  Here’s the code for the sample form:

Public Class Form1
    Private Sub mPopulate(ByVal combo As ComboBox)
        combo.Items.Add("Alpha")
        combo.Items.Add("Beta")
        combo.Items.Add("Gamma")
        combo.Items.Add("Delta")
        combo.Items.Add("Epsilon")
        combo.SelectedIndex = 0

    End Sub

    Private moTouchCombo As New TouchCombo
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        mPopulate(ComboBox1)
        mPopulate(ComboBox2)
        moTouchCombo.Connect(ComboBox2)
    End Sub
End Class

 

Here’s the code for the TouchCombo class:

 

Public Class TouchCombo

    Public Sub Connect(ByVal combo As ComboBox)
        combo.DrawMode = DrawMode.OwnerDrawVariable
        combo.DropDownHeight = 200
        combo.DropDownWidth = combo.Width * 1.5
        AddHandler combo.MeasureItem, AddressOf mMeasureItem
        AddHandler combo.DrawItem, AddressOf mDrawItem
        AddHandler combo.DropDown, AddressOf mDropDown
        AddHandler combo.DropDownClosed, AddressOf mDropDownClosed
        AddHandler combo.Disposed, AddressOf mDisposed
    End Sub

    Private Sub mDrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs)

        Dim loCombo As ComboBox = sender

        Using loBrush = New System.Drawing.SolidBrush(e.ForeColor)

            ' Draw the normal Background
            e.DrawBackground()

            ' If it's not dropped down, make it look normal
            If Not loCombo.DroppedDown OrElse e.State = DrawItemState.ComboBoxEdit OrElse e.State = DrawItemState.Default Then
                e.Graphics.DrawString(loCombo.Items(e.Index), loCombo.Font, loBrush, e.Bounds.X, e.Bounds.Y)
            Else
                ' Otherwise draw it big
                Using loFont As New System.Drawing.Font("Arial", 15, FontStyle.Bold)
                    e.Graphics.DrawString(loCombo.Items(e.Index), loFont, loBrush, e.Bounds.X, e.Bounds.Y)
                End Using
            End If

            e.DrawFocusRectangle()

        End Using

    End Sub
    Private Sub mMeasureItem(ByVal sender As Object, ByVal e As System.Windows.Forms.MeasureItemEventArgs)
        e.ItemHeight = 35
    End Sub
    Private Sub mDropDown(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim loCombo As ComboBox = sender
        loCombo.ItemHeight = 35
    End Sub

    Private Sub mDropDownClosed(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim loCombo As ComboBox = sender
        loCombo.ItemHeight = 15
    End Sub

    Private Sub mDisposed(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim loCombo As ComboBox = sender
        RemoveHandler loCombo.MeasureItem, AddressOf mMeasureItem
        RemoveHandler loCombo.DrawItem, AddressOf mDrawItem
        RemoveHandler loCombo.DropDown, AddressOf mDropDown
        RemoveHandler loCombo.DropDownClosed, AddressOf mDropDownClosed
        RemoveHandler loCombo.Disposed, AddressOf mDisposed
    End Sub
End Class

 

Download the project.

Getting the parent process in VB.Net

Standard

 

image

The .net framework’s Process object lacks a means of determining which process invoked it. 

There are 3 techniques I have seen for determining this:

  • Api Calls
  • Iterating through the process table
  • Using wmi

This code sample uses the 3rd technique.  

Usage:

The code exposes a new “Parent” process function on the standard System.Diagnostics.Process class.

MessageBox.Show(System.Diagnostics.Process.GetCurrentProcess.Parent.Id)

Source:

Imports System.Management
Public Module ProcessExtensions
    <System.Runtime.CompilerServices.Extension()> _
    Public Function Parent(ByVal process As Process) As Process
        Return process.GetProcessById(miGetParentProcessId(process.Id))
    End Function
    Private Function miGetParentProcessId(ByVal processId As Integer) As Integer

        Dim loQuery As SelectQuery = New SelectQuery(String.Format("select * from Win32_Process where ProcessId = {0}", processId))
        Dim loSearcher As ManagementObjectSearcher = New ManagementObjectSearcher(loQuery)
        Dim loProcesses As ManagementObjectCollection = loSearcher.Get()

        If loProcesses.Count > 0 Then
            Return loProcesses(0)("ParentProcessId")
        End If
        Return 0
    End Function
End Module

 

 

References

Kill a specific process – System.Management forum post

Retrieving the Parent Process of a Child when Multiple Instances Exist – Robert Villahermosa

System Management Select Query

Enabling callto (Skype) in your application

Standard

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

A Simple Scroll Controller for Winforms

Standard

 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

Automatically stretching a Silverlight 2 control on a webpage

Standard

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 :

Weird Science – Defining Winforms in XAML

Standard

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

Visual Basic 9 for the Insane – Extension Methods

Standard

 

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

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

Standard

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.

Visual Basic 9 for the Insane – Constructors for Free

Standard

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).