📄 atllabel.h
字号:
//
//
m_lf.lfEscapement = m_lf.lfOrientation = (nAngle * 10);
m_bRotation = bRotation;
ReconstructFont();
UpdateSurface();
return *this;
}
// =============================================================================================
// Function name : SetText3DHiliteColor
// Description : Sets the 3D font hilite color
// Return type : Reference to 'this' object
// Argument : COLORREF cr3DHiliteColor
// =============================================================================================
virtual CLabel& SetText3DHiliteColor(COLORREF cr3DHiliteColor)
{
m_cr3DHiliteColor = cr3DHiliteColor;
UpdateSurface();
return *this;
}
// =============================================================================================
// Function name : SubclassWindow
// Description :
// Return type : BOOL
// Argument : HWND hWnd
// =============================================================================================
BOOL SubclassWindow(HWND hWnd)
{
BOOL bRet = CWindowImpl<CLabel, CStatic>::SubclassWindow(hWnd);
if(bRet)
Init();
return bRet;
}
protected:
// =============================================================================================
// Function name : UpdateSurface
// Description :
// Return type : void
// =============================================================================================
void UpdateSurface()
{
CRect (rc);
GetWindowRect(rc);
RedrawWindow();
CWindow parent(GetParent());
parent.ScreenToClient(rc);
parent.InvalidateRect(rc,TRUE);
parent.UpdateWindow();
}
// =============================================================================================
// Function name : ReconstructFont
// Description : Helper function to build font after it was changed
// Return type : void
// =============================================================================================
void ReconstructFont()
{
if(m_hFont != NULL)
{
::DeleteObject(m_hFont);
m_hFont = NULL;
}
m_hFont = ::CreateFontIndirect(&m_lf);
ATLASSERT(m_hFont);
}
// =============================================================================================
// Function name : DrawGradientFill
// Description : Internal help function to gradient fill background
// Return type : void
// Argument : CDC* pDC
// Argument : CRect* pRect
// Argument : COLORREF crStart
// Argument : COLORREF crEnd
// Argument : int nSegments
// =============================================================================================
void DrawGradientFill(CDC* pDC, CRect* pRect, COLORREF crStart, COLORREF crEnd, int nSegments)
{
// Get the starting RGB values and calculate the incremental
// changes to be applied.
COLORREF cr;
int nR = GetRValue(crStart);
int nG = GetGValue(crStart);
int nB = GetBValue(crStart);
int neB = GetBValue(crEnd);
int neG = GetGValue(crEnd);
int neR = GetRValue(crEnd);
if(nSegments > pRect->Width())
nSegments = pRect->Width();
int nDiffR = (neR - nR);
int nDiffG = (neG - nG);
int nDiffB = (neB - nB);
int ndR = 256 * (nDiffR) / (max(nSegments,1));
int ndG = 256 * (nDiffG) / (max(nSegments,1));
int ndB = 256 * (nDiffB) / (max(nSegments,1));
nR *= 256;
nG *= 256;
nB *= 256;
neR *= 256;
neG *= 256;
neB *= 256;
int nCX = pRect->Width() / max(nSegments,1), nLeft = pRect->left, nRight;
pDC->SelectStockPen(NULL_PEN);
for (int i = 0; i < nSegments; i++, nR += ndR, nG += ndG, nB += ndB)
{
// Use special code for the last segment to avoid any problems
// with integer division.
if (i == (nSegments - 1))
nRight = pRect->right;
else
nRight = nLeft + nCX;
cr = RGB(nR / 256, nG / 256, nB / 256);
{
CBrush br;
br.CreateSolidBrush(cr);
HBRUSH pbrOld = pDC->SelectBrush(br);
pDC->Rectangle(nLeft, pRect->top, nRight + 1, pRect->bottom);
pDC->SelectBrush(pbrOld);
}
// Reset the left side of the drawing rectangle.
nLeft = nRight;
}
}
COLORREF m_crText;
COLORREF m_cr3DHiliteColor;
HBRUSH m_hwndBrush;
HBRUSH m_hBackBrush;
LOGFONT m_lf;
HFONT m_hFont;
CString m_strText;
BOOL m_bState;
BOOL m_bTimer;
BOOL m_bLink;
BOOL m_bTransparent;
BOOL m_bFont3d;
BOOL m_bToolTips;
BOOL m_bNotifyParent;
BOOL m_bRotation;
BOOL m_bPaintLabel;
FlashType m_Type;
HCURSOR m_hCursor;
Type3D m_3dType;
BackFillMode m_fillmode;
COLORREF m_crHiColor;
COLORREF m_crLoColor;
protected:
// =============================================================================================
// Function name : OnPaint
// Description : Handles all the drawing code for the label
// : Called by Windows... not by USER
// Return type : LRESULT
// Argument : UINT
// Argument : WPARAM wParam
// Argument : LPARAM
// Argument : BOOL& bHandled
// =============================================================================================
LRESULT OnPaint(UINT, WPARAM wParam, LPARAM, BOOL& bHandled)
{
if(!m_bPaintLabel)
{
bHandled = FALSE;
return 1;
}
CPaintDC dc(m_hWnd); // device context for painting
DWORD dwFlags = 0;
CRect rc;
GetClientRect(rc);
TCHAR cValue[1000];
GetWindowText(cValue, sizeof(cValue));
CString strText(cValue);
CBitmap bmp;
// Set up for double buffering...
CDC* pDCMem;
if (!m_bTransparent)
{
pDCMem = new CDC;
pDCMem->CreateCompatibleDC(dc.m_hDC);
bmp.CreateCompatibleBitmap(dc.m_hDC,rc.Width(),rc.Height());
pDCMem->SelectBitmap(bmp);
}
else
{
pDCMem = &dc;
}
UINT nMode = pDCMem->SetBkMode(TRANSPARENT);
COLORREF crText = pDCMem->SetTextColor(m_crText);
HFONT OldTempFont;
if(m_hFont != NULL)
OldTempFont = pDCMem->SelectFont(m_hFont);
// Fill in backgound if not transparent
if (!m_bTransparent)
{
if (m_fillmode == Normal)
{
CBrush br;
if (m_hBackBrush != NULL)
br.Attach(m_hBackBrush);
else
br.Attach(m_hwndBrush);
pDCMem->FillRect(rc,br);
br.Detach();
}
else // Gradient Fill
{
DrawGradientFill(pDCMem, &rc, m_crLoColor, m_crHiColor, 100);
}
}
// If the text is flashing turn the text color on
// then to the color of the window background.
LOGBRUSH lb;
ZeroMemory(&lb,sizeof(lb));
// Stop Checking complaining
if (m_hBackBrush)
::GetObject(m_hBackBrush,sizeof(lb),&lb);
// Something to do with flashing
if (!m_bState && m_Type == Text)
pDCMem->SetTextColor(lb.lbColor);
DWORD style = GetStyle();
switch (style & SS_TYPEMASK)
{
case SS_RIGHT:
dwFlags = DT_RIGHT | DT_WORDBREAK;
break;
case SS_CENTER:
dwFlags = SS_CENTER | DT_WORDBREAK;
break;
case SS_LEFTNOWORDWRAP:
dwFlags = DT_LEFT;
break;
default: // treat other types as left
case SS_LEFT:
dwFlags = DT_LEFT | DT_WORDBREAK;
break;
}
// If the text centered make an assumtion that
// the will want to center verticly as well
if (style & SS_CENTERIMAGE)
{
dwFlags = DT_CENTER;
// Apply
if (strText.Find(_T("\r\n")) == -1)
{
dwFlags |= DT_VCENTER;
// And because DT_VCENTER only works with single lines
dwFlags |= DT_SINGLELINE;
}
}
//
// 3333 DDDDD
// 3 D D
// 33 D D E F X
// 3 D D
// 3333 DDDDD
//
//
if (m_bRotation)
{
int nAlign = pDCMem->SetTextAlign (TA_BASELINE);
CPoint pt;
GetViewportOrgEx (pDCMem->m_hDC,&pt) ;
SetViewportOrgEx (pDCMem->m_hDC,rc.Width() / 2, rc.Height() / 2, NULL) ;
pDCMem->TextOut (0, 0, strText) ;
SetViewportOrgEx (pDCMem->m_hDC,pt.x / 2, pt.y / 2, NULL) ;
pDCMem->SetTextAlign (nAlign);
}
else
{
pDCMem->DrawText(cValue, -1,rc,dwFlags);
if (m_bFont3d)
{
pDCMem->SetTextColor(m_cr3DHiliteColor);
if (m_3dType == Raised)
rc.OffsetRect(-1,-1);
else
rc.OffsetRect(1,1);
pDCMem->DrawText(cValue, -1, rc,dwFlags);
m_3dType;
}
}
// Restore DC's State
pDCMem->SetBkMode(nMode);
pDCMem->SelectFont(OldTempFont);
pDCMem->SetTextColor(crText);
if (!m_bTransparent)
{
dc.BitBlt(0,0,rc.Width(),rc.Height(),pDCMem->m_hDC,0,0,SRCCOPY);
delete pDCMem;
}
return 0;
}
// =============================================================================================
// Function name : OnTimer
// Description : Used in conjunction with 'FLASH' functions
// Return type : LRESULT
// Argument : UINT uMsg
// Argument : WPARAM wParam
// Argument : LPARAM lParam
// Argument : BOOL& bHandled
// =============================================================================================
LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
m_bState = !m_bState;
UpdateSurface();
return 0;
}
// =============================================================================================
// Function name : OnSysColorChange
// Description :
// Return type : LRESULT
// Argument : UINT uMsg
// Argument : WPARAM wParam
// Argument : LPARAM lParam
// Argument : BOOL& bHandled
// =============================================================================================
LRESULT OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (m_hwndBrush)
::DeleteObject(m_hwndBrush);
m_hwndBrush = ::CreateSolidBrush(GetSysColor(COLOR_3DFACE));
UpdateSurface();
return 0;
}
// =============================================================================================
// Function name : OnLButtonDown
// Description : Called when a link is click on
// Return type : LRESULT
// Argument : UINT uMsg
// Argument : WPARAM wParam
// Argument : LPARAM lParam
// Argument : BOOL& bHandled
// =============================================================================================
LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (!m_bNotifyParent) // Fix
{
TCHAR cValue[1000];
GetWindowText(cValue, sizeof(cValue));
CString strLink(cValue);
ShellExecute(NULL,_T("open"),strLink,NULL,NULL,SW_SHOWNORMAL);
}
else
{
// To use notification in parent window
// Respond to a OnNotify in parent and disassemble the message
//
NMHDR nm;
nm.hwndFrom = m_hWnd;
nm.idFrom = GetDlgCtrlID();
nm.code = NM_LINKCLICK;
CWindow wnd(GetParent());
wnd.SendMessage(WM_NOTIFY,nm.idFrom,(LPARAM) &nm);
}
return 0;
}
// =============================================================================================
// Function name : OnSetCursor
// Description : Used in conjunction with 'LINK' function
// Return type : LRESULT
// Argument : UINT uMsg
// Argument : WPARAM wParam
// Argument : LPARAM lParam
// Argument : BOOL& bHandled
// =============================================================================================
LRESULT OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (m_hCursor)
{
::SetCursor(m_hCursor);
return TRUE;
}
return 0;
}
// =============================================================================================
// Function name : Init
// Description :
// Return type : void
// =============================================================================================
void Init()
{
ATLASSERT(::IsWindow(m_hWnd));
// Check if we should paint a label
TCHAR lpszBuffer[8];
if(::GetClassName(m_hWnd, lpszBuffer, 8))
{
if(lstrcmpi(lpszBuffer, _T("static")) == 0)
{
ModifyStyle(0, SS_NOTIFY); // we need this
DWORD dwStyle = GetStyle() & 0x000000FF;
if(dwStyle == SS_ICON || dwStyle == SS_BLACKRECT || dwStyle == SS_GRAYRECT ||
dwStyle == SS_WHITERECT || dwStyle == SS_BLACKFRAME || dwStyle == SS_GRAYFRAME ||
dwStyle == SS_WHITEFRAME || dwStyle == SS_OWNERDRAW ||
dwStyle == SS_BITMAP || dwStyle == SS_ENHMETAFILE)
m_bPaintLabel = FALSE;
}
}
// set font
if(m_bPaintLabel)
{
CWindow wnd = GetParent();
CFontHandle font = wnd.GetFont();
if(font.m_hFont != NULL)
{
font.GetLogFont(&m_lf);
m_hFont = ::CreateFontIndirect(&m_lf);
}
}
}
};
/////////////////////////////////////////////////////////////////////////////
#endif // !defined(ATL_LABEL_H)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -