The new vbAccelerator Site - more VB and .NET Code and Controls
Source Code
1 VB 5 Custom Controls &nbsp
&nbsp

vbAccelerator NeoCaption Component

Skin the entire non-client area (titlebar, border, menu, control box and buttons) of your VB project by adding this component to your project



NOTE: this code has been superceded by the version at the new site.




Black Metal Skin, about to change...

...to the Neo-Accelerator Skin


Download Code
VB5 code VB5 Component Binary (42kb) VB6 code VB6 Component Binary (42kb)
VB5 code VB5 Demonstration Project (61kb) VB6 code VB6 Demonstration Project (61kb)
VB5 code VB5 Full Source Code (134kb) VB6 code VB6 Full Source Code (134kb)
Required Files:
  • vbAccelerator SSubTmr.DLL for VB5
  • Required Files:
  • vbAccelerator SSubTmr6.DLL for VB6
  • Overview
    Unless you've been computing on another planet for the last year, you will probably have seen the rash of programs recently which implement a customised window appearance (notably WinAmp, NeoPlanet and StarDock's Object Desktop and WindowBlinds). In case you haven't been watching, check these out right now and have some fun:

    This code sample provides a DLL you can use right away to radically modify the non-client area of a form, similar to the sort of customisation provided by NeoPlanet and WindowBlinds. And, since the full source code is available, you get the chance to build your customised client area derivatives. Sounds like fun? It is!

    A Little History
    The first program out there I remember which offered any sort of customisation of the non-client area was Office 95, with those gradient caption bars. Although gradient captions aren't so much of interest now MS have rolled support into Win98/2000, they certainly were when Office 95 was launched. Suddenly everyone wanted a go at doing their own captions. How did you do it? And how come you could detach the menu bar in Office 95 - surely you could do this in your own app? After all, how hard could it be?

    Well, it turns out that drawing customised menu captions isn't easy at all. Windows just does not play fair - it continually redraws parts of the non-client area such as the Min/Max/Close buttons when you least expect it. Trying to reimplement a menu as a tear-off window whilst still allowing your app respond to Alt-Tab accelerator and the clicks in the Taskbar correctly is even more difficult.

    MS weren't very forthcoming on the subject of the Office 95 titlebar. The only Knowledge Base article (Q99046) on the subject coyly skirts around the topic, saying that whilst you could subclass WM_NCPAINT and WM_NCACTIVATE messages and then draw your own caption, it really isn't recommended; the whole idea of modifying the caption bar is foolish and outside the bounds of decent human behaviour (something even this author could agree with during the rash of windows which appeared at the time with primary red to neon blue gradients - very bad when encountered during a hangover).

    More interestingly, the Knowledge Base article somehow managed to totally avoid mentioning the fact that the Office implementation only worked at all because it was jam-packed with hacks. So we subclass two messages and do a little additional work afterwards? Yeah, right. Turns out you need to do all sorts of other somewhat abnormal things, such as removing the window style bit WS_VISIBLE during WM_SETCURSOR message processing and then putting it back again straight away afterwards. Anyway, luckily the nice people at Microsoft Systems Journal (MSJ) and Spy++ help you to understand what you really need to do.

    This sample brings together pieces of code from all sources, plus it adds some additional, VB specific workarounds to provide a full method for changing the size of the non-client area, plus drawing whatever you like into that region and providing an override to draw menus in a new style as well (this code is the basis for the vbAccelerator PopMenu2 object).

    Note: in the current version, this component does not work properly with MDI forms. When you maximise an MDI child, the system attempts to add new items to the menu for the control box and min/max/close buttons - which is not handled in the current code and causes a crash. A fix for this problem is under investigation.

    The vbAccelerator NeoCaption Component
    The DLL supplied with the download exposes two classes for public use:
    • cNeoCaption
    • cNCCalcSize
    cNeoCaption is a reference implementation of the Non-Client area modifier, including the drawing code and menuing. It implements the INCAreaModifier interface which must be supported in order to take advantage of the cNCCalcSize class - which is the basic framework for building radically customised non-client areas.

    Using the cNeoCaption Interface
    This should prove to be quite simple to use. There is one property to initialise the custom caption drawing and a number of others to control colours and fonts:
    • ActiveCaptionColor
      Sets the foreground colour of the caption to use when the form is active.
    • InActiveCaptionColor
      Sets the foreground colour of the caption to use when the form is inactive.
    • ActiveMenuColor
      Sets the foreground colour of the menu for menu items in the active window
    • ActiveMenuColorOver
      Sets the foreground colour of the menu when the window is active and the mouse is over the menu item
    • InActiveMenuColor
      Sets the foreground colour of the menu when the window is inactive.
    • MenuBackgroundColor
      Sets the background colour for the menu.
    • CaptionFont
      Sets the font to draw the form's caption. When the form is inactive, the Bold flag is removed. If the bold flag is not set, there is no change in the font between active and inactive states.
    • MenuFont
      Sets the font to draw the menu in.
    • Attach
      Starts the NeoCaption processing, sets which picture resources to use and supplies information about how the components of the non-client area should be drawn based on the picture resources.

      For example,

    Attach Me, picResource(2).Picture, picResource(3).Picture, 13, 14, 90, 142, 240, 372

    This starts processing with picResource(2) containing the titlebar and button graphics and picResource(3) containing the border graphics. The titlebar graphic is interpreted as having three sections: the active titlebar, the buttons and then the inactive titlebar. The numbers specify the coordinates and sizes of various components within the graphic. This picture demonstrates how these values are derived:

    NeoCaption TitleBar Graphic Organisation

    The border picture consists of seven square images in-line which represent 2 x left hand border, bottom-left corner, bottom border, 2 x right hand border and finally the bottom-right corner.
  • Detach
    Stops the NeoCaption processing. Called automatically when the form unloads. The sample provided in the demonstration download show how to use the NeoCaption component to swap different skins at runtime and even how to remove a skin from a form. You could improve on these samples by putting the caption information into an XML file using the XML Property Bag component and loading it from there!

    Using the cNCCalcSize Object
    To gain lower level control over non-client area processing, you can implement the INCAreaModifier interface and attach directly to the cNCCalcSize object. Implementing the INCAreaModifier interface involves doing the following:
    1. Returning Specific Values
      When the GetTopMarginHeight, GetLeftMarginWidth, GetRightMarginWidth and GetBottomMarginHeight methods are called, you get the opportunity to modify the border sizes and titlebar height to suit your own graphics. The hWnd property is queried when the cNCCalcSize object needs to know the handle of the window you want to modify the non-client area for.
    2. Performing NonClient Painting
      The NCPaint method is fired whenever you need to paint the Non-Client area. The method passes the size of the window and also a valid device context to paint into.
    3. Assigning Window Areas to their non-client function
      The HitTest method is called whenever Windows wants to know what function the area under the mouse should perform (e.g. is it the control menu, a border, titlebar, one of the min/max/close buttons etc). The caller assigns a default value for the function based on the x,y position but you can override this with the type of region you want.
    4. Non-Client MouseDown and MouseUp processing
      In customising the response to the HitTest method, you may also wish to customise how your application reacts to non-client mouse clicks. The NCMouseDown and NCMouseUp methods allow you to perform your own actions.
    5. Menu Processing
      The InitMenuPopup and AltKeyAccelerator methods enable your application to integrate customised menu painting into the non-client area (you would want to ignore these methods if menuing was being performed by a separate method, for example, using the vbAccelerator CoolMenu control).
    Implementing these functions from scratch is quite a lot of effort. If you want to do it, the best place to start is to examine how the cNeoCaption class works.



  • &nbsp
    &nbsp


    TopBack to top
    Source Code - What We're About!Back to ActiveX Control Source Code
    Source Code - What We're About!Back to Source Code

    &nbsp


    NOTE: this code has been superceded by the version at the new site.



    AboutContributeSend FeedbackPrivacy

    Copyright 2000, Steve McMahon ( steve@vbaccelerator.com). All Rights Reserved.
    Last updated: 21 March 2000