Link to home
Start Free TrialLog in
Avatar of AndreasF
AndreasF

asked on

Window moving

When you drag a window to the top of the desktop it jumps back to a position where a few pixels of the titlebar can be seen, so that the window cannot become lost. Now, I want to switch off this "feature".
Does anyone know how I can do this?
Avatar of AndreasF
AndreasF

ASKER

Edited text of question.
I would GUESS that this is being done in the WM_WINDOWPOSCHANGING message.  (This does other sorts of "validation" on the position.)   So I would try to handle this message in your window procedure (just igore the message, don't calll the default window procedure for it.)  and I think the behavior will go way.  

Let me know if you have any questions.
I'm kinda curious though, how are you draging the window so its caption could be positioned off the screen?  Since usually the mouse has to be on the caption to drag the window, part of the caption must always be visible on the screen (usually).
return HTCAPTION in OnHittest.
:-)
Okay, I just wanted to make sure we really understood each other.
Okay: I first commended out the call to CDialog::OnWindowPosChanging(...) so that the function did nothing but my app behaved like before.
Second I disabled this message in the PreTranslateMessage. Now - on the first move I tried on the window - the size of it changed to 0x0. So, what do I do wrong?
I didn't realize this was MFC.  Not my real area of expertise, but...

If you comment out OnWindowPosChanging, then it will be handled by the default window procedure, right?  That is what we don't want.  You want to handle OnWindowPosChanging, but your handling will be to ignore it.  i.e. I think you need a OnWindowPosChanging that does nothing.  right?

Note I may be wrong about this message too.  it is possible that the "adjustment" to the window position is made earlier.  You'll just have to try this and see and if it doesn't work, we'll have to work backwards.
If you want to remove a window from the screen, why don't you just hide it?
Tier:
I don't want to remove it.
I want to be able to drag this window as high as I want on the screen. Standard behaviour is that a window moves back - so that a small line of the title bar can be seen - if you drag it too high.
Hi;

A trick
<ALT>+<SPACE BAR> , <M> enable to move the windows independent of your original position.

T++, Radler.
I think you guys are missing the point.  Reread the question.

andreas, did you try handling OnWindowPosChanging() yet?
How about the WM_GETMINMAXINFO message?
He's not sizing the window, just moving it.
And he is using MFC which changes the equation a bit, since MFC tries to make things simple for you and does more default processing than DefWindowProc does under regular Win32
I think it is a default behavior of Windows, which can't be changed.
I'm sure it can be changed.  It is possible to move a window anywhere in the coordinate space, even off the visible part of the screen.  It is just that during the interactive (mouse) move process the OS is is puting restrictions on the window's final position.
>It is possible to move a window anywhere in the coordinate space, even off the visible part of the screen.

Yes, I agree.

>It is just that during the interactive (mouse) move process the OS is is puting restrictions on the window's final position.

That's what I meant. This behavior of the OS can't be changed.
Well, at the very least, you could impliment your own movement loop that tracked the movement and then set the window to the unadjusted postion in the end.  But I suspect it is not necessary to go to these lengths.  
But I think AndreasF wants to affect all the windows, not only his own windows.
No, I beleive this is for a window created by his program.  This is a window whose hittest alrways returns HTCAPTION so that the window can be moved by pressing the mouse on any part.  If it was a "regular" window, one that could be moved only using the caption, like you would find in another program, this would not be an issue because you can only move the window using the mouse on the caption, so the caption can't be moved off the screen.
In this case, try overriding OnWindowPosChanging or OnWindowPosChanged.
changing, changed is too late.
I have investigated all messages that come to the window from the point of releasing the left mousebutton after dragging the window.
Here is the summary:
WM_SYSCOMMAND  (SC_MOVE)
  .
  .
  .
  WM_LBUTTONUP
  WM_MOVING (left=-3;top=-52;right=378;bottom=184)
  WM_WINDOWPOSCHANGING(x=-3;y=-52;cx=381;cy=236;flags:SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER)
  WM_CAPTURECHANGED
  WM_WINDOWPOSCHANGING(x=-3;y=-18;cx=381;cy=202;flags:SWP_NOSIZE)
  .
  .(ncpaint, erasebkgnd,ctlcolordlg)
  .
  WM_WINDOWPOSCHANGED(x=-3;y=-18;cx=381;cy=236;flags:SWP_NOSIZE | SWP_NOZORDER | 0800)
    WM_MOVE
  WM_EXITSIZEMOVE

These results come from MS-Spy++
Perhaps this few lines help you.

By the way:
>It is possible to move a window anywhere in the coordinate space, even off the visible part of the screen.

It has to be possible. The Sonique MP3 player is the best example for what I want to have in my program. This player has a titlebar (I want to have it, too for some reasons) but it is clipped through SetWindowRgn.
You can download it from www.sonique.com
It's free.
Use a window without a capture and simulate the capture drawing. Anyway you don't use the capture for dragging.
Well, the caption shouldn't be seen anyway (as it is in sonique mp3 player).
But that's not my problem! The problem is the dragging (a window without a titlebar behaves like a window with a titlebar according to dragging, so your approach doesn't solve it).
AndreasE, take a look at what you found.

WM_WINDOWPOSCHANGING(x=-3;y=-52
WM_WINDOWPOSCHANGED(x=-3;y=-18

Y has changed!  It is less negative, forceing the window lower.  That looks to me like the default window procedure changed y when it handled the WM_WINDOWPOSCHANGING() message.  To prevent this, you need to prevent the default window procedure from processing the message.  (Which is exactly what I said from the start.)  Does that make sense?  What is you code for handling this message?
                   
nietod:
>Y has changed!
Yeah! That's what I wanted to show.
BUT: In Spy++ you see, when a Message is sent or posted and when a sent Message returns. The point is, that the first WM_WINDOWPOSCHANGING returns befor the second WM_WINDOWPOSCHANGING is sent. I wonder by what function it is sent (WM_SYSCOMMAND?).
Perhaps I have to implement my own movement loop as you suggested? But how?
Maybe, but that's a lot of work (not too bad, really but still more)  Before we go that route, how are you handling WM_WINDOWPOSCHANGING?  Post your code.
Well, I now switched to WIN32(left MFC behind).
Here is my WindowProc:

LRESULT __stdcall MyWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
      switch(Msg)
      {
            case WM_WINDOWPOSCHANGING:
                  return 0;
            break;
            case WM_NCHITTEST:
                  return HTCAPTION;
            break;
      }
      return DefWindowProc(hWnd, Msg, wParam, lParam);
}

That doesn't work...
Bummer.  

One "fix" would be to save the contents of the WINDOWPOS you get on the WM_WINDOWPOSCHANGING and then when you get the WM_WINDOWPOSCHANGED message look to see if the position differs from the WM_WINDOWPOSCHANGING's values.  If so, move the window to the propper location.  

This will work.  But its not great for two reasons, first you make see the window "flash" as it is moved to the "wrong" position and then to the "right" position.  That isn't a big problem, but it is anoying.  The other problem is where do you store the WINDOWPOS data?  You can't use a local because it must be stored between calls to your window procedure.  You could store it in a single global, but if you have more than 1 of these windows, there is the possibly that window possition messages become interleaved (I don't know if that is possible) in which case successive messages would destroy the data needed by earlier messages.)  Another posibility is to allocate the the data dynamically (uew new) and then store the pointer to the data in the window's extra data.  I think that is what I would do.  althoug to test this, I would just use a global variable to store it.

The other approach is to do the "dragging" yourself.  
Yes! It works in a slightly altered way (store in WM_MOVING and check in WM_EXITSIZEMOVE) but I noticed this flash and that's not nice. I know how to write the dragging on my own but I am very interrested in writing my own movement loop. Could you tell me how to do that?
Or is "do dragging yourself" == "write your own movement loop"?
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I will do that. Thanks for your help!