Click here to Skip to main content
Click here to Skip to main content

Sticky Windows - How to make your (top-level) forms to stick one to the other or to the screen

By , 8 Feb 2004
 

Sample Image - StickyWindows.jpg

Introduction

Delphi has a nice way of displaying its forms: all forms are (by default) top-level forms. This makes it easy to develop applications that are not restricted to the "MainFrame" client area but to the all screen, without having to have your application maximized. However, visually organizing such windows is sometimes hard for the end-user if he wants to maximize the visible area and minimize the window overlaps.

The class presented here tries to overcome this "arrangement" issue helping the end-user better organize their forms by sticking them one to the other and/or to the screen when moved or resized. (Code also takes care of correct sticking in multi screen environments but I did not manage to test it.)

Using the Code

The class inherits from System.Windows.Forms.NativeWindow, thus no inheritance is required in order to make your class Stick able.

In order to make your top-windows stick-able, all you have to do is declare a member variable of type StickyWindow and initialize it in your form:

private Blue.Windows.StickyWindow stickyWindow;
[...]
public 
Form2() // your constructor
{
stickyWindow = new 
Blue.Windows.StickyWindow ( this );
}

Now you have a form that will automatically stick on resize or move to all other forms that use the StickyWindow class and to the screen margins;

Customizations

There are few options you can customize about a Sticky Window:

  1. public bool StickOnMove

    Allows the form to try to stick when the form is moved.

  2. public bool StickOnResize

    Allows the form to try to stick when the form is resized.

  3. public bool StickToOther

    Allows the form to try to stick to other stick-able forms.

  4. public bool StickToScreen

    Allows the form to try to stick to the screen margins.

  5. public int StickGap

    Distance in pixels between two forms or a form and the screen where the sticking should start.

  6. public static void RegisterExternalReferenceForm( Form externalForm )

    Registers an external form (not StickyWindow form) in the list of forms that StickyWindows can stick to.

    E.g.: If you don't want your MainFrame to be stick-able but you want child forms to try to stick to it, than you will register your MainFrame with RegisterExternalReferenceForm so that other forms will try to stick to it.

  7. public static void UnregisterExternalReferenceForm ( Form externalForm )

    Same as RegisterExternalReferenceForm but it un-registers the form.

These are all the defined possible customizations of the StickyWindow.

Implementation Details

The idea behind the implementation is to filter the NC (NonClient) messages from the Form's message queue and do the own Moving/Resizing of the form by overriding the WndProc of the NativeWindow.

When a WM_NCLBUTTONDOWN is received for the Form, the StickyWindow checks the required operation (Move/Resize) and starts the algorithm for the requested operation.

While mouse is moved, the algorithm computes the new Form's position/size and then tries to compute the distance to the closest Form or screen border. If the shortest distance is smaller than the StickGap, the form will be moved/resized to touch the margins of the form/screen, thus sticking taking place.

While resize takes place, the form will take care not to shrink below Form.MinimumSize or SystemInformation.MinWindowTrackSize or to grow above Form.MaximumSize or SystemInformation.MaxWindowTrackSize.

Credits

  • The main credits go to WinAmp's team who made the idea of sticking windows popular.
  • The second credits go to Infopulse, the place where I've developed the first StickyWindows implementation in C++.

History

  • 09.Feb.2004: version 1.0

    First released version.

Copyright

You can use these sources for absolutely free.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Corneliu Tusnea
Web Developer
Australia Australia
Member
8 years commercial experience out of which 7 years developing financial applications for different stock exchanges.
5 years VC++ and about 2.5 years C# experience and a bit of Java.
 
Now working with the fantastic guys from Readify, a group of elite consultants specialising in technical readiness.
 
Keeping a blog at:
www.acorns.com.au
 
Developing:
Hawkeye - The .Net Runtime Object Editor - A developer's best tool.
 
