My MFC application is Dialog based and I need to adjust the dialog
size based on user's screen resolution. (which works fine). I have a
property sheet with 2 property pages on my dialog. I tried to adjust
the property sheet size when the dialog size adjusted, basically just
expand the property sheet to occupy the whole dialog, but I could not
have it done. Following is my code:
/*
CMyPage1, CMyPage2 are classes derived from CPropertyPage
*/
CPropertySheet* m_pMainTabs;
CPropertyPage* m_pMyPage1;
CPropertyPage* m_pMyPage2;
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//resize window to maximum screen size
CSize screenSize;
screenSize.cx = ::GetSystemMetrics(SM_CXSCREEN);
screenSize.cy = ::GetSystemMetrics(SM_CYSCREEN);
MoveWindow(0,0, screenSize.cx, screenSize.cy);
//create property sheet and pages
m_pMyPage1 = new CMyPage1();
m_pMyPage2 = new CMyPage2();
m_pMainTabs = new CPropertySheet;
//Resize PropertySheet before add pages
CRect rcDlg, rcSheet;
GetWindowRect(&rcDlg);
ScreenToClient( &rcDlg );
m_pMainTabs->SetWindowPos( NULL, rcDlg.left, rcDlg.top, rcDlg.Width()
+100, rcDlg.Height()+100,
SWP_NOZORDER | SWP_NOACTIVATE );
m_pMainTabs->AddPage(m_pMyPage1);
m_pMainTabs->AddPage(m_pMyPage2);
m_pMainTabs->Create(this, WS_CHILD | WS_VISIBLE);
m_pMainTabs->ModifyStyleEx (0, WS_EX_CONTROLPARENT);
m_pMainTabs->ModifyStyle( 0, WS_TABSTOP );
m_pMainTabs->SetActivePage(m_pMyPage1);
}
thanks in advance
-rockdale
Victor
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
http://support.microsoft.com/kb/300606
You said that you want to resize the propretysheet to take up the entire
main dialog. Why aren't you using the property sheet as your main dialog?
AliR.
"rockdale" <rockdal...@gmail.com> wrote in message
news:84864941-4fc7-4692...@v15g2000yqn.googlegroups.com...
My thoughts as well.
--
Ajay
I should not put the property sheet need to occupy the whole dialog.
This is just for simplify my question. My main dialog contains other
controls too. (not only the property sheet).
Victor- you are right. I can not call setwindowpos before I create the
propertysheet. Then here is another question, I create the
PropertySheet first then call the setwindowpos, then whenever I call
m_pMainTabs->GetWindowRect, I got the original size of the
propertysheet. I need the changed size so that I can lay out my
controls in the property page?
ALiR- Yes, I need to call The GetTabControl to get the CTabCtrl and
resize it. Now my problem is where should I resize my PropertyPage? I
read the MS article before but I do not need to make the Dialog
resizable, I just want to adjust the dialog size to the max of user
screen size and lay out the property sheet, property pages and
controls properly.
See my changed code below:
This code successfully resize the PropertySheet and its TabCtrl to the
dialog size,
in onInitDialog of PropertyPage
CRect rcPage;
CRect rcSheet;
GetParent()->GetWindowRect(&rcSheet);
GetWindowRect(&rcPage);
the rcSheet shows the original size of the property sheet.
and the rcPage shows the original size of the property page.
This OnInitDialog of propertyPage get called when I create the
propertysheet, and now I have not resize the property sheet yet, hence
I can not get the right size to layout my controls on the property
page.
I find some examples on CodeGuru and CodeParojects, but none of them
is what I wanted. Maybe somebody can show me links or point out what
should I do?
------------------------------------------------------
CPropertySheet* m_pMainTabs;
CPropertyPage* m_pMyPage1;
CPropertyPage* m_pMyPage2;
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//resize window to maximum screen size
CSize screenSize;
screenSize.cx = ::GetSystemMetrics(SM_CXSCREEN);
screenSize.cy = ::GetSystemMetrics(SM_CYSCREEN);
MoveWindow(0,0, screenSize.cx, screenSize.cy);
//Resize PropertySheet before add pages
CRect rcDlg, rcSheet;
GetWindowRect(&rcDlg);
m_pMainTabs->AddPage(m_pMyPage1);
m_pMainTabs->AddPage(m_pMyPage2);
// Now "initialize" the property sheet window.
if(!m_pMainTabs->Create(this, WS_CHILD | WS_VISIBLE)){
delete m_pMainTabs;
m_pMainTabs = NULL;
return;
}
m_pMainTabs->ModifyStyleEx (0, WS_EX_CONTROLPARENT);
m_pMainTabs->ModifyStyle( 0, WS_TABSTOP );
m_pMainTabs->SetWindowPos(NULL, rcDlg.left, rcDlg.top, rcDlg.Width(),
rcDlg.Height(),
SWP_NOZORDER | SWP_NOACTIVATE );
m_pMainTabs->GetWindowRect(&rcSheet);
ScreenToClient(&rcSheet);
m_pMainTabs->GetTabControl()->SetWindowPos( NULL, rcSheet.left,
rcSheet.top, rcSheet.Width(), rcSheet.Height(),
SWP_NOZORDER | SWP_NOACTIVATE );
m_pMainTabs->SetActivePage(m_pMyPage1);
--------------------------------;
Here is the answer all spelled out:
//////////////////////////// CMyPropertySheet.h
/////////////////////////////////
#pragma once
// CMyPropertySheet
class CMyPropertySheet : public CPropertySheet
{
DECLARE_DYNAMIC(CMyPropertySheet)
public:
CMyPropertySheet();
CMyPropertySheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT
iSelectPage = 0);
CMyPropertySheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT
iSelectPage = 0);
virtual ~CMyPropertySheet();
protected:
BOOL m_bNeedInit;
CRect m_rCrt;
virtual BOOL OnInitDialog();
afx_msg void OnSize(UINT nType, int cx, int cy);
DECLARE_MESSAGE_MAP()
};
//////////////////////////// CMyPropertySheet.cpp
/////////////////////////////////
// MyPropertySheet.cpp : implementation file
//
#include "stdafx.h"
#include "MyPropertySheet.h"
#include ".\mypropertysheet.h"
// CMyPropertySheet
IMPLEMENT_DYNAMIC(CMyPropertySheet, CPropertySheet)
CMyPropertySheet::CMyPropertySheet()
: m_bNeedInit(TRUE)
{
}
CMyPropertySheet::CMyPropertySheet(UINT nIDCaption, CWnd* pParentWnd, UINT
iSelectPage)
:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
, m_bNeedInit(TRUE)
{
}
CMyPropertySheet::CMyPropertySheet(LPCTSTR pszCaption, CWnd* pParentWnd,
UINT iSelectPage)
: CPropertySheet(pszCaption, pParentWnd, iSelectPage)
, m_bNeedInit(TRUE)
{
}
CMyPropertySheet::~CMyPropertySheet()
{
}
BEGIN_MESSAGE_MAP(CMyPropertySheet, CPropertySheet)
ON_WM_SIZE()
END_MESSAGE_MAP()
// CMyPropertySheet message handlers
BOOL CMyPropertySheet::OnInitDialog()
{
BOOL bResult = CPropertySheet::OnInitDialog();
m_bNeedInit = FALSE;
GetClientRect(&m_rCrt);
return bResult;
}
// Handle WM_SIZE events by resizing the tab control and by
// moving all the buttons on the property sheet.
void CMyPropertySheet::OnSize(UINT nType, int cx, int cy)
{
CRect r1;
CPropertySheet::OnSize(nType, cx, cy);
if (m_bNeedInit)
return;
CTabCtrl *pTab = GetTabControl();
ASSERT(NULL != pTab && IsWindow(pTab->m_hWnd));
int dx = cx - m_rCrt.Width();
int dy = cy - m_rCrt.Height();
GetClientRect(&m_rCrt);
HDWP hDWP = ::BeginDeferWindowPos(5);
pTab->GetClientRect(&r1);
r1.right += dx; r1.bottom += dy;
::DeferWindowPos(hDWP, pTab->m_hWnd, NULL,
0, 0, r1.Width(), r1.Height(),
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
// Move all buttons with the lower right sides
for (CWnd *pChild = GetWindow(GW_CHILD);
pChild != NULL;
pChild = pChild->GetWindow(GW_HWNDNEXT))
{
if (pChild->SendMessage(WM_GETDLGCODE) & DLGC_BUTTON)
{
pChild->GetWindowRect(&r1); ScreenToClient(&r1);
r1.top += dy; r1.bottom += dy; r1.left+= dx; r1.right += dx;
::DeferWindowPos(hDWP, pChild->m_hWnd, NULL,
r1.left, r1.top, 0, 0,
SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
}
// Resize everything else...
else
{
pChild->GetClientRect(&r1);
r1.right += dx; r1.bottom += dy;
::DeferWindowPos(hDWP, pChild->m_hWnd, NULL, 0, 0, r1.Width(),
r1.Height(),SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
}
}
::EndDeferWindowPos(hDWP);
}
And you can change the layout of the controls on your propertypages in the
OnSize handler of each of your PropertyPage classes.
AliR.
"rockdale" <rockdal...@gmail.com> wrote in message
news:977bf1d6-96a3-4f1c...@v38g2000yqb.googlegroups.com...
http://support.microsoft.com/kb/300606
Tom
"rockdale" <rockdal...@gmail.com> wrote in message
news:84864941-4fc7-4692...@v15g2000yqn.googlegroups.com...
AliR.
"Tom Serface" <t...@nospam.camaswood.com> wrote in message
news:C168BF05-72D1-4722...@microsoft.com...
But I do not think I can use the OnSize event.
A little bit background for what I am trying to achieve, (should write
this in the first post, sorry)
On my propertyPage, I need to dynamic create a matrix of buttons and
other controls (CList, More buttons, CEdit..etc), I need to calculate
how many buttons I need to create based on the screen size, and then
layout other controls properly, all these are working already.
So in my ideal world, I should be able to:
1. In InitDialog the main Dialog and Resize the Dialog to screen.
2. In InitDialog of the main Dialog Create the PropertySheet and
resize the sheet to the Dialog size.
3. In InitDialog of the PropertyPage, get the PropertySheet size and
adjust Property Page size, based on the size of peroperty page,
calculate number of buttons I need to create, create buttons and
controls and layout them properly based on the property page size.
And from what I experienced, since I can not Resize the property sheet
before I actually create(instancialize) it, the propertyPage get
created(InitDialog get called) in this process, when I get to where I
need the size of the proprerty page to calculate button bumber and
layout them, I get the ORIGINAL size since I have not resize the
property sheet yet.
Any more suggestion? Or I did it totally wrong?
Thanks again
-Rockdale
This way you have full control over when the dialogs get created, and at
what size they get created. That way you won't have to worry about catching
OnSize and changing things there. Although there is no way to specifiy a
size for a dialog when it is being created, you can create the dialog, and
then set its size, and then call a method in it to create its controls.
This is very simply to implement, you would have have this done, in the same
amount of time you have spent looking for the solution to the PropertySheet
problem.
The only trick here is to pass the tab control on your dialog as the parent
of the child dialogs that will be in the tab, and for placement of the
dialog you can use CTabCtrl::AdjustRect method to find the inside area of
the tab for placing your dialogs.
CRect Rect;
m_Tab.GetClientRect(&Rect);
m_Tab.AdjustRect(FALSE,&Rect);
m_Dlg1.SetWindowPos(NULL,Rect.left,Rect.top,Rect.Width(),Rect.Height(),SWP_NOZORDER);
m_Dlg2.SetWindowPos(NULL,Rect.left,Rect.top,Rect.Width(),Rect.Height(),SWP_NOZORDER);
m_Dlg1.CreateControls();
m_Dlg2.CreateControls();
m_Dlg1.ShowWindow(SW_SHOW);
And then catch the TCN_SELCHANGE message from the tab control, and hide the
current dialog (if not the same as newly selected dialog), and show the
newly selected tab's dialog.
AliR.
"rockdale" <rockdal...@gmail.com> wrote in message
news:dd51b434-80b1-4c50...@l33g2000pri.googlegroups.com...
Note that OnInitDialog is not necessarily the right time to make these decisions, such as
how many buttons will fit. What happens if the window is resized on the fly? I had to do
this, and would do dynamic layout of the buttons based ont he window size, and had to
support scrolling within the dialog/formview because when the window got small, the
buttons stacked vertically, pushing everything else down.
joe
After reading the last 2 posts. I first tried using CTabCtrl,(never
used CTabCtrl, I have always use PropertySheet for tabs :). Create
myPages and then resize them then create controls, It works, need some
minus tuning thought. Then it occur to me why I must put my create
controls code inside the OnInitDialog? I should put it in a seperate
function and and explicit call this function after I resize the
property sheet and property page. It works beautifully.
Something like this: (added code is between ####)
CPropertySheet* m_pMainTabs;
CPropertyPage* m_pMyPage1;
CPropertyPage* m_pMyPage2;
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//resize window to maximum screen size
CSize screenSize;
screenSize.cx = ::GetSystemMetrics(SM_CXSCREEN);
screenSize.cy = ::GetSystemMetrics(SM_CYSCREEN);
MoveWindow(0,0, screenSize.cx, screenSize.cy);
//Resize PropertySheet before add pages
CRect rcDlg, rcSheet;
GetWindowRect(&rcDlg);
m_pMainTabs->AddPage(m_pMyPage1);
m_pMainTabs->AddPage(m_pMyPage2);
// Now "initialize" the property sheet window.
if(!m_pMainTabs->Create(this, WS_CHILD | WS_VISIBLE)){
delete m_pMainTabs;
m_pMainTabs = NULL;
return;
}
m_pMainTabs->ModifyStyleEx (0, WS_EX_CONTROLPARENT);
m_pMainTabs->ModifyStyle( 0, WS_TABSTOP );
m_pMainTabs->SetWindowPos(NULL, rcDlg.left, rcDlg.top,
rcDlg.Width(),
rcDlg.Height(),
SWP_NOZORDER | SWP_NOACTIVATE );
m_pMainTabs->GetWindowRect(&rcSheet);
ScreenToClient(&rcSheet);
m_pMainTabs->GetTabControl()->SetWindowPos( NULL,
rcSheet.left,
rcSheet.top, rcSheet.Width(), rcSheet.Height(),
SWP_NOZORDER | SWP_NOACTIVATE );
###########################
m_pMyPage1->SetWindowPos( NULL, rcSheet.left, rcSheet.top,
rcSheet.Width(), rcSheet.Height(),
SWP_NOZORDER | SWP_NOACTIVATE );
m_pMyPage2->SetWindowPos( NULL, rcSheet.left, rcSheet.top,
rcSheet.Width(), rcSheet.Height(),
SWP_NOZORDER | SWP_NOACTIVATE );
m_pMyPage1->InitControls();
m_pMyPage2->InitControls();
############################
m_pMainTabs->SetActivePage(m_pMyPage1);
Again ,thanks guys.
-rockdale