3

I have what should be an extremely simple goal yet it seems intractable. I have to get some precisely-sized screen pix for documentation so I thought it would make sense to add a control to size my app's window to the exact dimensions I want.

I'm working with VS2010.

Here's the relevant code from my wizard-generated dialog:

DlgSetWindowSize::DlgSetWindowSize(CWnd* pParent /*=NULL*/)
    : CDialogEx(DlgSetWindowSize::IDD, pParent)
{
    m_width = 0;
    m_height = 0;
    m_parent = pParent;
}

void DlgSetWindowSize::OnBnClickedOk()
{
    CDialogEx::OnOK();
    SetWindowPos(m_parent, 0, 0, m_width, m_height, SWP_NOMOVE|SWP_NOZORDER|SWP_NOOWNERZORDER);
}

and here is the call to it:

void CMyAppView::OnWindowSize()
{
    DlgSetWindowSize d(this);
    if (IDOK == d.DoModal())
    {
        Invalidate();
    }
}

SetWindowPos returns a nonzero value, which indicates success according to the documentation (click here). Of course when running the dialog, I enter the pixel values I want for width and height. The debugger verifies that the expected values are being passed to SetWindowPos, and also that SetWindowPos gives a nonzero return. The bit switches in the last parameter to SetWindowPos are set to ignore the position parameters and only express the size parameters in that call, so that the window should be sized as I want without changing position.

Everything appears to be in order, but the window size doesn't change. I have applied this logic to my app's document window, and when that didn't work, I also applied it to the application's MainFrame window. Zero action.

Am I missing something here, or is there some completely different approach I should be using?

Vlad Feinstein
  • 10,960
  • 1
  • 12
  • 27
vacuumhead
  • 479
  • 1
  • 6
  • 16

1 Answers1

3

Judging by your use of CDialogEx and the naming convention, I guess you are using MFC, right?

Your call to SetWindowPos() operates on the dialog window itself, as this is a class method.

If you want to call parent's SetWindowPos(), you could do:

m_parent->SetWindowPos(0, 0, 0, m_width, m_height,
 SWP_NOMOVE|SWP_NOZORDER|SWP_NOOWNERZORDER);

Also please note that in MFC Document-View architecture, the document doesn't have a window.

Alternatively, you could use Win API call:

::SetWindowPos(m_parent->GetSafeHwnd(), 0, 0, 0, m_width, m_height,
 SWP_NOMOVE|SWP_NOZORDER|SWP_NOOWNERZORDER);
Vlad Feinstein
  • 10,960
  • 1
  • 12
  • 27
  • Yes, I should have mentioned MFC, and the window was my document's View window. You are correct on all counts. Both your stated solutions work fine when applied to the CMainFrame window. – vacuumhead Oct 22 '15 at 14:00
  • Curiously, when I applied your solution to my document's View window, the scroll bars were redrawn at the new size but the view's visual border still extended to the edges of the MainFrame view. – vacuumhead Oct 22 '15 at 14:03
  • @vacuumhead - was your View maximized in the mainframe at that time? Or was it a single-document (SDI) interface, where it is the only option? – Vlad Feinstein Oct 22 '15 at 18:00
  • It's an MDI app. The main frame itself is not maximized, but it appears that the document view is maximized within the mainframe, and I have had no luck in finding ways to change that. Long ago when I used to use VS6, view windows were not stuck in a maximized view, but when developing with VS2010 that appears to be the default. – vacuumhead Oct 22 '15 at 19:21
  • You need to read about MDI stuff: https://msdn.microsoft.com/en-us/library/windows/desktop/ms632591%28v=vs.85%29.aspx . MFC's CMDIFrameWndEx contains m_wndClientArea, which is responsible for layout of MDI child windows. You can, for example, m_wndClientArea.PostMessage(WM_MDICASCADE, 0, 0); to get out of the maximized state. See https://support.microsoft.com/en-us/kb/131994 for additional info / code examples. – Vlad Feinstein Oct 23 '15 at 14:31