Click here to Skip to main content
Click here to Skip to main content
Articles » Multimedia » GDI » General » Downloads
 
Add your own
alternative version

QuickFill: An efficient flood fill algorithm.

, 12 Mar 2004
Design and implimentation of efficient flood fill algorithms.
quickfilldemo_demo.zip
QuickFillDemo.exe
quickfilldemo_src.zip
CDibData
Doxygen.dat
CQuantize
QuickFill
test.bmp
QuickFillDemo
Debug
QuickFillDemo.clw
QuickFillDemo.dsp
QuickFillDemo.dsw
Release
res
bitmap1.bmp
bmp00001.bmp
bmp00002.bmp
bmp00003.bmp
bmp00004.bmp
checker.bmp
checker2.bmp
circle.bmp
clubs.bmp
cross.bmp
dchecker.bmp
diamon.bmp
dimonds.bmp
hart.bmp
it.bmp
ldiag.bmp
ne.bmp
nw.bmp
QuickFillDemo.ico
QuickFillDemoDoc.ico
rdiag.bmp
schecker.bmp
scircle.bmp
se.bmp
spades.bmp
square.bmp
sw.bmp
x.bmp
xsquare.bmp
// QuickFillDemoView.cpp : implementation of the CQuickFillDemoView class
//

#include "stdafx.h"
#include "QuickFillDemo.h"
#include "MainFrm.h"

#include "QuickFillDemoDoc.h"
#include "QuickFillDemoView.h"
#include "DlgMasks.h"

#pragma warning( disable : 4201 )
#include <Mmsystem.h>
#pragma warning( default : 4201 )

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

static const LG_MAXMAG = 10;
static const LG_SELPENWIDTH = 3;

/////////////////////////////////////////////////////////////////////////////
// CQuickFillDemoView

IMPLEMENT_DYNCREATE(CQuickFillDemoView, CScrollView)

BEGIN_MESSAGE_MAP(CQuickFillDemoView, CScrollView)
	//{{AFX_MSG_MAP(CQuickFillDemoView)
	ON_WM_ERASEBKGND()
	ON_WM_LBUTTONDOWN()
	ON_COMMAND(ID_OPENPATTERN, OnOpenpattern)
	ON_UPDATE_COMMAND_UI(ID_OPENPATTERN, OnUpdateOpenpattern)
	ON_COMMAND(ID_SLOWMODE, OnSlowmode)
	ON_UPDATE_COMMAND_UI(ID_SLOWMODE, OnUpdateSlowmode)
	ON_COMMAND(ID_FILLCOLOR, OnFillcolor)
	ON_UPDATE_COMMAND_UI(ID_FILLCOLOR, OnUpdateFillcolor)
	ON_COMMAND(ID_PATTERNCLEARCOLOR, OnPatternclearcolor)
	ON_UPDATE_COMMAND_UI(ID_PATTERNCLEARCOLOR, OnUpdatePatternclearcolor)
	ON_COMMAND(ID_CLOSEPATTERN, OnClosepattern)
	ON_UPDATE_COMMAND_UI(ID_CLOSEPATTERN, OnUpdateClosepattern)
	ON_COMMAND(ID_VIEW_MAG1, OnViewMag1)
	ON_UPDATE_COMMAND_UI(ID_VIEW_MAG1, OnUpdateViewMag1)
	ON_COMMAND(ID_VIEW_MAG2, OnViewMag2)
	ON_UPDATE_COMMAND_UI(ID_VIEW_MAG2, OnUpdateViewMag2)
	ON_COMMAND(ID_VIEW_MAG3, OnViewMag3)
	ON_UPDATE_COMMAND_UI(ID_VIEW_MAG3, OnUpdateViewMag3)
	ON_COMMAND(ID_VIEW_MAG4, OnViewMag4)
	ON_UPDATE_COMMAND_UI(ID_VIEW_MAG4, OnUpdateViewMag4)
	ON_COMMAND(ID_VIEW_MAG5, OnViewMag5)
	ON_UPDATE_COMMAND_UI(ID_VIEW_MAG5, OnUpdateViewMag5)
	ON_COMMAND(ID_VIEW_MAG6, OnViewMag6)
	ON_UPDATE_COMMAND_UI(ID_VIEW_MAG6, OnUpdateViewMag6)
	ON_COMMAND(ID_VIEW_MAG7, OnViewMag7)
	ON_UPDATE_COMMAND_UI(ID_VIEW_MAG7, OnUpdateViewMag7)
	ON_COMMAND(ID_VIEW_MAG8, OnViewMag8)
	ON_UPDATE_COMMAND_UI(ID_VIEW_MAG8, OnUpdateViewMag8)
	ON_COMMAND(ID_VIEW_MAG9, OnViewMag9)
	ON_UPDATE_COMMAND_UI(ID_VIEW_MAG9, OnUpdateViewMag9)
	ON_COMMAND(ID_VIEW_MAG10, OnViewMag10)
	ON_UPDATE_COMMAND_UI(ID_VIEW_MAG10, OnUpdateViewMag10)
	ON_COMMAND(ID_FILLMASK, OnFillmask)
	ON_UPDATE_COMMAND_UI(ID_FILLMASK, OnUpdateFillmask)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_COMMAND(ID_SHOWREVISIT, OnShowrevisit)
	ON_UPDATE_COMMAND_UI(ID_SHOWREVISIT, OnUpdateShowrevisit)
	//}}AFX_MSG_MAP
	ON_UPDATE_COMMAND_UI(ID_INDICATOR_POS, OnUpdatePos)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CQuickFillDemoView construction/destruction

CQuickFillDemoView::CQuickFillDemoView() :
	m_rcPos(4,4,4,4), m_nMag(2)
{
	m_clrFill = RGB(255,0,0);
	m_dSeconds = 0.0;		// Fill time in miliseconds.
	memset(&m_AnchorPoint,0,sizeof(m_AnchorPoint));
	memset(&m_rcSelect,0,sizeof(m_rcSelect));
	m_bSelected = m_bSelecting = FALSE;
}

CQuickFillDemoView::~CQuickFillDemoView()
{
}

BOOL CQuickFillDemoView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CScrollView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CQuickFillDemoView drawing

void CQuickFillDemoView::DrawSelectRect(CDC* pDC)
{
	// Draw selection rectangle
	if( pDC && m_bSelected )
	{
		CPen whitePen(PS_SOLID, LG_SELPENWIDTH, RGB(128, 128, 128));
		CPen* pOldPen = pDC->SelectObject(&whitePen);
		CGdiObject* pOldBrush = pDC->SelectStockObject(NULL_BRUSH);
		int nOldMode = pDC->SetROP2(R2_XORPEN);

		m_rcSelect.InflateRect(0,0,LG_SELPENWIDTH,LG_SELPENWIDTH);
		pDC->Rectangle(&m_rcSelect);
		m_rcSelect.InflateRect(0,0,-LG_SELPENWIDTH,-LG_SELPENWIDTH);
		
		pDC->SetROP2(nOldMode);
		pDC->SelectObject(pOldBrush);
		pDC->SelectObject(pOldPen);
	}
}

void CQuickFillDemoView::OnDraw(CDC* pDC)
{
	CQuickFillDemoDoc* pDoc = GetDocument();

	// TODO: add draw code for native data here
	BITMAP bm;
	CDC dcTemp;
	
	if( pDoc
		&& pDoc->m_Bitmap.GetSafeHandle() // avoid assertion
		&& pDoc->m_Bitmap.GetBitmap(&bm)
		&& dcTemp.CreateCompatibleDC(pDC) )
	{
		CBitmap* pOldBitmap = dcTemp.SelectObject(&pDoc->m_Bitmap);
		if( pOldBitmap )
		{
			CDC dcGrid;
			CBitmap bmpGrid, *pOldBmpGrid = NULL;
			if( m_nMag < 4
				|| !dcGrid.CreateCompatibleDC(&dcTemp)
				|| !bmpGrid.CreateCompatibleBitmap(
						&dcTemp, m_rcPos.Width(), m_rcPos.Height())
				// ignore warning C4706 here
				|| !(pOldBmpGrid=dcGrid.SelectObject(&bmpGrid)) )
			{
				pDC->StretchBlt(
					m_rcPos.left, m_rcPos.top,
					m_rcPos.Width(), m_rcPos.Height(),
					&dcTemp, 0, 0, bm.bmWidth, bm.bmHeight,
					SRCCOPY);
				dcTemp.SelectObject(pOldBitmap);
				DrawSelectRect(pDC);
			}
			else
			{
				// Copy to grid DC
				dcGrid.StretchBlt(
					0, 0, m_rcPos.Width(), m_rcPos.Height(),
					&dcTemp, 0, 0, bm.bmWidth, bm.bmHeight,
					SRCCOPY);
				dcTemp.SelectObject(pOldBitmap);

				// Draw grid lines
				CPen sepPen(PS_SOLID, 1, RGB(0x80, 0x80, 0x80));
				CPen* pOldPen = dcGrid.SelectObject(&sepPen);
				int bottom = m_rcPos.Height() - 1;
				int right = m_rcPos.Width() - 1;
				for( int x = 0; x <= right; x += m_nMag )

				{
					dcGrid.MoveTo(x, 0);
					dcGrid.LineTo(x, bottom);
				}
				for( int y = 0; y <= bottom; y += m_nMag )
				{
					dcGrid.MoveTo(0, y);
					dcGrid.LineTo(right, y);
				}

				dcGrid.SelectObject(pOldPen);

				DrawSelectRect(&dcGrid);

				// Copy grid to client DC
				pDC->BitBlt(
					m_rcPos.left, m_rcPos.top,
					m_rcPos.Width(), m_rcPos.Height(),
					&dcGrid, 0, 0, SRCCOPY);

				dcGrid.SelectObject(pOldBmpGrid);
			}

			// Exclude bitmap area from furthur drawing
			pDC->ExcludeClipRect(&m_rcPos);
		}
	}

#ifdef QUICKFILL_TEST
	// Show progress info
	int x = m_rcPos.right + 8, y = m_rcPos.top;
	//x += GetScrollPos(SB_HORZ);
	//y += GetScrollPos(SB_VERT);
	CString csInfo;
	CSize size;
	pDC->SetBkColor(::GetSysColor(COLOR_WINDOW));
	csInfo.Format(_T("Seconds: %lf"),m_dSeconds);
	size = pDC->TabbedTextOut(x, y, csInfo, 0, NULL, 0);
	pDC->ExcludeClipRect(x, y, x + size.cx, y + size.cy);
	y += 20;
	csInfo.Format(_T("Current Stack Size: %d"),m_Fill.GetStackSize());
	size = pDC->TabbedTextOut(x, y, csInfo, 0, NULL, 0);
	pDC->ExcludeClipRect(x, y, x + size.cx, y + size.cy);
	y += 20;
	csInfo.Format(_T("Maximum Stack Size: %d"),m_Fill.GetMaxStackSize());
	size = pDC->TabbedTextOut(x, y, csInfo, 0, NULL, 0);
	pDC->ExcludeClipRect(x, y, x + size.cx, y + size.cy);
	y += 20;
	csInfo.Format(_T("Visit List Size: %d"),m_Fill.GetVisitSize());
	size = pDC->TabbedTextOut(x, y, csInfo, 0, NULL, 0);
	pDC->ExcludeClipRect(x, y, x + size.cx, y + size.cy);
	y += 20;
	csInfo.Format(_T("Current Line: %d"),m_Fill.GetCurrentLine());
	size = pDC->TabbedTextOut(x, y, csInfo, 0, NULL, 0);
	pDC->ExcludeClipRect(x, y, x + size.cx, y + size.cy);
	y += 20;
	csInfo.Format(_T("Pixels Revisited: %d"),m_Fill.GetRevisitCount());
	size = pDC->TabbedTextOut(x, y, csInfo, 0, NULL, 0);
	pDC->ExcludeClipRect(x, y, x + size.cx, y + size.cy);
	y += 20;
	if( m_Fill.GetDirection() < 0 )
	{
		csInfo = _T("Direction: Up");
		size = pDC->TabbedTextOut(x, y, csInfo, 0, NULL, 0);
		pDC->ExcludeClipRect(x, y, x + size.cx, y + size.cy);
		y += 20;
	}
	else if( m_Fill.GetDirection() > 0 )
	{
		csInfo = _T("Direction: Down");
		size = pDC->TabbedTextOut(x, y, csInfo, 0, NULL, 0);
		pDC->ExcludeClipRect(x, y, x + size.cx, y + size.cy);
		y += 20;
	}
#endif


	// Draw background
	CRect rcClient;
	pDC->GetClipBox(&rcClient);
	pDC->FillSolidRect(
		rcClient.left,rcClient.top,
		rcClient.Width(),rcClient.Height(),
		::GetSysColor(COLOR_WINDOW));
}

void CQuickFillDemoView::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();

	CSize sizeTotal;
	CQuickFillDemoDoc* pDoc = GetDocument();
	
	if( m_nMag < 1 ) // simple safety
		m_nMag = 1;

	BITMAP bm;
	if(  pDoc
		&& pDoc->m_Bitmap.GetSafeHandle() // avoid assertion
		&& pDoc->m_Bitmap.GetBitmap(&bm) )
	{
		m_rcPos.SetRect(m_rcPos.left, m_rcPos.top,
			m_rcPos.left + m_nMag * bm.bmWidth,
			m_rcPos.top + m_nMag * bm.bmHeight);
	}
	sizeTotal.cx = m_rcPos.Width() + 2 * m_rcPos.left;
	sizeTotal.cy = m_rcPos.Height() + 2 * m_rcPos.top;
	SetScrollSizes(MM_TEXT, sizeTotal);
}

/////////////////////////////////////////////////////////////////////////////
// CQuickFillDemoView diagnostics

#ifdef _DEBUG
void CQuickFillDemoView::AssertValid() const
{
	CScrollView::AssertValid();
}

void CQuickFillDemoView::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}

CQuickFillDemoDoc* CQuickFillDemoView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CQuickFillDemoDoc)));
	return (CQuickFillDemoDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
//
void CQuickFillDemoView::Magnify(int nMag)
{
	if( 0 < nMag && nMag <= LG_MAXMAG )
	{
		CSize sizeTotal;
		CQuickFillDemoDoc* pDoc = GetDocument();

		BITMAP bm;
		if(  pDoc
			&& pDoc->m_Bitmap.GetSafeHandle() // avoid assertion
			&& pDoc->m_Bitmap.GetBitmap(&bm) )
		{
			m_rcPos.SetRect(m_rcPos.left, m_rcPos.top,
				m_rcPos.left + nMag * bm.bmWidth,
				m_rcPos.top + nMag * bm.bmHeight);
			if( m_bSelected )
				m_bSelected = FALSE;
		}
		sizeTotal.cx = m_rcPos.Width()  + 2 * m_rcPos.left;
		sizeTotal.cy = m_rcPos.Height() + 2 * m_rcPos.top;
		SetScrollSizes(MM_TEXT, sizeTotal);

		m_nMag = nMag;
		Invalidate();
	}
}

/////////////////////////////////////////////////////////////////////////////
// CQuickFillDemoView message handlers

BOOL CQuickFillDemoView::OnEraseBkgnd(CDC* /*pDC*/) 
{
	// TODO: Add your message handler code here and/or call default
	
	//return CScrollView::OnEraseBkgnd(pDC);
	return TRUE;
}

void CQuickFillDemoView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CPoint pt = point;
	pt.x += GetScrollPos(SB_HORZ);
	pt.y += GetScrollPos(SB_VERT);
	if( !m_bSelected )
	{
		m_AnchorPoint = pt;
		m_bSelecting  = FALSE;
	}
	else
	{
		m_rcSelect.InflateRect(0,0,LG_SELPENWIDTH,LG_SELPENWIDTH);
		if( m_rcSelect.PtInRect(pt) )
			m_rcSelect.InflateRect(0,0,-LG_SELPENWIDTH,-LG_SELPENWIDTH);
		else
		{
			m_rcSelect.InflateRect(0,0,-LG_SELPENWIDTH,-LG_SELPENWIDTH);
			m_AnchorPoint = pt;
			m_bSelecting  = FALSE;
			m_bSelected   = FALSE;
			::ReleaseCapture();
			InvalidateRect(&m_rcPos);
			UpdateWindow();
		}
	}
	CScrollView::OnLButtonDown(nFlags, point);
}

void CQuickFillDemoView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if( m_bSelecting )
	{
		m_bSelecting = FALSE;
		::ReleaseCapture();
		CScrollView::OnLButtonUp(nFlags, point);
		return;
	}

	CQuickFillDemoDoc* pDoc = GetDocument();

	// Get adjusted rectangle - compensates for scrolled DC
	CRect rc = m_rcPos;
	if( m_bSelected )
	{
		rc = m_rcSelect;
		rc.InflateRect(0,0,LG_SELPENWIDTH,LG_SELPENWIDTH);
	}
	rc.OffsetRect(-GetScrollPos(SB_HORZ), -GetScrollPos(SB_VERT));
	if( pDoc
		&& pDoc->m_Bitmap.GetSafeHandle()
		&& pDoc->m_BitmapBackup.GetSafeHandle()
		&& rc.PtInRect(point) )
	{
		rc = m_rcPos;
		rc.OffsetRect(-GetScrollPos(SB_HORZ), -GetScrollPos(SB_VERT));

		// restore backup
		CDC dc1, dc2;
		BITMAP bm;
		pDoc->m_Bitmap.GetBitmap(&bm);
		dc1.CreateCompatibleDC(NULL);
		CBitmap* old1 = dc1.SelectObject(&pDoc->m_Bitmap);
		dc2.CreateCompatibleDC(&dc1);
		CBitmap* old2 = dc2.SelectObject(&pDoc->m_BitmapBackup);
		dc1.BitBlt(0,0,bm.bmWidth,bm.bmHeight,&dc2,0,0,SRCCOPY);
		dc1.SelectObject(old1);
		dc2.SelectObject(old2);
		dc1.DeleteDC();
		dc2.DeleteDC();
		InvalidateRect(&m_rcPos);

		if( m_nMag < 1 ) // simple safety
			m_nMag = 1;

		// Start timing
		TIMECAPS timeCaps = { 0U, 0U };
		timeGetDevCaps(&timeCaps,sizeof(timeCaps));
		timeBeginPeriod(timeCaps.wPeriodMin);
		DWORD dwTime = timeGetTime();
		
		// Quick fill image
		if( m_bSelected )
		{
			CRect rcSelect = m_rcSelect;
			rcSelect.OffsetRect(-rc.left,-rc.top);
			rcSelect.OffsetRect(-GetScrollPos(SB_HORZ), -GetScrollPos(SB_VERT));
			rcSelect.InflateRect(-m_nMag,-m_nMag,0,0);
			rcSelect.left   /= m_nMag;
			rcSelect.top    /= m_nMag;
			rcSelect.right  /= m_nMag;
			rcSelect.bottom /= m_nMag;
			m_Fill.QuickFill(
				&pDoc->m_Bitmap, &rcSelect,
				(point.x - rc.left)/m_nMag,
				(point.y - rc.top )/m_nMag,
				m_clrFill);
		}
		else
		{
			m_Fill.QuickFill(
				&pDoc->m_Bitmap,
				(point.x - rc.left)/m_nMag,
				(point.y - rc.top )/m_nMag,
				m_clrFill);
		}

		// Stop timing
		m_dSeconds = timeGetTime() - dwTime;
		if( timeCaps.wPeriodMin )
			m_dSeconds /= (1000/timeCaps.wPeriodMin);
		timeEndPeriod(1);

		// Show result
		Invalidate();
	}
	CScrollView::OnLButtonUp(nFlags, point);
}

void CQuickFillDemoView::OnMouseMove(UINT nFlags, CPoint point) 
{
	CStatusBar* pStat = NULL;
	CMainFrame* pFrame = DYNAMIC_DOWNCAST(CMainFrame,AfxGetApp()->m_pMainWnd);
	if( pFrame )
		pStat = pFrame->GetStatusBar();
	if( pStat )
	{
		if( GetDocument() && m_rcPos.PtInRect(point) )
		{
			// Update position pane on status bar
			CRect rc = m_rcPos;
			rc.OffsetRect(-GetScrollPos(SB_HORZ), -GetScrollPos(SB_VERT));
			CString strPos;
			strPos.Format( _T("%d, %d"),
				(point.x - rc.left)/m_nMag,
				(point.y - rc.top)/m_nMag );
			pStat->SetPaneText(pStat->CommandToIndex(ID_INDICATOR_POS),strPos);

			if( !(nFlags & MK_LBUTTON) )
			{
				m_bSelecting = FALSE;
			}
			else
			{
				// Update selection rectangle if mouse cursor has moved
				if( !m_bSelected )
				{
					rc.SetRect(m_AnchorPoint,m_AnchorPoint);
					rc.InflateRect(2,2);
					m_bSelecting = !rc.PtInRect(point);
				}
				else
				{
					InvalidateRect(&m_rcPos);
				}
			}
		}
		else
		{
			pStat->SetPaneText(pStat->CommandToIndex(ID_INDICATOR_POS),_T("0, 0"));
			if( m_bSelecting )
				m_bSelecting = m_bSelecting; // break here
		}

		if( nFlags & MK_LBUTTON )
		{
			if( m_bSelecting )
			{
				SetCapture();
				m_bSelected = TRUE;
				CPoint pt = point;
				pt.x += GetScrollPos(SB_HORZ);
				pt.y += GetScrollPos(SB_VERT);
				m_rcSelect.SetRect(m_AnchorPoint,pt);
				m_rcSelect.NormalizeRect();
				
				if( point.x < m_rcPos.left )
					m_rcSelect.left = m_rcPos.left;
				else if( point.x > m_rcPos.right )
					m_rcSelect.right = m_rcPos.right;
				if( point.y < m_rcPos.top )
					m_rcSelect.top = m_rcPos.top;
				else if( point.y > m_rcPos.bottom )
					m_rcSelect.bottom = m_rcPos.bottom;

				// Adjust selection rectangle based on magnification
				m_rcSelect.OffsetRect(-m_rcPos.left,-m_rcPos.top);
				m_rcSelect.left   = m_nMag * (m_rcSelect.left/m_nMag);
				m_rcSelect.top    = m_nMag * (m_rcSelect.top /m_nMag);
				m_rcSelect.right  = m_nMag * ((m_rcSelect.right +m_nMag-1)/m_nMag);
				m_rcSelect.bottom = m_nMag * ((m_rcSelect.bottom+m_nMag-1)/m_nMag);
				m_rcSelect.OffsetRect(m_rcPos.left,m_rcPos.top);
			}

			if( m_bSelected )
			{
				InvalidateRect(&m_rcPos);
				UpdateWindow();
			}
		}
	}
	CScrollView::OnMouseMove(nFlags, point);
}

void CQuickFillDemoView::OnOpenpattern() 
{
	CFileDialog dlgFile(TRUE,_T("bmp"),NULL,
		OFN_HIDEREADONLY | OFN_ENABLESIZING | OFN_FILEMUSTEXIST,
		_T("Bitmap Files (*.bmp)|*.bmp||"));
	if( IDOK == dlgFile.DoModal() )
		m_Fill.SetPatternBitmap(dlgFile.GetFileName());
}

void CQuickFillDemoView::OnUpdateOpenpattern(CCmdUI* pCmdUI) 
{
	CQuickFillDemoDoc* pDoc = GetDocument();
	pCmdUI->Enable( pDoc && pDoc->m_Bitmap.GetSafeHandle() );
}

void CQuickFillDemoView::OnSlowmode() 
{
#ifdef QUICKFILL_SLOW
	m_Fill.SetSlowMode(!m_Fill.IsSlowMode());
#endif
}

void CQuickFillDemoView::OnUpdateSlowmode(CCmdUI* pCmdUI) 
{
#ifdef QUICKFILL_SLOW
	pCmdUI->Enable();
	pCmdUI->SetCheck(m_Fill.IsSlowMode());
#else
	pCmdUI->Enable(FALSE);
#endif
}

void CQuickFillDemoView::OnFillcolor() 
{
	CColorDialog dlg(m_clrFill);
	if( IDOK == dlg.DoModal() )
		m_clrFill = dlg.GetColor();
}

void CQuickFillDemoView::OnUpdateFillcolor(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(!m_Fill.HasPattern());
}

void CQuickFillDemoView::OnPatternclearcolor() 
{
	CColorDialog dlg(m_Fill.GetPatternClearColor());
	if( IDOK == dlg.DoModal() )
		m_Fill.SetPatternClearColor(dlg.GetColor());
}

void CQuickFillDemoView::OnUpdatePatternclearcolor(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(m_Fill.HasPattern());
}

void CQuickFillDemoView::OnClosepattern() 
{
	// Frees pattern bitmap and invalidates pattern clear color.
	m_Fill.SetPatternBitmap();
}

void CQuickFillDemoView::OnUpdateClosepattern(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(m_Fill.HasPattern());
}

void CQuickFillDemoView::OnViewMag1() 
{
	Magnify(1);
}

void CQuickFillDemoView::OnUpdateViewMag1(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(1 <= LG_MAXMAG);
	pCmdUI->SetCheck(m_nMag==1);
}

void CQuickFillDemoView::OnViewMag2() 
{
	Magnify(2);
}

void CQuickFillDemoView::OnUpdateViewMag2(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(2 <= LG_MAXMAG);
	pCmdUI->SetCheck(m_nMag==2);
}

void CQuickFillDemoView::OnViewMag3() 
{
	Magnify(3);
}

void CQuickFillDemoView::OnUpdateViewMag3(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(3 <= LG_MAXMAG);
	pCmdUI->SetCheck(m_nMag==3);
}

void CQuickFillDemoView::OnViewMag4() 
{
	Magnify(4);
}

void CQuickFillDemoView::OnUpdateViewMag4(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(4 <= LG_MAXMAG);
	pCmdUI->SetCheck(m_nMag==4);
}

void CQuickFillDemoView::OnViewMag5() 
{
	Magnify(5);
}

void CQuickFillDemoView::OnUpdateViewMag5(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(5 <= LG_MAXMAG);
	pCmdUI->SetCheck(m_nMag==5);
}

void CQuickFillDemoView::OnViewMag6() 
{
	Magnify(6);
}

void CQuickFillDemoView::OnUpdateViewMag6(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(6 <= LG_MAXMAG);
	pCmdUI->SetCheck(m_nMag==6);
}

void CQuickFillDemoView::OnViewMag7() 
{
	Magnify(7);
}

void CQuickFillDemoView::OnUpdateViewMag7(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(7 <= LG_MAXMAG);
	pCmdUI->SetCheck(m_nMag==7);
}

void CQuickFillDemoView::OnViewMag8() 
{
	Magnify(8);
}

void CQuickFillDemoView::OnUpdateViewMag8(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(8 <= LG_MAXMAG);
	pCmdUI->SetCheck(m_nMag==8);
}

void CQuickFillDemoView::OnViewMag9() 
{
	Magnify(9);
}

void CQuickFillDemoView::OnUpdateViewMag9(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(9 <= LG_MAXMAG);
	pCmdUI->SetCheck(m_nMag==9);
}

void CQuickFillDemoView::OnViewMag10() 
{
	Magnify(10);
}

void CQuickFillDemoView::OnUpdateViewMag10(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(10 <= LG_MAXMAG);
	pCmdUI->SetCheck(m_nMag==10);
}

void CQuickFillDemoView::OnFillmask() 
{
	// TODO: Add your command handler code here
	CDlgMasks dlg;
	if( dlg.DoModal() == IDOK )
	{
		BYTE mask[8];
		if( dlg.GetMask(mask,sizeof(mask)) )
			m_Fill.SetFillMask(mask);
	}
}

void CQuickFillDemoView::OnUpdateFillmask(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable();
}

void CQuickFillDemoView::OnUpdatePos(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable();
}

void CQuickFillDemoView::OnShowrevisit() 
{
#ifdef QUICKFILL_TEST
	m_Fill.SetShowRevisit(!m_Fill.GetShowRevisitFlag());
#endif
}

void CQuickFillDemoView::OnUpdateShowrevisit(CCmdUI* pCmdUI) 
{
#ifdef QUICKFILL_TEST
	pCmdUI->Enable();
	pCmdUI->SetCheck(m_Fill.GetShowRevisitFlag()?1:0);
#endif
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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

Share

About the Author

John R. Shaw
Software Developer
United States United States
I am a senior software engineer who has been designing and developing software for many years, mostly in C/C++. You might say that I think in code; which is why I am passionate about my first rule of coding: “First do no harm”. So if I get carried away in my explanations, please realize that it is just part of my personality. I enjoy learning new things and, when I have the time, passing that knowledge onto others.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141220.1 | Last Updated 13 Mar 2004
Article Copyright 2004 by John R. Shaw
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid