请教如何在工具按钮上既有图像又有文字。

sbg5000 2002-08-26 06:03:50
请教如何在工具按钮上既有图像又有文字。
...全文
135 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
ninny 2002-08-26
  • 打赏
  • 举报
回复
}

m_nOldAction = nNewAction;
m_nOldState = nNewState;
}
ninny 2002-08-26
  • 打赏
  • 举报
回复
m_bColorTab = TRUE;
m_crColorTab = crTab;

Redraw();
}

BOOL CSXButton::SetDefaultButton( BOOL bState )
{
CDialog *pDialog = (CDialog *)GetOwner();
// ASSERT( pDialog->IsKindOf( RUNTIME_CLASS( CDialog ) ) );

pDialog->SetDefID( GetDlgCtrlID() );

BOOL bPrevious = m_bDefault;
m_bDefault = bState;

Redraw();

// Return previous state
return bPrevious;
}

// Positioning Functions
int CSXButton::SetImageOffset( int nPixels )
{
int nPrevious = m_nImageOffsetFromBorder;

m_bUseOffset = TRUE;
m_nImageOffsetFromBorder = nPixels;

Redraw();

return nPrevious;
}

int CSXButton::SetTextOffset( int nPixels )
{
int nPrevious = m_nTextOffsetFromImage;

m_bUseOffset = TRUE;
m_nTextOffsetFromImage = nPixels;

Redraw();

return nPrevious;
}

CPoint CSXButton::SetImagePos( CPoint p )
{
CPoint pointPrevious = m_pointImage;

m_bUseOffset = FALSE;
m_pointImage = p;

Redraw();

return pointPrevious;
}
CPoint CSXButton::SetTextPos( CPoint p )
{
CPoint pointPrevious = m_pointText;

m_bUseOffset = FALSE;
m_pointText = p;

Redraw();

return pointPrevious;
}

// Centering a point helper function
void CSXButton::CheckPointForCentering( CPoint &p, int nWidth, int nHeight )
{
CRect rectControl;
GetClientRect( rectControl );

if( p.x == SXBUTTON_CENTER )
p.x = ( ( rectControl.Width() - nWidth ) >> 1 );
if( p.y == SXBUTTON_CENTER )
p.y = ( ( rectControl.Height() - nHeight ) >> 1 );
}


//
// Owner Draw function, the grand-daddy
//
void CSXButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
CDC* pDC = CDC::FromHandle(lpDIS->hDC);

CRect rectControl( lpDIS->rcItem );

UINT nOffset = 0; // For position adjustment of a pushed button
UINT nFrameStyle=0;
BOOL bDRAWFOCUSONLY = FALSE; // Optimize a bit
int nStateFlag; // Normal or Disabled
HBITMAP hBitmapToDraw; // Normal or Disabled bitmap (not used if uses icon)

UINT nNewState = lpDIS->itemState;
UINT nNewAction = lpDIS->itemAction;

// Find out what state the control and set some drawing flags
// according to the state.
if ( nNewState & ODS_SELECTED)
{
nFrameStyle = DFCS_PUSHED;
nOffset += 1;
}

if( nNewState & ODS_DISABLED )
{
nStateFlag = DSS_DISABLED;
hBitmapToDraw = m_hBitmapDisabled;
}
else
{
nStateFlag = DSS_NORMAL;
hBitmapToDraw = m_hBitmap;
}

// If only the focus is changing, don't redraw the whole control
if (nNewAction == ODA_FOCUS )
bDRAWFOCUSONLY = TRUE;

// If this is the defualt button, deflate the control so everything
// we do below (icon, text, focus ) is adjusted properly
if( m_bDefault )
rectControl.DeflateRect( 1, 1 );

if( !bDRAWFOCUSONLY )
{
//
// Draw 'default button' rectangle
//
if( m_bDefault ) // Can't use ODS_DEFAULT w/owner draw!!
{
CPen *pOldPen = (CPen*)pDC->SelectStockObject(BLACK_PEN);

pDC->Rectangle( &lpDIS->rcItem ); // don't use deflated rectangle
pDC->SelectObject( pOldPen );
}

//
// Draw button frame
//
pDC->DrawFrameControl(&rectControl, DFC_BUTTON, DFCS_BUTTONPUSH | nFrameStyle);

//
// Draw color tab
//
if (m_bColorTab)
{
CPen penTab;

#define COLORTABSIZE 8
if( penTab.CreatePen( PS_SOLID, 1, m_crColorTab) )
{
CPen* pOldPen = pDC->SelectObject( &penTab );

int nXOffset = rectControl.left+1 + nOffset;
int nYOffset = rectControl.top+1 + nOffset;
for (UINT nStep = 0; nStep < COLORTABSIZE; nStep++)
{
pDC->MoveTo( nXOffset, nYOffset + nStep );
pDC->LineTo( nXOffset + (COLORTABSIZE-nStep)-1, nYOffset + nStep );
}

pDC->SelectObject( pOldPen );
}
}

// Get control text
CString strTitle;
this->GetWindowText(strTitle);

//
// Draw Image
//
if( HasImage() )
{
CPoint pt;

if( m_bUseOffset )
{
pt.x = strTitle.IsEmpty() ? SXBUTTON_CENTER : rectControl.left + m_nImageOffsetFromBorder;
pt.y = SXBUTTON_CENTER;
}
else
pt = m_pointImage;

CheckPointForCentering( pt, m_nImageWidth, m_nImageHeight );

pt.Offset( nOffset, nOffset );

if( m_hIcon )
pDC->DrawState( pt, CSize(m_nImageWidth, m_nImageHeight), (HICON)m_hIcon, DST_ICON | nStateFlag, (CBrush *)NULL );
else if( m_hBitmap )
pDC->DrawState( pt, CSize(m_nImageWidth, m_nImageHeight), (HBITMAP)hBitmapToDraw, DST_BITMAP | nStateFlag );
}

//
// Draw Text
//
if ( !strTitle.IsEmpty() )
{
CPoint pt;
CSize sizeText = pDC->GetTextExtent(strTitle);

if( m_bUseOffset )
{
CRect rcClient;
GetClientRect(rcClient);
pt.x = !HasImage() ? SXBUTTON_CENTER :
m_nImageWidth + m_nTextOffsetFromImage + m_nImageOffsetFromBorder +
(max(0,rcClient.Width()-(m_nImageWidth + m_nTextOffsetFromImage + m_nImageOffsetFromBorder)-sizeText.cx)/2);
;
// pt.x = !HasImage() ? SXBUTTON_CENTER : m_nImageWidth + m_nTextOffsetFromImage + m_nImageOffsetFromBorder;
pt.y = SXBUTTON_CENTER;
}
else
pt = m_pointText;

// If we are centering the text vertically, it looks best of we
// center based on the height of the text, then move it up 1 more pixel
int nOffsetFixY = pt.y == SXBUTTON_CENTER ? -1 : 0;

CheckPointForCentering( pt, sizeText.cx, sizeText.cy );

pt.Offset( nOffset, nOffset + nOffsetFixY );

pDC->DrawState( pt, CSize(0,0), strTitle, DST_PREFIXTEXT|nStateFlag, TRUE, 0, (CBrush*)NULL );
}

} // End !focus only

//
// Draw focus rectange
//
if( !( nNewState & ODS_DISABLED ) ) // Make sure it's not disabled
{
// Redraw the focus if:
// 1. There is a change in focus state
// OR 2. The entire control was just redrawn and Focus is set
if( ( nNewState & ODS_FOCUS ) ^ ( m_nOldState & ODS_FOCUS ) ||
( !bDRAWFOCUSONLY && ( nNewState & ODS_FOCUS ) ) )
{

#define FOCUSOFFSET 3
CRect rect( rectControl );

// As control gets smaller, decrease focus size
int nDeflate = min( FOCUSOFFSET,
min( rect.Width(), rect.Height() ) >> 2 );
rect.DeflateRect( nDeflate, nDeflate);
pDC->DrawFocusRect(&rect);
}
ninny 2002-08-26
  • 打赏
  • 举报
回复
下面是类CSXButton的源程序。

头文件:

// SXButton.h : header file

// CSXButton window

#ifndef _SXBUTTON_H
#define _SXBUTTON_H

#define SXBUTTON_CENTER -1

class CSXButton : public CButton
{
// Construction
public:
CSXButton();

// Attributes
private:
// Positioning
BOOL m_bUseOffset;
CPoint m_pointImage;
CPoint m_pointText;
int m_nImageOffsetFromBorder;
int m_nTextOffsetFromImage;

// Image
HICON m_hIcon;
HBITMAP m_hBitmap;
HBITMAP m_hBitmapDisabled;
int m_nImageWidth, m_nImageHeight;

// Color Tab
char m_bColorTab;
COLORREF m_crColorTab;

// State
BOOL m_bDefault;
UINT m_nOldAction;
UINT m_nOldState;


// Operations
public:
// Positioning
int SetImageOffset( int nPixels );
int SetTextOffset( int nPixels );
CPoint SetImagePos( CPoint p );
CPoint SetTextPos( CPoint p );

// Image
BOOL SetIcon( UINT nID, int nWidth, int nHeight );
BOOL SetBitmap( UINT nID, int nWidth, int nHeight );
BOOL SetMaskedBitmap( UINT nID, int nWidth, int nHeight, COLORREF crTransparentMask );
BOOL HasImage() { return (BOOL)( m_hIcon != 0 | m_hBitmap != 0 ); }

// Color Tab
void SetColorTab(COLORREF crTab);

// State
BOOL SetDefaultButton( BOOL bState = TRUE );

private:
BOOL SetBitmapCommon( UINT nID, int nWidth, int nHeight, COLORREF crTransparentMask, BOOL bUseMask );
void CheckPointForCentering( CPoint &p, int nWidth, int nHeight );
void Redraw();

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSXButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CSXButton();

// Generated message map functions
protected:
//{{AFX_MSG(CSXButton)
afx_msg LRESULT OnGetText(WPARAM wParam, LPARAM lParam);
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};

#endif
/////////////////////////////////////////////////////////////////////////////


实现文件:

// SXButton.cpp : implementation file
//
///////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <SXButton.h> // Access non-local header (in a library)
//#include "SXButton.h" // Access local header

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSXButton

CSXButton::CSXButton()
{
m_bColorTab = FALSE;

m_hIcon = 0;
m_hBitmap = 0;
m_hBitmapDisabled = 0;

m_bDefault = FALSE;
m_nOldState = 0;
m_nOldAction = 0;

m_nImageOffsetFromBorder = 4;
m_nTextOffsetFromImage = 8;
m_bUseOffset = TRUE;
}

CSXButton::~CSXButton()
{
if( m_hIcon != 0 )
DeleteObject( m_hIcon );
if( m_hBitmap != 0 )
DeleteObject( m_hBitmap );
if( m_hBitmapDisabled != 0 )
DeleteObject( m_hBitmapDisabled );
}


BEGIN_MESSAGE_MAP(CSXButton, CButton)
//{{AFX_MSG_MAP(CSXButton)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()


inline void CSXButton::Redraw()
{
if( m_hWnd != NULL )
Invalidate();
}

//
// Various Attribute setting functions
//

// Image functions
BOOL CSXButton::SetIcon( UINT nID, int nWidth, int nHeight )
{
// GS980730 added AfxFindResourceHandle to make MFC find resources in DLLs too...
HINSTANCE hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nID),
RT_GROUP_ICON);
m_hIcon = (HICON)::LoadImage(hInstResource,
MAKEINTRESOURCE(nID),
IMAGE_ICON, nWidth, nHeight, 0);

if( m_hIcon == 0 )
return FALSE;

m_nImageWidth = nWidth;
m_nImageHeight = nHeight;

m_hBitmap = 0;

Redraw();

return TRUE;
}

BOOL CSXButton::SetBitmap( UINT nID, int nWidth, int nHeight )
{
return SetBitmapCommon( nID, nWidth, nHeight, 0, FALSE /* no mask */ );
}

BOOL CSXButton::SetMaskedBitmap( UINT nID, int nWidth, int nHeight, COLORREF crTransparentMask )
{
return SetBitmapCommon( nID, nWidth, nHeight, crTransparentMask, TRUE /* mask */ );
}

BOOL CSXButton::SetBitmapCommon( UINT nID, int nWidth, int nHeight, COLORREF crTransparentMask, BOOL bUseMask )
{
// GS980730 added AfxFindResourceHandle to make MFC find resources in DLLs too...
HINSTANCE hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nID),
RT_BITMAP);

// If it is not a masked bitmap, just go through the
// motions as if it was, but set then number of color mappings to 0

COLORMAP mapColor;
mapColor.from = crTransparentMask;
mapColor.to = ::GetSysColor( COLOR_BTNFACE );
HBITMAP bmTemp = (HBITMAP)::CreateMappedBitmap(hInstResource, nID, IMAGE_BITMAP, &mapColor, bUseMask ? 1 : 0 );
m_hBitmap = (HBITMAP)::CopyImage( bmTemp, IMAGE_BITMAP, nWidth, nHeight, LR_COPYDELETEORG );

// Create disabled bitmap. We need to make the masked area white so
// it will appear transparent when the bitmap is rendered as an
// 'embossed' (disabled) image in DrawItem() below. Since DrawState
// converts the image to monochrome, white is transparent, black is
// graphics data.
mapColor.to = RGB( 255, 255, 255 );
bmTemp = (HBITMAP)::CreateMappedBitmap(hInstResource, nID, IMAGE_BITMAP, &mapColor, bUseMask ? 1 : 0 );
m_hBitmapDisabled = (HBITMAP)::CopyImage( bmTemp, IMAGE_BITMAP, nWidth, nHeight, LR_COPYDELETEORG );

if( m_hBitmap == 0 || m_hBitmapDisabled == 0 )
return FALSE;

m_nImageWidth = nWidth;
m_nImageHeight = nHeight;

m_hIcon = 0;

Redraw();

return TRUE;
}

void CSXButton::SetColorTab(COLORREF crTab)
{
WadeHan 2002-08-26
  • 打赏
  • 举报
回复
www.codeproject.com
www.codeguru.com
WadeHan 2002-08-26
  • 打赏
  • 举报
回复
在网上找一个ToolBar的扩展类,最简单。:)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