Monthly Archives: December 2007

Disabling the context menu in the .Net CF WebBrowser Control

Standard

image

Although initially impressive, the WebBrowser control in the .NET Compact Framework 2.0 lacks the ability to be customised in a few important areas. An obvious one that people are asking about seems to be the ability to remove the default context menu.

None of the obvious solutions , such as setting the ContextMenu property to null seem to work.

The Problem
The internal PIE control that the WebBrowser control wraps has a COM property to disable it, but this is not exposed.

So how can we set the property?

The .NET CF 2.0 provides the answer. It introduced some new features that allows straight forward interaction with COM objects and controls.

Doing this with the WebBrowser control involves sending a special windows message (DTM_BROWSERDISPATCH) to the windows handle of the control to retrieve a pointer to the IDispatch interface, converted into an object (using the GetObjectForIUnknown call) , which is then cast to a marked up interface with the appropriate identifiers. These are found webvw.h which is part of the Compact Framework SDK.

This technique will only work for Windows Mobile (not Smartphone) based devices. For my own projects I use a compiler directive to screen avoid the COM calls on the Smartphone platform.

The Solution

I have cut down the solution to it’s bare essentials and encapsulated it in the class WebBrowserContactMenu. You should be able to reuse this class, unaltered in your own project.

Warning: Currently this solution WILL ONLY WORK FOR Windows Mobile 2003!   It is supposed to work for WM5 and above also (it all seems correct) but for some reason the SendMessage to DTM_BROWSERDISPATCH is not working at all.   I have researched the problem but as yet cannot find a workaround.  I will update this article if I do.  Any suggestions are welcome.

Imports System.Runtime.InteropServices
Imports System.Runtime.CompilerServices
Public Class WebBrowserContextMenu
Private moWebBrowser As WebBrowser
Public Sub New(ByVal control As WebBrowser)
moWebBrowser = control
End Sub
Const WM_USER As Integer = &H400
Const DTM_BROWSERDISPATCH As Integer = (WM_USER + 124)
Declare Function SendMessageLongRef Lib “Coredll” Alias “SendMessageW” (ByVal HWND As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByRef lParam As Integer) As Integer
Public Property Enabled() As Boolean
Get
Return mGetBrowserInterface.ContextMenuEnabled
End Get
Set(ByVal value As Boolean)
mGetBrowserInterface.ContextMenuEnabled = value
End Set
End Property

Private Function mGetBrowserInterface() As IBrowserBareEssentials

Dim liPtr As Integer = 0
SendMessageLongRef(moWebBrowser.Handle.ToInt32, DTM_BROWSERDISPATCH, 0, liPtr)

Return CType(System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(CType(liPtr, IntPtr)), IBrowserBareEssentials)

End Function

<ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIDispatch), Guid(“698E3FC9-70C3-11D0-81E8-00A0C90AD20A”)> _
Public Interface IBrowserBareEssentials

<DispId(185)> Property ContextMenuEnabled() As Boolean
End Interface
End Class

In the example project, a simple WebBrowser application hosts this class, instantiating it and using radio buttons to toggle the button. Here’s what the form code looks like:

Public Class Form1
Private moContextMenu As WebBrowserContextMenu
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
WebBrowser1.Navigate(New Uri(txtUrl.Text))
moContextMenu = New WebBrowserContextMenu(WebBrowser1)
End Sub
Private Sub cmdGo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdGo.Click
WebBrowser1.Navigate(New Uri(txtUrl.Text))
End Sub
Private Sub optEnabled_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles optEnabled.Click
moContextMenu.Enabled = optEnabled.Checked
End Sub
Private Sub optDisabled_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles optDisabled.Click
moContextMenu.Enabled = optEnabled.Checked
End Sub

End Class

Download the sample project. (14K)

Conclusion

The purpose of this article was to provide a direct solution to the context menu problem. I have by no means an exhaustive description of using COM with WebBrowser, but this may help as an introduction. At a future date I will share other uses for this technique.

Share this post :

kick it on DotNetKicks.com

WPF and the Supervising Controller/Presenter Pattern

Standard

image

I’ve previously stated that the MVP pattern could be advantages for XAML based applications.  I haven’t provided WPF examples yet as I fear that these may compromise the design-ability of the XAML layout.  

Florian Krusch describes the beginnings of an MVP style pattern for WPF (and Silverlight) applications in his article:

WPF – DM-V-VM or M-V-P – WTF?

He states that the pattern described by Martin Fowler  “Supervising Controller Pattern” (still under development at time of writing) may be relevant in this case.  (The term Controller and Presenter are used interchangeably in Fowler’s article)

This pattern has been created in order to facilitate frameworks such as WPF that have a data binding capability.   I understand however that it expects one-way data binding (read) with the view look at the model directly.  Updates to fields are delegated to the controller, which in turn updates the model.  This sortve neuters the 2-way data binding in WPF.

The true objective of these architectures is testability, with the assumption of the view being difficult to work with in the unit test environment.

An architecture that may work is something like the diagram below:

 

image 

In this proposal both the View and Model could be mocked successfully.

In future posts I’ll endeavour to  create some code to show how this may work in the real world.

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

Seeing is Believing – Using Powerpoint as a UI Design Tool

Standard

Image that provides a visual metaphor about how different owls see things differently

When talking about “interaction design”, designers talk about the practice of “Wire Framing”. 

In the past this “Wire Framing” involved creating fairly primitive mock-ups of user interfaces on paper, arranged to make a “Story Board”, much in the same way as makers of animated cartoons always have.

The use of these story boards has allowed designers to “run through” prospective designs with real users as well as developers.  A useful tool.

Although paper is certainly a useful tool (I use it alot myself).  I can’t help wondering if there’s a way of doing this on a computer effectively.  You’d think there would be wouldn’t you?

Draw It!

One approach is to use a graphics editor such as Photoshop or the ubiquitous MS Paint (for goodness sake use Paint.NET at least….).    This is good in that it helps the stakeholders understand what it is that the new product will look like.  It’s bad in that it isn’t interactive and it usually takes lots of time, sometimes with a mediocre result.  It’s good if you have a Graphic Artist to help.  (The difference between a developer and a Graphic Artist producing a piece of work is that although they will probably both take ages to produce something, at least the Graphic Artist produces something worth looking at).

Prototypes

Another approach is to create a prototype using the actual development tools.  In the Microsoft World, run up Visual Studio and start churning out miracles.  Sadly however this approach is still development and developers can get bogged down in the detail.

There’s also the “scary” side to an operational prototype.  That nightmare scenario where development budgets are reduced and the boss says “why don’t we just put the prototype into production”……Enough said.

So the trick, in my opinion is to create something that looks as real as possible (ie as impressive as possible), but clearly is not the “real thing”.

 

Enter – Expression Blend

The era of User Experiences ushers in another alluring alternative.  Microsoft for example offer designer-oriented products such as “Expression Blend” that allow designers to create WPF and Silverlight based user interfaces without having to run the equivalent development tool “Visual Studio”. 

Allegedly Expression Blend will allow designers to create user interfaces.  At last designers have the power to wireframe in a rich way, creating user experiences that behave like prototypes.   Like the craftsman in his workshop, the designer has created a beautiful puppet, which dances for his appreciative masters.  But what if Pinnochio wants to become a “real boy”?

When it comes time to create real software the developers add the code, like Blue Faerie’s pixie dust and bring the user interfaces to life.

A pretty story indeed.  But will it happen?  In the Microsoft world it’s something that was promised with web frameworks such as ASP.Net in the early days, the dream of separating  ui design from programming content.

Sometimes creating the desired ui experience does take a while, even for someone proficient in Expression Blend.   (Happy to be howled down on this point)  A lot longer than doing a hand sketch or using MS Paint anyway.

Powerpoint Magic

A technique that has been used in my team is to use PowerPoint to do our Ui concept demos.      It has proven to be so believable, I’ve had stakeholders ask me to click on ui elements that are not part of the demo, despite repeatedly telling them “it’s only powerpoint”. 

We create different slides for each ui state.  In it’s simplest form we press enter to advance to the next ui state. 

This does NOT involve complex animation and transitions.  This sort of thing, even in a normal powerpoint presentation just wastes time.

If there’s time we’ll add “Custom Actions” (Mouse Hover or Click) to some UI elements to advance to the next slide, but that’s it.

To create the slides, we usually begin with a base (in the case of a browser based app this may be a screenshot of a webbrowser frame).  Take screenshots of various UI elements from other applications using screen capture software.  (this is built in to Vista….I recommend using Gadwin if you’re running XP)  The more of these you have the more realistic your concept will look.  Use the built-in powerpoint text boxes for more conceptual work.

The screenshot below a screenshot of a proposed PDA application.   It uses a screenshot of Visual Studio’s emulator as a base:

Sample PDA Application Screenshot

 

Using this approach can have these advantages:

  • It can look exactly like the real thing
  • It’s easy to do
  • It’s fast
  • You can add annotations
  • You can add limited interactivity
  • It works for any kind of application, not just Microsoft Wpf/Silverlight
  • You can use any Powerpoint-like tool

Conclusion

The “User Experience” is a becoming a key differentiator in many software markets.  Creating prototypes can be an important technique in creating compelling Ui experiences.  Perhaps more of this would be done if people realised that even a tool like PowerPoint can be used to do this.

Links

 

Share this post :

Notes in the Moonlight

Standard

image

I was listening to a recent interview with Miguel De Icaza.  I learnt some new things about Mono (the open source re-implementation of the .Net Framework for Linux)  that I thought I’d record here for posterity:

  • They’ll soon be shipping a version of Moonlight that’s equivalent to Silverlight 1.0 for Linux
  • Even the earliest version of Moonlight was able to run the rich Silverlight application “Top Banana”
  • Mono runs on “Open Moko”, the hackable Linux Based Phone
  • Moonlight contains a cut-down version of the Mono CLR and class libraries, just like Silverlight does.  This is done via using the “mono linker” process, which removes unused functions from libraries to create a leaner install.

An interesting idea Miguel talked about was creating a nice modern xaml-based interface to “Open Moko”.  The iPhone has certainly raised expectations about mobile user interface and Miguel suggests that using XAML could an enable for this.

LinKS

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

Visual Basic 9 for the Insane – An Introduction

Standard

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