📄 ekutil.cpp
字号:
//=======================================================//
// Chapter 04: Dialog Boxes //
//=======================================================//
///////////////////////////////////////////////////////////
// EkDrawBitmap: function implementation
void EkDrawBitmap( CDC* pDC, CBitmap* pBitmap, CRect rect, BOOL bCenter /* = TRUE */ )
{
ASSERT_VALID( pDC );
ASSERT_VALID( pBitmap );
// 1 - Create compatible memory DC
CDC dcMem;
dcMem.CreateCompatibleDC( pDC );
// 2 - Select bitmap into memory DC
CBitmap* pOldBitmap = dcMem.SelectObject( pBitmap );
if( bCenter )
{
// 3 - Center bitmap in destination rectangle
BITMAP bitmap;
pBitmap->GetObject( sizeof( BITMAP ), &bitmap);
CSize sizeBitmap( bitmap.bmWidth, bitmap.bmHeight );
CSize diff = rect.Size() - sizeBitmap;
rect.DeflateRect( diff.cx / 2, diff.cy / 2 );
}
// 4 - Blit the bitmap from the memory DC to the real DC
pDC->BitBlt( rect.left, rect.top,
rect.Width(), rect.Height(),
&dcMem, 0, 0, SRCCOPY );
// 5 - Deselect bitmap from memory DC
dcMem.SelectObject( pOldBitmap );
}
///////////////////////////////////////////////////////////
// EkExpandDialog: function implementation
void EkExpandDialog( CDialog* pDlg, UINT nSmallID, UINT nLargeID, UINT nButtonID )
{
ASSERT_VALID( pDlg );
// 1 - Get the More/Less button control
CWnd* pWndButton = pDlg->GetDlgItem( nButtonID );
ASSERT_VALID( pWndButton );
// 2 - Load button resource string and parse More/Less parts
CString strButton;
VERIFY( strButton.LoadString( nButtonID ) );
CString strMore, strLess;
AfxExtractSubString( strMore, strButton, 0, _T( '\n' ) );
AfxExtractSubString( strLess, strButton, 1, _T( '\n' ) );
// 3 - Find out if we need to expand or collapse the dialog
CString strCaption;
pWndButton->GetWindowText( strCaption );
BOOL bExpand = ( strCaption == strMore ); // Collapse by default
// 4 - Get current dialog window rectangle
CRect rcDialog;
pDlg->GetWindowRect( &rcDialog );
int nNewHeight = -1;
if( bExpand )
{
// 5a - Change More/Less button caption
pWndButton->SetWindowText( strLess );
// 6a - Calculate new dialog height
CWnd* pWndLarge = pDlg->GetDlgItem( nLargeID );
ASSERT_VALID( pWndLarge );
CRect rcLarge;
pWndLarge->GetWindowRect( &rcLarge );
nNewHeight = rcLarge.top-rcDialog.top;
}
else
{
// 5b - Change More/Less button caption
pWndButton->SetWindowText( strMore );
// 6b - Calculate new dialog height
CWnd* pWndSmall = pDlg->GetDlgItem( nSmallID );
ASSERT_VALID( pWndSmall );
CRect rcSmall;
pWndSmall->GetWindowRect( &rcSmall );
nNewHeight = rcSmall.top-rcDialog.top;
}
// 7 - Set new dialog height
ASSERT( nNewHeight > 0 );
pDlg->SetWindowPos( NULL, 0, 0,
rcDialog.Width(), nNewHeight,
SWP_NOMOVE | SWP_NOZORDER );
// 8 - Set the enabled state for each control depending on whether
// the control is currently visible or not
CWnd* pWndControl = pDlg->GetWindow( GW_CHILD );
while( pWndControl != NULL )
{
CRect rcControl;
pWndControl->GetWindowRect( &rcControl );
pWndControl->EnableWindow( rcControl.top <= rcDialog.top + nNewHeight );
pWndControl = pWndControl->GetWindow( GW_HWNDNEXT );
}
// 9 - Check if a control still has the focus
// (can lose it if the active control becomes disabled)
CWnd* pWndActiveControl = CWnd::GetFocus();
if( pWndActiveControl == NULL )
{
// 10 - Set focus to "first" control on dialog
CWnd* pWndFirstControl = pDlg->GetNextDlgTabItem( NULL );
ASSERT_VALID( pWndFirstControl );
ASSERT( pWndFirstControl->IsWindowEnabled() );
pWndFirstControl->SetFocus();
}
}
//=======================================================//
// Chapter 05: Property Sheets //
//=======================================================//
///////////////////////////////////////////////////////////
// EkCenterPropertySheetButtons: function implementation
void EkCenterPropertySheetButtons( CPropertySheet* pPSheet,
BOOL bCenterOK,
BOOL bCenterCancel,
BOOL bCenterApply )
{
ASSERT_VALID( pPSheet );
ASSERT( bCenterOK || bCenterCancel || bCenterApply );
// Find "OK" button rectangle
CWnd* pWndOK = pPSheet->GetDlgItem( IDOK );
ASSERT( pWndOK != NULL );
CRect rcOK;
pWndOK->GetWindowRect( &rcOK );
pPSheet->ScreenToClient( &rcOK );
// Find "Cancel" button rectangle
CWnd* pWndCancel = pPSheet->GetDlgItem( IDCANCEL );
ASSERT( pWndCancel != NULL );
CRect rcCancel;
pWndCancel->GetWindowRect( &rcCancel );
pPSheet->ScreenToClient( &rcCancel );
// Find "Apply" button rectangle
CWnd* pWndApply = pPSheet->GetDlgItem( ID_APPLY_NOW );
ASSERT( pWndApply != NULL );
CRect rcApply;
pWndApply->GetWindowRect( &rcApply );
pPSheet->ScreenToClient( &rcApply );
// Find property sheet client rectangle
CRect rcClient;
pPSheet->GetClientRect( &rcClient );
// Compute layout values
int nButtonWidth = rcOK.Width();
int nButtonMargin = rcCancel.left - rcOK.right;
int nButtons = (bCenterOK ? 1 : 0) + (bCenterCancel ? 1 : 0)
+ (bCenterApply ? 1 : 0);
int nGlobalWidth = nButtonWidth * nButtons;
if( nButtons > 1 )
{
nGlobalWidth += nButtonMargin * (nButtons - 1);
}
int nCurrentX = ( rcClient.left + rcClient.right - nGlobalWidth ) / 2;
int nTop = rcOK.top;
// Center "OK" button
if( bCenterOK )
{
pWndOK->SetWindowPos( NULL,
nCurrentX,
nTop,
0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
nCurrentX += nButtonWidth + nButtonMargin;
}
// Center "Cancel" button
if( bCenterCancel )
{
pWndCancel->SetWindowPos( NULL,
nCurrentX,
nTop,
0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
nCurrentX += nButtonWidth + nButtonMargin;
}
// Center "Apply" button
if( bCenterApply )
{
pWndApply->SetWindowPos( NULL,
nCurrentX,
nTop,
0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
}
}
///////////////////////////////////////////////////////////
// EkCreateEmbeddedPropertySheet: function implementation
BOOL EkCreateEmbeddedPropertySheet( CWnd* pParent,
CPropertySheet* pPSheet,
DWORD dwStyle /* = WS_CHILD | WS_VISIBLE */,
DWORD dwExStyle /* = 0 */ )
{
ASSERT_VALID( pParent );
ASSERT_VALID( pPSheet );
// 1 - Create the embedded property sheet window
if( !pPSheet->Create( pParent, dwStyle, dwExStyle ) )
{
TRACE0( "Embedded property sheet creation failed\n" );
return FALSE;
}
// 2 - Add WS_TABSTOP and WS_EX_CONTROLPARENT to the property sheet styles
pPSheet->ModifyStyle( 0, WS_TABSTOP );
pPSheet->ModifyStyleEx ( 0, WS_EX_CONTROLPARENT );
// 3 - Add WS_EX_CONTROLPARENT to the parent window styles
pParent->ModifyStyleEx ( 0, WS_EX_CONTROLPARENT );
return TRUE;
}
///////////////////////////////////////////////////////////
// EkHidePropertySheetButtons: function implementation
void EkHidePropertySheetButtons( CPropertySheet* pPSheet,
BOOL bHideOK,
BOOL bHideCancel,
BOOL bHideApply )
{
ASSERT_VALID( pPSheet );
// Hide "OK" button
if( bHideOK )
{
CWnd* pWnd = pPSheet->GetDlgItem( IDOK );
ASSERT( pWnd != NULL );
pWnd->ShowWindow( SW_HIDE );
}
// Hide "Cancel" button
if( bHideCancel )
{
CWnd* pWnd = pPSheet->GetDlgItem( IDCANCEL );
ASSERT( pWnd != NULL );
pWnd->ShowWindow( SW_HIDE );
}
// Hide "Apply" button
if( bHideApply )
{
CWnd* pWnd = pPSheet->GetDlgItem( ID_APPLY_NOW );
ASSERT( pWnd != NULL );
pWnd->ShowWindow( SW_HIDE );
}
}
///////////////////////////////////////////////////////////
// EkPositionEmbeddedPropertySheet: function implementation
void EkPositionEmbeddedPropertySheet( CWnd* pParent,
CPropertySheet* pPSheet,
CRect rcNewPosition )
{
ASSERT_VALID( pParent );
ASSERT_VALID( pPSheet );
// 1 - Get current coordinates of tab control
// and property sheet window
CTabCtrl* pTabCtrl = pPSheet->GetTabControl();
ASSERT( pTabCtrl != NULL );
CRect rcTabCtrl;
pTabCtrl->GetWindowRect( &rcTabCtrl );
pParent->ScreenToClient( &rcTabCtrl );
CRect rcPSheet;
pPSheet->GetWindowRect( &rcPSheet );
pParent->ScreenToClient( &rcPSheet );
// 2 - Calculate margin between property sheet
// and tab control
int dcx = rcPSheet.Width() - rcTabCtrl.Width();
int dcy = rcPSheet.Height() - rcTabCtrl.Height();
// 3 - Move and resize property sheet window
// (also moves the tab window because it is a child
// of the property sheet window)
pPSheet->MoveWindow( rcNewPosition .left, rcNewPosition.top,
rcNewPosition .Width(), rcNewPosition.Height() );
// 4 - Resize tab control window to restore
// right / bottom margins
pTabCtrl->SetWindowPos( NULL,
0, 0,
rcNewPosition.Width() - dcx,
rcNewPosition.Height() - dcy,
SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE );
// 5 - Activate each property page to prevent drawing
// problem
int nCurrentPage = pPSheet->GetActiveIndex();
for( int i = 0; i < pPSheet->GetPageCount(); ++i )
{
pPSheet->SetActivePage( i );
}
pPSheet->SetActivePage( nCurrentPage );
}
void EkPositionEmbeddedPropertySheet( CWnd* pParent,
CPropertySheet* pPSheet,
UINT nIDPSheetArea )
{
ASSERT_VALID( pParent );
ASSERT_VALID( pPSheet );
// 1 - Retrieve property sheet destination position
CRect rcNewPosition;
CWnd* pWndNewArea = pParent->GetDlgItem( nIDPSheetArea );
if( pWndNewArea == NULL )
{
ASSERT( FALSE ); // Invalid nIDPSheetArea
return;
}
pWndNewArea->GetWindowRect( &rcNewPosition );
pParent->ScreenToClient( &rcNewPosition );
// 2 - Call overloaded function
EkPositionEmbeddedPropertySheet( pParent, pPSheet, rcNewPosition );
}
///////////////////////////////////////////////////////////
// EkResizePropertySheet: function implementation
void EkResizePropertySheet( CPropertySheet* pPSheet, int nWidth )
{
ASSERT_VALID( pPSheet );
// 1 - Get current dimensions of tab control
// and property sheet window
CTabCtrl* pTabCtrl = pPSheet->GetTabControl();
ASSERT( pTabCtrl != NULL );
CRect rcTabCtrl;
pTabCtrl->GetWindowRect( &rcTabCtrl );
pPSheet->ScreenToClient( &rcTabCtrl );
CRect rcPSheet;
pPSheet->GetWindowRect( &rcPSheet );
// 2 - Compute resizing offset
int dcx = rcPSheet.Width() - nWidth;
// 3 - Resize property sheet window
pPSheet->SetWindowPos( NULL,
0, 0,
nWidth,
rcPSheet.Height(),
SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE );
// 4 - Resize tab control window to restore
// right margin
pTabCtrl->SetWindowPos( NULL,
0, 0,
rcTabCtrl.Width() - dcx,
rcTabCtrl.Height(),
SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE );
// 5 - Activate each property page to prevent drawing
// problem
int nCurrentPage = pPSheet->GetActiveIndex();
for( int i = 0; i < pPSheet->GetPageCount(); ++i )
{
pPSheet->SetActivePage( i );
}
pPSheet->SetActivePage( nCurrentPage );
}
//=======================================================//
// Chapter 06: Toolbars and Status Bars //
//=======================================================//
/////////////////////////////////////////////////////////////////////////////
// CEkDrawStatusBar: class implementation
#include <afxpriv.h> // For WM_IDLEUPDATECMDUI message
CEkDrawStatusBar::CEkDrawStatusBar()
{
}
CEkDrawStatusBar::~CEkDrawStatusBar()
{
}
BEGIN_MESSAGE_MAP(CEkDrawStatusBar, CStatusBar)
//{{AFX_MSG_MAP(CEkDrawStatusBar)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CEkDrawStatusBar::OnPaint()
{
// 1 - Let base class paint itself
CStatusBar::OnPaint();
// 2 - Send a WM_IDLEUPDATECMDUI message to ourself
// to ensure our "drawing" panes repaint correctly
SendMessage( WM_IDLEUPDATECMDUI );
}
///////////////////////////////////////////////////////////
// EkCreateProgressBar: function implementation
BOOL EkCreateProgressBar( CProgressCtrl* pProgressCtrl,
CStatusBar* pStatusBar,
LPCTSTR szMessage /* = NULL */,
int nPaneIndex /* = 0 */,
int cxMargin /* = 10 */,
int cxMaxWidth /* = -1 */,
UINT nIDControl /* = 1 */ )
{
ASSERT_VALID( pProgressCtrl );
ASSERT_VALID( pStatusBar );
// 1 - Calculate destination rectangle for progress control
CRect rc;
pStatusBar->GetItemRect( nPaneIndex, &rc );
// 2 - Define progress bar horizontal offset
if( szMessage != NULL )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -