Home > Native Code, UI, Windows Mobile > Scrolling PropertyPage in MFC

Scrolling PropertyPage in MFC

26/11/2008

This piece of code can make a propertyPage scroll smoothly in MFC. It’s really easy to use…

1. CUtil:


#pragma once
#include "IPage.h"

//Indentation to move the window on each scrolling line
// This you can change as per your requirement
#define VERT_PTS 5

class CUtil
{
public:

static void ScrollPage_SetupScrollbars(IPage* pageInterface, CWnd* pageWnd)
{
CRect tempRect;
pageWnd->GetClientRect(&tempRect);
BOOL bMaximized;

//Max Vertical Scrolling is the difference between size
//of the Whole Property Page with Controls and that with
//the current one devided by the Indentation you set

pageInterface->m_nVertInc = (pageInterface->m_ClientRect.Height() - tempRect.Height()) / VERT_PTS;

pageInterface->m_nVscrollMax = max(0, pageInterface->m_nVertInc);
pageInterface->m_nVscrollPos = min(pageInterface->m_nVscrollPos, pageInterface->m_nVscrollMax);
pageWnd->SetScrollRange(SB_VERT, 0, pageInterface->m_nVscrollMax, FALSE);
pageWnd->SetScrollPos(SB_VERT, pageInterface->m_nVscrollPos, TRUE);
};

static void ScrollPage_ResetScrollbars(IPage* pageInterface, CWnd* pageWnd)
{
//Scroll the Window to its initial Position
pageWnd->ScrollWindowEx(    0,
pageInterface->m_nVscrollPos * VERT_PTS,
NULL,
NULL,
NULL,
NULL,
SW_SCROLLCHILDREN /*| SW_INVALIDATE*/
);
pageInterface->m_nVscrollPos = 0;

//Setup and Initialize a Vertical Scroll bar
//You can do the same for Horizontal Scroll bar
pageWnd->SetScrollPos(SB_VERT, pageInterface->m_nVscrollPos, TRUE);
};

static void ScrollPage_OnVScroll(IVihuniPage* pageInterface, CWnd* pageWnd, UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
int nInc; // The Increment required for Scrollbar from Current Position

//Select the Mode of Scrolling and set the Position
//Variables as below
switch (nSBCode)
{
case SB_TOP:
nInc = -pageInterface->m_nVscrollPos;
break;
case SB_BOTTOM:
nInc = pageInterface->m_nVscrollMax - pageInterface->m_nVscrollPos;
break;
case SB_LINEUP:        nInc = -1;                                        break;
case SB_LINEDOWN:   nInc = 1;                                        break;
case SB_PAGEUP:     nInc = min(-1, - pageInterface->m_nVertInc);    break;
case SB_PAGEDOWN:   nInc = max(1, pageInterface->m_nVertInc);        break;
case SB_THUMBTRACK: nInc = nPos - pageInterface->m_nVscrollPos;        break;
default:            nInc = 0;
}

//Fetch the Current Position and set the Increment Variable from
// the Current Position
nInc = max(-pageInterface->m_nVscrollPos, min(nInc, pageInterface->m_nVscrollMax - pageInterface->m_nVscrollPos));

// If the Position is changed ,move the Scrollbar and the Window too
if (nInc)
{
pageInterface->m_nVscrollPos += nInc;
int iMove = -VERT_PTS * nInc;

pageWnd->ScrollWindowEx(0, iMove, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN /*| SW_INVALIDATE*/ );
pageWnd->SetScrollPos(SB_VERT, pageInterface->m_nVscrollPos, TRUE);
}
};
};

2. IPage: the interface that every ScrollPropertyPage must implement:


#pragma once

interface IPage
{
public:
//Define the Variables that will be required for setting
//up a Vertical Scroll bar
int  m_nVertInc,m_nVscrollMax,m_nVscrollPos;

//Initialized the variable for Client Rectangle
CRect m_ClientRect;
};

3. In each ScrollPage, the main part will be:


// ScrollPropertyPage.cpp : implementation file
//

#include "stdafx.h"
#include "ScrollPropertyPage.h"
#include "Util.h"

// CScrollPropertyPage dialog

BEGIN_MESSAGE_MAP(CScrollPropertyPage, CPropertyPage)
ON_WM_VSCROLL()
END_MESSAGE_MAP()

// CScrollPropertyPage message handlers

void CScrollPropertyPage::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
CUtil::ScrollPage_OnVScroll(this, this, nSBCode, nPos, pScrollBar);
CPropertyPage::OnVScroll(nSBCode, nPos, pScrollBar);
}

BOOL CScrollPropertyPage::OnInitDialog()
{
CPropertyPage::OnInitDialog();

// Init for scroll
m_nVscrollPos = 0;
GetClientRect(&m_ClientRect);

//    Lấy bottom của control nằm thấp nhất!
CRect rLast;
GetDlgItem(IDC_BUTTON1)->GetWindowRect(&rLast);
m_ClientRect.bottom    = rLast.bottom + 5;

CHuniUtil::ScrollPage_ResetScrollbars(this, this);
CHuniUtil::ScrollPage_SetupScrollbars(this, this);

return TRUE;  // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

Advertisements
%d bloggers like this: