Foredecker

Jibe!

Archive for the ‘Coding’ Category

C# IShellLink COM Interop Example #1

with 2 comments

I recently needed to use C# to programmatically create a shortcut (.LNK file) to a console executable. This is easily done in native C/C++ using the ShellLink CoClass, the IShellLink interface and their related interfaces.

I looked around and couldn’t find a good C# COM interop example for the related native COM interfaces so I wrote one.   This was a good excuse for me to learn a litle bit about C# and COM interoperability.  You can find the source code here, provided under the Microsoft Permissive License.

This first cut provides a set of C# classes and related values for manipulating Windows Shell Links.  The public methods, properties and enumerations (or just publics) are C# style – I didn’t let the underlying native names leak through.

For example, an important native enumeration is the native SHELL_LINK_DATA_FLAGS enumeration.   I’ve seen some interop examples that expose the native names of things publicly in C#.   This works, but doesn’t follow the .NET Design Guidelines for Class Library Developers (in hardback on Amazon).   Exposing the native names is a bit ugly in .NET languages, and in C# in particular.

In the public aspects of my C# I provide the native functionally in a modern C# manner.  For example, I  provide a .NET enuneration named ShellLinkFlags which provides the values in SHELL_LINK_DATA_FLAGS.   These enumerations have C# style names like RunAsUser instead of SLDF_RUNAS_USER.

Another important attribute is that all of the publics are CLS compliant.  This enables all .NET languages to easily access these classes, not just C#.

There are some limitations to this code.  I built this so I could create shell links to EXEs – primarily console applications.    This code does not yet support the IShellLink.GetIDList() and IShellLInk.SetIDList() methiods.  So, it can only be used to link to things in the file system, and not shell objects such as printers.

The Project

This code is provided in a Visual Studio 2010 project built with C# and .NET 4.0 using the client profile.

The actual shell interop code is built in a separate class library named Eidos, which is the name of my general purpose C# library.   The namespace is Eidos.Shell.   You can use this directly, or easily incorporate it into your own code.

I’ve also included a couple of basic unit tests – you can extend these as needed.

There is also a simple program that will dump the contents of a Shell link file to the console.

The Code

The primary public class is ShellLink.  This provides a set of properties and methods that provides the functionality of IShellLink but in a C# manner.

One of the biggest differences between the C# APIs and the native COM interfaces are how Data Blocks and IShellLinkDataList are treated.    These are not exposed in the my .NET classes.  instead, they are wrapped using standard properties on the C# ShellLink class.

This works really well.  It means you can simply get and set property values just like you would with a “normal” .NET class.   The IShellLink class handles all the work of creating, writing and reading the data blocks using an internal IShellLinkDataList interface.

Download the Source

You can find the source code here, provided under the Microsoft Permissive License.

Advertisements

Written by foredecker

December 5, 2010 at 5:21 pm

Posted in Coding

WPF: Styling the Expander Control

with one comment

I recently needed to style a WPF expander control for a prototype project. Our team’s UX designer came up with a nice visual design.    So, I began to build my prototype and match his visual style (mocked up in Visio) in WPF.   I thought it would be easy…   it was, once I spent all morning  figuring out how to do it…

Here is screen shot of the prototype – it is pretty close to the mock up.

ScreenShot1

I started off with the Expander Control Template example on MSDN.  This wasn’t a bad start – it showed me how to change expander toggle button – nice.

But, I also needed to change the font used in the expander header.  That wasn’t shown in the example.   Ok, no problem – just use a setter in the style like this – right?

    <Style x:Key="MainViewExpander" TargetType="Expander">
        <Setter Property="FontSize" Value="18" />
        <Setter Property="FontWeight" Value="Bold" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Expander">

Example1Bzzzztttt… wrong.   That set the font appearance in the Expander header like I wanted, but all the controls in the Expander content property inherited the font appearance.  That’s not what I wanted at all.

I needed to style the appearance of the Expander header and its contents separately.

So, i dug around in MSDN a little more.  The key information turned out to be in the documentation for the Headered Content Control class.

This is an important class as it defines the base functionality for controls including the Expander, Group Box and TabItem controls – all very commonly used controls.

They key to getting the look I wanted is using Data Templates.   I’ve seen this used in many MSDN examples and WPF blog posts but until now, I never really understood them.

In short, data templates are like control templates but instead of defining how WPF structures the visual tree for a control, data template defines how WPF displays data.

We’ll, you might say “Duh Richard!”  That’s what the docs say….  Ya, Duh! For sure…  I didn’t grok exactly what this meant until now: they key for me was finally understanding that the data template is bound to the data it is intended to display.

All data template intentions are bound to a property on an object instance.   You can refer to this binding by using the simple most binding which is “{Binding}”.  You can see how this is used below.

The key is that all Headered Content Controls have a data template for the header content.    So, setting the font appearance for the Expander header was a simple matter of adding this setter to my style


        <Setter Property="HeaderTemplate">
            <Setter.Value>
                <DataTemplate>
                    <TextBlock
                        Text="{Binding}"
                        FontSize="18"
                        FontWeight="Bold"
                        Foreground="White"
                        />
                </DataTemplate>
            </Setter.Value>
        </Setter>

This worked great!  As you can see in the screen shot at the beginning of the post, I set the text appearance to the white, 18 size bold text I wanted.   Most importantly, the appearance of the content was not affected by the header’s appearance.

Now, in one case, I do want to determine the font appearance of all the children in an Expander’s content property.   As you can seen in the screen shot, the commands are in a larger, bold font style.

To accomplish this, I simply created a style derived from the main expander style -like this:

    <Style x:Key="MainViewExpanderCommands"
           BasedOn="{StaticResource MainViewExpander}"
           TargetType="Expander"
           >
        <Setter Property="FontSize" Value="20" />
        <Setter Property="FontWeight" Value="Bold" />
    </Style>

Then, in the MainView.xaml file, I used the derived style like this:

        <Expander
            Header="Commands"
            Grid.Column="0"
            IsExpanded="True"
            Style="{StaticResource                   MainViewExpanderCommands}"
            >
            <StackPanel>
                <Label Content="Open"    Foreground="#FFB4B4A9" />
                <Label Content="Save"    Foreground="#FFB4B4A9"/>
                <Label Content="Save As" Foreground="#FFB4B4A9"/>
                <Label Content="Close"   Foreground="#FFB4B4A9"/>
            </StackPanel>
        </Expander>

This worked fine – mostly.  If you look, you will see that each of the labels has the foreground set to a grey color.   I tried to do this in the derived style, bit alas, this didn’t work because the the intervening stack panel (which is the content for the expander) does not have the foreground property, so it is not inherited.

Here is the source code download

This code builds with the release candidate version of Visual Studio 2010.   It does not need any additional components (like NUnit).

Installing and building the project is easy:   Just download and run the installer.   It will put the project on your desktop.  Note, it doesn’t really ‘install’ anything – there are no shortcuts and it doesn’t write to the registry.  You can move the sample directory wherever you would like, or just delete it when you are done.  No un-installing is needed.   The contents are licensed with the Microsoft Public License.

Credit – I’d like to thank Josh Smith for his excellent examples of using the MVVM design pattern.   All my new WPF projects are MVVM and I learned the ropes from his blog posts.  The MVVM classes in this example are inspired by Josh’s MSDN article here.   I’m still a noob with both WPF and MVVM – the learning curve is very steep, and long.  But Josh’s blog and articles have been hugely helpful (as have many others…)

Written by foredecker

March 28, 2010 at 5:48 pm

Posted in Coding

Tagged with ,

BizzySpinner 2 – A WPF Spinning Busy State Indicator (with source)

with 4 comments

I’ve made a key improvement to my BizzySpinner control form my last post.  It now starts and stop smoothly instead of abruptly.  This is quite visually attractive.  But it was somewhat non-trivial to do.

In my first example, I had a single simple animation that was either running or stopped.  The animation behavior is now like this:

BizzySpinnerAcceleration

I tried to do this all in XAML but it proved quite complex to handle in in that language.   This was complicated as there are two key dependency properties to deal with that leads to several states: The Spin property controls the actually spinning state.   And the IsEnabled property inherited from UIElement.  Both must work correctly together.

