Hi Stephen ,
First of all thank you for your replies.
The checked the form print preview mode and is also not rendering correctly.
The chunk width is getting too small. So there are more chunks in print
preview than design or running mode in forms. i am including the code which
we used to implement the progress bar control.
Below is the OnDraw function of the progress control. its actually calling
its base call version
/////////////////////////////////////////////////////////////////////////////
// CprogCtrl::OnDraw - Drawing function
void CprogCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
CBaseCtrl::OnDraw(pdc,rcBounds,rcInvalid);
}
And this is the base class implemenation of CBaseCtrl::OnDraw
In which we check whether its print preview or not using the
iTechCaps==DT_RASPRINTER
condition.
/////////////////////////////////////////////////////////////////////////////
// CBaseCtrl::OnDraw - Drawing function
void CBaseCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect&
rcInvalid)
{
//assume mm_text since we are ui active, don't assume 0,0 though
int iTechCaps = pdc->GetDeviceCaps(TECHNOLOGY);
CRect rcNewBounds = rcBounds;
UINT nEdge = 0;
int iLogInch = pdc->GetDeviceCaps(LOGPIXELSX);
//going to screen, so 1 pixel is 1 pixel
m_iPixelSize = 1;
//O.K. Access no longer implements OnDrawMetafile.
//We now need to check for Raster printer.
if (iTechCaps == DT_RASPRINTER)
{
CClientDC dcScreen(NULL);
m_iPixelSize = (float) pdc->GetDeviceCaps(LOGPIXELSX) /
dcScreen.GetDeviceCaps(LOGPIXELSX);
CSize szW;
szW = pdc->GetWindowExt();
pdc->SetViewportExt(szW.cx,szW.cy);
DrawMe(pdc,rcNewBounds);// calls derived implementation CprogCtrl:
rawMe
}
else
{
// call virtual function DrawMe
DoDrawOffScreen(pdc,rcNewBounds,rcInvalid);
}
}
Here is the code for void CBaseCtrl:
oDrawOffScreen
/////////////////////////////////////////////////////////////////////////////
// CBaseCtrl:
oDrawOffScreen - Drawing function
void CBaseCtrl:
oDrawOffScreen(CDC* pdc, const CRect& rcBounds,const CRect&
rcInvalid)
{
CDC dcMem;
CBitmap bitOff;
CRect rcBoundsDP(rcBounds) ;
CRect rcInvalidDP(rcInvalid) ;
// Convert bounds to pixels.
pdc->LPtoDP(&rcBoundsDP) ;
pdc->LPtoDP(&rcInvalidDP) ;
// Create a DC that is compatible with the screen.
dcMem.CreateCompatibleDC(pdc) ;
// The bitmap bounds have 0,0 in the upper-left corner.
CRect rcBitmapBounds( 0,0,
rcBoundsDP.Width(),
rcBoundsDP.Height()) ;
// Create a really compatible bitmap.
bitOff.CreateBitmap(rcBitmapBounds.Width(),
rcBitmapBounds.Height(),
pdc->GetDeviceCaps(PLANES),
pdc->GetDeviceCaps(BITSPIXEL),
NULL) ;
// Select the bitmap into the memory DC.
CBitmap* pOldBitmap = dcMem.SelectObject(&bitOff) ;
// Save the memory DC state, since DrawMe might change it.
int iSavedDC = dcMem.SaveDC();
// Draw our control on the memory DC.
DrawMe(&dcMem, rcBitmapBounds) ;
// Restore the DC, since DrawMe might have changed mapping modes.
dcMem.RestoreDC(iSavedDC) ;
// We don't know what mapping mode pdc is using.
// BitBlt uses logical coordinates.
// Easiest thing is to change to MM_TEXT.
pdc->SetMapMode(MM_TEXT) ;
pdc->SetWindowOrg(0,0) ;
pdc->SetViewportOrg(0,0) ;
// Blt the memory DC to the screen.
pdc->BitBlt( rcInvalidDP.left,
rcInvalidDP.top,
rcInvalidDP.Width(),
rcInvalidDP.Height(),
&dcMem,
rcInvalidDP.left - rcBoundsDP.left,
rcInvalidDP.top - rcBoundsDP.top,
SRCCOPY) ;
// Clean up.
dcMem.SelectObject(pOldBitmap) ;
}
The Derive class(CprogCtrl) implementation for DrawMe is as follows,
which calls XP style drawing function such as
DrawLeftHorizontalWinXPBar(pdc,rcBar,percent)
in which m_hTheme is a handle in CThemeXp class to the dll.CThemeXp is
wrapper around the
UxTheme library.m_hTheme.DrawBackground is a function pointer to DLL's
DrawThemeBackground
function whose address is got through GetProcAddress.
/////////////////////////////////////////////////////////////////////////////
// CprogCtrl:
rawMe - Drawing function
void CprogCtrl:
rawMe(CDC *pdc,const CRect &rcBounds)
{
CBrush brBackColor(TranslateColor(GetBackColor()));
pdc->FillRect(rcBounds, &brBackColor);
long nValue = m_lValue;
long nMax = m_lMax;
long nMin = m_lMin;
long nRange = m_lMax - m_lMin;
float percent = ((float)nValue - nMin) / (float)nRange;
if (m_iOrientation == cHorizontal)
{
CRect rcBar(rcBounds);
rcBar.InflateRect(-1,-1);
if (m_iFillStyle == cLeft)
DrawLeftHorizontalWinXPBar(pdc,rcBar,percent);
else
DrawRightHorizontalWinXPBar(pdc,rcBar,percent);
}
else//vertical
{
CRect rcBar(rcBounds);
rcBar.InflateRect(-1,-1);
if (m_iFillStyle == cLeft)
DrawBottomVerticalWinXPBar(pdc,rcBar,percent);
else
DrawTopVerticalWinXPBar(pdc,rcBar,percent);
}
}
/////////////////////////////////////////////////////////////////////////////
// CprogCtrl:
rawLeftHorizontalWinXPBar - Drawing function
void CprogCtrl:
rawLeftHorizontalWinXPBar(CDC* pdc, const CRect
&rcProgress,const float percent)
{
BOOL bThemeAvailable = FALSE;
bTheme = m_hTheme.IsAvailable();
if(bThemeAvailable)
{
RECT rcClip;
RECT rcBar;
rcBar.left = rcProgress.left + m_iPixelSize;
rcBar.top = rcProgress.top + m_iPixelSize;
rcBar.right =rcProgress.right - m_iPixelSize;
rcBar.bottom =rcProgress.bottom - m_iPixelSize;
int iWidth = rcBar.right - rcBar.left;
rcClip.left = rcBar.left;
rcClip.top = rcBar.top;
rcClip.right = rcBar.left + iWidth*percent;
rcClip.bottom = rcBar.bottom;
//Draw the background and bar using these rectangles.
//Draw the background and bar using these rectangles.
bThemeAvailable = m_hTheme.Open(GetSafeHwnd(), L"PROGRESS");
m_hTheme.DrawBackground(pdc->GetSafeHdc(),PP_BAR,0, &rcProgress,NULL);
m_hTheme.DrawBackground(pdc->GetSafeHdc(),PP_CHUNK,0, &rcBar,&rcClip);
m_hTheme.Close();
}
}