ActiveX Ctrl AND CMemDC flickerfree drawing
Hi,
I want to use the CMemDC class from codeproject:
http://www.codeproject.com/KB/GDI/flickerfree.aspx?msg 91984
to create a flickerfree drawing in the OnDraw of my ActiveX control.
I did what was descriped in the article about the CMemDC class.
I have:
void CchessCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
if (!pdc)
return;
CMemDC pDC(pdc,&rcBounds);
DrawBoard(pDC,rcBounds);
}
void CchessCtrl::DrawBoard(CDC* pdc, CRect o_rcBounds)
{
BOOL b_Color;
int n_Rank;
int n_File;
long n_rcBoundsHeight;
long n_FieldHeight;
long n_X;
long n_Y;
CBrush o_WhiteBrush;
CBrush o_BlackBrush;
CBrush* po_Brush;
o_WhiteBrush.CreateSolidBrush(RGB(255,255,255));
o_BlackBrush.CreateSolidBrush(RGB(0,0,0));
n_rcBoundsHeight = o_rcBounds.Height ();
n_FieldHeight = (long) ceil((double)n_rcBoundsHeight / 8.0);
n_Y = 0;
b_Color = 0;
for(n_File = 0;n_File < 8; n_File ++)
{
n_X = 0;
for(n_Rank = 0;n_Rank < 8; n_Rank ++)
{
pdc->Rectangle(n_X,n_Y,n_X+n_FieldHeight,n_Y+n_FieldHeight);
if(b_Color)
po_Brush = &o_WhiteBrush;
else
po_Brush = &o_BlackBrush;
pdc->FillRect (CRect(n_X,n_Y,n_X+n_FieldHeight,n_Y
+n_FieldHeight),po_Brush);
n_X+=n_FieldHeight;
b_Color = !b_Color;
}
n_Y+=n_FieldHeight;
b_Color = !b_Color;
}
}
BOOL CchessCtrl::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return FALSE;
//return COleControl::OnEraseBkgnd(pDC);
}
void CchessCtrl::OnSize(UINT nType, int cx, int cy)
{
COleControl::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
Invalidate(TRUE);
}
i have included the memdc.h in stdafx.h like so:
#pragma once
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // Exclude rarely-used stuff from
Windows headers
#endif
#include "targetver.h"
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString
constructors will be explicit
#include <afxctl.h> // MFC support for ActiveX Controls
#include <afxext.h> // MFC extensions
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h> // MFC support for Internet Explorer 4
Comon Controls
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows
Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
// Delete the two includes below if you do not wish to use the MFC
// database classes
#ifndef _WIN64
#ifndef _AFX_NO_DB_SUPPORT
#include <afxdb.h> // MFC ODBC database classes
#endif // _AFX_NO_DB_SUPPORT
#ifndef _AFX_NO_DAO_SUPPORT
#include <afxdao.h> // MFC DAO database classes
#endif // _AFX_NO_DAO_SUPPORT
#include "memdc.h"
#endif // _WIN64
the CMemDC class:
#ifndef _MEMDC_H_
#define _MEMDC_H_
//////////////////////////////////////////////////
// CMemDC - memory DC
//
// Author: Keith Rule
// Email: keithr@europa.com
// Copyright 1996-2002, Keith Rule
//
// You may freely use or modify this code provided this
// Copyright is included in all derived versions.
//
// History - 10/3/97 Fixed scrolling bug.
// Added print support. - KR
//
// 11/3/99 Fixed most common complaint. Added
// background color fill. - KR
//
// 11/3/99 Added support for mapping modes other than
// MM_TEXT as suggested by Lee Sang Hun. - KR
//
// 02/11/02 Added support for CScrollView as supplied
// by Gary Kirkham. - KR
//
// This class implements a memory Device Context which allows
// flicker free drawing.
class CMemDC : public CDC {
private:
CBitmap m_bitmap; // Offscreen bitmap
CBitmap* m_oldBitmap; // bitmap originally found in CMemDC
CDC* m_pDC; // Saves CDC passed in constructor
CRect m_rect; // Rectangle of drawing area.
BOOL m_bMemDC; // TRUE if CDC really is a Memory DC.
public:
CMemDC(CDC* pDC, const CRect* pRect = NULL) : CDC()
{
ASSERT(pDC != NULL);
// Some initialization
m_pDC = pDC;
m_oldBitmap = NULL;
m_bMemDC = !pDC->IsPrinting();
// Get the rectangle to draw
if (pRect == NULL) {
pDC->GetClipBox(&m_rect);
} else {
m_rect = *pRect;
}
if (m_bMemDC) {
// Create a Memory DC
CreateCompatibleDC(pDC);
pDC->LPtoDP(&m_rect);
m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height
());
m_oldBitmap = SelectObject(&m_bitmap);
SetMapMode(pDC->GetMapMode());
SetWindowExt(pDC->GetWindowExt());
SetViewportExt(pDC->GetViewportExt());
pDC->DPtoLP(&m_rect);
SetWindowOrg(m_rect.left, m_rect.top);
} else {
// Make a copy of the relevent parts of the current DC for printing
m_bPrinting = pDC->m_bPrinting;
m_hDC = pDC->m_hDC;
m_hAttribDC = pDC->m_hAttribDC;
}
// Fill background
FillSolidRect(m_rect, pDC->GetBkColor());
}
~CMemDC()
{
if (m_bMemDC) {
// Copy the offscreen bitmap onto the screen.
m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height
(),
this, m_rect.left, m_rect.top, SRCCOPY);
//Swap back the original bitmap.
SelectObject(m_oldBitmap);
} else {
// All we need to do is replace the DC with an illegal value,
// this keeps us from accidently deleting the handles associated
with
// the CDC that was passed to the constructor.
m_hDC = m_hAttribDC = NULL;
}
}
// Allow usage as a pointer
CMemDC* operator->()
{
return this;
}
// Allow usage as a pointer
operator CMemDC*()
{
return this;
}
};
#endif
If i startup my ActiveX test dialog the control flickers a lot when
resized.
It does not work. What have i done wrong, can someone help please?
Thanks.