Keeping myself busy with my site:
www.bestgames.com.au website.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberibyk302 May '13 - 11:31 
GeneralMy vote of 5membermanoj kumar choubey28 Nov '12 - 19:13 
SuggestionEasy ImplementationmemberAlexKven31 Aug '12 - 6:05 
For all you users of this amazing code, here's a way to easily implement in all of your windows in an inherited manner:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Blue.Windows;
namespace Metropolis_Tycoon
{
    public class StickyForm : Form
    {
        protected StickyWindow StickyWindowInstance;
        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            StickyWindowInstance = new StickyWindow(this) { StickGap = 15 };
        }
    }
}
Simply copy this code, and derive all your windows from it. It even works if you change handle modifying properties like ShownInTaskbar!
GeneralMy vote of 5memberAlexKven31 Aug '12 - 6:02 
GeneralWinamp-like main window behaviormemberPHANT0Mas25 Oct '10 - 2:51 
GeneralIssues with FormBorderStylememberPadgett777 Mar '10 - 19:53 
GeneralVB .Net Versionmembervaduganathan23 Nov '09 - 23:58 
GeneralRe: VB .Net VersionmemberMr.PoorEnglish15 Feb '10 - 4:11 
GeneralWPF Adapted Project Downloadmemberricibald18 Oct '09 - 21:55 
GeneralThanks!memberbiocomp6 Mar '09 - 2:39 
Questionhow to make MDI childs to be sticky?memberMember 417923025 Feb '09 - 22:42 
Generalvery nice !memberJ1mp4n5312 Nov '08 - 23:37 
GeneralSticking doesn't work for Forms that are not shown in the Taskbarmembertexor12 Nov '08 - 8:31 
AnswerRe: Sticking doesn't work for Forms that are not shown in the Taskbarmembertexor13 Nov '08 - 19:25 
GeneralCustom Titelbar FormBorderStylememberBabybaer21 Oct '08 - 3:01 
GeneralRe: Custom Titelbar FormBorderStylememberBabybaer22 Oct '08 - 0:25 
GeneralDo i needmemberC# Beginner Nick30 Oct '07 - 10:55 
GeneralKeep Children Inside Parentmemberclintonpatrick18 Nov '06 - 12:12 
QuestionOnHandleChange()memberIanWorthington10 Jan '06 - 16:42 
GeneralUsing Sticky Windows for borderless formsmembernagarsoft7 May '05 - 23:37 
AnswerRe: Using Sticky Windows for borderless formsmemberandrei_t32 Dec '08 - 2:43 
QuestionStickyWindow Implementation without Windows Messages?membermalludoubleoseven25 Feb '05 - 5:11 
AnswerRe: StickyWindow Implementation without Windows Messages?memberTutu25 Feb '05 - 10:57 
GeneralRe: StickyWindow Implementation without Windows Messages?membercuriousharry28 Sep '05 - 6:42 
GeneralForm flashing when resizedmembernagarsoft12 Jul '04 - 9:38 
GeneralRe: Form flashing when resizedmemberKristoffer F6 Apr '05 - 23:50 
GeneralSticky Windows for MDImemberghentsch13 Feb '04 - 2:37 
GeneralRe: Sticky Windows for MDImemberTutu14 Feb '04 - 14:04 
GeneralRe: Sticky Windows for MDImemberghentsch18 Feb '04 - 2:44 
GeneralRe: Sticky Windows for MDImemberTutu7 Mar '04 - 11:20 
GeneralRe: Sticky Windows for MDImembern_dru9 Oct '07 - 23:12 
QuestionHave you considered writing a component that implements IExtenderProvider?memberdrewnoakes11 Feb '04 - 11:53 
AnswerRe: Have you considered writing a component that implements IExtenderProvider?memberTutu14 Feb '04 - 14:05 
QuestionRe: Have you considered writing a component that implements IExtenderProvider?memberBenjamin Liedblad5 Sep '05 - 20:01 
GeneralForm Dragging Capabilitymemberjaxterama11 Feb '04 - 9:05 
GeneralRe: Form Dragging CapabilitymemberTutu14 Feb '04 - 14:11 
GeneralRe: Form Dragging CapabilitymemberSpaceNuts16 Jun '04 - 10:44 
GeneralRe: Form Dragging CapabilitymemberJedon10 Mar '05 - 6:41 
GeneralRe: Form Dragging Capabilitymemberzythum18 Mar '05 - 6:46 
GeneralRe: Form Dragging Capabilitymembermickeymicks8 Sep '06 - 3:22 
GeneralRe: Form Dragging Capabilitymemberchr.dev26 Nov '07 - 4:34 
GeneralRe: Form Dragging CapabilitymemberLuka9 Sep '08 - 3:05 
QuestionAttribute form?memberKeith Farmer9 Feb '04 - 15:13 
AnswerRe: Attribute form?memberTutu9 Feb '04 - 19:14 
GeneralRe: Attribute form?memberKeith Farmer10 Feb '04 - 8:26 
QuestionAdd band object capability?memberKeith Farmer9 Feb '04 - 14:22 
AnswerRe: Add band object capability?memberTutu9 Feb '04 - 19:18 
GeneralRe: Add band object capability?memberKeith Farmer10 Feb '04 - 8:30 

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 9 Feb 2004
Article Copyright 2004 by Corneliu Tusnea
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid