www.pudn.com > spindial.zip > spinctl.cpp
// spinctl.cpp : Implementation of the CSpindialCtrl OLE control class.
//
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "spindial.h"
#include "spinctl.h"
#include "spinppg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// Numeric constants
const int MAX_POSITIONS = 4;
const int TICK_LEN = 6;
IMPLEMENT_DYNCREATE(CSpindialCtrl, COleControl)
/////////////////////////////////////////////////////////////////////////////
// Message map
BEGIN_MESSAGE_MAP(CSpindialCtrl, COleControl)
//{{AFX_MSG_MAP(CSpindialCtrl)
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// Dispatch map
BEGIN_DISPATCH_MAP(CSpindialCtrl, COleControl)
//{{AFX_DISPATCH_MAP(CSpindialCtrl)
DISP_PROPERTY_EX(CSpindialCtrl, "NeedlePosition", GetNeedlePosition, SetNeedlePosition, VT_I2)
DISP_DEFVALUE(CSpindialCtrl, "NeedlePosition")
//}}AFX_DISPATCH_MAP
DISP_FUNCTION_ID(CSpindialCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()
/////////////////////////////////////////////////////////////////////////////
// Event map
BEGIN_EVENT_MAP(CSpindialCtrl, COleControl)
//{{AFX_EVENT_MAP(CSpindialCtrl)
EVENT_CUSTOM("SpinPositive", FireSpinPositive, VTS_NONE)
//}}AFX_EVENT_MAP
END_EVENT_MAP()
/////////////////////////////////////////////////////////////////////////////
// Property pages
// TODO: Add more property pages as needed. Remember to increase the count!
BEGIN_PROPPAGEIDS(CSpindialCtrl, 1)
PROPPAGEID(CSpindialPropPage::guid)
END_PROPPAGEIDS(CSpindialCtrl)
/////////////////////////////////////////////////////////////////////////////
// Initialize class factory and guid
IMPLEMENT_OLECREATE_EX(CSpindialCtrl, "SPINDIAL.SpindialCtrl.1",
0x6889605, 0xb8d0, 0x101a, 0x91, 0xf1, 0x0, 0x60, 0x8c, 0xea, 0xd5, 0xb3)
/////////////////////////////////////////////////////////////////////////////
// Type library ID and version
IMPLEMENT_OLETYPELIB(CSpindialCtrl, _tlid, _wVerMajor, _wVerMinor)
/////////////////////////////////////////////////////////////////////////////
// Interface IDs
const IID BASED_CODE IID_DSpindial =
{ 0x37446b89, 0x5870, 0x101b, { 0xb5, 0x7b, 0x0, 0x60, 0x8c, 0xc9, 0x6a, 0xfa } };
const IID BASED_CODE IID_DSpindialEvents =
{ 0x37446b8a, 0x5870, 0x101b, { 0xb5, 0x7b, 0x0, 0x60, 0x8c, 0xc9, 0x6a, 0xfa } };
/////////////////////////////////////////////////////////////////////////////
// Control type information
static const DWORD BASED_CODE _dwSpindialOleMisc =
OLEMISC_ACTIVATEWHENVISIBLE |
OLEMISC_SETCLIENTSITEFIRST |
OLEMISC_INSIDEOUT |
OLEMISC_CANTLINKINSIDE |
OLEMISC_RECOMPOSEONRESIZE;
IMPLEMENT_OLECTLTYPE(CSpindialCtrl, IDS_SPINDIAL, _dwSpindialOleMisc)
/////////////////////////////////////////////////////////////////////////////
// CSpindialCtrl::CSpindialCtrlFactory::UpdateRegistry -
// Adds or removes system registry entries for CSpindialCtrl
BOOL CSpindialCtrl::CSpindialCtrlFactory::UpdateRegistry(BOOL bRegister)
{
if (bRegister)
return AfxOleRegisterControlClass(
AfxGetInstanceHandle(),
m_clsid,
m_lpszProgID,
IDS_SPINDIAL,
IDB_SPINDIAL,
FALSE, // Not insertable
_dwSpindialOleMisc,
_tlid,
_wVerMajor,
_wVerMinor);
else
return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}
/////////////////////////////////////////////////////////////////////////////
// CSpindialCtrl::CSpindialCtrl - Constructor
CSpindialCtrl::CSpindialCtrl()
{
InitializeIIDs(&IID_DSpindial, &IID_DSpindialEvents);
}
/////////////////////////////////////////////////////////////////////////////
// CSpindialCtrl::~CSpindialCtrl - Destructor
CSpindialCtrl::~CSpindialCtrl()
{
}
/////////////////////////////////////////////////////////////////////////////
// CSpindialCtrl::OnDraw - Drawing function
void CSpindialCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect&)
{
LPRECT lpr;
OLE_COLOR color;
CBrush br;
POINT centerPt;
POINT tickpos[MAX_POSITIONS];
CPen* pOldPen;
lpr = (LPRECT)(LPCRECT)rcBounds;
// Paint background using the ambient background color
color = AmbientBackColor();
br.CreateSolidBrush(TranslateColor(color));
pdc->FillRect(lpr, &br);
// Draw the dial using a black pen
pOldPen = (CPen*)pdc->SelectStockObject(BLACK_PEN);
pdc->Ellipse(lpr);
// Determine coordinates of center point
centerPt.x = lpr->left + ((lpr->right - lpr->left) / 2);
centerPt.y = lpr->top + ((lpr->bottom - lpr->top) / 2);
// Determine coordinates of intersections of tick marks and dial
tickpos[0].x = centerPt.x;
tickpos[0].y = lpr->top;
tickpos[1].x = lpr->right;
tickpos[1].y = centerPt.y;
tickpos[2].x = centerPt.x;
tickpos[2].y = lpr->bottom;
tickpos[3].x = lpr->left;
tickpos[3].y = centerPt.y;
// Draw each tick mark
pdc->MoveTo(tickpos[0]);
pdc->LineTo(tickpos[0].x, tickpos[0].y+TICK_LEN);
pdc->MoveTo(tickpos[1]);
pdc->LineTo(tickpos[1].x-TICK_LEN, tickpos[1].y);
pdc->MoveTo(tickpos[2]);
pdc->LineTo(tickpos[2].x,tickpos[2].y-TICK_LEN);
pdc->MoveTo(tickpos[3]);
pdc->LineTo(tickpos[3].x+TICK_LEN, tickpos[3].y);
// Draw pointer of dial
pdc->MoveTo(centerPt);
pdc->LineTo(tickpos[m_needlePosition]);
pdc->SelectObject(pOldPen);
return;
}
/////////////////////////////////////////////////////////////////////////////
// CSpindialCtrl::DoPropExchange - Persistence support
void CSpindialCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
PX_Short(pPX, _T("NeedlePosition"), m_needlePosition, 0);
}
/////////////////////////////////////////////////////////////////////////////
// CSpindialCtrl::OnResetState - Reset control to default state
void CSpindialCtrl::OnResetState()
{
COleControl::OnResetState(); // Resets defaults found in DoPropExchange
}
/////////////////////////////////////////////////////////////////////////////
// CSpindialCtrl::AboutBox - Display an "About" box to the user
void CSpindialCtrl::AboutBox()
{
CDialog dlgAbout(IDD_ABOUTBOX_SPINDIAL);
dlgAbout.DoModal();
}
/////////////////////////////////////////////////////////////////////////////
// CSpindialCtrl::GetNeedlePosition - Return needle position.
short CSpindialCtrl::GetNeedlePosition()
{
return m_needlePosition;
}
/////////////////////////////////////////////////////////////////////////////
// CSpindialCtrl::SetNeedlePosition - Set needle position.
void CSpindialCtrl::SetNeedlePosition(short nNewValue)
{
// Constrain value to 0..3 range
if ( (nNewValue > 3) || (nNewValue < 0) )
m_needlePosition = 0;
else
m_needlePosition = nNewValue;
SetModifiedFlag(TRUE);
InvalidateControl();
}
/////////////////////////////////////////////////////////////////////////////
// CSpindialCtrl::OnLButtonDown - Spin needle and fire event.
void CSpindialCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
// Spin needle position
SpinNeedlePosition();
// Fire "spin positive" event
FireSpinPositive();
COleControl::OnLButtonDown(nFlags, point);
}
/////////////////////////////////////////////////////////////////////////////
// CSpindialCtrl::SpinNeedlePosition - Spin needle to next position.
void CSpindialCtrl::SpinNeedlePosition()
{
short np = GetNeedlePosition();
if (np == 3) np = 0;
else np++;
SetNeedlePosition(np);
}