dotnet thoughts 

a dotnet developer's technical blog

How to use TaskDialog API in C#

The TaskDialog API replaces MessageBox. A message box is useful for prompting users for an acknowledgment, confirmation, or an answer to a yes or no question. Message boxes are popular because of the MessageBox function is convenient for developers to use. TaskDialog is the preferred API to use because it is similar to MessageBox but much more flexible. Previously, developers have created their own message box implementations when greater functionality was required. Unfortunately .Net framework doesn’t expose TaskDialog API directly; you need to use WIN32 api for it. Here is one Task dialog implementation in C#. Only limitation of Task Dialog API is it doesn’t supported by Windows operating systems less than Windows Vista.

Here is the API declarations.

[DllImport("comctl32.dll", CharSet = CharSet.Unicode, EntryPoint = "TaskDialog")]
static extern int TaskDialog(IntPtr hWndParent, IntPtr hInstance, String pszWindowTitle,
String pszMainInstruction, String pszContent, int dwCommonButtons,
IntPtr pszIcon, out TaskDialogResult pnButton);

//Dialog buttons
[Flags]
public enum TaskDialogButtons : int
{
    Ok = 0x0001,
    Cancel = 0x0008,
    Yes = 0x0002,
    No = 0x0004,
    Retry = 0x0010,
    Close = 0x0020
}

//Dialog Results
[Flags]
public enum TaskDialogResult : int
{
    IDOK = 1,
    IDCANCEL = 2,
    IDRETRY = 4,
    IDYES = 6,
    IDNO = 7,
    IDCLOSE = 8,
    NONE = 0
}

//Dialog Icons
[Flags]
public enum TaskDialogIcon
{
    Information = UInt16.MaxValue - 2,
    Warning = UInt16.MaxValue,
    Stop = UInt16.MaxValue - 1,
    Question = 0,
    SecurityWarning = UInt16.MaxValue - 5,
    SecurityError = UInt16.MaxValue - 6,
    SecuritySuccess = UInt16.MaxValue - 7,
    SecurityShield = UInt16.MaxValue - 3,
    SecurityShieldBlue = UInt16.MaxValue - 4,
    SecurityShieldGray = UInt16.MaxValue - 8
}

And here is my TaskDialog wrapper function.

public static TaskDialogResult Show(IntPtr handle, string messageTitle, string mainTitle,
    string mainContent, TaskDialogButtons taskDialogButtons, TaskDialogIcon taskDialogIcon)
{
    TaskDialogResult buttonClicked = TaskDialogResult.IDCANCEL;
    TaskDialog(handle, IntPtr.Zero, messageTitle, mainTitle, mainContent,
        (int)taskDialogButtons, (IntPtr)(int)taskDialogIcon, out buttonClicked);
    return buttonClicked;
}

And here is the screen shot of Task Dialog running in my Windows 7 machine.

Task Dialog - On Windows 7 machine

Task Dialog - On Windows 7 machine

WCF Callbacks – A quick introduction

WCF callbacks are an old topic, but recently I got a chance to play around it. WCF callback means instead of normal request – response pattern, it will be a bidirectional communication between client and server.

First need to create the service interface

[ServiceContract(CallbackContract = typeof(IServiceCallback),
Namespace = "http://dotnetthoughts.net/wcf")]
interface IService
{
    [OperationContract(IsOneWay = true)]
    void SayHello(string name);
}

If you notice the Service contract attribute, there is parameter, Callback contract, which is required to map the service call with the callback method. And here is the callback contract interface.

interface IServiceCallback
{
    [OperationContract(IsOneWay = true)]
    void Print(string message);
}

And here is the implementation of the service and callback interface.

class Service : IService
{
    public void SayHello(string name)
    {
        IServiceCallback callback =
            OperationContext.Current.GetCallbackChannel<IServiceCallback>();
        string message = string.Format("Hello {0}", name);
        callback.Print(message);
    }
}

class ServiceCallback : IServiceCallback
{
    public void Print(string message)
    {
        Console.WriteLine(message);
    }
}

I am using Self Hosting mode to host the service. And here is the implementation.

class Program
{
    static void Main(string[] args)
    {
        string baseAddress = "net.tcp://localhost:8080/";
        Uri[] addresses = { new Uri(baseAddress) };
        using (var serviceHost = new ServiceHost(typeof(Service), addresses))
        {
            serviceHost.AddServiceEndpoint(typeof(IService),
                new NetTcpBinding(), "IService");

            serviceHost.Open();
            Console.WriteLine("Service started.");
            Console.WriteLine("Press any key to stop.");
            Console.ReadKey(true);
            serviceHost.Close();
        }
    }
}

Now we need to create proxy to communicate to our service. Here is the proxy implementation.

class ServiceProxy : DuplexClientBase<IService>, IService
{
    public ServiceProxy(object callbackInstance,
        Binding binding, EndpointAddress remoteAddress)
        : base(callbackInstance, binding, remoteAddress)
    {

    }
    public void SayHello(string name)
    {
        Channel.SayHello(name);
    }
}

And finally here is the client implementation, in the client class; I am implementing the callback interface, so that I can get the callback result in the client.

class Client : IServiceCallback
{
    public void SayHelloToService(string name)
    {
        var proxy =
            new ServiceProxy(this, new NetTcpBinding(),
                new EndpointAddress("net.tcp://localhost:8080/IService"));
        proxy.SayHello(name);
    }

    public void Print(string message)
    {
        Console.WriteLine(message);
    }
}

Now start the Service first then create the instance of client class and invoke SayHelloToService with name parameter and it will be printed in the console. And here is the Test for the same.


[TestClass]
public class TestService : IServiceCallback
{
    private string actual = string.Empty;
    private AutoResetEvent autoResetEvent = null;
    [TestMethod]
    public void TestSayHello()
    {
        string expected = "Hello dotnetthoughts";
        autoResetEvent = new AutoResetEvent(false);
        var proxy =
            new ServiceProxy(this, new NetTcpBinding(),
                new EndpointAddress("net.tcp://localhost:8080/IService"));
        proxy.SayHello("dotnetthoughts");
        Assert.IsTrue(autoResetEvent.WaitOne(5000), @"Callback not recevied.");
        Assert.IsTrue(expected == actual, @"Invalid response from callback.");
    }

    public void Print(string message)
    {
        actual = message;
        autoResetEvent.Set();
    }
}

Happy Coding :)

Silverlight 5 Beta Is Available For Download

Microsoft Silverlight is a powerful tool for creating and delivering rich Internet applications and media experiences on the Web. Silverlight 5 builds on the foundation of Silverlight 4 for building business applications and premium media experiences. Among other capabilities, the Silverlight 5 beta highlights dramatic video quality and performance improvements, and features that improve developer productivity.

The final Silverlight 5 release will be available in 2011. You can find more details and can download the beta version from here

User Group Meeting – 11th June 2011 – Kochi

Venu
Orion India Systems Pvt Ltd, 103, 2nd floor, Tejomaya, Info park SEZ, Kakkanad, Kochin-682030

Agenda

  1. 09:30 – 09:40 Community updates
  2. 09:40 – 10:30 Scaffolding with EF 4.1 and ASP.NET MVC 3
  3. 10:30 – 11:15 Debugging Techniques in Visual Studio
  4. 11:15 – 11:30 Tea Break (15 min)
  5. 11:30 – 12:30 Introducing Parallel programming in .net 4.0
  6. 12.30 – 01:00 Ask the experts

Speakers

  1. Bijith K B -working as a Software Architect with Affiliated Compter Services (An Xerox Company) @ Infopark
  2. Shiju Varghese -Microsoft MVP in ASP.NET, is a Technical Architect on the Microsoft .Net technology stack with a focus on web application development and Domain-Driven Design.
  3. Yanesh Tyagi -is a technical architect with Millennium Consultants. He has extensive 16 years of experience working on different technologies, specially Microsoft Technologies.

Click Here to register. You can find more details Here

How to integrate FxCop to Visual Studio 2010 Professional

VS 2010 Professional doesn’t support Static code analysis. Here is a simple way to integrate FxCop to Visual Studio. (It was also using External tools option from Visual Studio tools menu.)

  1. In the Title text box, type FxCop.
  2. Integrate FxCop to Visual Studio

    Integrate FxCop to Visual Studio

    .

  3. To set the value of the Command text box, browse to the location where FxCop is installed, and select FxCopCmd.exe.
  4. In the arguments text box, type the following command : /c /f:$(TargetPath) /d:$(BinDir) – More information : FxCop command line reference
  5. Set the Initial Directory to the location where FxCopCmd should start.
  6. Select the Use Output window check box. – This will display the output of FxCopcmd.exe to output window, and you can double click and navigate to the line number.
  7. FxCop - Source code analysis results in VS output window

    FxCop - Source code analysis results in VS output window

  8. Click OK.

Happy static code analysis :)