xtargetbutton.cpp
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C++ 代码 · 共 815 行 · 第 1/2 页
CPP
815 行
// CxTargetButton.cpp : implementation file
/** 12/Aug/2001 v1.00
* - ing.davide.pizzolato@libero.it
*/
#include "stdafx.h"
#include "xTargetButton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CxTargetButton
CxTargetButton::CxTargetButton()
{
m_target = true;
m_Border=1; //draw 3D border
m_FocusRectMargin=3; //focus dotted rect margin
m_TextColor=GetSysColor(COLOR_BTNTEXT); // default button text color
m_flat = m_Checked = m_button_down = m_tracking = false;
m_Icon=m_IconDown=m_IconHighLight=NULL; // icon handle
m_IconBox.SetRectEmpty(); //icon location
m_IconAlign=BS_CENTER; //icon alignment
m_TextAlign=DT_CENTER; //text alignment
m_pLF=NULL; //font structure pointer
}
/////////////////////////////////////////////////////////////////////////////
CxTargetButton::~CxTargetButton()
{
m_Font.DeleteObject();
if (m_pLF) free(m_pLF);
if (m_IconDown!=m_Icon && m_IconDown) DestroyIcon(m_IconDown);
if (m_IconHighLight!=m_Icon && m_IconHighLight) DestroyIcon(m_IconHighLight);
if (m_Icon) DestroyIcon(m_Icon);
}
/////////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(CxTargetButton, CButton)
//{{AFX_MSG_MAP(CxTargetButton)
ON_WM_ERASEBKGND()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDBLCLK()
ON_WM_KILLFOCUS()
//ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)
ON_WM_KEYDOWN()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_MESSAGE(WM_CXTGT_RADIO , OnRadioInfo)
ON_MESSAGE(BM_SETCHECK , OnBMSetCheck)
ON_MESSAGE(BM_GETCHECK , OnBMGetCheck)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CxTargetButton message handlers
/////////////////////////////////////////////////////////////////////////////
void CxTargetButton::PreSubclassWindow()
{
m_Style=GetStyle(); //get general button styles
m_IsPushLike=((m_Style & BS_PUSHLIKE)!=0);
m_flat=((m_Style & BS_FLAT)!=0);
SetTextAlign(m_Style & 0x0300);
m_Style=GetButtonStyle(); ///get specific BS_ styles
if ((m_Style & BS_AUTOCHECKBOX)==BS_AUTOCHECKBOX)
// ||((m_Style & BS_CHECKBOX)==BS_CHECKBOX))
m_Style=BS_CHECKBOX;
else if ((m_Style & BS_AUTORADIOBUTTON)==BS_AUTORADIOBUTTON)
// ||((m_Style & BS_RADIOBUTTON)==BS_RADIOBUTTON))
m_Style=BS_RADIOBUTTON;
else { m_Style=BS_PUSHBUTTON; m_IsPushLike=true;}
//default radio & check-box has no border
if (!m_IsPushLike) m_Border = false;
CButton::PreSubclassWindow();
ModifyStyle(0, BS_OWNERDRAW);
}
/////////////////////////////////////////////////////////////////////////////
BOOL CxTargetButton::OnEraseBkgnd(CDC* pDC)
{ return 1; } // doesn't erase the button background
/////////////////////////////////////////////////////////////////////////////
void CxTargetButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT (lpDrawItemStruct);
//TRACE("* Captured: %08X\n", ::GetCapture());
//Check if the button state in not in inconsistent mode...
POINT mouse_position;
if ((m_button_down) && (::GetCapture() == m_hWnd) && (::GetCursorPos(&mouse_position))){
if (::WindowFromPoint(mouse_position) == m_hWnd){
if ((GetState() & BST_PUSHED) != BST_PUSHED) {
//TRACE("* Inconsistency up detected! Fixing.\n");
SetState(TRUE);
return;
}
} else {
if ((GetState() & BST_PUSHED) == BST_PUSHED) {
//TRACE("* Inconsistency up detected! Fixing.\n");
SetState(FALSE);
return;
} } }
//TRACE("* Drawing: %08x\n", lpDrawItemStruct->itemState);
bool btargetdone=false;
CString sCaption;
CDC *pRealDC = CDC::FromHandle(lpDrawItemStruct->hDC); // get device context
RECT r=lpDrawItemStruct->rcItem; // context rectangle
int cx = r.right - r.left ; // get width
int cy = r.bottom - r.top ; // get height
// get text box position
RECT tr={r.left+m_FocusRectMargin+2,r.top,r.right-m_FocusRectMargin-2,r.bottom};
CDC hdcMem; //create a memory DC to avoid flicker
hdcMem.CreateCompatibleDC(pRealDC);
CDC* pDC = &hdcMem; //(just use pRealDC to paint directly the screen)
CBitmap hBitmap; //create a destination for raster operations
hBitmap.CreateCompatibleBitmap(pRealDC,cx,cy);
CBitmap* pOldBitmap = hdcMem.SelectObject(&hBitmap); //select the destination for MemDC
GetWindowText(sCaption); // get button text
pDC->SetBkMode(TRANSPARENT);
// with MemDC we need to select the font...
//get text font
CFont* pOldFont=NULL;
if (m_Font.m_hObject) pOldFont = pDC->SelectObject(&m_Font);
else pDC->SelectObject(GetStockObject(DEFAULT_GUI_FONT));
// TEXTMETRIC tm;
// pDC->GetTextMetrics(&tm); // get font metrics
// accommodate text location
if (m_Icon){
switch (m_IconAlign){
case BS_LEFT:
tr.left+=m_IconBox.Width(); // shift left
break;
case BS_RIGHT:
tr.right-=m_IconBox.Width(); // shift right
break;
case BS_CENTER:
tr.top+=m_IconBox.bottom; // shift text under the icon
tr.bottom-=m_FocusRectMargin + 1;
}
}
// Select the correct skin
if (lpDrawItemStruct->itemState & ODS_DISABLED){ // DISABLED BUTTON
pDC->FillSolidRect(&r,GetSysColor(COLOR_BTNFACE));
if (m_Icon) //draw the icon
pDC->DrawState(m_IconBox.TopLeft(),m_IconBox.Size(),
m_Icon,DSS_DISABLED,(CBrush*)NULL);
// if needed, draw the standard 3D rectangular border
if ((m_Border)&&(m_flat==FALSE)) pDC->DrawEdge(&r,EDGE_RAISED,BF_RECT);
// paint the etched button text
pDC->SetTextColor(GetSysColor(COLOR_3DHILIGHT));
pDC->DrawText(sCaption,&tr,m_TextAlign);
pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
OffsetRect(&tr,-1,-1);
pDC->DrawText(sCaption,&tr,m_TextAlign);
} else {
//---------------------------------------------------------------------------
if ((lpDrawItemStruct->itemState & ODS_SELECTED)||m_Checked){ //SELECTED (DOWN) BUTTON
if (m_Style==BS_PUSHBUTTON){
pDC->FillSolidRect(&r,GetSysColor(COLOR_3DHILIGHT));
if (m_tracking) {
DrawTarget(pDC,&r,m_TextColor,3,4,3);
}
} else {
if (m_tracking){
pDC->FillSolidRect(&r,GetSysColor(COLOR_3DHILIGHT));
DrawTarget(pDC,&r,m_TextColor,3,4,3);
btargetdone=true;
} else {
pDC->FillSolidRect(&r,GetSysColor(COLOR_3DHILIGHT));
}
}
if (m_IconDown){ //draw the pushed icon
if (m_IsPushLike) m_IconBox.OffsetRect(1,1);
pDC->DrawState(m_IconBox.TopLeft(),m_IconBox.Size(),
m_IconDown,DSS_NORMAL,(CBrush*)NULL);
if (m_IsPushLike) m_IconBox.OffsetRect(-1,-1);
}
//shift text
if (m_IsPushLike) OffsetRect(&tr,1,1);
// if needed, draw the standard 3D rectangular border
if (m_Border){
if (m_flat) pDC->Draw3dRect(&r,GetSysColor(COLOR_BTNSHADOW),GetSysColor(COLOR_BTNHILIGHT));
else pDC->DrawEdge(&r,EDGE_SUNKEN,BF_RECT);
}
} else {
//---------------------------------------------------------------------------
// DEFAULT BUTTON
if (m_tracking){
pDC->FillSolidRect(&r,GetSysColor(COLOR_3DHILIGHT));
DrawTarget(pDC,&r,m_TextColor,3,4,3);
btargetdone=true;
} else {
pDC->FillSolidRect(&r,GetSysColor(COLOR_BTNFACE));
}
if (m_IconHighLight && m_tracking) { // draw the highlighted icon
pDC->DrawState(m_IconBox.TopLeft(),m_IconBox.Size(),
m_IconHighLight,DSS_NORMAL,(CBrush*)NULL);
} else if (m_Icon) //draw the icon
pDC->DrawState(m_IconBox.TopLeft(),m_IconBox.Size(),
m_Icon,DSS_NORMAL,(CBrush*)NULL);
// if needed, draw the standard 3D rectangular border
if ((m_Border)&&((m_tracking)||(m_flat==FALSE))){
if (lpDrawItemStruct->itemState & ODS_DEFAULT){
pDC->DrawEdge(&r,EDGE_SUNKEN,BF_RECT);
InflateRect(&r,-1,-1);
pDC->DrawEdge(&r,EDGE_RAISED,BF_RECT);
} else {
if (m_flat) pDC->Draw3dRect(&r,GetSysColor(COLOR_BTNHILIGHT),GetSysColor(COLOR_BTNSHADOW));
//else pDC->DrawEdge(&r,EDGE_RAISED,BF_RECT);
else pDC->Draw3dRect(&r,GetSysColor(COLOR_BTNHILIGHT),GetSysColor(COLOR_BTNSHADOW));
}
}
//---------------------------------------------------------------------------
}
// paint the focus rect
if ((lpDrawItemStruct->itemState & ODS_FOCUS)&&(m_FocusRectMargin>0)){
if (m_tracking || (lpDrawItemStruct->itemState & ODS_SELECTED)){
if (!btargetdone) {
DrawTarget(pDC,&r,m_TextColor,3,4,3,1);
}
}else{
DrawTarget(pDC,&r,GetSysColor(COLOR_INFOBK),3,4,3);
}
// InflateRect(&r,-m_FocusRectMargin,-m_FocusRectMargin);
// m_dh.Draw(pDC->GetSafeHdc(),1+r.left,r.top);
// m_dh.Draw(pDC->GetSafeHdc(),1+r.left,r.bottom);
// m_dv.Draw(pDC->GetSafeHdc(),r.left,1+r.top);
// m_dv.Draw(pDC->GetSafeHdc(),r.right,1+r.top);
}
// paint the enabled button text
pDC->SetTextColor(m_TextColor);
pDC->DrawText(sCaption,&tr,m_TextAlign);
}
if (pOldFont) pDC->SelectObject(pOldFont); //restore the old font object
pRealDC->BitBlt(0,0,cx,cy,&hdcMem,0,0,SRCCOPY); //copy in the real world
//restore the old objects to avoid memory leakage <David Scambler>
if (pOldBitmap) hdcMem.SelectObject(pOldBitmap);
// hdcMem.DeleteDC(); the destructor will do this for us
// hBitmap.DeleteObject(); the destructor will do this for us
}
/////////////////////////////////////////////////////////////////////////////
void CxTargetButton::DrawTarget(CDC *pDC, RECT *r, DWORD color, int border, int width, int height, int offset)
{
if (m_target){
int x,y;
CPen pen;
if (pen.CreatePen(PS_SOLID, 1, color))
{
CPen* pOldPen = pDC->SelectObject(&pen);
pDC->MoveTo(offset+border+width,offset+border);
pDC->LineTo(offset+border,offset+border);
pDC->LineTo(offset+border,offset+border+height+1);
x = r->right - border - 2 +(1-m_IsPushLike);
pDC->MoveTo(offset+x - width,offset+border);
pDC->LineTo(offset+x,offset+border);
pDC->LineTo(offset+x,offset+border+height+1);
y = r->bottom - border - 2+(1-m_IsPushLike);
pDC->MoveTo(offset+border+width,offset+y);
pDC->LineTo(offset+border,offset+y);
pDC->LineTo(offset+border,offset+y-height-1);
pDC->MoveTo(offset+x - width,offset+y);
pDC->LineTo(offset+x,offset+y);
pDC->LineTo(offset+x,offset+y-height-1);
pDC->SelectObject(pOldPen);
}
}
}
/////////////////////////////////////////////////////////////////////////////
void CxTargetButton::SetIcon(UINT nIcon, UINT nIconAlign, UINT nIconDown, UINT nIconHighLight)
{
if (m_IconDown!=m_Icon && m_IconDown) DestroyIcon(m_IconDown);
if (m_IconHighLight!=m_Icon && m_IconHighLight) DestroyIcon(m_IconHighLight);
if (m_Icon) DestroyIcon(m_Icon);
m_Icon = (HICON)::LoadImage(AfxGetInstanceHandle(),
MAKEINTRESOURCE(nIcon),
IMAGE_ICON, 0, 0, 0);
if (m_Icon){ // if success...
ICONINFO iinfo; // get icon info
GetIconInfo(m_Icon, &iinfo);
m_IconBox.left=m_IconBox.top=0;
m_IconBox.right = iinfo.xHotspot * 2;
m_IconBox.bottom = iinfo.yHotspot * 2;
long x,y;
RECT rect;
GetWindowRect(&rect);
y=rect.bottom-rect.top;
x=rect.right-rect.left;
switch (nIconAlign){ //set the icon location
case BS_RIGHT:
m_IconAlign=BS_RIGHT;
m_IconBox.OffsetRect(x - iinfo.xHotspot*2 - m_FocusRectMargin,
max(0, (long)(y/2 - iinfo.yHotspot)));
break;
case BS_LEFT:
m_IconAlign=BS_LEFT;
m_IconBox.OffsetRect(m_FocusRectMargin,
max(0, (long)(y/2 - iinfo.yHotspot)));
break;
default:
m_IconAlign=BS_CENTER;
m_IconBox.OffsetRect(max(0, (long)(x/2 - iinfo.xHotspot)),
max(0, (long)(y/2 - 2*iinfo.yHotspot)));
}
//release icon mask bitmaps (Orioli Alessandro <aorioli@temaweb.it>)
if( iinfo.hbmColor ) DeleteObject( iinfo.hbmColor );
if( iinfo.hbmMask ) DeleteObject( iinfo.hbmMask );
if (nIconDown > 0){ //load down icon
m_IconDown = (HICON)::LoadImage(AfxGetInstanceHandle(),
MAKEINTRESOURCE(nIconDown),
IMAGE_ICON, 0, 0, 0);
if (m_IconDown==NULL) m_IconDown= m_Icon;
} else { m_IconDown= m_Icon; } //reuse resource handle
if (nIconHighLight > 0){ //load highlighted icon
m_IconHighLight = (HICON)::LoadImage(AfxGetInstanceHandle(),
MAKEINTRESOURCE(nIconHighLight),
IMAGE_ICON, 0, 0, 0);
if (m_IconHighLight==NULL) m_IconHighLight= m_Icon;
} else { m_IconHighLight= m_Icon; } //reuse resource handle
}
}
/////////////////////////////////////////////////////////////////////////////
void CxTargetButton::SetTextAlign(UINT nTextAlign)
{
// see DrawText() styles...
switch (nTextAlign){
case BS_RIGHT:
m_TextAlign=DT_RIGHT;
break;
case BS_LEFT:
m_TextAlign=DT_LEFT;
break;
default:
m_TextAlign=DT_CENTER;
}
m_TextAlign|=(DT_SINGLELINE|DT_VCENTER);
}
/////////////////////////////////////////////////////////////////////////////
void CxTargetButton::SetFlat(bool bFlag)
{ m_flat=bFlag; } //set flat border mode
/////////////////////////////////////////////////////////////////////////////
COLORREF CxTargetButton::SetTextColor(COLORREF new_color)
{
COLORREF tmp_color=m_TextColor;
m_TextColor=new_color;
return tmp_color; //returns the previous color
}
/////////////////////////////////////////////////////////////////////////////
void CxTargetButton::SetToolTipText(CString s, CString sDown)
{
m_ToolTipUp = s; //normal tooltip
m_ToolTipDw = sDown; //tooltip for checked state
//select the down tooltip if the button is already checked <Jesper Kinn錽>
if (m_Checked && !m_ToolTipDw.IsEmpty()) s = m_ToolTipDw;
if(m_tooltip.m_hWnd==NULL){
if(m_tooltip.Create(this)) //first assignment
if(m_tooltip.AddTool(this, (LPCTSTR)s)){
m_tooltip.Activate(1);
// enable multiline tooltips <Derek Lakin>
m_tooltip.SendMessage(TTM_SETMAXTIPWIDTH, 0, 300);
}
} else {
m_tooltip.UpdateTipText((LPCTSTR)s,this);
}
}
/////////////////////////////////////////////////////////////////////////////
void CxTargetButton::RelayEvent(UINT message, WPARAM wParam, LPARAM lParam)
{
// This function will create a MSG structure, fill it in a pass it to
// the ToolTip control, m_ttip. Note that we ensure the point is in window
// coordinates (relative to the control's window).
if(NULL != m_tooltip.m_hWnd){
MSG msg;
msg.hwnd = m_hWnd;
msg.message = message;
msg.wParam = wParam;
msg.lParam = lParam;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?