// LabelEx.cpp : implementation file // #include "stdafx.h" #include "ylgl.h" #include "LabelEx.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // caculate the logic x and y, change into physics x and y.(int printer DC) //#define CALCF(x) (-MulDiv(x, GetDeviceCaps(pDC->m_hDC, LOGPIXELSY), 72)) //#define CALCY(y) (MulDiv(y, GetDeviceCaps(pDC->m_hDC, LOGPIXELSY), 72)) //#define CALCX(x) (MulDiv(x, GetDeviceCaps(pDC->m_hDC, LOGPIXELSX), 72)) #define CALCF2(x) (x) #define CALCY2(y) (y) #define CALCX2(x) (x) // each added font can have 4 attributes #define FACE_NORMAL 0 #define FACE_NORMALBOLD 1 #define FACE_BIG 2 #define FACE_BIGBOLD 3 // for Print text, you should let it by left or right, and up or bottom // these formats can be combined with the | operator #define FORMAT_NORMAL 0 //default should be by left and top #define FORMAT_HCENTER 1 #define FORMAT_VCENTER 2 #define FORMAT_RIGHT 4 #define FORMAT_LEFT 8 #define FORMAT_UP 16 #define FORMAT_BOTTOM 32 ///////////////////////////////////////////////////////////////////////////// // CLabelEx CLabelEx::CLabelEx() { m_bClicked=FALSE; m_bOver=FALSE; m_bUnderLine=FALSE; m_bAutoUnderLine=FALSE; m_bBorder=FALSE; m_bHighLight=TRUE; m_bBackUnderLine=FALSE; m_crText=RGB(0,0,0); m_crBorder=RGB(0,0,0); m_crBG=RGB(255,255,255); m_crUnderLine=RGB(0,0,255); m_hHandCur=AfxGetApp()->LoadCursor(IDC_HAND); } CLabelEx::~CLabelEx() { if(m_BGBm.GetSafeHandle()!=NULL) m_BGBm.DeleteObject(); if(m_MouseOverBGBm.GetSafeHandle()!=NULL) m_MouseOverBGBm.DeleteObject(); if(m_ClickedBGBm.GetSafeHandle()!=NULL) m_ClickedBGBm.DeleteObject(); if(m_LabelBm.GetSafeHandle()!=NULL) m_LabelBm.DeleteObject(); if(m_MouseOverLabelBm.GetSafeHandle()!=NULL) m_MouseOverLabelBm.DeleteObject(); if(m_ClickedLabelBm.GetSafeHandle()!=NULL) m_ClickedLabelBm.DeleteObject(); } BEGIN_MESSAGE_MAP(CLabelEx, CStatic) //{{AFX_MSG_MAP(CLabelEx) ON_WM_PAINT() ON_WM_MOUSEMOVE() ON_WM_LBUTTONDOWN() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CLabelEx message handlers void CLabelEx::AutoDraw2(CDC *pDC, CRect &StrRect, CString &str, float fscale) {//不支持换行 CString tempbz,temp; BOOL bRun=0; CSize size; int fontsize=24; int i=0; LOGFONT log; ll: tempbz=str; i=0; SetFontFace(pDC, fontsize, 1, "宋体"); while(1) { if(!tempbz.IsEmpty ()) { temp=tempbz; GetStrSize(pDC, (LPTSTR)(LPCTSTR)temp, size); CRect temprc=StrRect; if(size.cx>temprc.Width ())break; tempbz=""; if(bRun) { // pDC->DrawText (temp, temprc, DT_LEFT|DT_VCENTER|DT_SINGLELINE); DrawText(pDC, (LPTSTR)(LPCTSTR)temp, temprc, 0, 0, FORMAT_LEFT | FORMAT_VCENTER); } } else break; } if(tempbz.IsEmpty ()==0) { fontsize--; goto ll; } if(bRun==0) { bRun=1; goto ll; } } void CLabelEx::AutoDraw(CDC *pDC, CRect &StrRect, CString &str, float fscale) { CString tempbz,temp; BOOL bRun=0; CSize size; int fontsize=24; int i=0; LOGFONT log; ll: tempbz=str; i=0; SetFontFace(pDC, fontsize, 1, "宋体"); while(1) { if(!tempbz.IsEmpty ()) { temp=tempbz; GetStrSize(pDC, (LPTSTR)(LPCTSTR)temp, size); int right=0; CRect temprc=StrRect; temprc.top += i*(fontsize*fscale);i++; temprc.bottom =temprc.top +fontsize; if(temprc.bottom >StrRect.bottom )break; while(size.cx>temprc.Width ()) { right++; temp=tempbz.Left (tempbz.GetLength ()-(right)); if(GIsHalfHZ(temp)) { right++; temp.Delete (temp.GetLength ()-1); } GetStrSize(pDC, (LPTSTR)(LPCTSTR)temp, size); } if(temp.Find ("\r\n")!=-1) { temp=temp.Left (temp.Find ("\r\n"));//i++; tempbz=tempbz.Right (tempbz.GetLength ()-temp.GetLength ()-2); } else tempbz=tempbz.Right (tempbz.GetLength ()-temp.GetLength ()); if(bRun) DrawText(pDC, (LPTSTR)(LPCTSTR)temp, temprc, 0, 0, FORMAT_LEFT | FORMAT_VCENTER); } else break; } if(tempbz.IsEmpty ()==0) { fontsize--; goto ll; } if(bRun==0) { bRun=1; goto ll; } } void CLabelEx::OnPaint() { CPaintDC dc(this); CDC *pDC=&dc; pDC->SetTextColor(m_crText); pDC->SetBkMode(TRANSPARENT); // pDC->SelectObject(this->GetFont()); ///准备工作 CRect rect; CDC MemDC; CPen BorderPen,*pOldPen,UnderLinePen; CBrush BGBrush,*pOldBrush; BITMAP bm; int nTextLeft=0,nTextTop=0; //文字输出的位置 this->GetClientRect(&rect); MemDC.CreateCompatibleDC(pDC); MemDC.SetMapMode(pDC->GetMapMode()); ///画边框 if(m_bBorder) { BorderPen.CreatePen(PS_SOLID,1,m_crBorder); BGBrush.CreateSolidBrush(m_crBG); pOldPen=pDC->SelectObject(&BorderPen); pOldBrush=pDC->SelectObject(&BGBrush); pDC->Rectangle(&rect); pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush); rect.DeflateRect(1,1); } ///贴背景图 if(m_bClicked && m_ClickedBGBm.GetSafeHandle()!=NULL) { MemDC.SelectObject(m_ClickedBGBm); pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(), &MemDC,0,0,SRCCOPY); } else if(m_bOver && m_MouseOverBGBm.GetSafeHandle()!=NULL)//鼠标经过的时候 { MemDC.SelectObject(m_MouseOverBGBm); pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(), &MemDC,0,0,SRCCOPY); } else if(m_BGBm.GetSafeHandle()!=NULL) { MemDC.SelectObject(m_BGBm); pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(), &MemDC,0,0,SRCCOPY); } ///贴标签图片 if(m_bClicked && m_ClickedLabelBm.GetSafeHandle()!=NULL) { m_ClickedLabelBm.GetBitmap(&bm); double fScal=bm.bmWidth*1.0/bm.bmHeight; nTextLeft=int(rect.Height()*fScal)+4; MemDC.SelectObject(m_ClickedLabelBm); pDC->StretchBlt(rect.left,rect.top,int(rect.Height()*fScal),rect.Height(), &MemDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY); } else if(m_bOver && m_MouseOverLabelBm.GetSafeHandle()!=NULL) { m_MouseOverLabelBm.GetBitmap(&bm); double fScal=bm.bmWidth*1.0/bm.bmHeight; nTextLeft=int(rect.Height()*fScal)+4; MemDC.SelectObject(m_MouseOverLabelBm); pDC->StretchBlt(rect.left,rect.top,int(rect.Height()*fScal),rect.Height(), &MemDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY); } else if(m_LabelBm.GetSafeHandle()!=NULL) { m_LabelBm.GetBitmap(&bm); double fScal=bm.bmWidth*1.0/bm.bmHeight; nTextLeft=int(rect.Height()*fScal)+4; MemDC.SelectObject(m_LabelBm); pDC->StretchBlt(rect.left,rect.top,int(rect.Height()*fScal),rect.Height(), &MemDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY); } else { nTextLeft=4; } ///输出文字 TEXTMETRIC tm; pDC->GetTextMetrics(&tm); /* nTextTop=rect.top+(rect.Height()-tm.tmHeight)/2; if(strText.GetLength()>0) { pDC->TextOut(nTextLeft,nTextTop,strText); }*/ CString strText; this->GetWindowText(strText); rect.left +=2; rect.top +=2; if(strText.Find ("\r\n")==-1) AutoDraw2(pDC, rect, strText, 1.1); else AutoDraw(pDC, rect, strText, 1.1); ///画下划线 if(m_bUnderLine) { nTextLeft-=2; nTextTop=nTextTop+tm.tmHeight+1; UnderLinePen.CreatePen(PS_SOLID,1,m_crUnderLine); pOldPen=pDC->SelectObject(&UnderLinePen); pDC->MoveTo(nTextLeft,nTextTop); pDC->LineTo(nTextLeft+tm.tmAveCharWidth*strText.GetLength(),nTextTop); } MemDC.DeleteDC (); } void CLabelEx::PreSubclassWindow() { // TODO: Add your specialized code here and/or call the base class DWORD dwStyle = GetStyle(); ::SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwStyle | SS_NOTIFY); SetFont(GetParent()->GetFont()); CStatic::PreSubclassWindow(); } void CLabelEx::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default /* if (m_bOver) // Cursor is currently over control { CRect rect; GetClientRect(rect); if (!rect.PtInRect(point)) { m_bOver = FALSE; if(m_bAutoUnderLine) ///自动下划线 { this->SetUnderLine(FALSE,RGB(0,0,0)); } if(m_bHighLight) //自动高亮 { ///恢复原来的字体颜色 this->SetTextColor(m_crBackText); } RedrawWindow(); ReleaseCapture(); return; } } else // Cursor has just moved over control { m_bOver = TRUE; if(m_bAutoUnderLine) { this->SetUnderLine(TRUE,RGB(0,0,255)); } if(m_bHighLight) { m_crBackText=m_crText; this->SetTextColor(RGB(0,0,255)); } RedrawWindow(); SetCapture(); // ::SetCursor(m_hHandCur); }*/ CStatic::OnMouseMove(nFlags, point); } void CLabelEx::SetTextColor(COLORREF crText) { m_crText=crText; } void CLabelEx::SetUnderLine(BOOL bUnderLine, COLORREF crUnderLine) { m_bUnderLine=bUnderLine; m_crUnderLine=crUnderLine; } void CLabelEx::SetBorder(BOOL bBorder, COLORREF crBorder) { m_bBorder=bBorder; m_crBorder=crBorder; } void CLabelEx::SetBkColor(COLORREF crBkColor) { m_crBG=crBkColor; } void CLabelEx::EnableAutoUnderLine(BOOL bAutoUnderLine) { m_bAutoUnderLine=bAutoUnderLine; if(m_bAutoUnderLine) ///设置了自动下划线 { m_bBackUnderLine=m_bUnderLine;//保存原来下划线的状态 m_bUnderLine=FALSE; } else ///取消了自动下划线 { m_bUnderLine=m_bBackUnderLine;//回复原来下划线的状态 } } void CLabelEx::RedrawWindow() { CStatic::RedrawWindow(); //RECT rect; //this->GetWindowRect(&rect); //GetParent()->ScreenToClient(&rect); //GetParent()->InvalidateRect(&rect); } void CLabelEx::SetBGBitmap(UINT ID) { if(m_BGBm.GetSafeHandle()!=NULL) m_BGBm.DeleteObject(); m_BGBm.LoadBitmap(ID); } void CLabelEx::SetMouseOverBGBitmap(UINT ID) { if(m_MouseOverBGBm.GetSafeHandle()!=NULL) m_MouseOverBGBm.DeleteObject(); m_MouseOverBGBm.LoadBitmap(ID); } void CLabelEx::SetClickedBGBitmap(UINT ID) { if(m_ClickedBGBm.GetSafeHandle()!=NULL) m_ClickedBGBm.DeleteObject(); m_ClickedBGBm.LoadBitmap(ID); } void CLabelEx::SetLabelBitmap(UINT ID) { if(m_LabelBm.GetSafeHandle()!=NULL) m_LabelBm.DeleteObject(); m_LabelBm.LoadBitmap(ID); } void CLabelEx::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default m_bClicked=!m_bClicked; RedrawWindow(); CStatic::OnLButtonDown(nFlags, point); } void CLabelEx::SetMouseOverLabelBitmap(UINT ID) { if(m_MouseOverLabelBm.GetSafeHandle()!=NULL) m_MouseOverLabelBm.DeleteObject(); m_MouseOverLabelBm.LoadBitmap(ID); } void CLabelEx::SetClickedLabelBitmap(UINT ID) { if(m_ClickedLabelBm.GetSafeHandle()!=NULL) m_ClickedLabelBm.DeleteObject(); m_ClickedLabelBm.LoadBitmap(ID); } ///自动感应字体颜色 void CLabelEx::EnableHighLight(BOOL bHighLight) { m_bHighLight=bHighLight; } int CLabelEx::SetFontFace(CDC *pDC, int iFont, BOOL bWeight, CString name) { LOGFONT log; log.lfHeight = CALCF2(iFont); //add a kind of fond,let height equles 13 log.lfWidth = 0; log.lfEscapement = 0; log.lfOrientation = 0; if(bWeight) log.lfWeight = FW_BLACK; else log.lfWeight = FW_REGULAR; log.lfItalic = false; log.lfUnderline = false; log.lfStrikeOut = 0; log.lfCharSet = ANSI_CHARSET; log.lfOutPrecision = OUT_DEFAULT_PRECIS; log.lfClipPrecision = CLIP_DEFAULT_PRECIS; log.lfQuality = DEFAULT_QUALITY; log.lfPitchAndFamily = DEFAULT_PITCH || FF_ROMAN; #ifdef VC60 strcpy (log.lfFaceName,name); #else _tcscpy_s(log.lfFaceName, 32, name); #endif if(m_newfont.GetSafeHandle ())m_newfont.DeleteObject (); m_newfont.CreateFontIndirect(&log); pDC->SelectObject(&m_newfont); return 0; } int CLabelEx::GetStrSize(CDC *pDC, char *str, CSize &size) { int ret=GetTextExtentPoint32(pDC->GetSafeHdc(), str, strlen(str), &size); if(ret==0)return 0; // size.cx = MulDiv(size.cx, 72, GetDeviceCaps(pDC->m_hDC, LOGPIXELSX)); // size.cy = MulDiv(size.cy, 72, GetDeviceCaps(pDC->m_hDC, LOGPIXELSY)); return 1; } int CLabelEx::DrawText(CDC *pDC, char *str, CRect &m_rt, int iFont, int iFace, int format) { SIZE Size; GetTextExtentPoint32(pDC->GetSafeHdc(), str, strlen(str), &Size); int left, top; if (format & FORMAT_HCENTER) { left = CALCX2(m_rt.left) + CALCX2(m_rt.Width())/2 - Size.cx/2; if (left < CALCX2(m_rt.left)) left = CALCX2(m_rt.left); } else if(format & FORMAT_RIGHT) { left = CALCX2(m_rt.left) + CALCX2(m_rt.Width()) - Size.cx; if (left < CALCX2(m_rt.left)) left = CALCX2(m_rt.left); } else left = CALCX2(m_rt.left); if (format & FORMAT_VCENTER) { top = CALCY2(m_rt.top) + CALCY2(m_rt.Height())/2 - Size.cy/2; if (top < CALCY2(m_rt.top)) top = CALCY2(m_rt.top); } else top = CALCY2(m_rt.top); pDC->TextOut(left, top, str); return 1; } void CLabelEx::Paint() { CDC *pDC=GetDC(); pDC->SetTextColor(m_crText); pDC->SetBkMode(TRANSPARENT); // pDC->SelectObject(this->GetFont()); ///准备工作 CRect rect; CDC MemDC; CPen BorderPen,*pOldPen,UnderLinePen; CBrush BGBrush,*pOldBrush; BITMAP bm; int nTextLeft=0,nTextTop=0; //文字输出的位置 this->GetClientRect(&rect); MemDC.CreateCompatibleDC(pDC); MemDC.SetMapMode(pDC->GetMapMode()); ///画边框 if(m_bBorder) { BorderPen.CreatePen(PS_SOLID,1,m_crBorder); BGBrush.CreateSolidBrush(m_crBG); pOldPen=pDC->SelectObject(&BorderPen); pOldBrush=pDC->SelectObject(&BGBrush); pDC->Rectangle(&rect); pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush); rect.DeflateRect(1,1); } ///贴背景图 if(m_bClicked && m_ClickedBGBm.GetSafeHandle()!=NULL) { MemDC.SelectObject(m_ClickedBGBm); pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(), &MemDC,0,0,SRCCOPY); } else if(m_bOver && m_MouseOverBGBm.GetSafeHandle()!=NULL)//鼠标经过的时候 { MemDC.SelectObject(m_MouseOverBGBm); pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(), &MemDC,0,0,SRCCOPY); } else if(m_BGBm.GetSafeHandle()!=NULL) { MemDC.SelectObject(m_BGBm); pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(), &MemDC,0,0,SRCCOPY); } ///贴标签图片 if(m_bClicked && m_ClickedLabelBm.GetSafeHandle()!=NULL) { m_ClickedLabelBm.GetBitmap(&bm); double fScal=bm.bmWidth*1.0/bm.bmHeight; nTextLeft=int(rect.Height()*fScal)+4; MemDC.SelectObject(m_ClickedLabelBm); pDC->StretchBlt(rect.left,rect.top,int(rect.Height()*fScal),rect.Height(), &MemDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY); } else if(m_bOver && m_MouseOverLabelBm.GetSafeHandle()!=NULL) { m_MouseOverLabelBm.GetBitmap(&bm); double fScal=bm.bmWidth*1.0/bm.bmHeight; nTextLeft=int(rect.Height()*fScal)+4; MemDC.SelectObject(m_MouseOverLabelBm); pDC->StretchBlt(rect.left,rect.top,int(rect.Height()*fScal),rect.Height(), &MemDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY); } else if(m_LabelBm.GetSafeHandle()!=NULL) { m_LabelBm.GetBitmap(&bm); double fScal=bm.bmWidth*1.0/bm.bmHeight; nTextLeft=int(rect.Height()*fScal)+4; MemDC.SelectObject(m_LabelBm); pDC->StretchBlt(rect.left,rect.top,int(rect.Height()*fScal),rect.Height(), &MemDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY); } else { nTextLeft=4; } ///输出文字 TEXTMETRIC tm; pDC->GetTextMetrics(&tm); /* nTextTop=rect.top+(rect.Height()-tm.tmHeight)/2; if(strText.GetLength()>0) { pDC->TextOut(nTextLeft,nTextTop,strText); }*/ CString strText; this->GetWindowText(strText); rect.left +=2; rect.top +=2; if(strText.Find ("\r\n")==-1) AutoDraw2(pDC, rect, strText, 1.1); else AutoDraw(pDC, rect, strText, 1.1); ///画下划线 if(m_bUnderLine) { nTextLeft-=2; nTextTop=nTextTop+tm.tmHeight+1; UnderLinePen.CreatePen(PS_SOLID,1,m_crUnderLine); pOldPen=pDC->SelectObject(&UnderLinePen); pDC->MoveTo(nTextLeft,nTextTop); pDC->LineTo(nTextLeft+tm.tmAveCharWidth*strText.GetLength(),nTextTop); } MemDC.DeleteDC (); ReleaseDC(pDC); }