This gave me two significant problems:

  1. The XAML was really complicated and difficult to read.  I don’t know about you, but to me, XAML is very verbose and difficult to read.  Syntax highlighting helps, but only to a degree.   There is also no such thing as a XAML debugger so a lot of trial and error is involved with large amounts of XAML.   Kaxaml is really helpful, but this was hard even with that tool.
  2. I couldn’t get a fully correct state machine in XAML: No matter what I tried I could toggle the IsEnabled and Spin dependency properties and cause the spinner to “jump” unattractively.

BizzySpinnerAcceleration-Page2 So, I simply used C# code to do this.   This approach was much simpler.   It was easy to implement the two cooperating state machines needed to implement all cases.   The spinning state machine is shown to the right.   It has four states and six transitions – not at all difficult to implement.

This state machine is implemented in the ControlSpinning() function on line 432 in BizzySpinner.xaml.cs.

The transitions caused by the SpinUp and SpinDown values are straight forward and implemented using a couple of switch statements

The transitions labeled Acceleration Complete and Deceleration Complete are more interesting:  they are implemented using the Completed event on the DoubleAnimation using to spin the control.

For example when the spinner goes form the Not Spinning state to the Accelerating state, the code simply attaches a function to the animation’s Completed event like this:

Code Snippet
  1. spinAnimation.From = SpinAngle;
  2. spinAnimation.To = (SpinAngle + (OneRotation / 8));
  3. spinAnimation.Duration = new Duration(TimeSpan.FromSeconds(SpinRate/4));
  4. spinAnimation.DecelerationRatio = 0.0;
  5. spinAnimation.AccelerationRatio = 1.0;
  6. spinAnimation.Completed += SpinContinuously;
  7. theSpinState = SpinState.Accelerating;
  8. this.BeginAnimation(SpinAngleProperty, spinAnimation);

This is the code that causes the spinner to accelerate to its normal spinning rate.  The key line is #7.   When the spinner has finished accelerating the SpinContinuously member is called.  It looks like this:

Code Snippet
  1. void SpinContinuously(object sender, EventArgs e)
  2. {
  3. spinAnimation.Completed -= SpinContinuously;
  4. spinAnimation.From = SpinAngle;
  5. spinAnimation.To = SpinAngle + OneRotation;
  6. spinAnimation.Duration = new Duration(TimeSpan.FromSeconds(SpinRate));
  7. spinAnimation.DecelerationRatio = 0.0;
  8. spinAnimation.AccelerationRatio = 0.0;
  9. spinAnimation.RepeatBehavior = RepeatBehavior.Forever;
  10. theSpinState = SpinState.Running;
  11. this.BeginAnimation(SpinAngleProperty, spinAnimation);
  12. }

Note line 3 which disconnects the SpinContinuously from the animations Completed event.   This is super important as we don’t want this called again because the next state transition when the animation completes is a different one.

The other important state machine is the one that handles the IsEnabled and Spin dependency properties.   This is what sends the SpinUp and SpinDown commands to the spinning state machine.

BizzySpinnerAcceleration-Page3

This is simpler than it looks:  there are only four important transitions – the ones in green where the SpinUp and SpinDown commands are sent to the spinning state machine.

This is all handled easily in the IsEnabledChanged event handler like this:

Code Snippet
  1. private void IsEnabledChangedHandler(Object sender, DependencyPropertyChangedEventArgs e)
  2. {
  3. if ( !(bool)e.NewValue)
  4. {
  5. //
  6. // Going enabled
  7. //
  8. Background = BackgroundBrushSave;
  9. LeaderBrush = LeaderBrushSave;
  10. TailBrush = TailBrushSave;
  11. // The control is enabled, turn on spinning if the Spin property is ture
  12. ControlSpinning(Spin ? SpinCommand.SpinUp : SpinCommand.SpinDown);
  13. } else {
  14. //
  15. // Going disabled
  16. //
  17. if (theSpinState == SpinState.NotSpinning)
  18. {
  19. SetDisabledBrushes();
  20. }
  21. else
  22. {
  23. ControlSpinning(SpinCommand.SpinDown);
  24. }
  25. }
  26. }

The resulting animation is very pleasing – the control spins up and down smoothly.   Its rotational rate can also be controlled dynamically.

You will need NUnit 2.5.3 (download) as I’ve added assertions. The code builds for C# 3.0 and .NET 3.5 using the client profile.  As with the last post, the project is for the Visual Studio 2010 BETA which you can download for free..

Installing and building the project is easy:   Just download and run the installer.   It will put the project on your desktop.  Note, it doesn’t really ‘install’ anything – there are no shortcuts and it doesn’t write to the registry.  You can move the sample directory wherever you would like, or just delete it when you are done.  No un-installing is needed.   Also note that the contents are licensed with the Microsoft Public License.

Here is the source code download

Written by foredecker

January 11, 2010 at 3:49 am

Posted in Coding

Tagged with ,

BizzySpinner – A WPF Spinning Busy Sate Indicator (with source)

leave a comment »

I’ve been working on a pet project that does a lot of network I/O and database queries.   One of the things I need to do is run long running things in the background – off the UI thread and keep the UI responsive.  So, I’ve built a spinning busy state indicator.  I’ve included the source code as well.

BizzySpinnerMy graphical design skills are pretty lame, but I saw some others on the net and Mine doesn’t look too bad.

I’m still learning WPF.  I started about two years ago (see my old posts) but was distracted by shipping a little thing we call Windows-7.  Given our team is very likely to build some production WPF based products, I need to get back on the stick and learn the WPF basics.

As with any new project, I found several good examples on the ‘tubes.  Sacha Barber’s example on CodeProject.com was a good start and where I got the inspiration for my basic graphical design.   This one is similar, and this one is native on GDI+.  Here is another one on the Expression Behaviors Gallery.

While all are good examples, I wanted to code my own completely from scratch.   I had a few goals in mind:

  1. Full support for styles and templates
  2. Fully sizeable
  3. Rotate in either direction
  4. Could be disabled – like most other controls
  5. Could be ‘spun’ manually –without an animation

This means I need to build a fully custom WPF control – a class that derives from System.Windows.Controls.Control. This turned out to be really easy – once I got past the learning curve!

Until recently, my WPF code and XAML were pretty klunky – the code seemed complicated to me and had a faint ‘just not right’ code smell.  The more I looked at it, the riper it got.   You can see some of this stinky cheese here.   [ wow?  was that really two years ago?  I suppose that’s why they call shipping Windows-7 ‘work’ ]

In any case, I’ve had the time to do some hacking recently and I’ve learned a ton.   One thing I’ve noted is there is a LOT more WPF information on the ‘tubes than there was two years ago, and the WPF MSDN Library documentation is way, way better.   This made my recent efforts much easier.

The major thing I learned recently is that I had been going about WPF develop all wrong.  All my previous hacks had been procedural in nature – doing the UI work in code.   I hadn’t really groked how fundamental dependency properties and data binding are to WPF development.  These simply are not framework features you can use – they are fundamental constructs.  Tying things together with dependency properties and data bindings is just they way to do things in WPF.   It took me a bit to grok it, but I had one of those ah-Ha! moments are few days ago.  Groovy.

As with my other posts, I’m including the fully buildable source code.  The code currently uses the .NET 3.5 Client Profile but it builds with Beta-2 of Visual Studio 2010.     You can find the code attached.

The current code is fully functional. I’ve packaged the spinner its own assembly called Fenestra which Latin for ‘window’, clever huh?  I’ve also included a developer framework (DF) that lets me test the control.  It looks like this:

The DF lets me control the properties including the size, the spin rate and watch the events happen.   Its very simple code.  In the image above you can see two spinners, the one on the left is the default theme for the control.  The one on the right is a templated and styled version.    BizzySpinnerDF

All of the elements are fully style-able.   Each item in the spinner is a WPF Shape which means their key attributes can be bound to the control’s dependency properties.

CirclesI drew the fundamental shapes in Expression Design 3 which has a learning curve all its own.  I used it because it directly produces XAML.   Once I got the basic knack of using the tool, it wasn’t too hard to do.  You can find the original design files in the BizzySpinnerDF directory.  They are named Circles.design and Rectangles.design.

Installing and building the project is easy:   Just download and run the installer.   It will put the project on your desktop.  Note, it doesn’t really ‘install’ anything – there are no shortcuts and it doesn’t write to the registry.  You can move the sample directory wherever you would like, or just delete it when you are done.  No un-installing is needed.   Also note that the contents are licensed with the Microsoft Public License.

Here is the download

Written by foredecker

January 1, 2010 at 2:57 am

Posted in Coding

Tagged with