www.pudn.com > WBDraw.rar > CustomizeDialog.cpp
/////////////////////////////////////////////////////////////////////////////
// CustomizeDialog.cpp: implementation of the CCustomizeDialog class.
//
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2001 by Nikolay Denisov. All rights reserved.
//
// This code is free for personal and commercial use, providing this
// notice remains intact in the source files and all eventual changes are
// clearly marked with comments.
//
// You must obtain the author's consent before you can include this code
// in a software library.
//
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// Please email bug reports, bug fixes, enhancements, requests and
// comments to: nick@actor.ru
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CustomizeDialog.h"
#include "ToolBarEx.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCustomizeDialog dialog
#ifdef CUSTOM_DRAW
#define IDC_LB_AVAILABLE 0x00C9 // revealed using Spy++
#define IDC_LB_CURRENT 0x00CB
#define STR_SEPARATOR _T("Separator")
#endif // CUSTOM_DRAW
static const int cxPadding = 3;
static const int cyPadding = 3;
IMPLEMENT_DYNAMIC( CCustomizeDialog, CWnd )
CCustomizeDialog::CCustomizeDialog( CToolBarEx* pToolBar,
TextOptions TextOptions,
IconOptions IconOptions )
{
ASSERT_VALID(pToolBar);
m_pToolBar = pToolBar;
m_eTextOptions=TextOptions;
m_eIconOptions=IconOptions;
#ifdef CUSTOM_DRAW
GetColors();
#endif // CUSTOM_DRAW
}
/////////////////////////////////////////////////////////////////////////////
// Operations
void CCustomizeDialog::SetTextOptions( TextOptions eTextOptions)
{
m_eTextOptions = eTextOptions;
if (IsWindow(m_wndTextOptions.m_hWnd))
m_wndTextOptions.SetCurSel(eTextOptions);
}
void CCustomizeDialog::SetIconOptions( IconOptions eIconOptions)
{
m_eIconOptions = eIconOptions;
if (IsWindow(m_wndIconOptions.m_hWnd))
{
m_wndIconOptions.SetCurSel(eIconOptions);
#ifdef CUSTOM_DRAW
// set the height also
int nHeight = GetButtonSize().cy;
CWnd* pWnd = GetDlgItem( IDC_LB_AVAILABLE );
if ( pWnd != 0 )
{
pWnd->SendMessage( LB_SETITEMHEIGHT, 0, nHeight );
pWnd->Invalidate();
}
pWnd = GetDlgItem( IDC_LB_CURRENT );
if ( pWnd != 0 )
{
pWnd->SendMessage( LB_SETITEMHEIGHT, 0, nHeight );
pWnd->Invalidate();
}
#endif // CUSTOM_DRAW
}
}
/////////////////////////////////////////////////////////////////////////////
// CCustomizeDialog message handlers
BEGIN_MESSAGE_MAP(CCustomizeDialog, CWnd)
//{{AFX_MSG_MAP(CCustomizeDialog)
ON_WM_MEASUREITEM()
ON_WM_DRAWITEM()
ON_WM_CTLCOLOR()
ON_WM_SYSCOLORCHANGE()
//}}AFX_MSG_MAP
ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
ON_CBN_SELENDOK(IDC_CB_TEXTOPTIONS, OnTextOptions)
ON_CBN_SELENDOK(IDC_CB_ICONOPTIONS, OnIconOptions)
END_MESSAGE_MAP()
LRESULT CCustomizeDialog::OnInitDialog( WPARAM /*wParam*/, LPARAM /*lParam*/ )
{
CRect rcClient;
GetClientRect( rcClient );
CRect rcWindow;
GetWindowRect( rcWindow );
// create the windows // sizes are hardcoded //ugly way
CRect rc;
CFont *pFont =GetFont();
ASSERT_VALID(pFont);
//static wnd
rc=CRect(4,2,49,8);
MapDialogRect(m_hWnd,&rc);
rc.left+=rcClient.left;
rc.top+=rcClient.bottom;
VERIFY(m_wndTextOptionsText.Create(_T("Te&xt options:"),WS_CHILD|WS_VISIBLE,rc,this));
m_wndTextOptionsText.SetFont(pFont);
m_wndTextOptionsText.SetWindowPos(NULL,rc.left,rc.top,rc.right,rc.bottom,SWP_NOZORDER|SWP_NOACTIVATE);
//Text options
rc=CRect(52,0,123,50);
MapDialogRect(m_hWnd,&rc);
rc.left+=rcClient.left;
rc.top+=rcClient.bottom;
VERIFY(m_wndTextOptions.Create(WS_CHILD |WS_VISIBLE |CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP,rc,this, IDC_CB_TEXTOPTIONS));
m_wndTextOptions.SetFont(pFont);
m_wndTextOptions.AddString(_T("Show Text Labels"));
m_wndTextOptions.AddString(_T("Selective Text on Right"));
m_wndTextOptions.AddString(_T("No Text Labels"));
SetTextOptions(m_eTextOptions);
m_wndTextOptions.SetWindowPos(NULL,rc.left,rc.top,rc.right,rc.bottom,SWP_NOZORDER|SWP_NOACTIVATE);
//static wnd
rc=CRect(4,20,49,8);
MapDialogRect(m_hWnd,&rc);
rc.left+=rcClient.left;
rc.top+=rcClient.bottom;
VERIFY(m_wndIconOptionsText.Create(_T("Ico&n options:"),WS_CHILD|WS_VISIBLE,rc,this));
m_wndIconOptionsText.SetFont(pFont);
m_wndIconOptionsText.SetWindowPos(NULL,rc.left,rc.top,rc.right,rc.bottom,SWP_NOZORDER|SWP_NOACTIVATE);
//icon combo
rc=CRect(52,18,123,50);
MapDialogRect(m_hWnd,&rc);
rc.left+=rcClient.left;
rc.top+=rcClient.bottom;
VERIFY(m_wndIconOptions.Create(WS_CHILD |WS_VISIBLE |CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP,rc,this, IDC_CB_ICONOPTIONS));
m_wndIconOptions.SetFont(pFont);
m_wndIconOptions.AddString(_T("Small Icons"));
m_wndIconOptions.AddString(_T("Large Icons"));
SetIconOptions(m_eIconOptions);
m_wndIconOptions.SetWindowPos(NULL,rc.left,rc.top,rc.right,rc.bottom,SWP_NOZORDER|SWP_NOACTIVATE);
// final rect
rc=CRect(0,0,179,34);
MapDialogRect(m_hWnd,&rc);
rc.left+=rcClient.left;
rc.top+=rcClient.bottom;
// Increase height of Customize Toolbar dialog accordingly
rcWindow.bottom += (rc.bottom+cyPadding);
VERIFY( SetWindowPos( 0, 0, 0, rcWindow.Width(), rcWindow.Height(),
SWP_NOZORDER | SWP_NOMOVE ) );
//Set Title
ASSERT(m_pToolBar);
CString strName,strOrgName;
m_pToolBar->GetWindowText(strName);
if (!strName.IsEmpty())
{
GetWindowText(strOrgName);
SetWindowText(strOrgName + _T(" - ")+ strName);
}
return Default();
}
HBRUSH CCustomizeDialog::OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor )
{
HBRUSH hbr = CWnd::OnCtlColor( pDC, pWnd, nCtlColor );
#ifdef CUSTOM_DRAW
if ( nCtlColor == CTLCOLOR_LISTBOX )
{
UINT nIDCtl = ( UINT )pWnd->GetDlgCtrlID();
if ( ( nIDCtl == IDC_LB_AVAILABLE ) ||
( nIDCtl == IDC_LB_CURRENT ) )
{
hbr = ::GetSysColorBrush( COLOR_BTNFACE );
}
}
#endif // CUSTOM_DRAW
return hbr;
}
void CCustomizeDialog::OnTextOptions()
{
m_eTextOptions=(TextOptions)m_wndTextOptions.GetCurSel();
m_pToolBar->SetTextOptions(( TextOptions )m_eTextOptions,TRUE);
}
void CCustomizeDialog::OnIconOptions()
{
m_eIconOptions=(IconOptions)m_wndIconOptions.GetCurSel();
#ifdef CUSTOM_DRAW
m_pToolBar->SetIconOptions(( IconOptions )m_eIconOptions,TRUE); // do not update if custom draw is not enabled
int nHeight = GetButtonSize().cy;
CWnd* pWnd = GetDlgItem( IDC_LB_AVAILABLE );
if ( pWnd != 0 )
{
pWnd->SendMessage( LB_SETITEMHEIGHT, 0, nHeight );
pWnd->Invalidate();
}
pWnd = GetDlgItem( IDC_LB_CURRENT );
if ( pWnd != 0 )
{
pWnd->SendMessage( LB_SETITEMHEIGHT, 0, nHeight );
pWnd->Invalidate();
}
#endif // CUSTOM_DRAW
}
void CCustomizeDialog::OnMeasureItem( int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct )
{
#ifdef CUSTOM_DRAW
if ( lpMeasureItemStruct->CtlType == ODT_LISTBOX )
{
if ( ( nIDCtl == IDC_LB_AVAILABLE ) ||
( nIDCtl == IDC_LB_CURRENT ) )
{
lpMeasureItemStruct->itemHeight = GetButtonSize().cy;
return;
}
}
#endif // CUSTOM_DRAW
CWnd::OnMeasureItem( nIDCtl, lpMeasureItemStruct );
}
void CCustomizeDialog::OnDrawItem( int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct )
{
#ifdef CUSTOM_DRAW
if ( lpDrawItemStruct->CtlType == ODT_LISTBOX )
{
if ( ( nIDCtl == IDC_LB_AVAILABLE ) || ( nIDCtl == IDC_LB_CURRENT ) )
{
CDC* pDC = CDC::FromHandle( lpDrawItemStruct->hDC );
int nSavedDC = pDC->SaveDC();
ASSERT( nSavedDC );
CFont *pToolBarFont= m_pToolBar->GetFont();
if (pToolBarFont) pDC->SelectObject(pToolBarFont);
// Get all needed info about the item being drawn
CRect rcItem( &lpDrawItemStruct->rcItem );
int nItem = ( SHORT )HIWORD( lpDrawItemStruct->itemData );
int nImage = ( SHORT )LOWORD( lpDrawItemStruct->itemData );
int nIndex = ( int )lpDrawItemStruct->itemID;
bool bSelected = ( lpDrawItemStruct->itemState & ODS_SELECTED ) != 0;
bool bFocused = ( lpDrawItemStruct->itemState & ODS_FOCUS ) != 0;
bool bSeparator = false;
bool bHidden = false;
//I found these magic numbers by trial, they may be wrong
if ( ( nItem < 0 ) || ( nItem > m_pToolBar->m_ToolBarInfo.GetUpperBound() ) )
{
// actually hidden or last seperator
bHidden = ((nItem & 0x4000)==0x4000) || ((nItem & 0xa000)==0xa000); //magic number
bSeparator =(nItem &0x2000)==0x2000; //magic number
nItem &=0xFF; //magic number
}
// Calculate rectangles for image, text and focus frame
CSize szButton = GetButtonSize();
CRect rcImage( rcItem );
rcImage.right = rcImage.left + szButton.cx;
CRect rcText( rcItem );
rcText.left += szButton.cx + 5;
rcText.right -= 2;
CRect rcLabel( rcItem );
rcLabel.left += szButton.cx + 1;
// Cache system colors
COLORREF clrText = bSelected ? m_clrHighLightText : m_clrBtnText ;
COLORREF clrBack = bSelected ? m_clrHighLight : m_clrBtnFace ;
pDC->FillSolidRect( rcImage, m_clrBtnFace );
pDC->FillSolidRect( rcLabel, clrBack );
// Draw focus rect, if needed
if ( bFocused )
{
CBrush brush( RGB(
255 - GetRValue( clrBack ),
255 - GetGValue( clrBack ),
255 - GetBValue( clrBack ) ) );
rcLabel.DeflateRect( 2, 2 );
pDC->FrameRect( rcLabel, &brush );
VERIFY( brush.DeleteObject() );
}
// Get item text to be drawn
CString strText;
if ( !bSeparator )
strText= m_pToolBar->m_ToolBarInfo[ nItem ].btnText;
else
strText=STR_SEPARATOR;
// Prepare to draw item text
int nFormat = DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_END_ELLIPSIS;
pDC->SetBkMode( TRANSPARENT );
pDC->SetTextColor( clrText );
if ( !bSeparator )
{
// Draw item image, if any
if ( nImage >= 0 )
{
if ( bSelected )
{
pDC->Draw3dRect( rcImage, m_clr3dHilite, m_clr3dShadow );
}
CToolBarCtrl& tbCtrl = m_pToolBar->GetToolBarCtrl();
ASSERT(m_pToolBar->m_hbmImageWell);
CSize szImage = ( m_pToolBar->GetIconOptions() == ioSmallIcons ) ?
CToolBarEx::m_szImageSmall : CToolBarEx::m_szImageLarge;
CDC dc;
VERIFY( dc.CreateCompatibleDC( pDC ) );
CBitmap * pbmpImage =CBitmap::FromHandle(m_pToolBar->m_hbmImageWell);
CBitmap* pOldBitmap = dc.SelectObject( pbmpImage );
ASSERT(rcImage.Width()>=szImage.cx);
ASSERT(rcImage.Height()>=szImage.cy);
VERIFY( pDC->BitBlt((rcImage.Width()-szImage.cx)/2+ rcImage.left,(rcImage.Height()-szImage.cy)/2+rcImage.top , szImage.cx, szImage.cy,&dc, nImage*szImage.cx, 0, SRCCOPY ) );
dc.SelectObject( pOldBitmap );
VERIFY( pbmpImage->Detach() );
}
if ( m_pToolBar->m_ToolBarInfo[ nItem ].tbButton.fsStyle & TBSTYLE_DROPDOWN )
{
// This button is drop-down button. To indicate this simple fact
// we draw an arrow on right like one that submenu items have.
CRect rcArrow( rcText );
rcArrow.left = rcArrow.right - ::GetSystemMetrics( SM_CXMENUCHECK );
rcText.right -= rcArrow.Width();
CBrush brush( clrText );
CBrush* pOldBrush = pDC->SelectObject( &brush );
CDC dc;
VERIFY( dc.CreateCompatibleDC( pDC ) );
CBitmap bmpArrow;
VERIFY( bmpArrow.CreateCompatibleBitmap( pDC, rcArrow.Width(), rcArrow.Height() ) );
CBitmap* pOldBitmap = dc.SelectObject( &bmpArrow );
CRect rc( 0, 0, rcArrow.Width(), rcArrow.Height() );
VERIFY( dc.DrawFrameControl( rc, DFC_MENU, DFCS_MENUARROW ) );
VERIFY( pDC->BitBlt( rcArrow.left, rcArrow.top, rcArrow.Width(), rcArrow.Height(),
&dc, 0, 0, 0x00B8074A /*=PSDPxax*/ ) );
dc.SelectObject( pOldBitmap );
VERIFY( bmpArrow.DeleteObject() );
pDC->SelectObject( pOldBrush );
VERIFY( brush.DeleteObject() );
}
if (bHidden)
{
if ( bSelected )
{
pDC->SetTextColor( m_clrBtnFace );
pDC->DrawText( strText, rcText, nFormat );
}
else
{
CRect rcTemp( rcText );
rcTemp.OffsetRect( 1, 1 );
pDC->SetTextColor( m_clr3dHilite );
pDC->DrawText( strText, -1, rcTemp, nFormat );
pDC->SetTextColor( m_clrGrayText );
pDC->DrawText( strText, rcText, nFormat );
}
}
else
{
pDC->DrawText( strText, rcText, nFormat );
}
}
else
{
if (bHidden)
{
if ( bSelected )
{
pDC->SetTextColor( m_clrBtnFace );
pDC->DrawText( strText, rcText, nFormat );
}
else
{
CRect rcTemp( rcText );
rcTemp.OffsetRect( 1, 1 );
pDC->SetTextColor( m_clr3dHilite );
pDC->DrawText( strText, -1, rcTemp, nFormat );
pDC->SetTextColor( m_clrGrayText );
pDC->DrawText( strText, rcText, nFormat );
}
}
else
{
// Draw the separator bar in the middle
rcImage.DeflateRect( cxPadding, cyPadding );
int y = ( rcImage.top + rcImage.bottom ) / 2;
rcImage.top = y - 1;
rcImage.bottom = y + 1;
pDC->Draw3dRect( rcImage, m_clr3dShadow, m_clr3dHilite );
pDC->DrawText( strText, rcText, nFormat );
}
}
VERIFY( pDC->RestoreDC( nSavedDC ) );
return;
}
}
#endif //CUSTOM_DRAW
CWnd::OnDrawItem( nIDCtl, lpDrawItemStruct );
}
#ifdef CUSTOM_DRAW
CSize CCustomizeDialog::GetButtonSize() const
{
CSize szImage = ( m_pToolBar->GetIconOptions() == ioSmallIcons ) ?
CToolBarEx::m_szImageSmall : CToolBarEx::m_szImageLarge;
return szImage + CSize( cxPadding * 2, cyPadding * 2 );
}
#endif //CUSTOM_DRAW
LRESULT CCustomizeDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
if (message==WM_HELP)
{
LPHELPINFO lphi = (LPHELPINFO) lParam;
if ( (lphi->iCtrlId != IDC_CB_TEXTOPTIONS) && (lphi->iCtrlId != IDC_CB_ICONOPTIONS) )
return DefWindowProc(message,wParam,lParam);
}
return CWnd::WindowProc(message, wParam, lParam);
}
void CCustomizeDialog::OnSysColorChange()
{
#ifdef CUSTOM_DRAW
//get the color again
GetColors();
#endif // CUSTOM_DRAW
CWnd::OnSysColorChange();
}
#ifdef CUSTOM_DRAW
void CCustomizeDialog::GetColors()
{
m_clrHighLightText=::GetSysColor( COLOR_HIGHLIGHTTEXT);
m_clrBtnText=::GetSysColor( COLOR_BTNTEXT );
m_clrHighLight= ::GetSysColor(COLOR_HIGHLIGHT );
m_clrGrayText = ::GetSysColor( COLOR_GRAYTEXT );
m_clrBtnFace = ::GetSysColor( COLOR_BTNFACE );
m_clr3dShadow = ::GetSysColor( COLOR_3DSHADOW );
m_clr3dHilite = ::GetSysColor( COLOR_3DHILIGHT );
}
#endif // CUSTOM_DRAW