Help for Tune Smithy Koch snowflake icon.gif

How to let user click and drag anywhere on window or dialog to move it

From Tune Smithy

(Difference between revisions)
Jump to: navigation, search
WikiSysop (Talk | contribs)
(New page: This is dead simple when you know how, though you can struggle for ages if you don't know the trick. Windows sends your window or dialog a WM_NCHITTEST to detect the various parts of the ...)
Newer edit →

Revision as of 09:31, 23 February 2010

This is dead simple when you know how, though you can struggle for ages if you don't know the trick.

Windows sends your window or dialog a WM_NCHITTEST to detect the various parts of the window such as the resizing borders, or title bar etc. To let the user move the window with click and drag, just tell Windows that everything is the title bar.

For a normal window made using e.g. CreateWindow with a DefWindowProc(..) you do it like this:

<sourcelang="c">

switch (message)
{
case WM_NCHITTEST:
 {
   POINT pt;
   RECT rcClient;
   GetCursorPos(&pt);
   GetClientRect(hDlg,&rcClient);
   ClientToScreenRect(hDlg,&rcClient);
   if(PtInRect(&rcClient,pt))
    return HTCAPTION;
 }
 break;
}

</source> Or alternatively call DefWindowProc for the message, and check to see if its return value is HTCLIENT and if so return HTCAPTION.

You might think you could just return HTCAPTION whatever happens - but there are many other possible return values to show e.g. that the mouse is in the Close button, or over one of the resizing borders of the dialog etc.

If it is a dialog you need to do it like this:

switch(message)
 {
 case WM_NCHITTEST:
  {
   POINT pt;
   RECT rcClient;
   GetCursorPos(&pt);
   GetClientRect(hDlg,&rcClient);
   ClientToScreenRect(hDlg,&rcClient);
   if(PtInRect(&rcClient,pt))
   {
    //Because it is a dialog need to do it this way and return 1
    SetWindowLong(hDlg,DWL_MSGRESULT,HTCAPTION);
    return 1;
    // For a normal window would use:
    // return HTCAPTION;
   }
  }
  break;
 }

That's because you just return 1 to show that the message is processed, and with no DefWindowProc you need to use SetWindowLong with DWL_MSGRESULT to supply Windows with the return value.

Personal tools
Namespaces
Variants
Actions
Navigation
How to use the wiki
More
Toolbox