Click here to Skip to main content
15,896,453 members
Articles / Programming Languages / Objective C

Applying Observer Pattern in C++ Applications

Rate me:
Please Sign up or sign in to vote.
4.69/5 (27 votes)
8 Jan 2001 158.4K   2.1K   109  
This article explains how to avoid object dependencies using the Observer Pattern with a simple example.
// TimeMon.cpp : implementation of the CTimeMonitor class
//
#include "stdafx.h"
#include "TimeMon.h"

// Predefined event id for timer
#define ID_TIME_MONITOR 0x10012

/////////////////////////////////////////////////////////////////////////////
// CTimeMonitor message handlers

BEGIN_MESSAGE_MAP(CTimeMonitor, CCardioMonitor)
	//{{AFX_MSG_MAP(CTimeMonitor)
		ON_WM_TIMER()
		ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

CTimeMonitor::CTimeMonitor( CCardioSubject * pCardioSubject ) : CCardioMonitor( pCardioSubject )
{
	// Step 1 - Initialize class members
	m_nDuration		= pCardioSubject->GetDuration();
	m_tsElapsedTime	= CTimeSpan( 0, 0, 0, 0 );
}

CTimeMonitor::~CTimeMonitor()
{
}

BOOL CTimeMonitor::Update( CSubject * pSubject )
{
	// Step 1 - Make sure the right subject updates the time monitor
	if( m_pCardioSubject != pSubject )
	{
		return FALSE;
	}
	// Step 2 - Update the window with the elapsed time
	Invalidate();
	return TRUE;
}

BOOL CTimeMonitor::Create( const RECT & rRect, CWnd * pParentWnd, UINT nID )
{
	// Step 1 - Adjust Rectangle
	CRect WndRect = CRect( rRect.left, rRect.top, rRect.left + 140, rRect.top + 120 );
	// Step 2 - Create window
	return CWnd::Create( NULL, NULL, WS_VISIBLE | WS_BORDER | WS_CHILD | WS_TABSTOP, 
		WndRect, pParentWnd, nID );
}

void CTimeMonitor::OnPaint() 
{
	CRect		ClientRect;
	CRect		DrawRect;
	CRect		TitleRect;
	CString	csTitle = "Time Monitor";
	CString	csText1 = "Total     Time";
	CString	csText2 = "Elapsed Time";
	CString	csTotalTime		= itoa( m_nDuration, "           ", 10 ) + CString( ":00" );
	CString	csElapsedTime	= m_tsElapsedTime.Format( "%M:%S" );

	CPaintDC dc(this);

	// Step 1 - Set background color, mode and text color
	GetClientRect( ClientRect );
	dc.FillSolidRect( ClientRect, RGB( 255, 0, 0 ) );
	TitleRect = CRect( ClientRect.left, ClientRect.top, ClientRect.right, ClientRect.top + 30 );
	dc.FillSolidRect( TitleRect, RGB( 0, 128, 128 ) );
	dc.SetBkMode( TRANSPARENT );
	dc.SetTextColor( RGB( 255, 255, 255 ) );

	// Step 2 - Set the text
	DrawRect = CRect( ClientRect.left, ClientRect.top + 5, ClientRect.right, ClientRect.top + 45 );
	dc.DrawText( csTitle, DrawRect, DT_CENTER | DT_WORDBREAK );

	DrawRect = CRect( ClientRect.left + 15, ClientRect.top + 35, ClientRect.left + 80, ClientRect.top + 75 );
	dc.DrawText( csText1, DrawRect, DT_LEFT | DT_WORDBREAK );

	DrawRect = CRect( ClientRect.left + 85, ClientRect.top + 40, ClientRect.left + 135, ClientRect.top + 60 );
	dc.DrawText( csTotalTime, DrawRect, DT_LEFT | DT_WORDBREAK );

	DrawRect = CRect( ClientRect.left + 15, ClientRect.top + 75, ClientRect.left + 80, ClientRect.top + 115 );
	dc.DrawText( csText2, DrawRect, DT_LEFT | DT_WORDBREAK );
	
	DrawRect = CRect( ClientRect.left + 85, ClientRect.top + 80, ClientRect.left + 135, ClientRect.top + 105 );
	dc.DrawText( csElapsedTime, DrawRect, DT_LEFT | DT_WORDBREAK );
}

void CTimeMonitor::OnTimer( UINT nIDEvent ) 
{
	// Step 1 - Timer will be fired every second, so increment the time span every second
	m_tsElapsedTime += CTimeSpan( 0, 0, 0, 1 );
	// Step 2 - Update the cardio subject
	m_pCardioSubject->SetElapsedTime( m_tsElapsedTime );
	// Step 3 - Check if the duration is completed, to stop the timer. Convert 
	// everything to seconds and compare it
	if( m_tsElapsedTime.GetTotalSeconds() >= m_nDuration * 60 )
	{
		Stop();
	}
	CWnd::OnTimer( nIDEvent );
}

BOOL CTimeMonitor::Start()
{
	// Step 1 - Check if the duration is not elapsed to start the timer
	if( m_tsElapsedTime.GetTotalSeconds() < m_nDuration * 60 )
	{
		SetTimer( ID_TIME_MONITOR, 1000, NULL );
		return TRUE;
	}
	return FALSE;
}

VOID CTimeMonitor::Stop()
{
	// Step 1 - Kill the timer
	KillTimer( ID_TIME_MONITOR );
}

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.


Written By
Switzerland Switzerland
Kulathu Sarma is working as a Technology Manager for GoldAvenue, a company based in Geneva, Switzerland and responsible for supporting e-business initiatives of GoldAvenue in B2B and B2C Sectors. He has been programming in C/C++ for 9 years and actively working on Patterns for the past 5 years.

Comments and Discussions