Click here to Skip to main content
Click here to Skip to main content

Resizable Property Sheet/Wizard using CDialogResize

By , 12 Mar 2007
 

Screenshot

Introduction

Since I once created an re-sizable property sheet implementation in plain C, I decided also to do so in WTL. My goal during implementation was to stay as close as possible on WTL original source. This leads to an implementation which could 1 by 1 replaced by conventional source.

Features

  1. Resizable Property Sheet window class
  2. Resizable Property Sheet Page class (see CDialogResize for more information about usage)
  3. Double buffered redraw is possible using WS_EX_COMPOSITED (Sheet window only)
  4. CDialogResize extension called CDialogResizeDynamic to support runtime resize map manipulation

Background

Since the property sheet class implements Wizard (97) style dialogs and default property sheets, and since I want to derive my new class from CDialogResize, I was forced to create a WTL modifications.

Instead of using static GetDlgResizeMap() I decided to use a dynamic Implementation to support runtime resize manipulation. I derived a new class from CDialogResize and added methods for adding and removing resize map entries.

BEGIN_DLGRESIZE_MAP_EX(CResizablePropertySheetImpl)
    DLGRESIZE_CONTROL_EX(ID_PSHEET_OK, DLSZ_MOVE_X | DLSZ_MOVE_Y)
    DLGRESIZE_CONTROL_EX(ID_PSHEET_APPLY, DLSZ_MOVE_X | DLSZ_MOVE_Y)
    DLGRESIZE_CONTROL_EX(ID_PSHEET_CANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y)
    DLGRESIZE_CONTROL_EX(ID_PSHEET_HELP, DLSZ_MOVE_X | DLSZ_MOVE_Y)
    DLGRESIZE_CONTROL_EX(ID_PSHEET_TAB, DLSZ_SIZE_X | DLSZ_SIZE_Y)
END_DLGRESIZE_MAP_EX()

Above declaration will be evaluated as

    void StaticResizeMap() {
        InitialMap.Add(ID_PSHEET_OK, DLSZ_MOVE_X | DLSZ_MOVE_Y);
        ...
        InitialMap.Add(ID_PSHEET_TAB, DLSZ_SIZE_X | DLSZ_SIZE_Y);
        InitialMap.Add(-1, 0);
    }

Please note, the use of the old BEGIN_DLGRESIZE_MAP has no effect and will be ignored. StaticResizeMap method will be called within CDialogResizeDynamic constructor.

Using the code

There is not much need of code modification on your existing source code. You have to replace CPropertySheetImpl with CResizablePropertySheetImpl

