Click here to Skip to main content
Click here to Skip to main content
Go to top

Corner Bowl Popup Help Control

, 16 Nov 2010
Rate this:
Please Sign up or sign in to vote.
Provides a simple icon users can easily identify as a help provider. Once a user moves their mouse over the icon, a visually pleasing popup window displays context sensitive help that remains visible until they choose to close the view.

sample.jpg

Introduction

The other day, I received an email response to a sales follow up I'd sent to a potential customer which stated he was not going to buy my software, Corner Bowl Log Manager, because he was unable to get it to work. I gathered my thoughts, then called him up because surely if he couldn't get the software to work, others were in the same predicament. In summary, the user interface was not intuitive. To make matters worse, he did not know he could simply press F1 to access the associated help. This was unexpected. As I recall, the F1 help command was introduced by Microsoft as a usability standard back when Windows 95 was released, which all Windows developers should now religiously implement. Well, maybe, we all do, but even some IT professionals, such as those that use my software, do not know about the power of the F1 key. As I search for words to write this article, I even see Help printed on the F1 key. So what to do? Simple, add a question mark icon next to the controls of confusion, and popup a multi-line tooltip that explains in detail how to use the dialog to configure the software. This article offers a C# alternative to the built-in tooltip control, which is both visually pleasing and highly customizable.

Requirements

Provide a simple icon users can easily identify as a help provider. Once a user moves their mouse over the icon, a visually pleasing popup window must display context sensitive help that remains visible until they choose to close the view.

Design

This control consists of a fixed size UserControl that handles MouseOver events. When you move the mouse over the control, a popup window is displayed. This popup window uses properties contained within the UserControl to determine the size, content, and UI styles to apply. Knowing that the built-in tooltips were dated, I searched for a UI solution. I found the toolbar tooltips in Microsoft Office Word 2007 offered a good solution that would fulfill my requirements. The Word tooltips popup a window which has round corners, a border, a gradient background, a title, a message, a horizontal line, an F1 information message, and portrays a transparent based shadow (see Figure 1).

Figure 1 (Microsoft Word 2007 Tooltip)

Word_Tooltip_Sample.jpg

Since I had never created a window with transparent attributes, I searched this site to find a transparent window sample. red_moon's A ToolTip with Title, Multiline Contents, and Image provided a sample which taught me the necessary steps to implement transparency. In summary, to display round corners or a transparent shadow, the WS_EX_LAYERED style must be applied to the window. This is accomplished by overriding the CreateParams property. Once overridden, paint messages are no longer fired. Instead, within the constructor, the code must draw to a memory mapped bitmap which is selected into a memory device context for drawing via the UpdateLayeredWindows user32 API. Lastly, the window is displayed by calling the ShowWindow user32 API. For more information, see Layer Windows on MSDN.

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= WS_EX_LAYERED;
        return cp;
    }
}

private void SelectBitmap(Bitmap bmp)
{
    IntPtr hDC = GetDC(IntPtr.Zero);
    try
    {
        IntPtr hMemDC = CreateCompatibleDC(hDC);
        try
        {
            IntPtr hBmp = bmp.GetHbitmap(Color.FromArgb(0));
            try
            {
                IntPtr previousBmp = SelectObject(hMemDC, hBmp);
                try
                {
                    Point ptDst = new Point(Left, Top);
                    Size size = new Size(bmp.Width, bmp.Height);
                    Point ptSrc = new Point(0, 0);

                    BLENDFUNCTION blend = new BLENDFUNCTION();
                    blend.BlendOp = AC_SRC_OVER;
                    blend.BlendFlags = 0;
                    blend.SourceConstantAlpha = 255;
                    blend.AlphaFormat = AC_SRC_ALPHA;

                    UpdateLayeredWindow(
                        Handle,
                        hDC,
                        ref ptDst,
                        ref size,
                        hMemDC,
                        ref ptSrc,
                        0,
                        ref blend,
                        ULW_ALPHA);
                }
                finally
                {
                    SelectObject(hDC, previousBmp);
                }
            }
            finally
            {
                DeleteObject(hBmp);
            }
        }
        finally
        {
            DeleteDC(hMemDC);
        }
    }
    finally
    {
        ReleaseDC(IntPtr.Zero, hDC);
    }
}

Implementation

I created a new control, assigned a background image, and set the minimum and maximum size to 16x16. I added Title and Message properties which provide a means to assign the necessary help information at either design time or runtime. To prevent the control from receiving focus, I overrode the TabStop property and set the value to false. I also added properties for all UI aspects of the control, enabling the look to be quickly customized.

To get all fonts and colors used by Word, I took a screenshot of the Word tooltip and pasted it into Paint. Using the color picker tool, I figured out which colors they used. Finally, I took screenshots of each potentially matching font and pasted the bitmap into Paint, comparing widths, heights, and styles until I found what I think is the correct font.

Next, I added MouseEnter and MouseLeave event handlers which show and hide the popup window accordingly. Please note, I did not include a timer that automatically closes the popup window. Instead, to dismiss the popup window, the user simply moves their mouse off the control. This format provides everyone with as much time as necessary to read and understand the help without having to worry the tooltip is going to disappear on them.

Aside from the few nuances described earlier, the Form code is fairly simple. Once the bitmap is created, it's simple bit math to get the correct positions and sizes of the internal drawing components. The exception to this is the shadow code. I looked at many different solutions, but ultimately went with red_moon's concept.

Testing

Once the control was complete, I created a test application which used a timer to show and hide the popup window infinitely while I watched the memory in Task Manager. I used a large message that would display a huge bitmap so I was able to more quickly identify any issues.

Sample Application

Once I was satisfied the code was not leaking, I created a sample application for this article (Figure 2). I added a properties grid which quickly surfaced many properties I needed to hide. I overrode those properties, and set the Browsable attribute to false, which has the effect of hiding each tagged property within Visual Studio's design mode.

Figure 2 (Sample Application)

Sample_Application.jpg

What's Missing

Many of the tooltip controls that are available offer a fading option; however, Corner Bowl Log Manager is targeted at Windows Server and is typically used through Remote Desktop. For those of you with experience managing servers through Remote Desktop, you already know that although fading looks great on your desktop, it performs very poorly over a network link. This control does not include a fading option although it would be very easy for you to add.

Source Control

The source code contained within this article has been posted to CodePlex and therefore contains source control information. Although this article contains a working version of this control, the source code tip must be downloaded from CodePlex at: http://cbpopuphelpcontrol.codeplex.com.

Conclusion

The code contained within this article is quite simple, and I hope self-explanatory. Hopefully my work here will be appreciated by other C# developers that need simple inline context-sensitive help without the requirement of loading a .CHM or other help files.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

Michael Janulaitis
President Corner Bowl Software
United States United States
I am a self taught developer that has been developing both backend and frontend Windows applications since the early 1990s. I started out working for Intel as a C/C++ developer in their network management software division located here in Utah. After 3 years I left the large corporate environment to work with a startup company called emWare which developed device management software. While at emWare I worked on low level multi-threaded network server code written in C/C++ and Java as well as many frontend MFC and later C# applications. I eventually started my own software company in 2006 called Corner Bowl Software which provides enterprise class systems management software.

Comments and Discussions

 
GeneralMy vote of 5 PinmemberScruffyDuck27-Mar-13 1:50 
GeneralMy vote of 5 Pinmemberjiekey peng14-Nov-11 17:03 
GeneralI like the design but in all fairness... Pinmemberafinnell21-Dec-10 8:28 
Generalnice one PinmemberPranay Rana18-Dec-10 9:57 
GeneralMy vote of 5 PinmemberScruffyDuck17-Dec-10 20:16 
GeneralRe: My vote of 5 PinmemberMichael Janulaitis22-Dec-10 3:50 
GeneralMy vote of 5 Pinmemberv# guy16-Dec-10 23:58 
GeneralRe: My vote of 5 PinmemberMichael Janulaitis22-Dec-10 3:49 
GeneralMy vote of 5 PinmemberRaviRanjankr16-Dec-10 2:59 
GeneralRe: My vote of 5 PinmemberMichael Janulaitis16-Dec-10 5:39 
GeneralExcellent app! 5 PinmemberDrABELL15-Dec-10 18:29 
GeneralMy vote of 5 PinmemberMember 68182722-Nov-10 14:13 
GeneralRe: My vote of 5 PinmemberMichael Janulaitis1-Dec-10 6:16 
GeneralThanx PinmemberPoul_L18-Nov-10 3:43 
GeneralRe: Thanx PinmemberMichael Janulaitis18-Nov-10 5:04 
GeneralRe: Thanx PinmemberPoul_L18-Nov-10 5:58 
GeneralRe: Thanx PinmemberMichael Janulaitis19-Nov-10 1:22 
GeneralRe: Thanx PinmemberPoul_L21-Nov-10 1:56 
GeneralVery Nice PinmemberDoncp18-Nov-10 1:34 
GeneralRe: Very Nice PinmemberMichael Janulaitis18-Nov-10 5:00 
Generalthanx for the update but [modified] PinmemberPoul_L17-Nov-10 3:36 
GeneralRe: thanx for the update but PinmemberMichael Janulaitis17-Nov-10 10:03 
GeneralRe: thanx for the update but PinmemberMichael Janulaitis17-Nov-10 10:13 
GeneralRe: thanx for the update but PinmemberPoul_L17-Nov-10 10:39 
GeneralVote 5 PinmemberIgor Kushnarev17-Nov-10 2:24 
GeneralRe: Vote 5 PinmemberMichael Janulaitis17-Nov-10 10:03 
GeneralMy vote of 5 PinmemberPogoboyKramer16-Nov-10 6:25 
GeneralRe: My vote of 5 PinmemberMichael Janulaitis16-Nov-10 7:09 
Generalnecely done PinmemberCIDev16-Nov-10 5:54 
GeneralRe: necely done PinmemberMichael Janulaitis16-Nov-10 7:07 
GeneralSo nice [modified] PinmemberPoul_L16-Nov-10 3:03 
GeneralRe: So nice PinmemberMichael Janulaitis16-Nov-10 3:20 
GeneralRe: So nice PinmemberPoul_L16-Nov-10 3:29 
GeneralRe: So nice PinmemberMichael Janulaitis16-Nov-10 7:06 
QuestionLocalizable? PinmemberPinx15-Nov-10 22:51 
AnswerRe: Localizable? PinmemberMichael Janulaitis15-Nov-10 23:38 
GeneralRe: Localizable? PinmemberPinx16-Nov-10 1:12 
GeneralRe: Localizable? PinmemberMichael Janulaitis16-Nov-10 1:35 
GeneralMy vote of 5 PinmemberNagy Vilmos15-Nov-10 21:40 
GeneralRe: My vote of 5 PinmemberMichael Janulaitis15-Nov-10 23:42 
GeneralGreat control, but two issues Pinmemberimgen14-Nov-10 5:53 
GeneralRe: Great control, but two issues Pinmember_mjanulaitis_14-Nov-10 7:34 
GeneralMy vote of 5 Pinmemberlinuxjr14-Nov-10 5:32 
GeneralRe: My vote of 5 PinmemberMichael Janulaitis15-Nov-10 15:14 
Generalnice job but........... PinmemberOmar Amin Ibrahim14-Nov-10 2:56 
GeneralRe: nice job but........... Pinmember_mjanulaitis_14-Nov-10 7:39 
GeneralMy vote of 5 Pinmemberburak29913-Nov-10 23:54 
GeneralRe: My vote of 5 PinmemberMichael Janulaitis15-Nov-10 15:13 
GeneralMy vote of 5 PinmemberErik Anderson13-Nov-10 19:58 
GeneralRe: My vote of 5 PinmemberMichael Janulaitis15-Nov-10 15:13 

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

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

| Advertise | Privacy | Mobile
Web01 | 2.8.140922.1 | Last Updated 16 Nov 2010
Article Copyright 2010 by Michael Janulaitis
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid