Click here to Skip to main content
15,891,905 members
Articles / Programming Languages / C#

A simple C# Wave editor, part 1: Background and analysis

Rate me:
Please Sign up or sign in to vote.
4.77/5 (80 votes)
5 Aug 200411 min read 356K   8.2K   132  
The first phase of a RIFF/Wave editing "swiss army knife", in which we'll learn how to extract all the data present in common Wave files and store it in an XML document.
// MMWaveEditXCtl.cpp : Implementation of the CMMWaveEditXCtrl ActiveX Control class.

#include "stdafx.h"
#include "MMWaveEditX.h"
#include "MMWaveEditXCtl.h"
#include "MMWaveEditXPpg.h"


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


IMPLEMENT_DYNCREATE(CMMWaveEditXCtrl, COleControl)


/////////////////////////////////////////////////////////////////////////////
// Message map

BEGIN_MESSAGE_MAP(CMMWaveEditXCtrl, COleControl)
	//{{AFX_MSG_MAP(CMMWaveEditXCtrl)
	ON_WM_MOUSEMOVE()
	ON_WM_TIMER()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_SETCURSOR()
	//}}AFX_MSG_MAP
	ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// Dispatch map

BEGIN_DISPATCH_MAP(CMMWaveEditXCtrl, COleControl)
	//{{AFX_DISPATCH_MAP(CMMWaveEditXCtrl)
	DISP_PROPERTY_EX(CMMWaveEditXCtrl, "Waveform", GetWaveform, SetWaveform, VT_COLOR)
	DISP_PROPERTY_EX(CMMWaveEditXCtrl, "DB", GetDB, SetDB, VT_COLOR)
	DISP_PROPERTY_EX(CMMWaveEditXCtrl, "Divider", GetDivider, SetDivider, VT_COLOR)
	DISP_PROPERTY_EX(CMMWaveEditXCtrl, "ScaleBackround", GetScaleBackround, SetScaleBackround, VT_COLOR)
	DISP_PROPERTY_EX(CMMWaveEditXCtrl, "ScaleTicks", GetScaleTicks, SetScaleTicks, VT_COLOR)
	DISP_PROPERTY_EX(CMMWaveEditXCtrl, "ScaleNumbers", GetScaleNumbers, SetScaleNumbers, VT_COLOR)
	DISP_PROPERTY_EX(CMMWaveEditXCtrl, "MinTickSize", GetMinTickSize, SetMinTickSize, VT_I4)
	DISP_PROPERTY_EX(CMMWaveEditXCtrl, "MajTickSize", GetMajTickSize, SetMajTickSize, VT_I4)
	DISP_PROPERTY_EX(CMMWaveEditXCtrl, "MajTickInterval", GetMajTickInterval, SetMajTickInterval, VT_I4)
	DISP_PROPERTY_EX(CMMWaveEditXCtrl, "ScaleHeight", GetScaleHeight, SetScaleHeight, VT_I4)
	DISP_PROPERTY_EX(CMMWaveEditXCtrl, "MinTickInterval", GetMinTickInterval, SetMinTickInterval, VT_I4)
	DISP_PROPERTY_EX(CMMWaveEditXCtrl, "TrackerHeight", GetTrackerHeight, SetTrackerHeight, VT_I4)
	DISP_PROPERTY_EX(CMMWaveEditXCtrl, "TrackBack", GetTrackBack, SetTrackBack, VT_COLOR)
	DISP_PROPERTY_EX(CMMWaveEditXCtrl, "TrackPen", GetTrackPen, SetTrackPen, VT_COLOR)
	DISP_FUNCTION(CMMWaveEditXCtrl, "LoadWaveFile", LoadWaveFile, VT_EMPTY, VTS_BSTR)
	DISP_FUNCTION(CMMWaveEditXCtrl, "GetCurrentZoomScale", GetCurrentZoomScale, VT_I4, VTS_NONE)
	DISP_FUNCTION(CMMWaveEditXCtrl, "GetFileLengthInSeconds", GetFileLengthInSeconds, VT_R4, VTS_NONE)
	DISP_FUNCTION(CMMWaveEditXCtrl, "GetScrollRanges", GetScrollRanges, VT_EMPTY, VTS_PI4 VTS_PI4)
	DISP_FUNCTION(CMMWaveEditXCtrl, "ZoomIn", ZoomIn, VT_EMPTY, VTS_NONE)
	DISP_FUNCTION(CMMWaveEditXCtrl, "ZoomOut", ZoomOut, VT_EMPTY, VTS_NONE)
	DISP_FUNCTION(CMMWaveEditXCtrl, "ScrollToPosition", ScrollToPosition, VT_EMPTY, VTS_I4)
	DISP_FUNCTION(CMMWaveEditXCtrl, "GetCurFilePosition", GetCurFilePosition, VT_I4, VTS_NONE)
	DISP_FUNCTION(CMMWaveEditXCtrl, "SetPlayingPosition", SetPlayingPosition, VT_EMPTY, VTS_I4)
	DISP_FUNCTION(CMMWaveEditXCtrl, "GetCurSelectionRange", GetCurSelectionRange, VT_EMPTY, VTS_PI4 VTS_PI4)
	DISP_STOCKPROP_BACKCOLOR()
	DISP_STOCKPROP_FONT()
	//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()


/////////////////////////////////////////////////////////////////////////////
// Event map

BEGIN_EVENT_MAP(CMMWaveEditXCtrl, COleControl)
	//{{AFX_EVENT_MAP(CMMWaveEditXCtrl)
	EVENT_CUSTOM("Message", FireMessage, VTS_BSTR)
	EVENT_CUSTOM("ProgressIndicator", FireProgressIndicator, VTS_I4)
	//}}AFX_EVENT_MAP
END_EVENT_MAP()


/////////////////////////////////////////////////////////////////////////////
// Property pages

// TODO: Add more property pages as needed.  Remember to increase the count!
BEGIN_PROPPAGEIDS(CMMWaveEditXCtrl, 2)
	PROPPAGEID(CLSID_StockFontPage)
	PROPPAGEID(CLSID_StockColorPage)
END_PROPPAGEIDS(CMMWaveEditXCtrl)


/////////////////////////////////////////////////////////////////////////////
// Initialize class factory and guid

IMPLEMENT_OLECREATE_EX(CMMWaveEditXCtrl, "MMWAVEEDITX.MMWaveEditXCtrl.1",
	0x9551e46, 0xe250, 0x11d2, 0x9a, 0x56, 0, 0x80, 0xc6, 0x5, 0xad, 0xa4)


/////////////////////////////////////////////////////////////////////////////
// Type library ID and version

IMPLEMENT_OLETYPELIB(CMMWaveEditXCtrl, _tlid, _wVerMajor, _wVerMinor)


/////////////////////////////////////////////////////////////////////////////
// Interface IDs

const IID BASED_CODE IID_DMMWaveEditX =
		{ 0x2daa664, 0x4abb, 0x11d3, { 0x9a, 0x58, 0, 0x80, 0xc6, 0x5, 0xad, 0xa4 } };
const IID BASED_CODE IID_DMMWaveEditXEvents =
		{ 0x2daa665, 0x4abb, 0x11d3, { 0x9a, 0x58, 0, 0x80, 0xc6, 0x5, 0xad, 0xa4 } };


/////////////////////////////////////////////////////////////////////////////
// Control type information

static const DWORD BASED_CODE _dwMMWaveEditXOleMisc =
	OLEMISC_ACTIVATEWHENVISIBLE |
	OLEMISC_SETCLIENTSITEFIRST |
	OLEMISC_INSIDEOUT |
	OLEMISC_CANTLINKINSIDE |
	OLEMISC_RECOMPOSEONRESIZE;

IMPLEMENT_OLECTLTYPE(CMMWaveEditXCtrl, IDS_MMWAVEEDITX, _dwMMWaveEditXOleMisc)


/////////////////////////////////////////////////////////////////////////////
// CMMWaveEditXCtrl::CMMWaveEditXCtrlFactory::UpdateRegistry -
// Adds or removes system registry entries for CMMWaveEditXCtrl

BOOL CMMWaveEditXCtrl::CMMWaveEditXCtrlFactory::UpdateRegistry(BOOL bRegister)
{
	// TODO: Verify that your control follows apartment-model threading rules.
	// Refer to MFC TechNote 64 for more information.
	// If your control does not conform to the apartment-model rules, then
	// you must modify the code below, changing the 6th parameter from
	// afxRegApartmentThreading to 0.

	if (bRegister)
		return AfxOleRegisterControlClass(
			AfxGetInstanceHandle(),
			m_clsid,
			m_lpszProgID,
			IDS_MMWAVEEDITX,
			IDB_MMWAVEEDITX,
			afxRegApartmentThreading,
			_dwMMWaveEditXOleMisc,
			_tlid,
			_wVerMajor,
			_wVerMinor);
	else
		return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}


/////////////////////////////////////////////////////////////////////////////
// CMMWaveEditXCtrl::CMMWaveEditXCtrl - Constructor

CMMWaveEditXCtrl::CMMWaveEditXCtrl()
{
	InitializeIIDs(&IID_DMMWaveEditX, &IID_DMMWaveEditXEvents);

	// TODO: Initialize your control's instance data here.
	m_bInitialized = FALSE;
	m_bCursorOn=FALSE;
	m_bLButtonDown=FALSE;

	m_bRightDrag=FALSE;
	m_bLeftDrag=FALSE;
	m_bDraggingSelection=FALSE;
	m_bPlayingCursVisible = FALSE;

	m_nTimer = -1;

	SetRect(&m_rcLastPlayingPos,-1,-1,-1,-1);
}


/////////////////////////////////////////////////////////////////////////////
// CMMWaveEditXCtrl::~CMMWaveEditXCtrl - Destructor

CMMWaveEditXCtrl::~CMMWaveEditXCtrl()
{
	// TODO: Cleanup your control's instance data here.
}


/////////////////////////////////////////////////////////////////////////////
// CMMWaveEditXCtrl::OnDraw - Drawing function

void CMMWaveEditXCtrl::OnDraw(
			CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
	CRect rcBoundries = rcBounds;

	rcBoundries.top += m_lTrackerHeight;

	CBmpDC	bmpDC(pdc,rcBoundries,FALSE);

	m_WaveFile.Draw(&bmpDC,rcBoundries);

	m_rcLastSelectRect = m_WaveFile.GetSelectionRect(rcBoundries);

	if(m_rcLastSelectRect.left != -1)
	{
		m_rcLastSelectRect.top += (m_lScaleHeight)+1;
		m_rcLastSelectRect.top -=m_lTrackerHeight;

		bmpDC.InvertRect(&m_rcLastSelectRect);

		m_rcLastSelectRect.top +=m_lTrackerHeight;
	}

	pdc->BitBlt(0,m_lTrackerHeight,rcBounds.Width(),rcBounds.Height(),&bmpDC,0,0,SRCCOPY);
	pdc->FillSolidRect(0,0,rcBoundries.Width(),m_lTrackerHeight,clr_TrackBack);
	m_bPlayingCursVisible=FALSE;

}


/////////////////////////////////////////////////////////////////////////////
// CMMWaveEditXCtrl::DoPropExchange - Persistence support

void CMMWaveEditXCtrl::DoPropExchange(CPropExchange* pPX)
{
	ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
	COleControl::DoPropExchange(pPX);

	// TODO: Call PX_ functions for each persistent custom property.
	
	PX_Color(pPX,"Waveform",clr_Waveform,RGB(0,0,0));
	PX_Color(pPX,"DB",clr_DB,RGB(150,150,150));
	PX_Color(pPX,"Divider",clr_Divider,RGB(255,255,255));
	PX_Color(pPX,"ScaleBackround",clr_ScaleBackround,RGB(100,100,100));
	PX_Color(pPX,"ScaleTicks",clr_ScaleTicks,RGB(0,0,0));
	PX_Color(pPX,"ScaleNumbers",clr_ScaleNumbers,RGB(255,255,255));

	PX_Color(pPX,"TrackBack",clr_TrackBack,RGB(50,50,50));
	PX_Color(pPX,"TrackPen",clr_TrackPen,RGB(255,255,255));
	
	PX_Long(pPX,"MinTickSize",m_lMinTickSize,5);
	PX_Long(pPX,"MajTickSize",m_lMajTickSize,10);
	PX_Long(pPX,"MinTickInterval",m_lMinTickInterval,10);
	PX_Long(pPX,"MajTickInterval",m_lMajTickInterval,80);
	PX_Long(pPX,"ScaleHeight",m_lScaleHeight,30);
	PX_Long(pPX,"TrackerHeight",m_lTrackerHeight,4);


	if(pPX->IsLoading() == TRUE && m_bInitialized == FALSE)
	{
		m_bInitialized =TRUE;
		m_WaveFile.m_lpOwnerCtrl=this;
	}
}


/////////////////////////////////////////////////////////////////////////////
// CMMWaveEditXCtrl::OnResetState - Reset control to default state

void CMMWaveEditXCtrl::OnResetState()
{
	COleControl::OnResetState();  // Resets defaults found in DoPropExchange

	// TODO: Reset any other control state here.
}


/////////////////////////////////////////////////////////////////////////////
// CMMWaveEditXCtrl message handlers

void CMMWaveEditXCtrl::LoadWaveFile(LPCTSTR sWave) 
{
	CString sVal = sWave;
	m_WaveFile.InitializeFile(sVal);
}
long CMMWaveEditXCtrl::GetCurrentZoomScale() 
{
	return m_WaveFile.m_lCurrentZoomFactor;
}

float CMMWaveEditXCtrl::GetFileLengthInSeconds() 
{
	return m_WaveFile.GetFileLengthInSeconds();
}

void CMMWaveEditXCtrl::GetScrollRanges(long FAR* lpLow, long FAR* lpHigh) 
{
	// TODO: Add your dispatch handler code here
	long low;
	long high;
	CRect rcBounds;

	GetClientRect(&rcBounds);

	m_WaveFile.GetScrollRanges(low,high,rcBounds);

	*lpLow = low;
	*lpHigh = high;
}

void CMMWaveEditXCtrl::ZoomIn() 
{
	m_WaveFile.ZoomInToNextLevel();
	StopTheTimer();
	Invalidate(FALSE);
	m_bCursorOn = FALSE;
	StartTheTimer();

}
void CMMWaveEditXCtrl::ZoomOut() 
{
	m_WaveFile.ZoomOutToNextLevel();
	StopTheTimer();
	Invalidate(FALSE);
	m_bCursorOn = FALSE;
	StartTheTimer();

}
void CMMWaveEditXCtrl::ScrollToPosition(long lValue) 
{
	m_WaveFile.m_lCurFilePosition = lValue;
	StopTheTimer();
	Invalidate(FALSE);
	UpdateWindow();
	DrawCursor();
	StartTheTimer();
}
OLE_COLOR CMMWaveEditXCtrl::GetWaveform() 
{
	return clr_Waveform;
}

void CMMWaveEditXCtrl::SetWaveform(OLE_COLOR nNewValue) 
{
	clr_Waveform=nNewValue;
	SetModifiedFlag();
}
OLE_COLOR CMMWaveEditXCtrl::GetDB() 
{
	return clr_DB;
}
void CMMWaveEditXCtrl::SetDB(OLE_COLOR nNewValue) 
{
	clr_DB=nNewValue;
	SetModifiedFlag();
}
OLE_COLOR CMMWaveEditXCtrl::GetDivider() 
{
	return clr_Divider;
}
void CMMWaveEditXCtrl::SetDivider(OLE_COLOR nNewValue) 
{
	clr_Divider=nNewValue;
	SetModifiedFlag();
}
OLE_COLOR CMMWaveEditXCtrl::GetScaleBackround() 
{
	return clr_ScaleBackround;
}
void CMMWaveEditXCtrl::SetScaleBackround(OLE_COLOR nNewValue) 
{

	clr_ScaleBackround = nNewValue;
	SetModifiedFlag();
}

OLE_COLOR CMMWaveEditXCtrl::GetScaleTicks() 
{
	return clr_ScaleTicks;
}
void CMMWaveEditXCtrl::SetScaleTicks(OLE_COLOR nNewValue) 
{
	clr_ScaleTicks=nNewValue;
	SetModifiedFlag();
}
OLE_COLOR CMMWaveEditXCtrl::GetScaleNumbers() 
{
	return clr_ScaleNumbers;
}
void CMMWaveEditXCtrl::SetScaleNumbers(OLE_COLOR nNewValue) 
{
	clr_ScaleNumbers=nNewValue;
	SetModifiedFlag();
}
long CMMWaveEditXCtrl::GetMinTickSize() 
{
	return m_lMinTickSize;
}

void CMMWaveEditXCtrl::SetMinTickSize(long nNewValue) 
{
	m_lMinTickSize=nNewValue;
	SetModifiedFlag();
}
long CMMWaveEditXCtrl::GetMajTickSize() 
{
	return m_lMajTickSize;
}
void CMMWaveEditXCtrl::SetMajTickSize(long nNewValue) 
{
	m_lMajTickSize=nNewValue;
	SetModifiedFlag();
}
long CMMWaveEditXCtrl::GetMajTickInterval() 
{
	return m_lMajTickInterval;
}
void CMMWaveEditXCtrl::SetMajTickInterval(long nNewValue) 
{
	m_lMajTickInterval=nNewValue;
	SetModifiedFlag();
}
long CMMWaveEditXCtrl::GetScaleHeight() 
{
	return m_lScaleHeight;
}

void CMMWaveEditXCtrl::SetScaleHeight(long nNewValue) 
{
	m_lScaleHeight=nNewValue;
	SetModifiedFlag();
}

long CMMWaveEditXCtrl::GetMinTickInterval() 
{
	return m_lMinTickInterval;
}
void CMMWaveEditXCtrl::SetMinTickInterval(long nNewValue) 
{
	m_lMinTickInterval=nNewValue;
	SetModifiedFlag();
}

long CMMWaveEditXCtrl::GetCurFilePosition() 
{
	// TODO: Add your dispatch handler code here

	return 0;
}

void CMMWaveEditXCtrl::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
//	COleControl::OnMouseMove(nFlags, point);

	CClientDC dc(this);


	CRect rcBounds;
	GetClientRect(&rcBounds);

	if(rcBounds.PtInRect(point) == TRUE)
	{

		rcBounds.bottom = rcBounds.top + m_lTrackerHeight;
		dc.FillSolidRect(&rcBounds,clr_TrackBack);
		rcBounds.left = point.x;
		rcBounds.right = point.x+2;
		dc.FillSolidRect(&rcBounds,clr_TrackPen);


		if(m_rcLastSelectRect.left != -1 && m_bLButtonDown == FALSE)
		{
			if(point.x < m_rcLastSelectRect.right+4 && point.x > (m_rcLastSelectRect.right-4))
			{
				m_bRightDrag = TRUE;
			}
			else if(point.x > m_rcLastSelectRect.left-4 && point.x < (m_rcLastSelectRect.left+4))
			{
				m_bLeftDrag = TRUE;
			}
			else
			{
				m_bRightDrag = FALSE;
				m_bLeftDrag = FALSE;
			}

			if(m_bRightDrag == TRUE || m_bLeftDrag == TRUE)
				::SetCursor(::LoadCursor(NULL,IDC_SIZEWE));

		}

		if(m_bLButtonDown == TRUE && m_bDraggingSelection == FALSE)
		{
			// we are selecting something...
			//InvertRect
			StopTheTimer();

			CClientDC dc(this);

			CRect rcBounds;
			CRect rcCursor;

			GetClientRect(&rcBounds);

			CBmpDC	bmpDC(&dc,rcBounds,TRUE);

			m_WaveFile.SetCursorPosition(point.x);

			if(m_rcLastSelectRect.left != -1)
				bmpDC.InvertRect(&m_rcLastSelectRect);

			m_rcLastSelectRect = m_WaveFile.GetSelectionRect(rcBounds);

			m_rcLastSelectRect.top += (m_lTrackerHeight+m_lScaleHeight)+1;

			bmpDC.InvertRect(&m_rcLastSelectRect);


			

			if(m_bCursorOn == TRUE)
				bmpDC.DrawFocusRect(&m_rcLastCursorPos);

			rcCursor = rcBounds;
			m_WaveFile.IsCursorVisible(rcCursor);
			m_bCursorOn = TRUE;
			m_rcLastCursorPos = rcCursor;
			m_rcLastCursorPos.right = m_rcLastCursorPos.left +2;
			m_rcLastCursorPos.top += (m_lTrackerHeight+m_lScaleHeight);
			bmpDC.DrawFocusRect(&m_rcLastCursorPos);
			
			dc.BitBlt(0,0,rcBounds.Width(),rcBounds.Height(),&bmpDC,0,0,SRCCOPY);
			StartTheTimer();
		}
		else if(m_bLButtonDown == TRUE && m_bDraggingSelection == TRUE)
		{
			StopTheTimer();

			CClientDC dc(this);

			CRect rcBounds;
			CRect rcCursor;

			GetClientRect(&rcBounds);

			CBmpDC	bmpDC(&dc,rcBounds,TRUE);

			if(m_rcLastSelectRect.left != -1)
				bmpDC.InvertRect(&m_rcLastSelectRect);

			m_rcLastSelectRect = m_WaveFile.SizingSelection(point.x,rcBounds);

			//m_rcLastSelectRect = m_WaveFile.GetSelectionRect(rcBounds);

			m_rcLastSelectRect.top += (m_lTrackerHeight+m_lScaleHeight)+1;

			bmpDC.InvertRect(&m_rcLastSelectRect);


			

			if(m_bCursorOn == TRUE)
				bmpDC.DrawFocusRect(&m_rcLastCursorPos);

			rcCursor = rcBounds;
			m_WaveFile.IsCursorVisible(rcCursor);
			m_bCursorOn = TRUE;
			m_rcLastCursorPos = rcCursor;
			m_rcLastCursorPos.right = m_rcLastCursorPos.left +2;
			m_rcLastCursorPos.top += (m_lTrackerHeight+m_lScaleHeight);
			bmpDC.DrawFocusRect(&m_rcLastCursorPos);
			
			dc.BitBlt(0,0,rcBounds.Width(),rcBounds.Height(),&bmpDC,0,0,SRCCOPY);
			StartTheTimer();

			::SetCursor(::LoadCursor(NULL,IDC_SIZEWE));
		}
	}
}
long CMMWaveEditXCtrl::GetTrackerHeight() 
{
	return m_lTrackerHeight;
}

void CMMWaveEditXCtrl::SetTrackerHeight(long nNewValue) 
{
	m_lTrackerHeight = nNewValue;
	SetModifiedFlag();
}

OLE_COLOR CMMWaveEditXCtrl::GetTrackBack() 
{
	return clr_TrackBack;
}

void CMMWaveEditXCtrl::SetTrackBack(OLE_COLOR nNewValue) 
{
	clr_TrackBack = nNewValue;
	SetModifiedFlag();
}

OLE_COLOR CMMWaveEditXCtrl::GetTrackPen() 
{
	return clr_TrackPen;
}

void CMMWaveEditXCtrl::SetTrackPen(OLE_COLOR nNewValue) 
{
	clr_TrackPen=nNewValue;
	SetModifiedFlag();
}

void CMMWaveEditXCtrl::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if(nIDEvent == 1971)
	{
		// Its our Timer!
		CRect rcBounds;

		GetClientRect(&rcBounds);
		CClientDC dc(this);

		if(m_bCursorOn == TRUE)
		{
			dc.DrawFocusRect(&m_rcLastCursorPos);
			m_bCursorOn = FALSE;
		}
		else
		{
			if(m_WaveFile.IsCursorVisible(rcBounds) == TRUE)
			{
				m_bCursorOn = TRUE;
				m_rcLastCursorPos = rcBounds;
				m_rcLastCursorPos.right = m_rcLastCursorPos.left +2;
				m_rcLastCursorPos.top += (m_lTrackerHeight+m_lScaleHeight);
				dc.DrawFocusRect(&m_rcLastCursorPos);
			}
		}


	}
	COleControl::OnTimer(nIDEvent);
}
void CMMWaveEditXCtrl::DrawCursor()
{
	CRect rcBounds;

	GetClientRect(&rcBounds);
	CClientDC dc(this);

	if(m_WaveFile.IsCursorVisible(rcBounds) == TRUE)
	{
		m_rcLastCursorPos = rcBounds;
		m_rcLastCursorPos.right = m_rcLastCursorPos.left +2;
		m_rcLastCursorPos.top += (m_lTrackerHeight+m_lScaleHeight);
		dc.DrawFocusRect(&m_rcLastCursorPos);
		m_bCursorOn = TRUE;
	}
}
void CMMWaveEditXCtrl::StartTheTimer()
{
	 if(m_nTimer != -1)
		 KillTimer(m_nTimer);

	 m_nTimer = SetTimer(1971,500,NULL);

}
void CMMWaveEditXCtrl::StopTheTimer()
{
	 if(m_nTimer != -1)
		 KillTimer(m_nTimer);

	 m_nTimer = -1;
}

void CMMWaveEditXCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(m_bRightDrag == FALSE && m_bLeftDrag == FALSE)
	{

		m_WaveFile.SetCursorPosition(point.x);
		m_WaveFile.SetCursorAsStartSelec();
		
		CRect rcBounds;

		GetClientRect(&rcBounds);



		CClientDC dc(this);

		if(m_rcLastSelectRect.left != -1)
			dc.InvertRect(&m_rcLastSelectRect);

		m_rcLastSelectRect = m_WaveFile.GetSelectionRect(rcBounds);

		if(m_bCursorOn == TRUE)
			dc.DrawFocusRect(&m_rcLastCursorPos);

		m_WaveFile.IsCursorVisible(rcBounds);
		m_bCursorOn = TRUE;
		m_rcLastCursorPos = rcBounds;
		m_rcLastCursorPos.right = m_rcLastCursorPos.left +2;
		m_rcLastCursorPos.top += (m_lTrackerHeight+m_lScaleHeight);
		dc.DrawFocusRect(&m_rcLastCursorPos);

		StopTheTimer();
		StartTheTimer();
		SetCapture();

		m_bDraggingSelection = FALSE;
		m_bLButtonDown = TRUE;
	}
	else
	{
		SetCapture();
		::SetCursor(::LoadCursor(NULL,IDC_SIZEWE));
		CRect rcBounds;
		GetClientRect(&rcBounds);
		m_WaveFile.BeginingDragOfSelection(point.x,rcBounds,m_bLeftDrag);
		m_bLButtonDown = TRUE;
		m_bDraggingSelection = TRUE;
	}
	//COleControl::OnLButtonDown(nFlags, point);
}

void CMMWaveEditXCtrl::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	m_bLButtonDown = FALSE;
	m_bRightDrag = FALSE;
	m_bLeftDrag = FALSE;
	m_bDraggingSelection = FALSE;
	ReleaseCapture();
	
	//COleControl::OnLButtonUp(nFlags, point);
}

BOOL CMMWaveEditXCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	// TODO: Add your message handler code here and/or call default
	
	return COleControl::OnSetCursor(pWnd, nHitTest, message);
}

void CMMWaveEditXCtrl::SetPlayingPosition(long lPosition) 
{
	//m_bPlayingCursVisible
	CClientDC dc(this);

	if(m_bPlayingCursVisible == TRUE)
		dc.DrawFocusRect(&m_rcLastPlayingPos);

	if(lPosition == -1)
	{
		m_bPlayingCursVisible = FALSE;
		return;
	}

	CRect rcBounds;
	CRect rcCursor;

	GetClientRect(&rcBounds);

	rcCursor = rcBounds;

	if(m_WaveFile.IsPointVisible(rcCursor,lPosition) == TRUE)
	{
		m_bPlayingCursVisible = TRUE;

		m_rcLastPlayingPos = rcCursor;
		m_rcLastPlayingPos.right = m_rcLastPlayingPos.left +2;
		m_rcLastPlayingPos.top += (m_lTrackerHeight+m_lScaleHeight);
		dc.DrawFocusRect(&m_rcLastPlayingPos);
	}
	
}

void CMMWaveEditXCtrl::GetCurSelectionRange(long FAR* lStartPos, long FAR* lEndPos) 
{
	long lLow;
	long lHigh;

	m_WaveFile.GetSelectionRanges(lLow,lHigh);

	*lStartPos = lLow;
	*lEndPos = lHigh;

}

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


Written By
Web Developer
Canada Canada
Jonathan Kade is a native of Detroit, MI. He's interested in multimedia, hardware/software interfacing, working with low-level data, and low-level programming in general.

Comments and Discussions