13

Let's say I have a window and I want to save its position when the window closes and restore it when the window is opened again. The typical way to do this is to call GetWindowPlacement / SetWindowPlacement. This takes care of remember the position and the maximized / minimized state.

On Windows 7, you can dock a window to the side of the screen using the "Aero Snap" feature. My question is how do you save and restore windows that have been "Snapped" so that you can restore the "Snap" state. GetWindowPlacement / SetWindowPlacement does not solve this problem (to my knowledge) and I haven't seen any "Snap" API's in Windows 7.

There is a similar question on here How to detect window was resized by Windows7 but in this case it seems that the OP just wanted the restore position, not the "Snap" state.

Community
  • 1
  • 1
Maurice Flanagan
  • 5,179
  • 3
  • 30
  • 37
  • 1
    No, not exposed. Storing the working area size as well could be a workaround. Does anybody ever change the video resolution these days? – Hans Passant Dec 03 '11 at 16:46
  • 1
    I don't know a way of saving the snap state in a way that windows will restore the "normal" state when you drag away again. Note that snapped is NOT maximised. – Deanna Dec 05 '11 at 14:57
  • @Hans Passant, the problem with storing the working area size is that even then, I have no way of knowing that the window was snapped (I could infer it from the fact that rcNormal != windowPos) – Maurice Flanagan Dec 05 '11 at 21:43
  • @ Deanna, that's the conclusion I'm coming too as well, I don't see any way to get a window into the snapped state where it gets restored when you drag it off the edge, I'm surprised they didn't expose that, oh well! – Maurice Flanagan Dec 05 '11 at 21:44

2 Answers2

6

The workaround is to call GetWindowRect() to get the actual window coordinates and copy them over the bad coordinates in WINDOWPLACEMENT::rcNormalPosition.

ronalchn
  • 12,225
  • 10
  • 51
  • 61
  • One thing to add is that you should only write over WINDOWPLACEMENT::rcNormalPosition if showCmd is SW_NORMAL. For instance, if the window is maximized, you will not be able to easily restore your window to normal position if you have stored the maximized window size as the normal size. – Christian Cheney Oct 02 '12 at 19:03
  • 2
    `if(SW_NORMAL == wp.showCmd) GetWindowRect(&wp.rcNormalPosition);` – Christian Cheney Oct 02 '12 at 19:33
  • 3
    The problem is that `GetWindowRect` uses screen coords, but GetWindowPlacement uses work area coords. – David Heffernan Jun 27 '13 at 14:33
0

The way I solved it was to override CWinAppEx::SaveState, to update the WINDOWPLACEMENT before saving it:

BOOL MyApp:SaveState(LPCTSTR lpszSectionName, CFrameImpl *pFrameImpl)
{
  WINDOWPLACEMENT wp;
  wp.length = sizeof(WINDOWPLACEMENT);
  m_pMainWnd->GetWindowPlacement(&wp);
  if (wp.showCmd == SW_SHOWNORMAL)
  {
    m_pMainWnd->GetWindowRect(&wp.rcNormalPosition);
    m_pMainWnd->SetWindowPlacement(&wp);
  }

  return __super::SaveState(lpszSectionName, pFrameImpl);
}
A Lundgren
  • 23
  • 4