看到一些软件,如果工具条上的按钮太多,就在最右边显示一个下拉式的菜单,里面包含有没有被显示出的工具按钮?我知道用ReBar,但我却实现不了,哪位老兄能给出一段参考源码???拜托了!!!
解决方案 »
- vs2005调试发生怪事?
- LNK2001 错误!
- 如何实现拖动效果???
- Knuth《计算机程序设计艺术》2卷 中文版
- 多线程使用内存
- MFC中虚函数的问题。
- 关于vc的一个问题,急
- 请问这样将十进制数转化为16进制
- 请问:1.如何使基于对话框的应用程序启动时即为最大化并禁止用户修改窗体大小;2.如何动态创建控件及修改其属性(如botton,editbox,特别是修改picture控件的大小)?谢谢,每题20分.
- 我怎样才能得到并口的每根针的状态(0,1)?DOS,WINDOWS,NT
- 我要做一个自己的CMyEdit可以改变字的颜色的?怎么做?UP有分?在线等逮
- help me 关于函数的传值问题??问题解决,当时给分
有n多例子,看了别忘了分..........
#if !defined(AFX_CHEVBAR_H__ADA7D7F6_E2C1_11D3_84C7_0080450EA020__INCLUDED_)
#define AFX_CHEVBAR_H__ADA7D7F6_E2C1_11D3_84C7_0080450EA020__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000#define _WIN32_IE 0x0500
#define RBBS_USECHEVRON 0x00000200
#define RBN_CHEVRONPUSHED (RBN_FIRST - 10)
typedef struct tagNMREBARCHEVRON
{
NMHDR hdr;
UINT uBand;
UINT wID;
LPARAM lParam;
RECT rc;
LPARAM lParamNM;} NMREBARCHEVRON, *LPNMREBARCHEVRON;class CChevBar : public CReBar
{
public:
CChevBar();public: //{{AFX_VIRTUAL(CChevBar)
//}}AFX_VIRTUALpublic:
virtual ~CChevBar();protected:
//{{AFX_MSG(CChevBar)
//}}AFX_MSG /*
Reflection handler for the Chevron push
*/
void OnChevronPushed( NMHDR * pNotifyStruct, LRESULT* result ); DECLARE_MESSAGE_MAP()
};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}#endif // !defined(AFX_CHEVBAR_H__ADA7D7F6_E2C1_11D3_84C7_0080450EA020__INCLUDED_)
//
//Chev.cpp
#include "stdafx.h"
#include "Chev.h"
#include "ChevBar.h"
#include "ToolMenu.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/*
Usage:
if (!m_wndReBar.AddBar(&m_wndToolBar, NULL, NULL, RBBS_USECHEVRON))
return -1;
REBARBANDINFO rbbi;
CSize sizeBar;
m_wndToolBar.GetToolBarCtrl().GetMaxSize (&sizeBar);
rbbi.cbSize = sizeof(rbbi);
rbbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_SIZE | RBBIM_ID;
rbbi.cxMinChild = 0;
rbbi.cyMinChild = sizeBar.cy;
rbbi.cx = rbbi.cxIdeal = sizeBar.cx;
rbbi.wID = 0;
m_wndReBar.GetReBarCtrl().SetBandInfo(0, &rbbi);
*/
/////////////////////////////////////////////////////////////////////////////
// CChevBarCChevBar::CChevBar()
{
}CChevBar::~CChevBar()
{
}
BEGIN_MESSAGE_MAP(CChevBar, CReBar)
//{{AFX_MSG_MAP(CChevBar)
//}}AFX_MSG_MAP // Reflection message entry for Chevron push
ON_NOTIFY_REFLECT( RBN_CHEVRONPUSHED, OnChevronPushed )
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CChevBar
/*
This is the handler when a chevron is pushed.
*/
void CChevBar::OnChevronPushed( NMHDR * pNotifyStruct, LRESULT* result )
{
NMREBARCHEVRON* pChev = (NMREBARCHEVRON*) pNotifyStruct;
// Has the band of the chevron that generated this message
int iBand = pChev->uBand; // Have to get the child window handle this band holds
REBARBANDINFO rbinfo;
rbinfo.cbSize = sizeof(rbinfo);
rbinfo.fMask = RBBIM_CHILD;
GetReBarCtrl().GetBandInfo ( iBand, &rbinfo ); // Check if the child window is a toolbar
// Some rebar bands may have other windows, so that is left as an exercise
// to the user :-)
CToolBar *pTBar = (CToolBar *)CToolBar::FromHandle ( rbinfo.hwndChild );
ASSERT(pTBar);
ASSERT(pTBar->IsKindOf(RUNTIME_CLASS(CToolBar))); // Create a popup menu to show hidden buttons
CToolMenu pop;
pop.CreatePopupMenu (); // The CToolMenu uses the toolbar pointer to get associated text and image
// information. If there is a better way please do so.
// This menu was created with local scope, hence the temp pointer
// pTBar can be stored i guess...
pop.m_pToolbar = pTBar; // We have to determine the hidden buttons
/*
1. Obtain band rectangle (subtract chevron width if you want to)
2. Get the button rectangle
3. Check if the intersecting rectangle is same as the button rectangle
4. If they intersect then the button is shown
*/ // Get band rectangle.
CRect rectBand;
GetReBarCtrl ().GetRect( iBand, &rectBand );
rectBand.right = rectBand.Width ();
rectBand.left = 0 ;
// It depends on the user to decide if this subtraction is necessary, if they feel
// happy about the chevron hiding a part of a button then remove this code
CRect rectChevron;
rectChevron = pChev->rc;
rectBand.right -= rectChevron.Width (); // Screen co-ordinates for Menu to be displayed
CPoint ptMenu;
ptMenu.x = rectChevron.left;
ptMenu.y = rectChevron.bottom;
ClientToScreen ( &ptMenu ); // This flag indicates if atleast one has been added to the menu
// POPUP Menu is shown only if atleast one item has to be shown
BOOL bAtleastOne=FALSE;
int iCount, iButtonCount = pTBar->GetToolBarCtrl().GetButtonCount();
for ( iCount = 0 ; iCount < iButtonCount ; iCount++ )
{
// Get the id of the toolbar button
int id = pTBar->GetItemID( iCount );
// If the button is a separator then we can also add a separator to the
// popup menu
if ( pTBar->GetButtonStyle ( iCount ) & TBSTYLE_SEP )
{
// It wouldnt be nice if there is a separator as the first item in the menu
if ( bAtleastOne )
pop.AppendMenu ( MF_SEPARATOR );
}
else
{
// Get the button rectangle
CRect rectButton;
pTBar->GetItemRect ( iCount, &rectButton ); // Check the intersection of the button and the band
CRect interRect;
interRect.IntersectRect ( &rectButton, &rectBand ); // if the intersection is not the same as button then
// the button is not completely visible, so add to menu
if ( interRect != rectButton )
{ UINT iMenuStyle = MF_OWNERDRAW;
// Have to reflect the state of the menu item, so check the state of the
// button and enable or disable the items
if ( pTBar->GetToolBarCtrl().IsButtonEnabled ( id ) )
iMenuStyle |= MF_ENABLED;
else
iMenuStyle |= MF_DISABLED; // Add the item to the menu with the id of the toolbar button
// This id is used to notify the parent if the user selects that item
pop.AppendMenu ( iMenuStyle, id ); // Yeah, have added one, so can show the menu
bAtleastOne=TRUE;
}
}
} // Show the menu if atleast one item has been added
if ( bAtleastOne )
pop.TrackPopupMenu ( TPM_LEFTALIGN|TPM_TOPALIGN, ptMenu.x, ptMenu.y, this ); // Delete our menu
pop.DestroyMenu ();
}
#if !defined(AFX_TOOLMENU_H__E8777520_DE4C_11D3_84C7_0080450EA020__INCLUDED_)
#define AFX_TOOLMENU_H__E8777520_DE4C_11D3_84C7_0080450EA020__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000/////////////////////////////////////////////////////////////////////////////
/*
This is our custom owner drawn menu that shows the hidden tool bar buttons
with optional text
*/
class CToolMenu : public CMenu
{
public:
CToolMenu(); // The toolbar from which the bitmaps/icons have to be extracted
CToolBar* m_pToolbar; // Overridables
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);public:
virtual ~CToolMenu();
};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}#endif // !defined(AFX_TOOLMENU_H__E8777520_DE4C_11D3_84C7_0080450EA020__INCLUDED_)//ToolMenu.cpp
#include "stdafx.h"
#include "ToolMenu.h"
#include "afxpriv.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CToolMenu
/*
Toooooo lazy to calculate or to obtain from the system
*/
#define MENU_SPACETEXT 10
#define MENU_TOPFACTORS 2
#define MENU_LEFTFACTORS 4
#define MENU_RIGHTFACTORS 4
#define MENU_BOTTOMFACTORS 2
#define MENU_MAXWIDTH 100CToolMenu::CToolMenu()
{
}CToolMenu::~CToolMenu()
{
}/////////////////////////////////////////////////////////////////////////////
/*
This is the drawing routine for the owner drawn menu
The toolbar pointer have to be valid !
*/
void CToolMenu::DrawItem( LPDRAWITEMSTRUCT lpds )
{ // If toolbar not set then you cannot proceed drawing so just skip
if ( !m_pToolbar )
return; // Get the image list, gotta do this because i have to draw the bitmap
CImageList * pImgList = m_pToolbar->GetToolBarCtrl().GetImageList();
ASSERT( pImgList ); // Get the size of the image
int cx, cy, iIndex, iImage;
UINT iID, iStyle;
::ImageList_GetIconSize(*pImgList, &cx, &cy); // Have to find which image the button is using, image list wants index
iID = lpds->itemID;
iIndex = m_pToolbar->CommandToIndex ( iID );
m_pToolbar->GetButtonInfo ( iIndex, iID, iStyle, iImage ); CDC dc;
dc.Attach ( lpds->hDC ); // Get the drawing rectangle
CRect rectDraw = lpds->rcItem;
// Refer DrawIndirect( ) API for the drawstyle, raster op, etc...
// Only selection/checked/grayed state is handled here
// Add or change here for all the drawing operations...
int iRasterOP = SRCCOPY;
int iDrawStyle= ILD_NORMAL; COLORREF clrTextBack;
COLORREF clrTextFore;
COLORREF clrMaskFore; clrTextBack = ::GetSysColor (COLOR_MENU);
clrTextFore = ::GetSysColor (COLOR_MENUTEXT);
clrMaskFore = CLR_DEFAULT; // Get appropriate colors from the system for painting our menu
if ((lpds->itemState & ODS_SELECTED) &&
(lpds->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)))
{
clrTextBack = ::GetSysColor (COLOR_HIGHLIGHT);
}
dc.FillSolidRect ( rectDraw, clrTextBack ); if (lpds->itemState & ODS_GRAYED || lpds->itemState & ODS_DISABLED )
{
clrTextFore = ::GetSysColor (COLOR_GRAYTEXT);
iDrawStyle= ILD_BLEND25;
clrMaskFore = CLR_NONE;
}
CPoint lefttop;
lefttop.x = rectDraw.left + MENU_LEFTFACTORS;
lefttop.y = rectDraw.top + MENU_TOPFACTORS ; // A special 3d rect for the checked state
if (lpds->itemState & ODS_CHECKED )
{
clrTextFore = ::GetSysColor (COLOR_3DHILIGHT); CRect rect3D;
rect3D.SetRect ( lefttop.x, lefttop.y, lefttop.x+cx, lefttop.y+cy );
rect3D.InflateRect (2,2);
dc.Draw3dRect( &rect3D, RGB(0,0,0), clrTextFore );
} // Draw the toolbar button bitmap
pImgList->DrawIndirect( &dc, iImage, lefttop, CSize(cx, cy), CPoint(0, 0),
iDrawStyle, iRasterOP, clrTextBack, clrMaskFore); // Now time to draw the text
CRect rectText = rectDraw;
rectText.DeflateRect ( MENU_SPACETEXT + MENU_LEFTFACTORS + cx, MENU_TOPFACTORS, MENU_RIGHTFACTORS, MENU_BOTTOMFACTORS ); COLORREF clrTextForeold = dc.SetTextColor( clrTextFore );
dc.SetBkMode ( TRANSPARENT );
// Try to load the string from resource
// The resource of the toolbar buttons usually have the format
// Status bar text\ntooltip
// this extracts the tooltip text and displays
// Users who dont like this, please change whatever you wanted to display
CString strText;
if ( strText.LoadString ( iID ) )
{
int iPos = strText.Find ( '\n', 0 );
if ( iPos != -1 )
{
CString strTemp = strText.Mid( iPos+1 );
dc.DrawText ( strTemp, -1, &rectText, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS );
}
} dc.SetTextColor( clrTextForeold ); // Detach the dc
dc.Detach ();
}void CToolMenu::MeasureItem( LPMEASUREITEMSTRUCT lpms )
{
// no tool bar, then no op
if ( !m_pToolbar )
return; // Get imagelist
CImageList * pImgList = m_pToolbar->GetToolBarCtrl().GetImageList();
ASSERT( pImgList ); // get image size
int cx, cy;
::ImageList_GetIconSize(*pImgList, &cx, &cy); // Calculate width and height of the item.
// To lazy to get the info from system or to calculate.
lpms->itemHeight = cy + MENU_BOTTOMFACTORS + MENU_TOPFACTORS;
lpms->itemWidth = cx + MENU_LEFTFACTORS + MENU_RIGHTFACTORS +
MENU_MAXWIDTH + MENU_SPACETEXT;
}
用法我写在
上条回复的Usage里面了!
这也是我下载的代码,只不过整理了一下而已!:)还有在MSDN中有篇标题为
Creating an Internet Explorer-style Toolbar
的文章也详细的讲解了Chevron的的用法!