class CMyPropertySheet :
    public CResizablePropertySheetImpl<CMyPropertySheet> {
public:
    CMyPropertySheet(ATL::_U_STRINGorID title = (LPCTSTR) NULL, 
     UINT uStartPage = 0, HWND hWndParent = NULL,
    bool EnableDoubleBuffering = false, bool IsWizard = false)
    : CResizablePropertySheetImpl<CMyPropertySheet>(title, 
     uStartPage, hWndParent, EnableDoubleBuffering, IsWizard) {
    }
    ...

As you may note constructor is extended by two additional parameters. EnableDoubleBuffering will enable double buffering (no flickering) as the name implies. IsWizard will create an wizard style property sheet. However, you should use double buffering with care because it may slow down rendering and may cause unpredictable behaviour in some circumstances.

class CMyResizablePropertyPage :
    public CResizablePropertyPageImpl<CMyResizablePropertyPage> {
public:
    enum { IDD = IDD_0 };
    CMyResizablePropertyPage(ATL::_U_STRINGorID title = (LPCTSTR) NULL, 
     bool IsExterior = false) :
    CResizablePropertyPageImpl<CMyResizablePropertyPage>(title, 
     IsExterior) {
    }
    ...

As you may note, I extended property page constructor. If IsExterior is true, an exterior page will be created i.e. that page that usually is used for welcome and completion page.

To add, remove or change resize map items at runtime you may use one of the new CDialogResizeDynamic methods:

    void AddToResizeMap(int ControlId, DWORD ResizeFlags);
    void RemoveFromResizeMap(int ControlId);
    void ChangeResizeMapEntry(int ControlId, DWORD ResizeFlags);

Adding new resize map groups after DlgResize_Init is called is currently not possible.

History

  • 2007/03/07: Added some extensions, resize map is dynamic now.
  • 2004/02/24: Initial release

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

bkausbk
Germany Germany
Member
Hobby: system programing (operating system and hardware)
Prefered languages are x86 assembler, c and c++.
Currently student of applied computer science at university of applied sciences Bingen (Germany)

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralExcellent But MFC!!!!memberMPTP13 Apr '09 - 22:41 
This is very nice but I want this article in MFC, Could you please do it?
GeneralRe: Excellent But MFC!!!!memberbkausbk4 Dec '09 - 1:05 
This implementation is dedicated to WTL/ATL. There are many MFC implementations out there but at that time this was created almost no good implementation for WTL.
GeneralExcellentmemberYogesh P. Dhakad1 May '07 - 13:40 
Helped me a lot while taking a transistion from MFC to WTL. Thanks.
 
Regards
GeneralNice, but...memberfree2000fly3 Aug '06 - 20:44 
But your class don't support DoModal() method, you would like to supply?Smile | :)
 
gg hh

GeneralRe: Nice, but... [modified]memberfree2000fly4 Aug '06 - 15:41 
I have Impl it. Laugh | :laugh:
 
this is the header file:
 
#ifndef __ATL_RESIZABLE_PROPERTY_SHEET_H__ 
#define __ATL_RESIZABLE_PROPERTY_SHEET_H__ 
 
#pragma once
 
// Resizable Property Sheet Implemenation based on CPropertySheetImpl by
// Benjamin Kalytta (http://www.kalytta.com)
// Version: 1.1 
// modifyed by free2000fly 

#ifndef _WTL_NEW_PAGE_NOTIFY_HANDLERS 
#define _WTL_NEW_PAGE_NOTIFY_HANDLERS 
#endif  // _WTL_NEW_PAGE_NOTIFY_HANDLERS 

#if _WIN32_WINNT  <  0x0501
#pragma message ("Double buffered windows using WS_EX_COMPOSITED requires Windows XP and higher, I'll set _WIN32_WINNT 0x0501")
#define _WIN32_WINNT 0x0501
#endif
 
#ifndef __ATLCRACK_H__
#include  < atlcrack.h > 
#endif
 
namespace WTL 
{ 
 
#define BEGIN_DLGRESIZE_MAP_EX(thisClass) \
	static void *ResizeMapStart; \
	static int ResizeMapIdx; \
	static const _AtlDlgResizeMap* GetDlgResizeMap() { \
		static _AtlDlgResizeMap ResizeMap[] = { 
 
#define ALT_DLGRESIZE_MAP_EX() \
		{ -1, 0 }, \
 
#define END_DLGRESIZE_MAP_EX() \
			{ -1, 0 }, \
			{ -1, 0 }, \
		}; \
		ResizeMapStart = ResizeMap; \
		return (_AtlDlgResizeMap*) (&ResizeMap[ResizeMapIdx]); \
	}
 

template  < class T, class TBase = CPropertySheetWindow > 
class ATL_NO_VTABLE CResizablePropertySheetImpl 
    : public CPropertySheetImpl < T, TBase  >  
    , public CDialogResize < T >  
    , public CMessageFilter 
{ 
private:
	bool EnableDoubleBuffering;
	bool IsWizard;
	
	enum {
		ID_PSHEET_OK = IDOK,
		ID_PSHEET_APPLY = ID_APPLY_NOW,
		ID_PSHEET_CANCEL = IDCANCEL,
		ID_PSHEET_HELP = IDHELP,
		ID_PSHEET_TAB = ATL_IDC_TAB_CONTROL,
		ID_PSHEET_PREV = ID_WIZBACK,
		ID_PSHEET_NEXT = ID_WIZNEXT,
		ID_PSHEET_FINISH = ID_WIZFINISH,
		ID_PSHEET_BOTTOMFRAME = ID_WIZFINISH + 1,
		ID_PSHEET_TOPFRAME = ID_WIZFINISH + 2,
	};
	
public:
 
	CResizablePropertySheetImpl(ATL::_U_STRINGorID title = (LPCTSTR) NULL, UINT uStartPage = 0, 
        HWND hWndParent = NULL, bool EnableDoubleBuffering = false, bool IsWizard = false) 
        : CPropertySheetImpl < T, TBase >  (title, uStartPage, hWndParent) 
    {
		this- > EnableDoubleBuffering = EnableDoubleBuffering;
		this- > IsWizard = IsWizard;
		if (IsWizard) {
			SetWizardMode();
		}
	}
 
	static int CALLBACK PropSheetCallback(HWND hWnd, UINT uMsg, LPARAM lParam) 
    {
		if (uMsg == PSCB_PRECREATE) { 
            LPDLGTEMPLATE Template = (LPDLGTEMPLATE) lParam;
			// remove dialog border styles
			Template- > style &= ~DS_MODALFRAME;
 
			// add child window and clipping styles
			Template- > style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW;
			return 0;
		} 
		return CPropertySheetImpl < T > ::PropSheetCallback(hWnd, uMsg, lParam);
	}
 
    void OnSheetInitialized()
    {
        _Module.GetMessageLoop()- > AddMessageFilter(this); 
    }
 
    virtual void OnFinalMessage(HWND hWnd) 
    { 
        hWnd; 
        CMessageLoop* pLoop = _Module.GetMessageLoop(); 
        ATLASSERT(pLoop != NULL);
        pLoop- > RemoveMessageFilter(this); 
    } 
 
    void SetWizardMode() {
		SetActiveResizeMap(1);
		IsWizard = true;
		CPropertySheetImpl < T > ::SetWizardMode();
	}
 
	void SetHeader(LPCTSTR szbmHeader) {
		SetActiveResizeMap(1);
		IsWizard = true;
		CPropertySheetImpl < T > ::SetHeader(szbmHeader);
	}
 
	void SetHeader(HBITMAP hbmHeader) {
		SetActiveResizeMap(1);
		IsWizard = true;
		return CPropertySheetImpl < T > ::SetHeader(hbmHeader);
	}
	
	void SetWatermark(LPCTSTR szbmWatermark, HPALETTE hplWatermark = NULL) {
		SetActiveResizeMap(1);
		IsWizard = true;
		CPropertySheetImpl < T > ::SetWatermark(szbmWatermark, hplWatermark);
	}
 
	void SetWatermark(HBITMAP hbmWatermark, HPALETTE hplWatermark = NULL) {
		SetActiveResizeMap(1);
		IsWizard = true;
		return CPropertySheetImpl < T > ::SetWatermark(hbmWatermark, hplWatermark);
	}
 
	// This is required to handle modeless Dialog messages correctly 
	virtual BOOL PreTranslateMessage(LPMSG pMsg) 
    { 
		if (IsDialogMessage(pMsg)) {
			if (!::IsWindow(m_hWnd) || GetActivePage() == NULL) {
				// Not really clean code, but better than creating an 
				// extra property sheet Message Loop class 
				PostQuitMessage(0);
			}
			return TRUE;
		}
		return FALSE;
	}
 
	// --- CDialogResize enhancement --- 

	void SetActiveResizeMap(int MapIdx) 
    {
		if (ResizeMapStart == NULL) {
			// ResizeMapStart not yet initialized 
			GetDlgResizeMap();
		}
		int Idx = 0;
		bool WasMapEnd = false;
		while (true) 
        {
			if (((_AtlDlgResizeMap*) ResizeMapStart)[Idx].m_nCtlID == -1 && 
                ((_AtlDlgResizeMap*) ResizeMapStart)[Idx].m_dwResizeFlags == 0) 
            {
				if (WasMapEnd) break;
				MapIdx--;
				if (MapIdx == 0) {
					ResizeMapIdx = Idx + 1;
					break;
				}
				WasMapEnd = true;
			} else {
				WasMapEnd = false;
			}
			Idx++;
		}
	}
	
	void OnSize(WPARAM wParam, CSize Size) 
    { 
		// Resize Property Sheet controls manually first 
		BOOL Handled = FALSE;
		CDialogResize < T > ::OnSize(WM_SIZE, 0, MAKELONG(Size.cx, Size.cy), Handled);
		UpdatePropertyPage(GetActivePage());
		SetMsgHandled(FALSE);
	}
 
	LRESULT OnSetActive(LPNMHDR Hdr) 
    {
		UpdatePropertyPage((HWND) ((LPPSHNOTIFY) Hdr)- > lParam);
		SetMsgHandled(FALSE);
		return TRUE;
	} 
 
    LRESULT OnWmShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 
    { 
        uMsg, wParam, lParam, bHandled; 
        { 
            DlgResize_Init();
            if (EnableDoubleBuffering) {
                SetWindowLongPtr(GWL_EXSTYLE, GetWindowLongPtr(GWL_EXSTYLE) | WS_EX_COMPOSITED);
            }
        } 
 
        bHandled = FALSE; 
        return S_OK; 
    } 
 
	BEGIN_MSG_MAP_EX(CResizablePropertySheetImpl)
        MESSAGE_HANDLER(WM_SHOWWINDOW, OnWmShowWindow) 
		MSG_WM_SIZE(OnSize);
		NOTIFY_CODE_HANDLER_EX(PSN_SETACTIVE, OnSetActive)
		CHAIN_MSG_MAP(CPropertySheetImpl < T > )
		CHAIN_MSG_MAP(CDialogResize < T > )
	END_MSG_MAP()
 
    BEGIN_DLGRESIZE_MAP_EX(CResizablePropertySheetImpl)
		DLGRESIZE_CONTROL(ID_PSHEET_OK, DLSZ_MOVE_X | DLSZ_MOVE_Y)
		DLGRESIZE_CONTROL(ID_PSHEET_APPLY, DLSZ_MOVE_X | DLSZ_MOVE_Y)
		DLGRESIZE_CONTROL(ID_PSHEET_CANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y)
		DLGRESIZE_CONTROL(ID_PSHEET_HELP, DLSZ_MOVE_X | DLSZ_MOVE_Y)
		DLGRESIZE_CONTROL(ID_PSHEET_TAB, DLSZ_SIZE_X | DLSZ_SIZE_Y)
	ALT_DLGRESIZE_MAP_EX()
		DLGRESIZE_CONTROL(ID_PSHEET_PREV, DLSZ_MOVE_X | DLSZ_MOVE_Y)
		DLGRESIZE_CONTROL(ID_PSHEET_NEXT, DLSZ_MOVE_X | DLSZ_MOVE_Y)
		DLGRESIZE_CONTROL(ID_PSHEET_FINISH, DLSZ_MOVE_X | DLSZ_MOVE_Y)
		DLGRESIZE_CONTROL(ID_PSHEET_CANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y)
		DLGRESIZE_CONTROL(ID_PSHEET_HELP, DLSZ_MOVE_X | DLSZ_MOVE_Y)
		DLGRESIZE_CONTROL(ID_PSHEET_TOPFRAME, DLSZ_SIZE_X)
		DLGRESIZE_CONTROL(ID_PSHEET_BOTTOMFRAME, DLSZ_MOVE_Y)
		DLGRESIZE_CONTROL(ID_PSHEET_BOTTOMFRAME, DLSZ_SIZE_X)
	END_DLGRESIZE_MAP_EX()
private:
 
	void UpdatePropertyPage(HWND hWnd) 
    {
		// Adjust property page size 
		CPropertyPageWindow Wnd = hWnd;
		CSize PageMargin;
 
		if (Wnd) {
			RECT rc, rctf, rcbf;
			GetClientRect(&rc);
			
			int Width = 0;
			int Height = 0;
			int Top = 0;
			int Left = 0;
 
			if (IsWizard) {
                ::GetWindowRect(GetDlgItem(ID_PSHEET_TOPFRAME), &rctf);
                ::GetWindowRect(GetDlgItem(ID_PSHEET_BOTTOMFRAME), &rcbf);
				ScreenToClient(&rctf);
				ScreenToClient(&rcbf);
 
				PageMargin.cx = 11;
				PageMargin.cy = 11;
 
				if (::GetProp(hWnd, _T("IsExterior"))) {
					Left = 0;
					Top = 0;
					Width = rc.right;
					Height = rcbf.top;
				} else {
					Top = rctf.top + PageMargin.cy;
					Left = PageMargin.cx;
					Width = rc.right - Left - PageMargin.cx;
					Height = rcbf.top - Top - PageMargin.cy;
				}
			} else {
				RECT rci;
				CTabCtrl Tab = GetTabControl();
				Tab.GetItemRect(HwndToIndex(Wnd), &rci);
				Tab.GetWindowRect(&rc);
				ScreenToClient(&rc);
				
				PageMargin.cx = 4;
				PageMargin.cy = 4;
 
				Top = rc.top + rci.bottom + PageMargin.cy;
				Left = rc.left + PageMargin.cx;
				Width = rc.right - PageMargin.cx - Left;
				Height = rc.bottom - PageMargin.cy - Top;
			}
			Wnd.SetWindowPos(NULL, Left, Top, Width, Height, SWP_NOACTIVATE | SWP_NOZORDER);
		}
	}
};
 
// Static class members declaration and initialization  

template  < class T, class TBase >  void *CResizablePropertySheetImpl < T, TBase > ::ResizeMapStart = NULL; 
template  < class T, class TBase >  int CResizablePropertySheetImpl < T, TBase > ::ResizeMapIdx = 0; 
 
template  < class T, class TBase = CPropertyPageWindow > 
class ATL_NO_VTABLE CResizablePropertyPageImpl 
    : public CPropertyPageImpl < T, TBase  > , public CDialogResize < T >  
{
private:
	bool IsDoubleBufferEnabled;
public:
	CResizablePropertyPageImpl(ATL::_U_STRINGorID title = (LPCTSTR) NULL, 
        bool IsExterior = false, bool bDoubleBuffer = false) 
        : CPropertyPageImpl < T >  (title) 
    {
		if (IsExterior) m_psp.dwFlags |= PSP_HIDEHEADER;
		IsDoubleBufferEnabled = bDoubleBuffer;
	}
	
	LRESULT OnInitDialog(HWND hWnd, LPARAM lParam) {
		if (m_psp.dwFlags & PSP_HIDEHEADER) {
			SetProp(m_hWnd, _T("IsExterior"), (HANDLE) 1);
		}
		if (IsDoubleBufferEnabled) {
			SetWindowLongPtr(GWL_EXSTYLE, GetWindowLongPtr(GWL_EXSTYLE) | WS_EX_COMPOSITED);
		}
		DlgResize_Init(false, false);
		SetMsgHandled(FALSE);
		return FALSE;
	}
 
	void OnDestroy() {
		RemoveProp(m_hWnd, _T("IsExterior"));
		SetMsgHandled(false);
	}
 
	void EnableDoubleBuffering() {
		if (m_hWnd) {
			SetWindowLongPtr(GWL_EXSTYLE, GetWindowLongPtr(GWL_EXSTYLE) | WS_EX_COMPOSITED);
		} else {
			IsDoubleBufferEnabled = true;
		}
	}
 
	void DisableDoubleBuffering() {
		if (m_hWnd) {
			SetWindowLongPtr(GWL_EXSTYLE, GetWindowLongPtr(GWL_EXSTYLE) & ~WS_EX_COMPOSITED);
		} else {
			IsDoubleBufferEnabled = false;
		}
	}
 
	void AddPageFlags(UINT Flags) {
		m_psp.dwFlags |= Flags;
	}
 
	void RemovePageFlags(UINT Flags) {
		m_psp.dwFlags &= ~Flags;
	}
 
	BEGIN_MSG_MAP_EX(CResizablePropertyPageImpl)
		MSG_WM_INITDIALOG(OnInitDialog)
		MSG_WM_DESTROY(OnDestroy);
		// forward WM_NOTIFY message to parent (Property Sheet) manually 
		if (uMsg == WM_NOTIFY) {
			// since lParam in LPPSHNOTIFY struct isn't used, we'll use it 
			if (((LPNMHDR) lParam)- > code == PSN_SETACTIVE) {
				((LPPSHNOTIFY) lParam)- > lParam = (LPARAM) m_hWnd;
				::SendMessage(GetParent(), uMsg, wParam, lParam);
			}
		}
		CHAIN_MSG_MAP(CPropertyPageImpl < T > )
		CHAIN_MSG_MAP(CDialogResize < T > )
	END_MSG_MAP()
}; 
 

}; // namespace WTL 

 
#endif  // __ATL_RESIZABLE_PROPERTY_SHEET_H__ 

 


 
Free2000Fly

GeneralRe: Nice, but...memberfree2000fly4 Aug '06 - 16:02 
And this is the cpp file:
 
 
// 
// ... 
// 
 
#define  WIZARD_MODEL   1 
#define  MODELESS       1 
 
// ----- My user defined property sheet ----- 
 
class CMyPropertySheet : public CResizablePropertySheetImpl < CMyPropertySheet >  
{
private:
public:
    CMyPropertySheet(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, 
        HWND hWndParent = NULL, bool bDoubleBuffer = false, bool IsWizard = false)
        : CResizablePropertySheetImpl < CMyPropertySheet > (title, uStartPage, hWndParent, bDoubleBuffer, IsWizard) 
    { } 
 

    LRESULT OnWmDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 
    { 
        ::DestroyIcon(m_hIconSmall); 
        ::DestroyIcon(m_hIcon); 
 
        return S_OK; 
    }
 
    void OnShowWindow(BOOL, int) 
    { 
        CString strTitle; 
#if defined(WIZARD_MODEL)
        strTitle = _T("Wizard style ");         
#else 
        strTitle = _T("Property style "); 
#endif 
 
#if defined(MODELESS) 
        strTitle += _T("modeless dialog");         
#else 
        strTitle += _T("model dialog"); 
#endif 
        SetWindowText( strTitle ); 
 
        m_hIcon = (HICON)::LoadImage(_Module.GetResourceInstance(), 
            MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 
            ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), 
            LR_DEFAULTCOLOR);
        SetIcon(m_hIcon, TRUE);
        m_hIconSmall = (HICON)::LoadImage(_Module.GetResourceInstance(), 
            MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 
            ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), 
            LR_DEFAULTCOLOR);
        SetIcon(m_hIconSmall, FALSE); 
 
        CenterWindow(GetDesktopWindow());
        
        SetMsgHandled(FALSE);
    }
 
    BEGIN_MSG_MAP_EX(CMyPropertySheet) 
        MESSAGE_HANDLER(WM_DESTROY, OnWmDestroy) 
        MSG_WM_SHOWWINDOW(OnShowWindow) 
        CHAIN_MSG_MAP(CResizablePropertySheetImpl < CMyPropertySheet > ) 
    END_MSG_MAP() 
 
private: 
    HICON m_hIcon, m_hIconSmall; 
};
 

int Run(LPTSTR lpstrCmdLine = NULL, int nCmdShow = SW_SHOWDEFAULT) 
{
    CMessageLoop theLoop;
    CMyPropertySheet Sheet((LPCTSTR) NULL);
    _Module.AddMessageLoop(&theLoop);
 
#if defined(WIZARD_MODEL)
    Sheet.SetHeader((LPCTSTR) IDB_HEADER);
    Sheet.SetWatermark((LPCTSTR) IDB_WATERMARK);
#endif // defined(WIZARD_MODEL) 
 
    CResizablePropertyPage0 pgWelcome((LPCTSTR) NULL, true);
    CResizablePropertyPage1 pgMiddle;
    CResizablePropertyPage2 pgComplete((LPCTSTR) NULL, true);
 
    pgMiddle.SetHeaderTitle(_T("Header title of this wizard page 1"));
    pgMiddle.SetHeaderSubTitle(_T("This is the sub header title of this page"));
 
    Sheet.AddPage (pgWelcome);
    Sheet.AddPage (pgMiddle);
    Sheet.AddPage (pgComplete);
 
    // just test double buffering here 
    pgWelcome.EnableDoubleBuffering(); 
    pgMiddle.EnableDoubleBuffering(); 
    pgComplete.EnableDoubleBuffering();
 
    int nRet = 0; 
 
#if defined(MODELESS) 
    if (Sheet.Create(GetDesktopWindow()) == NULL) {
        ATLTRACE(_T("Main dialog creation failed!\n"));
        return 0;
    }
 
    Sheet.ShowWindow(nCmdShow);
 
    nRet = theLoop.Run();
 
    // If "Finish" button is pressed, Property Sheet window handle will not be destroyed 
    if (Sheet.IsWindow()) {
        // Get real dialog result 
        nRet = Sheet.GetResult();
        Sheet.DestroyWindow();
    }
#else // !defined(MODELESS) 
    Sheet.DoModal(GetDesktopWindow()); 
#endif // !defined(MODELESS) 
 
    _Module.RemoveMessageLoop();
    return nRet;
}
 
