#include "stdafx.h"
#include "KnobControlST.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define PI 3.14159265358979323846
CKnobControlST::CKnobControlST()
{
FreeResources(FALSE);
m_nLargeChange = 50;
m_nSmallChange = 10;
// Show scales
m_bShowSmallScale = TRUE;
m_bShowLargeScale = TRUE;
// Knob is not rotating
m_bIsKnobRotating = FALSE;
// Default colors
m_cFgColor.SetFromCOLORREF(::GetSysColor(COLOR_3DFACE));
m_cBkColor.SetFromCOLORREF(::GetSysColor(COLOR_3DFACE));
m_cScaleColor.SetValue((ARGB)Color.Black);
// Do not draw as a transparent button
m_bDrawTransparent = FALSE;
m_pbmpOldBk = NULL;
// No defined callbacks
::ZeroMemory(&m_csCallbacks, sizeof(m_csCallbacks));
}
CKnobControlST::~CKnobControlST()
{
// Restore old bitmap (if any)
if (m_dcBk.m_hDC && m_pbmpOldBk)
{
m_dcBk.SelectObject(m_pbmpOldBk);
} // if
FreeResources();
}
BEGIN_MESSAGE_MAP(CKnobControlST, CSliderCtrl)
//{{AFX_MSG_MAP(CKnobControlST)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_CTLCOLOR_REFLECT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_MOUSEWHEEL()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CKnobControlST::FreeResources(BOOL bCheckForNULL)
{
if (bCheckForNULL)
{
// Destroy the icon (if any)
// Note: the following line MUST be here! even if
// BoundChecker says it's unnecessary!
if (m_hIcon != NULL) ::DestroyIcon(m_hIcon);
} // if
// No icon
m_hIcon = NULL;
m_cxIcon = 0;
m_cyIcon = 0;
} // End of FreeResources
void CKnobControlST::OnLButtonDown(UINT nFlags, CPoint point)
{
CSliderCtrl::OnLButtonDown(nFlags, point);
if (m_rKnob.Contains(point.x, point.y))
{
// Start Rotation of knob
m_bIsKnobRotating = TRUE;
}
} // End of OnLButtonDown
void CKnobControlST::OnLButtonUp(UINT nFlags, CPoint point)
{
CSliderCtrl::OnLButtonUp(nFlags, point);
// Stop rotation
m_bIsKnobRotating = FALSE;
if (m_rKnob.Contains(point.x, point.y))
{
// Get value
SetPos(GetValueFromPosition(Point(point.x, point.y)));
Invalidate();
// Notify parent window
SendChangeCallback();
}
//this.Cursor = Cursors.Default;
} // End of OnLButtonUp
void CKnobControlST::OnMouseMove(UINT nFlags, CPoint point)
{
CSliderCtrl::OnMouseMove(nFlags, point);
//--------------------------------------
// Following Handles Knob Rotating
//--------------------------------------
if (m_bIsKnobRotating)
{
//this.Cursor = Cursors.Hand;
Point p(point.x, point.y);
SetPos(GetValueFromPosition(p));
Invalidate();
// Notify parent window
SendChangeCallback();
} // if
} // End of OnMouseMove
BOOL CKnobControlST::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
BOOL bRetValue = CSliderCtrl::OnMouseWheel(nFlags, zDelta, pt);
Invalidate();
// Notify parent window
SendChangeCallback();
return bRetValue;
} // End of OnMouseWheel
void CKnobControlST::OnPaint()
{
CPaintDC dc(this); // device context for painting
Graphics g(dc.m_hDC); // GDI+ object for painting
DrawItem(&g);
} // End of OnPaint
BOOL CKnobControlST::OnEraseBkgnd(CDC* /*pDC*/)
{
return FALSE;
} // End of OnEraseBkgnd
HBRUSH CKnobControlST::CtlColor(CDC* /*pDC*/, UINT /*nCtlColor*/)
{
return (HBRUSH)::GetStockObject(NULL_BRUSH);
} // End of CtlColor
void CKnobControlST::DrawItem(Graphics* pGfx)
{
CRect rCtrl;
GetClientRect(rCtrl);
Pen fgPen(m_cFgColor);
Pen scalePen(m_cScaleColor);
Bitmap OffScreenImage(rCtrl.Width(), rCtrl.Height());
Graphics gOffScreen(&OffScreenImage);
gOffScreen.SetSmoothingMode(SmoothingModeAntiAlias);
// Get smaller from height and width
int nSize = rCtrl.Width();
if (rCtrl.Width() > rCtrl.Height())
{
nSize = rCtrl.Height();
} // if
// Allow 10% gap on all side to determine size of knob control
m_rKnob.X = (int)(nSize*0.10);
m_rKnob.Y = (int)(nSize*0.10);
m_rKnob.Width = (int)(nSize*0.80);
m_rKnob.Height = (int)(nSize*0.80);
m_pntKnob.X = m_rKnob.X + m_rKnob.Width / 2;
m_pntKnob.Y = m_rKnob.Y + m_rKnob.Height / 2;
LinearGradientBrush bKnob(m_rKnob, OffsetColor(m_cFgColor, 55), OffsetColor(m_cFgColor, -55), LinearGradientModeForwardDiagonal);
// Prepare draw... paint control background
// Draw transparent?
if (m_bDrawTransparent)
PaintBk(&gOffScreen);
else
OnDrawBackground(&gOffScreen, &rCtrl);
gOffScreen.FillEllipse(&bKnob, m_rKnob);
// Draw border of knob
gOffScreen.DrawEllipse(&fgPen, m_rKnob);
// Draw focus rectangle ?
if (GetFocus() == this)
{
Pen DottedPen(OffsetColor(m_cFgColor, -40));
DottedPen.SetDashStyle(DashStyleDash);
DottedPen.SetDashCap(DashCapFlat);
gOffScreen.DrawEllipse(&DottedPen, m_rKnob);
} // if
// Get current position of pointer
Point Arrow = GetKnobPosition(&m_rKnob);
// Draw pointer arrow that shows knob position
DrawInsetCircle(&gOffScreen, Rect(Arrow.X - 3, Arrow.Y - 3, 6, 6), &fgPen);
// Draw small and large scales
if (m_bShowSmallScale)
{
for (int i = GetRangeMin(); i <= GetRangeMax();i += m_nSmallChange)
{
gOffScreen.DrawLine(&scalePen, GetMarkerPoint(0, i, &m_rKnob), GetMarkerPoint(3, i, &m_rKnob));
} // for
} // if
if (m_bShowLargeScale)
{
for (int i = GetRangeMin(); i <= GetRangeMax(); i += m_nLargeChange)
{
gOffScreen.DrawLine(&scalePen, GetMarkerPoint(0, i, &m_rKnob), GetMarkerPoint(5, i, &m_rKnob));
} // for
} // if
// Draw icon
if (m_hIcon) OnDrawIcon(&gOffScreen, &m_rKnob);
// Drawimage on screen
pGfx->DrawImage(&OffScreenImage, 0, 0);
} // End of DrawItem
void CKnobControlST::PaintBk(Graphics* pGfx)
{
Bitmap* pbmpBk = Bitmap::FromHBITMAP((HBITMAP)m_bmpBk, NULL);
pGfx->DrawImage(pbmpBk, 0, 0);
delete pbmpBk;
} // End of PaintBk
void CKnobControlST::SendChangeCallback()
{
if (m_csCallbacks.hWnd) ::SendMessage(m_csCallbacks.hWnd, m_csCallbacks.nMessage, m_csCallbacks.wParam, m_csCallbacks.lParam);
} // End of SendChangeCallback
void CKnobControlST::InitToolTip()
{
if (m_ToolTip.m_hWnd == NULL)
{
// Create ToolTip control
m_ToolTip.Create(this);
// Create inactive
m_ToolTip.Activate(FALSE);
// Enable multiline
m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, 400);
} // if
} // End of InitToolTip
BOOL CKnobControlST::PreTranslateMessage(MSG* pMsg)
{
InitToolTip();
m_ToolTip.RelayEvent(pMsg);
if (pMsg->message == WM_KEYDOWN)
{
switch (pMsg->wParam)
{
case VK_END:
if (GetPos() != GetRangeMin())
{
SetPos(GetRangeMin());
Invalidate();
// Notify parent window
SendChangeCallback();
} // if
return 1;
case VK_HOME:
if (GetPos() != GetRangeMax())
{
SetPos(GetRangeMax());
Invalidate();
// Notify parent window
SendChangeCallback();
} // if
return 1;
case VK_PRIOR:
if (GetPos() + m_nLargeChange <= GetRangeMax())
SetPos(GetPos() + m_nLargeChange);
else
SetPos(GetRangeMax());
Invalidate();
// Notify parent window
SendChangeCallback();
return 1;
case VK_NEXT:
if (GetPos() - m_nLargeChange >= GetRangeMin())
SetPos(GetPos() - m_nLargeChange);
else
SetPos(GetRangeMin());
Invalidate();
// Notify parent window
SendChangeCallback();
return 1;
case VK_UP:
case VK_RIGHT:
if (GetPos() < GetRangeMax())
{
SetPos(GetPos() + 1);
Invalidate();
// Notify parent window
SendChangeCallback();
} // if
return 1;
case VK_DOWN:
case VK_LEFT:
if (GetPos() > GetRangeMin())
{
SetPos(GetPos() - 1);
Invalidate();
// Notify parent window
SendChangeCallback();
} // if
return 1;
} // switch
} // if
return CSliderCtrl::PreTranslateMessage(pMsg);
} // End of PreTranslateMessage
Color CKnobControlST::OffsetColor(Color cColor, short shOffset)
{
BYTE byRed = 0;
BYTE byGreen = 0;
BYTE byBlue = 0;
short shOffsetR = shOffset;
short shOffsetG = shOffset;
short shOffsetB = shOffset;
if (shOffset < -255 || shOffset > 255) return cColor;
// Get RGB components of specified color
byRed = cColor.GetR();
byGreen = cColor.GetG();
byBlue = cColor.GetB();
// Calculate max. allowed real offset
if (shOffset > 0)
{
if (byRed + shOffset > 255) shOffsetR = (short)(255 - byRed);
if (byGreen + shOffset > 255) shOffsetG = (short)(255 - byGreen);
if (byBlue + shOffset > 255) shOffsetB = (short)(255 - byBlue);
shOffset = min(min(shOffsetR, shOffsetG), shOffsetB);
} // if
else
{
if (byRed + shOffset < 0) shOffsetR = (short)-byRed;
if (byGreen + shOffset < 0) shOffsetG = (short)-byGreen;
if (byBlue + shOffset < 0) shOffsetB = (short)-byBlue;
shOffset = max(max(shOffsetR, shOffsetG), shOffsetB);
} // else
Color c1(cColor.GetAlpha(),
(BYTE)(byRed + shOffset),
(BYTE)(byGreen + shOffset),
(BYTE)(byBlue + shOffset));
return c1;
} // End of OffsetColor
void CKnobControlST::DrawInsetCircle(Graphics* g, Rect r, Pen* p)
{
Color PenColor;
p->GetColor(&PenColor);
Pen p1(OffsetColor(PenColor, -50));
Pen p2(OffsetColor(PenColor, 50));
for (int i = 0; i < p->GetWidth(); i++)
{
Rect r1(r.X +i, r.Y +i, r.Width - i*2, r.Height - i*2);
g->DrawArc(&p2, r1, -45, 180);
g->DrawArc(&p1, r1, 135, 180);
} // for
} // End of DrawInsetCircle
Point CKnobControlST::GetKnobPosition(Rect* rKnob)
{
Point Pos(0,0);
// Avoid divide-by-zero
if (GetRangeMax() - GetRangeMin() == 0) return Pos;
double degree = 270 * GetPos() / (GetRangeMax() - GetRangeMin());
degree = (degree + 135) * PI / 180;
Pos.X = (int)(cos(degree) * (rKnob->Width / 2 - 10) + rKnob->X + rKnob->Width / 2);
Pos.Y = (int)(sin(degree) * (rKnob->Width / 2 - 10) + rKnob->Y + rKnob->Height / 2);
return Pos;
} // End of GetKnobPosition
Point CKnobControlST::GetMarkerPoint(int length, int Value, Rect* rKnob)
{
Point Pos(0,0);
// Avoid divide-by-zero
if (GetRangeMax() - GetRangeMin() == 0) return Pos;
double degree = 270 * Value / (GetRangeMax() - GetRangeMin());
degree = (degree + 135) * PI / 180;
Pos.X = (int)(cos(degree) * (rKnob->Width / 2 - length + 7) + rKnob->X + rKnob->Width / 2);
Pos.Y = (int)(sin(degree) * (rKnob->Width / 2 - length + 7) + rKnob->Y + rKnob->Height / 2);
return Pos;
} // End of GetMarkerPoint
int CKnobControlST::GetValueFromPosition(Point p)
{
double degree = 0.0;
int v = 0;
if (p.X <= m_pntKnob.X)
{
degree = (double)(m_pntKnob.Y - p.Y ) / (double)(m_pntKnob.X - p.X );
degree = atan(degree);
degree = (degree) * (180 / PI) + 45;
v = (int)(degree * (GetRangeMax() - GetRangeMin())/ 270);
} // if
else
{
if (p.X > m_pntKnob.X)
{
degree = (double)(p.Y - m_pntKnob.Y ) / (double)(p.X - m_pntKnob.X );
degree = atan(degree);
degree = 225 + (degree) * (180 / PI);
v = (int)(degree * (GetRangeMax() - GetRangeMin()) / 270);
} // if
} // else
if (v > GetRangeMax()) v = GetRangeMax();
if (v < GetRangeMin()) v = GetRangeMin();
return v;
} // End of GetValueFromPosition
// This function is called every time the control background needs to be painted.
// If the control is in transparent mode this function will NOT be called.
// This is a virtual function that can be rewritten in CKnobControlST-derived classes.
//
// Parameters:
// [IN] pGfx
// Pointer to a GDI+ Graphics object that indicates the graphic context.
// [IN] pRect
// Pointer to a CRect object that indicates the bounds of the
// area to be painted.
//
// Return value:
// KNOBCONTROLST_OK
// Function executed successfully.
//
DWORD CKnobControlST::OnDrawBackground(Graphics* pGfx, LPCRECT /*pRect*/)
{
// Draw control background
pGfx->Clear(m_cBkColor);
return KNOBCONTROLST_OK;
} // End of OnDrawBackground
// This function is called every time the icon associated to the control needs to be painted.
// If the control has no icon this function will NOT be called.
// This is a virtual function that can be rewritten in CKnobControlST-derived classes.
//
// Parameters:
// [IN] pGfx
// Pointer to a GDI+ Graphics object that indicates the graphic context.
// [IN] rpKnob
// Pointer to a GDI+ Rect object that indicates the bounds of the
// area taken by the control.
//
// Return value:
// KNOBCONTROLST_OK
// Function executed successfully.
//
DWORD CKnobControlST::OnDrawIcon(Graphics* pGfx, Rect* rpKnob)
{
int nX = 0, nY = 0;
Bitmap bmpIcon(m_hIcon);
nX = rpKnob->X;
nY = rpKnob->Y;
// Center icon into knob control
nX += (rpKnob->Width - m_cxIcon) / 2;
//if (nX < 0) nX = 0;
nY += (rpKnob->Height - m_cyIcon) / 2;
//if (nY < 0) nY = 0;
pGfx->DrawImage(&bmpIcon, nX, nY);
return KNOBCONTROLST_OK;
} // End of OnDrawIcon
// This function sets the icon to be displayed.
// Any previous icon will be removed.
//
// Parameters:
// [IN] nIcon
// A Windows icon resource ID
// [IN] bRepaint
// If TRUE the control will be immediately repainted
// [IN] hInstance
// Handle of the instance that contains the icon.
// If NULL the icon will be loaded from the .EXE resources
//
// Return value:
// KNOBCONTROLST_OK
// Function executed successfully.
// KNOBCONTROLST_INVALIDRESOURCE
// Failed loading the specified resource.
//
DWORD CKnobControlST::SetIcon(int nIcon, BOOL bRepaint, HINSTANCE hInstance)
{
HINSTANCE hInstResource;
HICON hIcon;
if (hInstance == NULL)
hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nIcon), RT_GROUP_ICON);
else
hInstResource = hInstance;
// Load icon from resource
hIcon = (HICON)::LoadImage(hInstResource, MAKEINTRESOURCE(nIcon), IMAGE_ICON, 0, 0, 0);
return SetIcon(hIcon, bRepaint);
} // End of SetIcon
// This function sets the icon to be displayed.
// Any previous icon will be removed.
//
// Parameters:
// [IN] hIcon
// Handle fo the icon to show.
// Pass NULL to remove any icon from the control.
// [IN] bRepaint
// If TRUE the control will be immediately repainted
//
// Return value:
// KNOBCONTROLST_OK
// Function executed successfully.
// KNOBCONTROLST_INVALIDRESOURCE
// Failed loading the specified resource.
//
DWORD CKnobControlST::SetIcon(HICON hIcon, BOOL bRepaint)
{
BOOL bRetValue;
ICONINFO ii;
// Free any loaded resource
FreeResources();
if (hIcon)
{
m_hIcon = hIcon;
// Get icon dimension
ZeroMemory(&ii, sizeof(ICONINFO));
bRetValue = ::GetIconInfo(m_hIcon, &ii);
if (bRetValue == FALSE)
{
FreeResources();
return KNOBCONTROLST_INVALIDRESOURCE;
} // if
m_cxIcon = (BYTE)(ii.xHotspot * 2);
m_cyIcon = (BYTE)(ii.yHotspot * 2);
::DeleteObject(ii.hbmMask);
::DeleteObject(ii.hbmColor);
} // if
// Repaint control
if (bRepaint) Invalidate();
return KNOBCONTROLST_OK;
} // End of SetIcon
// This function sets the foreground and background colors of the control.
//
// Parameters:
// [IN] cFgColor
// A GDI+ Color object indicating the color of the knob control.
// [IN] cBkColor
// A GDI+ Color object indicating the background color of the knob control.
// [IN] bRepaint
// If TRUE the control will be repainted.
//
void CKnobControlST::SetColors(Color cFgColor, Color cBkColor, BOOL bRepaint)
{
SetFgColor(cFgColor, FALSE);
SetBkColor(cBkColor, bRepaint);
} // End of SetColors
// This function sets the foreground color of the control.
//
// Parameters:
// [IN] cFgColor
// A GDI+ Color object indicating the color of the knob control.
// [IN] bRepaint
// If TRUE the control will be repainted.
//
void CKnobControlST::SetFgColor(Color cFgColor, BOOL bRepaint)
{
m_cFgColor = cFgColor;
// Repaint control
if (bRepaint) Invalidate();
} // End of SetFgColor
// This function sets the background color of the control.
//
// Parameters:
// [IN] cBkColor
// A GDI+ Color object indicating the background color of the knob control.
// [IN] bRepaint
// If TRUE the control will be repainted.
//
void CKnobControlST::SetBkColor(Color cBkColor, BOOL bRepaint)
{
m_cBkColor = cBkColor;
// Repaint control
if (bRepaint) Invalidate();
} // End of SetBkColor
// This function sets the scale color of the control.
//
// Parameters:
// [IN] cColor
// A GDI+ Color object indicating the scale color of the knob control.
// [IN] bRepaint
// If TRUE the control will be repainted.
//
void CKnobControlST::SetScaleColor(Color cColor, BOOL bRepaint)
{
m_cScaleColor = cColor;
// Repaint control
if (bRepaint) Invalidate();
} // End of SetScaleColor
// This function sets the alpha component of the colors used to draw the control.
//
// Parameters:
// [IN] byAlpha
// A BYTE value indicating the alpha component.
// [IN] bRepaint
// If TRUE the control will be repainted.
//
void CKnobControlST::SetAlpha(BYTE byAlpha, BOOL bRepaint)
{
ARGB argb = 0;
// Create an ARGB value from the four component values.
argb = Color::MakeARGB(byAlpha, m_cFgColor.GetR(), m_cFgColor.GetG(), m_cFgColor.GetB());
m_cFgColor.SetValue(argb);
// Create an ARGB value from the four component values.
argb = Color::MakeARGB(byAlpha, m_cScaleColor.GetR(), m_cScaleColor.GetG(), m_cScaleColor.GetB());
m_cScaleColor.SetValue(argb);
// Repaint control
if (bRepaint) Invalidate();
} // End of SetAlpha
// This function returns the alpha component of the colors used to draw the control.
//
// Return value:
// A BYTE indicating the alpha component.
//
BYTE CKnobControlST::GetAlpha()
{
return m_cFgColor.GetAlpha();
} // End of GetAlpha
// This function sets if the large scale around the control must be drawn.
//
// Parameters:
// [IN] bShow
// If TRUE the scale will be drawn.
// [IN] bRepaint
// If TRUE the control will be repainted.
//
void CKnobControlST::ShowLargeScale(BOOL bShow, BOOL bRepaint)
{
m_bShowLargeScale = bShow;
// Repaint control
if (bRepaint) Invalidate();
} // End of ShowLargeScale
// This function sets if the small scale around the control must be drawn.
//
// Parameters:
// [IN] bShow
// If TRUE the scale will be drawn.
// [IN] bRepaint
// If TRUE the control will be repainted.
//
void CKnobControlST::ShowSmallScale(BOOL bShow, BOOL bRepaint)
{
m_bShowSmallScale = bShow;
// Repaint control
if (bRepaint) Invalidate();
} // End of ShowSmallScale
// This function sets the value of the large control step.
//
// Parameters:
// [IN] nLargeChange
// New value of the large control step.
// [IN] bRepaint
// If TRUE the control will be repainted.
//
void CKnobControlST::SetLargeChangeValue(int nLargeChange, BOOL bRepaint)
{
m_nLargeChange = nLargeChange;
// Repaint control
if (bRepaint) Invalidate();
} // End of SetLargeChangeValue
// This function sets the value of the small control step.
//
// Parameters:
// [IN] nSmallChange
// New value of the small control step.
// [IN] bRepaint
// If TRUE the control will be repainted.
//
void CKnobControlST::SetSmallChangeValue(int nSmallChange, BOOL bRepaint)
{
m_nSmallChange = nSmallChange;
// Repaint control
if (bRepaint) Invalidate();
} // End of SetSmallChangeValue
// This function sets the text to show in the control tooltip.
//
// Parameters:
// [IN] nId
// ID number of the string resource containing the text to show.
// [IN] bActivate
// If TRUE the tooltip will be created active.
//
void CKnobControlST::SetTooltipText(int nId, BOOL bActivate)
{
CString sText;
// load string resource
sText.LoadString(nId);
// If string resource is not empty
if (sText.IsEmpty() == FALSE) SetTooltipText((LPCTSTR)sText, bActivate);
} // End of SetTooltipText
// This function sets the text to show in the control tooltip.
//
// Parameters:
// [IN] lpszText
// Pointer to a null-terminated string containing the text to show.
// [IN] bActivate
// If TRUE the tooltip will be created active.
//
void CKnobControlST::SetTooltipText(LPCTSTR lpszText, BOOL bActivate)
{
// We cannot accept NULL pointer
if (lpszText == NULL) return;
// Initialize ToolTip
InitToolTip();
// If there is no tooltip defined then add it
if (m_ToolTip.GetToolCount() == 0)
{
CRect rectBtn;
GetClientRect(rectBtn);
m_ToolTip.AddTool(this, lpszText, rectBtn, 1);
} // if
// Set text for tooltip
m_ToolTip.UpdateTipText(lpszText, this, 1);
m_ToolTip.Activate(bActivate);
} // End of SetTooltipText
// This function enables or disables the control tooltip.
//
// Parameters:
// [IN] bActivate
// If TRUE the tooltip will be activated.
//
void CKnobControlST::ActivateTooltip(BOOL bActivate)
{
// If there is no tooltip then do nothing
if (m_ToolTip.GetToolCount() == 0) return;
// Activate tooltip
m_ToolTip.Activate(bActivate);
} // End of ActivateTooltip
// This function sets the callback message that will be sent to the
// specified window each time the control reaches a new position.
//
// Parameters:
// [IN] hWnd
// Handle of the window that will receive the callback message.
// Pass NULL to remove any previously specified callback message.
// [IN] nMessage
// Callback message to send to window.
// [IN] wParam
// First 32 bits user specified value that will be passed to the callback function.
// [IN] lParam
// Second 32 bits user specified value that will be passed to the callback function.
//
// Remarks:
// the callback function must be in the form:
// LRESULT On_ChangeCallback(WPARAM wParam, LPARAM lParam)
// Where:
// [IN] wParam
// First 32 bits user specified value.
// [IN] lParam
// Second 32 bits user specified value.
//
// Return value:
// KNOBCONTROLST_OK
// Function executed successfully.
//
DWORD CKnobControlST::SetChangeCallback(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
{
m_csCallbacks.hWnd = hWnd;
m_csCallbacks.nMessage = nMessage;
m_csCallbacks.wParam = wParam;
m_csCallbacks.lParam = lParam;
return KNOBCONTROLST_OK;
} // End of SetChangeCallback
// This function enables the transparent mode.
// Note: this operation is not reversible.
// DrawTransparent should be called just after the control is created.
// Do not use trasparent controls until you really need it (you have a bitmapped
// background) since each transparent control makes a copy in memory of its background.
// This may bring unnecessary memory use and execution overload.
//
// Parameters:
// [IN] bRepaint
// If TRUE the control will be repainted.
//
DWORD CKnobControlST::DrawTransparent(BOOL bRepaint)
{
m_bDrawTransparent = TRUE;
// Restore old bitmap (if any)
if (m_dcBk.m_hDC != NULL && m_pbmpOldBk != NULL)
{
m_dcBk.SelectObject(m_pbmpOldBk);
} // if
m_bmpBk.DeleteObject();
m_dcBk.DeleteDC();
// Repaint the button
if (bRepaint) Invalidate();
return KNOBCONTROLST_OK;
} // End of DrawTransparent
DWORD CKnobControlST::SetBk(CDC* pDC)
{
if (m_bDrawTransparent && pDC)
{
// Restore old bitmap (if any)
if (m_dcBk.m_hDC != NULL && m_pbmpOldBk != NULL)
{
m_dcBk.SelectObject(m_pbmpOldBk);
} // if
m_bmpBk.DeleteObject();
m_dcBk.DeleteDC();
CRect rect;
CRect rect1;
GetClientRect(rect);
GetWindowRect(rect1);
GetParent()->ScreenToClient(rect1);
m_dcBk.CreateCompatibleDC(pDC);
m_bmpBk.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
m_pbmpOldBk = m_dcBk.SelectObject(&m_bmpBk);
m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, rect1.left, rect1.top, SRCCOPY);
return KNOBCONTROLST_OK;
} // if
return KNOBCONTROLST_BADPARAM;
} // End of SetBk
#undef PI