||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
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
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
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
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:
The text of the message
The colour of the background
The colour of the text
The font used to display the text
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
The class depends upon the windows definitions which were
ported over from WinUser.h. This listing contains those
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