// 
// ... 
// 
 

 
free2000fly

GeneralRe: Nice, but...memberbkausbk6 Mar '07 - 16:20 
Thanks for adding modal support. I added this code to the newest version.
GeneralList Control on a page with double buffering causes problemsmembermichael_ro200022 Dec '05 - 23:27 
Hi,
 
I have encountered a bug with pages that have a List Control. If double buffering is enabled (either for Property Sheet, for that page or both) there is a problem. Just moving around the mouse over the page will cause the page to continuously repaint and the processor to go to 100% activity. Of course, resizing is also slow.
 
As far as I can tell the problem is cause by the presence of the List Control on the page. Pages having other controls seem to work OK.
 
I am using Windows XP SP2 and the project was compiled with VS 7.1.
 
To reproduce the problem, using the example provided:
 
1. Add a new dialog containing a label and a List control. Set the List View attribute as "Report"
2. Change the Middle page IDD and Resize map:
 
enum { IDD = IDD_LIST_DIALOG };
...
BEGIN_DLGRESIZE_MAP(CResizablePropertyPage1)
DLGRESIZE_CONTROL(IDC_ST_TEXT, DLSZ_SIZE_X)
DLGRESIZE_CONTROL(IDC_LIST, DLSZ_SIZE_X | DLSZ_SIZE_Y)
END_DLGRESIZE_MAP()
 
3. Change the initialization of the variables:
CMyPropertySheet Sheet((LPCTSTR) NULL, 0, NULL, true, true);
...
CResizablePropertyPage0 pgWelcome((LPCTSTR) NULL, true, true);
CResizablePropertyPage1 pgMiddle((LPCSTR)NULL, false, true);
CResizablePropertyPage2 pgComplete((LPCTSTR) NULL, true, true);
 
Did anyone encountered this problem before?
 
Any help would be appreciated.
 
All the best,
Mike

GeneralRe: List Control on a page with double buffering causes problemsmembermichael_ro200023 Dec '05 - 1:27 
The problem can be better observed some columns are added to list:
 
CListViewCtrl list(GetDlgItem(IDC_LIST));
list.AddColumn("One", 0);
list.AddColumn("Two", 1);
 
Also, in some cases, the list is painted wrong to begin with (no border). This depends on how you turn on/off double buffering for the sheet and the page. The only case when the list is display and resize correctly is when double buffering is disabled for both.
GeneralRe: List Control on a page with double buffering causes problemsmemberbkausbk5 Feb '06 - 23:41 
Thank you for reporting this. It seems that WS_EX_COMPOSITED causes problems in conjunction with List controls and Resize Map. May be I'll remove this Double Buffering feature.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 12 Mar 2007
Article Copyright 2005 by bkausbk
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid