Snapping Windows

Environment: VC6 SP4, W2K SP2

In the process of creating my own shell for Windows I found that having all of the individual elements snap to the edge of the screen very useful. To make this process much easier I put together a small class that provides drop in window snapping. It uses a MFC like class so modifying it to use MFC should be easy. NOTE: For dialog windows use the CSnapDlg instead.

The Features

  • Snaps to the edge of the desktop
  • Adjusts to screen resolution changes

How it Works

When the mouse is pressed in the non-client area of the window, the position is saved as an offset from the top left corner of the window. Then when the WM_MOVING message is sent it modifies the windows position based on the precalculated offset.

It is quite simple to use. Here is how to use it.

// register class
CTestWnd twWnd;
twWnd.RegisterClass("CSNAPWNDTEST",IDI_CSNAPWNDTEST,IDC_CSNAPWNDTEST);

// Perform application initialization:
twWnd.Init(NULL,
           "CSnapWnd Test",
           NULL,
           WS_OVERLAPPEDWINDOW,
           CW_USEDEFAULT,
           0,
           CW_USEDEFAULT,
           0,
           NULL,
           nCmdShow);

Downloads

Download demo project and source - 30.6 KB


Comments

  • all those guys argueing ...

    Posted by Legacy on 09/25/2002 12:00am

    Originally posted by: markus

    why do you all cry: it doesn't work, it doesn't work! it works, change those (really) small 5 pixels to 20 and see!
    this sample works on all windows platforms, there isn't any win2k-specific code in it. you can even do this with visual basic (which is almost always compatible to win3.1!).
    so be quiet and blame yourself, or try to get it working!
    ps: go to aac.net.tf for the best audio grabber, written in vb!

    Reply
  • What about snapping ALL APPLICATIONS ?

    Posted by Legacy on 02/26/2002 12:00am

    Originally posted by: Guillaume APOSTOLY

    I'm looking for a long time for a tool that will allow all application of windows to snap on the edges and together.
    This could be achieved by tracking the windows resizing and moving at the mouse level.
    When you're resizing a window, by example, your "customised mouse driver" must then see that you're reaching the edge of another application (or the border of the screen) and speed up your mouse to make it snap.
    It must'nt be hard to do but I haven't got time to do MFC programming now ...
    If you make it, tell me about it !!! :o)

    Reply
  • Is there any ways to prevent global docking?

    Posted by Legacy on 01/04/2002 12:00am

    Originally posted by: LastCall_

    Hi,
    I was looking on the web a tricks to "undock" windows in Windows 2000... Is there any way I can do that? (registry setting, etc.) Or I have to change the code of the application in cause?

    Reply
  • It DOES work

    Posted by Legacy on 12/27/2001 12:00am

    Originally posted by: Alec

    Come on people. It does work, it's just that it has a very low threshold. Some of you don't even know what it's SUPPOSED to do. What it does is to SNAP the window to the edge of the screen when you move it close enough. I'm sure you've seen this enough times in other places...

    Try running the program. Then shrink the window somewhat, it makes it easier to see. Then move the window near to the edge of the screen. Now SLOWLY move it closer and closer to the edge of the screen. When you get close enough, the window will jump to align itself with the edge. Move the window off screen and move it's edge back close to the screen-edge and it does the same.

    If you still don't see it, open the workspace, and change the line in SnapWnd.cpp from

    m_nSnapPixels = 5;
    to
    m_nSnapPixels = 50;

    rebuild and run it. You CAN'T miss it now.


    To Anish, good job. It works properly and it even works when you resize the window even when it's attached. I made a similar thing last year with the help of Christian Weiske <cweiske@cweiske.de>. We eventually got it working and I couldn't have been happier. Good work.

    Reply
  • Not Work

    Posted by Legacy on 12/23/2001 12:00am

    Originally posted by: wujp

    Not Work in NT4

    Reply
  • it is the about dialog that snaps the the sdi!!!!!

    Posted by Legacy on 12/20/2001 12:00am

    Originally posted by: mike hogan

    see title

    Reply
  • Does nothing, what's this thing do ?

    Posted by Legacy on 12/07/2001 12:00am

    Originally posted by: Hans Wedemeyer

    Does not work, at least I don't see anything expect a frame window...

    Reply
  • Excellent!

    Posted by Legacy on 12/02/2001 12:00am

    Originally posted by: Tom Malik

    Congratulations on a job extremely well done. This class works very well (awesome for MDI's). I have tested it and it works seamlessly. Hats off to you.. and thank you!

    Reply
  • Why don't you post a screen shot, which many people find helps?

    Posted by Legacy on 11/13/2001 12:00am

    Originally posted by: Jason

    Why don't you post a screen shot, which many people find helps?

    Reply
  • Works good for me - here's a refinement

    Posted by Legacy on 11/01/2001 12:00am

    Originally posted by: Chris

    Don't know what everyone's moaning about.  Seems to work ok on the platforms I've used it on.
    
    

    However - I would add these refinements...

    1)

    instead of

    GetWindowRect(GetDesktopWindow(),&m_rDesktopRect);

    to get the desktop rect use

    SystemParametersInfo(SPI_GETWORKAREA, NULL, &m_rDesktopRect, 0);

    and when snapped you can resize the desktop using

    SystemParametersInfo(SPI_SETWORKAREA, NULL, &m_rDesktopRect, 0);

    so that other applications are restricted to the available area

    2)

    When snapping use

    m_rDesktopRect.left instead of 0
    and
    m_rDesktopRect.top instead of 0

    Now the window will always snap to the edge of the client area no matter where the taskbar is placed.

    3)

    Handle WM_SETTINGCHANGE as well as WM_DISPLAYCHANGE to update the desktop when the client area is changed.

    4)

    Use ::EnumWindows to go through open windows and resize them. I did this to allow the docking app to remain always on top and not obscure the caption bars of any other apps. Something like this:

    BOOL CALLBACK CTickerDlg::EnumWindowsProc(HWND hwnd, LPARAM lParam)
    {
    long lStyle;
    HWND hTray = NULL;
    RECT workRect, windowRect;

    try
    {
    hTray = ::FindWindow("Shell_TrayWnd", "");
    lStyle = ::GetWindowLong(hwnd, GWL_STYLE);
    workRect = *(RECT*)lParam;

    if((::IsWindowVisible(hwnd)) && (!::IsIconic(hwnd)) && (lStyle&WS_VISIBLE) && (hwnd != hTray) && hwnd != g_hTicker)
    {
    if(lStyle&WS_MAXIMIZE)
    {
    ::MoveWindow(hwnd, workRect.left, workRect.top, workRect.right-workRect.left, workRect.bottom-workRect.top, true);
    }
    else
    {
    ::GetWindowRect(hwnd, &windowRect);
    if(windowRect.top < workRect.top)
    {
    windowRect.top=workRect.top;
    }
    if(windowRect.bottom-windowRect.top > workRect.bottom-workRect.top)
    {
    windowRect.bottom=windowRect.top + (workRect.bottom-workRect.top);
    }
    ::MoveWindow(hwnd, windowRect.left, windowRect.top, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, true);
    }
    }
    return true;
    }
    catch(...)
    {
    TRACE("ERROR: exception thrown in CTickerDlg::EnumWindowsProc()");
    return false;
    }
    }


    I have refined the code to create a docking HTML ticker application which docks to the top or bottom of the client area. If anyone would like the code then let me know.

    I found the original class a great help. Hope someone finds this helpful.

    Cheers

    Chris

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: November 20, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Are you wanting to target two or more platforms such as iOS, Android, and/or Windows? You are not alone. 90% of enterprises today are targeting two or more platforms. Attend this eSeminar to discover how mobile app developers can rely on one IDE to create applications across platforms and approaches (web, native, and/or hybrid), saving time, money, and effort and introducing apps to market faster. You'll learn the trade-offs for gaining long …

  • IBM Worklight is a mobile application development platform that lets you extend your business to mobile devices. It is designed to provide an open, comprehensive platform to build, run and manage HTML5, hybrid and native mobile apps.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds