780 lines
17 KiB
C++
780 lines
17 KiB
C++
// ==========================================================================
|
|
// Class Implementation :
|
|
// COXStatic
|
|
// ==========================================================================
|
|
|
|
// Implementation file : OXStatic.cpp
|
|
|
|
// Version: 9.3
|
|
|
|
// This software along with its related components, documentation and files ("The Libraries")
|
|
// is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
|
|
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
|
|
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
|
|
// to obtain this file, or directly from our office. For a copy of the license governing
|
|
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
|
|
|
|
////////////////
|
|
// COXStatic implements a static control which could be set to use
|
|
// user-defined color and font to draw text. Also you can show tooltip
|
|
// and you can make COXStatic automatically adjust its size to fit drawn text
|
|
//
|
|
#include "StdAfx.h"
|
|
#include "OXStatic.h"
|
|
#include "UTB64Bit.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////
|
|
|
|
IMPLEMENT_DYNAMIC(COXStatic, CStatic)
|
|
|
|
BEGIN_MESSAGE_MAP(COXStatic, CStatic)
|
|
//{{AFX_MSG_MAP(COXStatic)
|
|
ON_WM_CTLCOLOR_REFLECT()
|
|
ON_MESSAGE(WM_SETTEXT,OnSetText)
|
|
ON_WM_SIZE()
|
|
ON_WM_DESTROY()
|
|
ON_WM_ERASEBKGND()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
///////////////////
|
|
// Constructor
|
|
//
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns :
|
|
// --- Effect : Constructs the object
|
|
COXStatic::COXStatic()
|
|
{
|
|
// background color
|
|
m_clrBk=::GetSysColor(COLOR_BTNFACE);
|
|
// type of filling
|
|
m_typeFillBackground=NOGRADIENT;
|
|
// text color
|
|
m_clr=::GetSysColor(COLOR_WINDOWTEXT);
|
|
|
|
m_bShowToolTip=FALSE;
|
|
m_bToolTipUserDefined=FALSE;
|
|
|
|
m_bFitToText=FALSE;
|
|
|
|
m_bCreated=FALSE;
|
|
m_bIsDefaultFontSet=FALSE;
|
|
}
|
|
|
|
|
|
void COXStatic::SetBkColor(COLORREF clr, BOOL bRedraw)
|
|
{
|
|
m_clrBk=clr;
|
|
if(bRedraw)
|
|
::InvalidateRect(GetSafeHwnd(),NULL,TRUE);
|
|
}
|
|
|
|
|
|
void COXStatic::SetBackgroundFillType(BackgroundFillType typeFillBackground,
|
|
BOOL bRedraw)
|
|
{
|
|
m_typeFillBackground=typeFillBackground;
|
|
if(bRedraw)
|
|
::InvalidateRect(GetSafeHwnd(),NULL,TRUE);
|
|
}
|
|
|
|
|
|
void COXStatic::SetTextColor(COLORREF clr, BOOL bRedraw)
|
|
{
|
|
m_clr=clr;
|
|
if(bRedraw)
|
|
::InvalidateRect(GetSafeHwnd(),NULL,TRUE);
|
|
}
|
|
|
|
// --- In : plf - pointer to LOGFONT structure
|
|
// --- Out : plf - filled the structure with the LOGFONT
|
|
// of the font that COXStatic object uses to draw text
|
|
// --- Returns: TRUE if plf was successfully populated with
|
|
// LOGINFO of the font used by COXStatic object,
|
|
// otherwise returns FALSE and plf is undefined
|
|
// --- Effect :
|
|
BOOL COXStatic::GetTextLogFont(LOGFONT* plf) const
|
|
{
|
|
if((HFONT)m_font==NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
return m_font.GetObject(sizeof(*plf),plf);
|
|
}
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
//
|
|
// --- Returns: pointer to the font used by COXStatic object if succeed,
|
|
// otherwise returns NULL
|
|
// --- Effect :
|
|
CFont* COXStatic::GetTextFont()
|
|
{
|
|
if((HFONT)m_font==NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
return &m_font;
|
|
}
|
|
|
|
// --- In : plf - pointer to LOGFONT structure
|
|
// --- Out :
|
|
// --- Returns: TRUE if font was successfully set
|
|
// --- Effect : sets the font that COXStatic object uses to draw text;
|
|
// if you call this function as SetTextLogFont(NULL) then
|
|
// text will be drawn using the font which is associated
|
|
// with CStatic window by default
|
|
BOOL COXStatic::SetTextLogFont(LOGFONT* plf, BOOL bRedraw)
|
|
{
|
|
if ((HFONT)m_font!=NULL)
|
|
{
|
|
m_font.DeleteObject();
|
|
}
|
|
|
|
BOOL bResult=TRUE;
|
|
if(plf!=NULL)
|
|
{
|
|
bResult=m_font.CreateFontIndirect(plf);
|
|
}
|
|
|
|
if(bResult)
|
|
{
|
|
if(m_bFitToText)
|
|
{
|
|
AdjustToFitText();
|
|
}
|
|
else
|
|
{
|
|
if(bRedraw)
|
|
{
|
|
::InvalidateRect(GetSafeHwnd(),NULL,TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
// --- In : pFont - pointer to CFont
|
|
// --- Out :
|
|
// --- Returns: TRUE if font was successfully set
|
|
// --- Effect : sets the font that COXStatic object uses to draw text
|
|
BOOL COXStatic::SetTextFont(CFont* pFont, BOOL bRedraw)
|
|
{
|
|
ASSERT_VALID(pFont);
|
|
|
|
BOOL bResult=TRUE;
|
|
if(pFont!=&m_font)
|
|
{
|
|
if ((HFONT)m_font!=NULL)
|
|
m_font.DeleteObject();
|
|
|
|
LOGFONT lf;
|
|
bResult=pFont->GetLogFont(&lf);
|
|
if(bResult)
|
|
bResult=m_font.CreateFontIndirect(&lf);
|
|
}
|
|
|
|
if(bResult)
|
|
{
|
|
if(m_bFitToText)
|
|
{
|
|
AdjustToFitText();
|
|
}
|
|
else
|
|
{
|
|
if(bRedraw)
|
|
{
|
|
::InvalidateRect(GetSafeHwnd(),NULL,TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns: TRUE if default font was successfully set to the
|
|
// COXStatic object, otherwise returns FALSE
|
|
// --- Effect : make COXStatic object to use default font to draw text.
|
|
// Note that function declared as virtual, so you can put
|
|
// in any derivation of COXStatic class your own definition
|
|
// of "default font". COXStatic class uses the font which is
|
|
// associated with CStatic window as default.
|
|
BOOL COXStatic::SetDefaultTextFont()
|
|
{
|
|
if(!IsStaticText(this))
|
|
return TRUE;
|
|
|
|
CFont* pFont=GetFont();
|
|
if(pFont==NULL)
|
|
return FALSE;
|
|
|
|
ASSERT_VALID(pFont);
|
|
|
|
if((HFONT)m_font!=NULL)
|
|
m_font.DeleteObject();
|
|
|
|
LOGFONT lf;
|
|
BOOL bResult=pFont->GetObject(sizeof(lf), &lf);
|
|
if(bResult)
|
|
{
|
|
bResult=m_font.CreateFontIndirect(&lf);
|
|
|
|
if (bResult && m_bFitToText)
|
|
AdjustToFitText();
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
// if TRUE then we will adjust size of static control window
|
|
// to match the size of the text otherwise we will use original
|
|
// size of static control's window
|
|
void COXStatic::SetFitToText(BOOL bFitText)
|
|
{
|
|
m_bFitToText=bFitText;
|
|
AdjustToFitText();
|
|
}
|
|
|
|
// Sets the tooltip text. If tooltip text wasn't set and tootip control is still
|
|
// to be shown then COXStatic would use window's text as the tooltip text
|
|
void COXStatic::SetToolTipText(LPCTSTR sText)
|
|
{
|
|
m_sToolTipText=sText;
|
|
|
|
if(m_sToolTipText.IsEmpty())
|
|
{
|
|
// mark tooltip text as not userdefined to use
|
|
// window text as tooltip
|
|
m_bToolTipUserDefined=FALSE;
|
|
}
|
|
else
|
|
{
|
|
// mark tooltip text as userdefined
|
|
m_bToolTipUserDefined=TRUE;
|
|
}
|
|
|
|
FormatToolTipText();
|
|
}
|
|
|
|
// Returns tooltip text if it was set previously by SetToolTipText function.
|
|
// If bForse is TRUE then returns the tooltip text even if it wasn't set by
|
|
// SetToolTipText function, otherwise returns empty string
|
|
CString COXStatic::GetToolTipText(BOOL bForce)
|
|
{
|
|
if(!bForce && !m_bToolTipUserDefined)
|
|
{
|
|
return _T("");
|
|
}
|
|
return m_sToolTipText;
|
|
}
|
|
|
|
// if set to TRUE, the tooltip will be shown (by default TRUE)
|
|
void COXStatic::SetShowToolTip(BOOL bShowToolTip)
|
|
{
|
|
m_bShowToolTip=bShowToolTip;
|
|
|
|
if(::IsWindow(m_ttc.GetSafeHwnd()))
|
|
// activate/deactivate tooltip control
|
|
m_ttc.Activate(m_bShowToolTip);
|
|
|
|
FormatToolTipText();
|
|
}
|
|
|
|
//////////////////
|
|
// Handle reflected WM_CTLCOLOR to set custom control color and font.
|
|
// For non-text controls, do nothing.
|
|
// Note that function is declared as virtual, so any COXStatic derived
|
|
// class can define its own function to draw itself.
|
|
//
|
|
HBRUSH COXStatic::CtlColor(CDC* pDC, UINT nCtlColor)
|
|
{
|
|
UNREFERENCED_PARAMETER(nCtlColor);
|
|
|
|
ASSERT(nCtlColor==CTLCOLOR_STATIC);
|
|
DWORD dwStyle=GetStyle();
|
|
if (!(dwStyle & SS_NOTIFY))
|
|
{
|
|
// Turn on notify flag to get mouse messages and STN_CLICKED.
|
|
// Otherwise, I'll never get any mouse clicks!
|
|
::SetWindowLongPtr(m_hWnd, GWL_STYLE, dwStyle | SS_NOTIFY);
|
|
}
|
|
|
|
HBRUSH hbr = NULL;
|
|
if(IsStaticText(this))
|
|
{
|
|
// this is a text control: set up font and colors
|
|
//
|
|
|
|
if((HFONT)m_font!=NULL)
|
|
{
|
|
// use our font
|
|
pDC->SelectObject(&m_font);
|
|
}
|
|
|
|
// use our visited/unvisited colors
|
|
pDC->SetTextColor(m_clr);
|
|
pDC->SetBkMode(TRANSPARENT);
|
|
|
|
// return hollow brush to preserve parent background color
|
|
hbr=(HBRUSH)::GetStockObject(HOLLOW_BRUSH);
|
|
}
|
|
return hbr;
|
|
}
|
|
|
|
// handles WM_SETTEXT message in order to possibly adjust size of
|
|
// control's window or update tooltip text
|
|
LRESULT COXStatic::OnSetText(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UNREFERENCED_PARAMETER(wParam);
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
|
|
BOOL bResult=(BOOL)Default();
|
|
|
|
FormatToolTipText();
|
|
if(m_bFitToText)
|
|
AdjustToFitText();
|
|
RedrawWindow();
|
|
|
|
return bResult;
|
|
}
|
|
|
|
// if m_bFitToText is TRUE then adjusts the size of control's window
|
|
// to the size of the text, otherwise set size of window to its original size
|
|
void COXStatic::AdjustToFitText()
|
|
{
|
|
if(!IsStaticText(this))
|
|
{
|
|
// just return if static control is not text control
|
|
return;
|
|
}
|
|
|
|
// get the parent window
|
|
// all operations with coordinates use parent as origin
|
|
CWnd* pParent = GetParent();
|
|
if(pParent==NULL)
|
|
{
|
|
// just return if we didn't find any parent
|
|
return;
|
|
}
|
|
|
|
CRect rect;
|
|
if (!m_bFitToText)
|
|
{
|
|
// if m_bFitToText is FALSE then reset the size of control's window
|
|
// to its original size
|
|
rect=m_rectOriginal;
|
|
}
|
|
else
|
|
{
|
|
// Get the current window position
|
|
GetWindowRect(rect);
|
|
|
|
pParent->ScreenToClient(rect);
|
|
|
|
// Get the size of the window text
|
|
CString strWndText;
|
|
GetWindowText(strWndText);
|
|
|
|
CDC* pDC = GetDC();
|
|
CFont* pOldFont=NULL;
|
|
if ((HFONT)m_font!=NULL)
|
|
{
|
|
// use our font
|
|
pOldFont=pDC->SelectObject(&m_font);
|
|
}
|
|
CSize sizeText = pDC->GetTextExtent(strWndText);
|
|
if(pOldFont!=NULL)
|
|
{
|
|
pDC->SelectObject(pOldFont);
|
|
}
|
|
ReleaseDC(pDC);
|
|
|
|
// make sure the size of text is no more than the size of
|
|
// the client part of parent window
|
|
CRect rectClient;
|
|
pParent->GetClientRect(&rectClient);
|
|
if(sizeText.cx>rectClient.Width())
|
|
{
|
|
sizeText.cx=rectClient.Width();
|
|
}
|
|
if(sizeText.cy>rectClient.Height())
|
|
{
|
|
sizeText.cy=rectClient.Height();
|
|
}
|
|
|
|
// Get the text justification via the window style
|
|
DWORD dwStyle = GetStyle();
|
|
|
|
// Recalc the window size and position based on the text justification
|
|
if(dwStyle & SS_CENTERIMAGE)
|
|
{
|
|
rect.DeflateRect(0, (rect.Height() - sizeText.cy)/2);
|
|
}
|
|
else
|
|
{
|
|
rect.bottom = rect.top + sizeText.cy;
|
|
}
|
|
|
|
DWORD dwStaticStyle=GetStyle()&0x0000000f;
|
|
switch(dwStaticStyle)
|
|
{
|
|
// SS_CENTER
|
|
case 1:
|
|
rect.DeflateRect((rect.Width() - sizeText.cx)/2, 0);
|
|
break;
|
|
// SS_RIGHT
|
|
case 2:
|
|
rect.left=rect.right - sizeText.cx;
|
|
break;
|
|
// SS_LEFT
|
|
default:
|
|
rect.right=rect.left + sizeText.cx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Change information about window's rect in tooltip control
|
|
if(::IsWindow(m_ttc.GetSafeHwnd()))
|
|
{
|
|
CToolInfo toolInfo;
|
|
if(m_ttc.GetToolInfo(toolInfo,this,ID_HLTOOLTIP))
|
|
{
|
|
toolInfo.rect.left=0;
|
|
toolInfo.rect.top=0;
|
|
toolInfo.rect.right=rect.Width();
|
|
toolInfo.rect.bottom=rect.Height();
|
|
m_ttc.SetToolInfo(&toolInfo);
|
|
}
|
|
}
|
|
|
|
// Move the window
|
|
SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER);
|
|
}
|
|
|
|
// builds tooltip text
|
|
void COXStatic::FormatToolTipText()
|
|
{
|
|
// set only if tooltip is shown
|
|
if(m_bShowToolTip)
|
|
{
|
|
// if tooltip text wasn't set then set it to the window text
|
|
if(!m_bToolTipUserDefined)
|
|
{
|
|
if(IsStaticText(this))
|
|
{
|
|
GetWindowText(m_sToolTipText);
|
|
}
|
|
else
|
|
{
|
|
m_sToolTipText.Empty();
|
|
}
|
|
}
|
|
|
|
if(::IsWindow(m_ttc.GetSafeHwnd()))
|
|
m_ttc.UpdateTipText(m_sToolTipText, this, ID_HLTOOLTIP);
|
|
}
|
|
}
|
|
|
|
// handle it to pass a mouse message to a tool tip control for processing
|
|
BOOL COXStatic::PreTranslateMessage(MSG* pMsg)
|
|
{
|
|
if(::IsWindow(m_ttc.GetSafeHwnd()))
|
|
{
|
|
m_ttc.Activate(m_bShowToolTip);
|
|
m_ttc.RelayEvent(pMsg);
|
|
}
|
|
return CStatic::PreTranslateMessage(pMsg);
|
|
}
|
|
|
|
// handle it to initialize tooltip control and save the original size
|
|
// of static control window
|
|
void COXStatic::PreSubclassWindow()
|
|
{
|
|
if(!m_bCreated && !InitStatic())
|
|
{
|
|
TRACE(_T("COXStatic::PreSubclassWindow: failed to initialize static control\n"));
|
|
}
|
|
|
|
CStatic::PreSubclassWindow();
|
|
}
|
|
|
|
// handle it to update original size of window and if m_bFitToText is TRUE then
|
|
// resize it to fit to its text
|
|
void COXStatic::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
CStatic::OnSize(nType, cx, cy);
|
|
|
|
// TODO: Add your message handler code here
|
|
if(m_bFitToText)
|
|
{
|
|
AdjustToFitText();
|
|
}
|
|
else
|
|
{
|
|
// update the original size of the static control window
|
|
GetWindowRect(&m_rectOriginal);
|
|
CWnd* pParent = GetParent();
|
|
if(pParent!=NULL)
|
|
{
|
|
pParent->ScreenToClient(&m_rectOriginal);
|
|
}
|
|
|
|
// Change information about window's rect in tooltip control
|
|
if(::IsWindow(m_ttc.GetSafeHwnd()))
|
|
{
|
|
CToolInfo toolInfo;
|
|
if(m_ttc.GetToolInfo(toolInfo,this,ID_HLTOOLTIP))
|
|
{
|
|
toolInfo.rect.left=0;
|
|
toolInfo.rect.top=0;
|
|
toolInfo.rect.right=m_rectOriginal.Width();
|
|
toolInfo.rect.bottom=m_rectOriginal.Height();
|
|
m_ttc.SetToolInfo(&toolInfo);
|
|
}
|
|
}
|
|
|
|
RedrawWindow();
|
|
}
|
|
}
|
|
|
|
// helper function, defines if static control displays text or graphics
|
|
BOOL COXStatic::IsStaticText(CStatic* pStatic) const
|
|
{
|
|
DWORD dwStyle=pStatic->GetStyle();
|
|
return ((dwStyle&0xFF)>SS_RIGHT && (dwStyle&0xFF)!=SS_SIMPLE &&
|
|
(dwStyle&0xFF)!=SS_LEFTNOWORDWRAP) ? FALSE : TRUE;
|
|
}
|
|
|
|
BOOL COXStatic::InitStatic()
|
|
{
|
|
ASSERT(::IsWindow(GetSafeHwnd()));
|
|
|
|
// save the original size of the static control window
|
|
GetWindowRect(&m_rectOriginal);
|
|
CWnd* pParent = GetParent();
|
|
if(pParent!=NULL)
|
|
{
|
|
pParent->ScreenToClient(&m_rectOriginal);
|
|
}
|
|
|
|
// Create the tooltip
|
|
CRect rect;
|
|
GetClientRect(rect);
|
|
m_ttc.Create(this);
|
|
m_ttc.AddTool(this, m_sToolTipText, rect, ID_HLTOOLTIP);
|
|
|
|
FormatToolTipText();
|
|
|
|
// set up default font once!
|
|
if(!m_bIsDefaultFontSet && SetDefaultTextFont())
|
|
m_bIsDefaultFontSet=TRUE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL COXStatic::Create(LPCTSTR lpszText, DWORD dwStyle, const RECT& rect,
|
|
CWnd* pParentWnd, UINT nID/*=0xffff*/)
|
|
{
|
|
// mark control as being created
|
|
m_bCreated=TRUE;
|
|
|
|
BOOL bResult=CStatic::Create(lpszText, dwStyle, rect, pParentWnd, nID);
|
|
if(bResult)
|
|
{
|
|
// Initialize static control
|
|
if(!InitStatic())
|
|
{
|
|
TRACE(_T("COXStatic::Create: failed to initialize static control"));
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
void COXStatic::OnDestroy()
|
|
{
|
|
if(::IsWindow(m_ttc.GetSafeHwnd()))
|
|
{
|
|
m_ttc.DelTool(this, ID_HLTOOLTIP);
|
|
m_ttc.DestroyWindow();
|
|
}
|
|
|
|
CStatic::OnDestroy();
|
|
}
|
|
|
|
BOOL COXStatic::OnEraseBkgnd(CDC* pDC)
|
|
{
|
|
// redraw the background
|
|
if(m_clrBk!=CLR_NONE)
|
|
{
|
|
DrawBackground(pDC);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void COXStatic::DrawBackground(CDC* pDC)
|
|
{
|
|
ASSERT(pDC!=NULL);
|
|
|
|
CRect rect;
|
|
GetClientRect(rect);
|
|
pDC->IntersectClipRect(rect);
|
|
|
|
switch(m_typeFillBackground)
|
|
{
|
|
case NOGRADIENT:
|
|
{
|
|
CBrush brush(m_clrBk);
|
|
ASSERT((HBRUSH)brush!=NULL);
|
|
pDC->FillRect(rect,&brush);
|
|
break;
|
|
}
|
|
case GRADIENT_LEFT:
|
|
case GRADIENT_CENTER:
|
|
case GRADIENT_RIGHT:
|
|
{
|
|
FillGradient(pDC,m_typeFillBackground,rect,GetBkColor());
|
|
break;
|
|
}
|
|
default:
|
|
ASSERT(FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
void COXStatic::FillGradient(CDC* pDC, BackgroundFillType typeFillBackground,
|
|
CRect rect, COLORREF clr)
|
|
{
|
|
ASSERT(typeFillBackground!=NOGRADIENT);
|
|
|
|
// red, green and blue color vals
|
|
COLORREF clrBackground=clr;
|
|
int red=GetRValue(clrBackground);
|
|
int green=GetGValue(clrBackground);
|
|
int blue=GetBValue(clrBackground);
|
|
|
|
int cxCap=rect.Width();
|
|
int cyCap=rect.Height();
|
|
|
|
int nCurBlock;
|
|
// width of area to shade and width squared
|
|
int nWidth, nWidth_x_2;
|
|
// width of one shade band
|
|
int nDelta;
|
|
UINT nNumberShade=128;
|
|
|
|
switch(typeFillBackground)
|
|
{
|
|
case GRADIENT_LEFT:
|
|
{
|
|
nCurBlock=cxCap;
|
|
nWidth=cxCap;
|
|
nWidth_x_2=cxCap*cxCap;
|
|
nDelta=__max(nWidth/nNumberShade,1);
|
|
|
|
while(nCurBlock>0)
|
|
{
|
|
// paint bands right to left
|
|
int nRest_x_2=(nWidth-nCurBlock)*(nWidth-nCurBlock);
|
|
PaintRect(pDC, nCurBlock, 0, nDelta, cyCap,
|
|
RGB(red-(red*nRest_x_2)/nWidth_x_2,
|
|
green-(green*nRest_x_2)/nWidth_x_2,
|
|
blue-(blue*nRest_x_2)/nWidth_x_2));
|
|
// next band
|
|
nCurBlock-=nDelta;
|
|
}
|
|
// whatever's left ==> black
|
|
PaintRect(pDC,0,0,nCurBlock+nDelta,cyCap,RGB(0,0,0));
|
|
|
|
break;
|
|
}
|
|
|
|
case GRADIENT_CENTER:
|
|
{
|
|
nCurBlock=cxCap/2;
|
|
nWidth=cxCap/2;
|
|
nWidth_x_2=cxCap*cxCap/4;
|
|
nDelta=__max(nWidth/(2*nNumberShade),1);
|
|
|
|
while(nCurBlock>0)
|
|
{
|
|
// paint bands right to left
|
|
int nRest_x_2=(nWidth-nCurBlock)*(nWidth-nCurBlock);
|
|
PaintRect(pDC, nWidth+nCurBlock, 0, nDelta, cyCap,
|
|
RGB(red-(red*nRest_x_2)/nWidth_x_2,
|
|
green-(green*nRest_x_2)/nWidth_x_2,
|
|
blue-(blue*nRest_x_2)/nWidth_x_2));
|
|
// next band
|
|
nCurBlock-=nDelta;
|
|
}
|
|
// whatever's left ==> black
|
|
PaintRect(pDC,nWidth,0,nCurBlock+nDelta,cyCap,RGB(0,0,0));
|
|
|
|
nCurBlock=0;
|
|
while(nCurBlock<=nWidth)
|
|
{
|
|
// paint bands left to right
|
|
int nRest_x_2=nCurBlock*nCurBlock;
|
|
PaintRect(pDC, nCurBlock, 0, nDelta, cyCap,
|
|
RGB(red-(red*nRest_x_2)/nWidth_x_2,
|
|
green-(green*nRest_x_2)/nWidth_x_2,
|
|
blue-(blue*nRest_x_2)/nWidth_x_2));
|
|
// next band
|
|
nCurBlock+=nDelta;
|
|
}
|
|
// whatever's left ==> black
|
|
PaintRect(pDC,nCurBlock-nDelta,0,nWidth-nCurBlock+nDelta,cyCap,RGB(0,0,0));
|
|
|
|
break;
|
|
}
|
|
|
|
case GRADIENT_RIGHT:
|
|
{
|
|
nCurBlock=0;
|
|
nWidth=cxCap;
|
|
nWidth_x_2=cxCap*cxCap;
|
|
nDelta=__max(nWidth/nNumberShade,1);
|
|
|
|
while(nCurBlock<nWidth)
|
|
{
|
|
// paint bands left to right
|
|
int nRest_x_2=nCurBlock*nCurBlock;
|
|
PaintRect(pDC, nCurBlock, 0, nDelta, cyCap,
|
|
RGB(red-(red*nRest_x_2)/nWidth_x_2,
|
|
green-(green*nRest_x_2)/nWidth_x_2,
|
|
blue-(blue*nRest_x_2)/nWidth_x_2));
|
|
// next band
|
|
nCurBlock+=nDelta;
|
|
}
|
|
// whatever's left ==> black
|
|
PaintRect(pDC,nCurBlock-nDelta,0,nWidth-nCurBlock+nDelta-1,cyCap,RGB(0,0,0));
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void COXStatic::PaintRect(CDC* pDC, int x, int y, int w, int h, COLORREF color)
|
|
{
|
|
CBrush brush(color);
|
|
CBrush* pOldBrush = pDC->SelectObject(&brush);
|
|
pDC->PatBlt(x, y, w, h, PATCOPY);
|
|
pDC->SelectObject(pOldBrush);
|
|
}
|
|
|