Link to home
Start Free TrialLog in
Avatar of NormB062799
NormB062799

asked on

How to prevent window moving

I want prevent the user from being able to move the main (and only) window of my application by grabbing the caption bar.  I can't figure out how to do this.

In the PreCreate method of the MainFrm
is set the CREATESTRUCT as follows:

      cs.style = WS_OVERLAPPED | WS_CAPTION | FWS_ADDTOTITLE| WS_SYSMENU | WS_MAXIMIZE;

In the InitiInstance of the application, I set:
 m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);

This creates the window that I want: a maximized window with a title and an X to close it, with no min or max box.  It also creates a system menu that I don't need but I found that if I remove that, the top right X to close the application disappears.  (I can live with the system menu).

Despite my SHOW_MAXIMIZED, the user can still grab the window by the caption bar and move it around.  I would like to prevent that from happening.  I also want to keep the window maximized and not allow a min or restore box.

Everything I've thought of doesn't work.  Any suggestions?
ASKER CERTIFIED SOLUTION
Avatar of Wyn
Wyn

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
Avatar of Wyn
Wyn

Handle the WM_WINDOWPOSCHANGING message and add the SWP_NOMOVE to the "flags" field:
((LPWINDOWPOS) lParam)->flag = ((LPWINDOWPOS) lParam)->flag|SWP_NOMOVE;

 
Avatar of NormB062799

ASKER

So why doesn't this work?

void CMainFrame::OnWindowsPosChanging(WINDOWPOS* lpwndpos)
{
      lpwndpos->flags = lpwndpos->flags | SWP_NOMOVE;
      CFrameWnd::OnWindowPosChanged(lpwndpos);
}
it's

OnWindowPosChanging,not OnWindowsPosChanging.

e.g:
void CMainFrame::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
lpwndpos->flags = lpwndpos->flags | SWP_NOMOVE;
CFrameWnd::OnWindowPosChanging(lpwndpos);
}

Sure it works.I have tested.

Free to ask if you have probs.

Work it out.

Regards
Wyn


I corrected my spelling error and had great hopes this would work.  Unfortunately not.  I can still grab the application window from the caption bar and move it all over the screen.  There must must something else I'm doing wrong.  I have this code in MainFrm.cpp.  Is that where it belongs?

As an alternative, I tried using WS_OVERLAPPEDWINDOW instead of WS_OVERLAPPED.  That seems to prevent the movement if I maximize the window.  However, it introduces a minimize and restore button that I don't want and can't seem to remove without creating further problems.

Learning this MFC is like trying to climb the North face of Mt Everest!
Okay,let me ask:
1:
have you declared the
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct)
in your mainframe .h
?
2:
have you added
ON_WM_WINDOWPOSCHANGING( )
in your mainframe .cpp message macro
?
3:
have you defined your function like this in mainframe.cpp:

void CMainFrame::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
lpwndpos->flags = lpwndpos->flags | SWP_NOMOVE;
CFrameWnd::OnWindowPosChanging(lpwndpos); }
?

If all you have properly done ,it should work ,check it carefully!!

>>There must something else I'm doing >>wrong

not likely,check above carefully.
btw,it's CFrameWnd::OnWindowPosChanging,not changed.I mention it 'cause i find your past code used the latter.


If still dont work.Mail your code and I correct it for you but I think if you follow above,it should work!!!

MFC? Yes ,I do think so but it's shortcut for efficiency without losing  control...
Best Regards
Wyn.
sorry,the first question is
declare this in mainframe.h
afx_msg void OnWindowPosChanging(WINDOWPOS* lpwndpos);

:-)
Finally!  I feel like a real dummy with this.  I had neglected #2, adding ON_WM_WINDOWPOSCHANGING( )
to the message macro.  Thanks for sticking with me on what should be a rather elementary problem for you.

Actually, the code as it exists caused another problem.  It seems to prevent the app window from positioning itself at 0,0 as it did before.  The app seems to start at any old place.  Of course, you can't just use SetWindowPos since it's intercepted by the new message handler.  I solved it by using a flag like this:


void CMainFrame::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
      if (!juststarted)
            lpwndpos->flags = lpwndpos->flags | SWP_NOMOVE;
      else
            juststarted = 0;
      CFrameWnd::OnWindowPosChanging(lpwndpos);
}

In OnCreate I set juststarted = 1 then immediately call SetWindowPos to set the window at the origin.  If there is a more elegant way, I'd appreciate hearing about it.