.
In Depth Banner
Skip Navigation Links

Select your preferred language

Using Native Windows in

Windows Forms Applications.

The classes and controls provided in Windows Forms are well suited to most applications.  There are however, a few situations when a non-standard window is required for which Windows Forms does not have an answer.  For example, a custom made tool-tip window is very difficult to create using the standard Windows Forms repertoire. 

Windows Forms does in fact provide an answer but it's one that's not often used and has received little attention from the mainstream Windows Forms evangelists.  Certainly, it's cool to build on top of classes that are just packed full of functionality but sometimes you just need to go back to basics. 

The NativeWindow class provides the basic functionality, is simple to use and enables you to do many of the things which the over complicated and overstuffed Windows Forms classes are too top-heavy for.  It's very simple in operation, having few members, and requires a bit of Win32 Interop to drive it.  The simplest configuration for NativeWindow is to create a simple class based upon it that delegates the window procedure to a more mundane Windows Forms class.  For example, a tool tip control must be based on the extender-provider model  which is a type of class normally derived from the Windows Forms component class.  The component however, has no window of its own and so, in order to display something on screen, requires the addition of some graphical element.  To do this, a NativeWindow can be encapsulated in the component that delegates all the windows messages received by the window back to the component that owns it.  Not all classes however,  have a WndProc.  Rather than create a different implementation for each and every class that needs a native window, it's better to create an interface that can be implemented by any class and which adds the requisite WndProc method.  

The code shown in listing 1 shows the interface and the ExtNativeWindow class 

The host class implements IWndProcProvider and at construction, instantiates an ExtNativeWindow class as shown in this listing.

When the window is created, you need to specify windows styles and classes. This can be accomplished using the NativeWindow base-class method CreateHandle. This method takes a CreateParams structure as a parameter and creates a window to the specifications provided. For the simple tool-tip window it's necessary to create a window that is a popup window, on top of all other windows and show it in a non-activated state so that the focus is not transferred to the tooltip window. This is accomplished as follows:

  • Override CreateParams to specify the window style and class. The class could be one created using RegisterClass via interop or a standard system-registered class such as Static or tooltips_class32 can be used.

  • When the window is shown, the ShowWindow method is used through interop and the SW_SHOWNOCACTIVATE constant is used to prevent focus being transferred to the tooltip window.

These techniques require the import of the ShowWindow API from User32.DLL and indeed, other useful methods can be imported, such as SendMessage or PostMessage that enable you to communicate with the native window at a low level.

To facilitate the use of the NativeWindow class, the code defines the window styles, show-constants and all the windows messages although the demonstration uses only WM_PAINT.

Painting is all done using GDI+ so no interop is required for the output of graphics. There is one requirement though, that when the paint message has been serviced, the tooltip window area is validated to prevent the WM_PAINT message being triggered constantly. For this, the ValidateRect method is imported and used to validate the whole window after painting.

Of course, any message can be serviced by the host class.  You only need to add a case for each of the messages.  The Message structure contains the windows parameters, that you must know how to use,  and the window handle.  

The NWTip class.

To demonstrate the use of the native window, the NWTip class, a simple extender provider, was created. Extender-providers use a trick of the design-time IDE to apparently add properties to objects they extend. In this case, the tooltips created can have a different colour and font for each control. The default is yellow and black using the menu font but you can adjust each parameter as you like.

The additional properties provided are:

TipText
The text of the message
TipColor
The colour of the background
TipTextColor
The colour of the text
TipFont
The font used to display the text
TipBorderColor
The colour of the line-border around the tooltip.

Data associated with each extended control is stored in a simple class that has properties for each of the properties in the above table. The extender provider uses a hashtable to store the data under the key derived from the reference to the control being extended.

Whenever a control is associated with some extended tooltip data, the MouseHover and MouseLeave events of the control are hooked to and serviced by the extender provider. This enables the code to detect when the cursor is hovering over the control, retrieve the associated data and create a tip-window to display near it.

When the cursor leaves the control, the tip window is destroyed after a short delay.

This listing shows the complete NWTip class.

The class depends upon the windows definitions which were ported over from WinUser.h. This listing contains those enumerations.

Summary.

The final product is a fusion of old and new technologies that adds a great feature to the toolbox. Figure 1 shows tooltips generated by the NWTip control. All controls have a different style and colour scheme.

Figure 1. Simple native windows as novel tooltips.

 

As usual the code is on the Code Page and you can use this control with the royalty free commercial license.

You can find the Source Code files here.

Return to the main index.

 

Copyright © Bob Powell 2000-.  All rights reserved.