Click here to Skip to main content
15,884,388 members
Articles / Programming Languages / C#

Silverlight Slideshow With Remote Control and Windows Taskbar Support

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
28 Dec 2011CPOL3 min read 16.6K   3   2
In this post, I will build a simple slideshow application to demonstrate some of the capabilities of the Native Extensions for Microsoft Silverlight library.

Native Extensions for Microsoft Silverlight is a collection of COM automation based runtime libraries and Silverlight libraries which allow elevated trust out of browser applications to utilize windows platform feature. For example, you can build applications which use Sensor API, Speech API, react to remote control, integrate with windows 7 taskbar or listen to windows messages sent to the host window. In this post, I will build a simple slideshow application to demonstrate some of the capabilities of the library.

The application allows users to choose images from their computer and control the slideshow with remote control as well as with taskbar buttons. Building the slideshow itself is very easy so I will briefly explain how it works: When the user selects pictures, a timer is started. When the timer tick event is fired, it fades out current image, switches to the next image and fades it in. The user is also able to stop the slideshow and manually switch between the images. The buttons can be also triggered with remote control and taskbar buttons.

Responding to Remote Control Buttons

According to remote control documentation to respond to remote control, you need to listen to various windows messages. For example, let’s implement pause/resume when APPCOMMAND_MEDIA_PAUSE or APPCOMMAND_MEDIA_PLAY commands are received. To interpret these commands, we need to catch WM_APPCOMMAND message.

C#
public MainPage()
{
    InitializeComponent();

    WindowMessageInterceptor.Current.WindowMessage += MessageReceived;
    WindowMessageInterceptor.Current.AddMessageIntercept(NativeMethods.WM_APPCOMMAND);
}

As you have probably guessed, MessageReceived is a method which will be called when the host window receives WM_APPCOMMAND message. The handler will also receive message details such as wParam and lParam. To get the command which triggered the message, we need to process lParam by calling GET_APPCOMMAND_LPARAM Macro. The macro is defined in Winuser.h as:

C#
#define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK))

HIWORD is another macro defined in Windef.h as:

C#
#define HIWORD(l) ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff))

The corresponding code in C# looks like this:

C#
public static int GET_APPCOMMAND_LPARAM(int lParam)
{
    return (short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK);
}

private static int HIWORD(int lParam)
{
    return ((lParam >> 16) & 0xffff);
}

We are now ready to implement the MessageReceived handler:

C#
private void MessageReceived(object sender, WindowMessageEventArgs e)
{
    if (e.Message == NativeMethods.WM_APPCOMMAND)
    {
        int cmd = NativeMethods.GET_APPCOMMAND_LPARAM(e.lParam);
        switch (cmd)
        {
            case NativeMethods.APPCOMMAND_MEDIA_PLAY:
                  ResumeSlideShow();
                  break;
            case NativeMethods.APPCOMMAND_MEDIA_PAUSE:
                  PauseSlideShow();
                  break;
        }
    }
}

Let’s add support for navigating between the images using left and right buttons on the controller. These buttons don’t generate WM_APPCOMMAND message. Instead, they trigger WM_KEYDOWN message which Silverlight supports out of the box. This means that to respond to these buttons we need to simply respond to KeyDown event:

C#
private void SlideShowKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Left)
    {
        PreviousImage();
    }

    if (e.Key == Key.Right)
    {
        NextImage();
    }
}

Adding Support for taskbar Buttons

The first step in adding support for taskbar buttons is to add the actual buttons. First, we create the buttons and then instruct the taskbar to show them:

C#
private void CreateTaskbarButtons()
{
    for (int i = 0; i < 4; i++)
    {
        var thumbbarButton = TaskbarButton.Current.CreateThumbbarButton((uint)(i + 1));
        thumbbarButton.Flags = THUMBBUTTONFLAGS.THBF_ENABLED;

        thumbbarButton.ImageDataType = ButtonImageDataType.PNG;
        var resourceInfo = Application.GetResourceStream(new Uri(
            string.Format("images/{0}.png", i), UriKind.Relative));
        using (var br = new BinaryReader(resourceInfo.Stream))
        {
            thumbbarButton.Image = br.ReadBytes((int)resourceInfo.Stream.Length);
        }

        taskbarButtons.Add(thumbbarButton);
     }

    taskbarButtons[0].Tooltip = "First Image";
    taskbarButtons[1].Tooltip = "Previous Image";
    taskbarButtons[2].Tooltip = "Next Image";
    taskbarButtons[3].Tooltip = "Last Image";

    TaskbarButton.Current.ShowThumbbarButtons();
}

You have probably noticed that the code snippet is creating buttons but there are no event handlers to respond when they are clicked. Instead, we need to use WindowMessageInterceptor class again and subscribe to CommandMessage event. The event is raised in response to WM_COMMAND message which is generated when a taskbar button is clicked. Apart from subscribing to the event, we need to call the AddCommandMessageIntercept method and specify which control notification code we are interested in. This way, the event will be raised only for that particular notification code. In the case of taskbar buttons, the notification code is THBN_CLICKED.

C#
WindowMessageInterceptor.Current.CommandMessage += CommandMessage;
WindowMessageInterceptor.Current.AddCommandMessageIntercept(NativeMethods.THBN_CLICKED);

When the event handler is called, it will receive an instance of CommandMessageEventArgs class specifying the notification code and control identifier. The control identifier corresponds to the ButtonID we passed to the CreateThumbbarButton method when we created the buttons. This way, we can identify which button caused the event to fire.

C#
private void CommandMessage(object sender, CommandMessageEventArgs e)
{
    if (e.NotifyCode != NativeMethods.THBN_CLICKED)
    {
        return;
    }

    switch (e.ControlID)
    {
        case 1:
            FirstImage();
            break;
        case 2:
            PreviousImage();
            break;
        case 3:
            NextImage();
            break;
        case 4:
            LastImage();
            break;
    }
}

To view a demo of the application, click Silverlight remote control demo.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Georgia Georgia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionSource? Pin
JustinSays11-Jan-12 18:15
JustinSays11-Jan-12 18:15 
AnswerRe: Source? Pin
Giorgi Dalakishvili13-Jan-12 8:54
mentorGiorgi Dalakishvili13-Jan-12 8:54 
Source code is available at https://github.com/Giorgi/Silverlight-Remote-Control[^]
Giorgi Dalakishvili

#region signature

My Articles

My Blog

#endregion

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.