|
|
Comments and Discussions
|
|
 |

|
This is very nice but I want this article in MFC, Could you please do it?
|
|
|
|

|
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.
|
|
|
|

|
Helped me a lot while taking a transistion from MFC to WTL. Thanks.
Regards
|
|
|
|

|
But your class don't support DoModal() method, you would like to supply?
gg hh
|
|
|
|

|
I have Impl it.
this is the header file:
#ifndef __ATL_RESIZABLE_PROPERTY_SHEET_H__
#define __ATL_RESIZABLE_PROPERTY_SHEET_H__
#pragma once
#ifndef _WTL_NEW_PAGE_NOTIFY_HANDLERS
#define _WTL_NEW_PAGE_NOTIFY_HANDLERS
#endif
#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;
Template- > style &= ~DS_MODALFRAME;
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);
}
virtual BOOL PreTranslateMessage(LPMSG pMsg)
{
if (IsDialogMessage(pMsg)) {
if (!::IsWindow(m_hWnd) || GetActivePage() == NULL) {
PostQuitMessage(0);
}
return TRUE;
}
return FALSE;
}
void SetActiveResizeMap(int MapIdx)
{
if (ResizeMapStart == NULL) {
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)
{
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)
{
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);
}
}
};
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);
if (uMsg == WM_NOTIFY) {
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()
};
};
#endif
Free2000Fly
|
|
|
|

|
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
|
|
|
|

|
Thanks for adding modal support. I added this code to the newest version.
|
|
|
|

|
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
|
|
|
|

|
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.
|
|
|
|

|
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 News Suggestion Question Bug Answer Joke Rant Admin
|
Make Property Sheet/Wizards resizable without much modification.
| Type | Article |
| Licence | |
| First Posted | 22 Feb 2005 |
| Views | 59,515 |
| Downloads | 1,407 |
| Bookmarked | 28 times |
|
|