📄 coolcontrolsmanager.cpp
字号:
// The minimal thumb size depends on the system version
// For Windows 98 minimal thumb size is a half of scrollbar size
// and for Windows NT is always 8 pixels regardless of system metrics.
// I really don't know why.
int nMinThumbSize;
if ( GetVersion() & 0x80000000 ) // Windows 98 code
nMinThumbSize = nScrollSize / 2;
else
nMinThumbSize = 8;
// Calculate the arrow rectangles
RECT rc1 = rect, rc2 = rect;
if ( nType == SB_HORZ )
{
if ( ( rect.right - rect.left ) < 2 * nScrollSize )
nScrollSize = ( rect.right - rect.left ) / 2;
rc1.right = rect.left + nScrollSize;
rc2.left = rect.right - nScrollSize;
}
else // SB_VERT
{
if ( ( rect.bottom - rect.top ) < 2 * nScrollSize )
nScrollSize = ( rect.bottom - rect.top ) / 2;
rc1.bottom = rect.top + nScrollSize;
rc2.top = rect.bottom - nScrollSize;
}
// Draw the scrollbar arrows
DrawScrollbarThumb( hDC, rc1 );
DrawScrollbarThumb( hDC, rc2 );
// Disabled scrollbar never have a thumb
if ( bScrollbarCtrl == TRUE && IsWindowEnabled( m_hWnd ) == FALSE )
return;
SCROLLINFO si;
si.cbSize = sizeof( SCROLLINFO );
si.fMask = SIF_ALL;
GetScrollInfo( m_hWnd, bScrollbarCtrl ? SB_CTL : nType, &si );
// Calculate the size and position of the thumb
int nRange = si.nMax - si.nMin + 1;
if ( nRange )
{
int nScrollArea = ( nType == SB_VERT ? ( rect.bottom - rect.top ) : ( rect.right - rect.left ) ) - 2 * nScrollSize;
int nThumbSize;
if ( si.nPage == 0 ) // If nPage is not set then thumb has default size
nThumbSize = GetSystemMetrics( SM_CXHTHUMB );
else
nThumbSize = max( MulDiv( si.nPage ,nScrollArea, nRange ), nMinThumbSize );
if ( nThumbSize >= nScrollArea )
{
nThumbSize = nScrollArea;
if ( bScrollbarCtrl == FALSE )
return;
}
int nThumbPos;
if ( UINT( nRange ) == si.nPage )
{
nThumbPos = 0;
nThumbSize--;
}
else
nThumbPos = MulDiv( si.nPos - si.nMin, nScrollArea - nThumbSize, nRange - si.nPage );
if ( nType == SB_VERT )
{
rc1.top += nScrollSize + nThumbPos;
rc1.bottom = rc1.top + nThumbSize;
}
else // SB_HORZ
{
rc1.left += nScrollSize + nThumbPos;
rc1.right = rc1.left + nThumbSize;
}
if ( nThumbSize <= nScrollArea ) // Don't draw the thumb when it's larger than the scroll area
DrawScrollbarThumb( hDC, rc1 );
}
}
BOOL CCoolControlsManager::CCMControl::IsFocused()
{
return m_hWnd == GetFocus() ? TRUE : FALSE;
}
//////////////////////////////////////////////////////////////////////////////
// CCMEdit class
void CCoolControlsManager::CCMEdit::DrawControl( HDC hDC, const RECT& rc )
{
RECT rect = rc;
// Check if edit window has an associated up-down control.
// If so draw a border around both controls
HWND hWnd = GetNextWindow( m_hWnd, GW_HWNDNEXT );
if ( hWnd )
{
TCHAR szBuf[MAX_CLASSNAME];
// Retrieve window class name
GetClassName( hWnd, szBuf, MAX_CLASSNAME );
if ( lstrcmpi( szBuf, _T( "msctls_updown32" ) ) == 0 ) // Up-down is found
{
DWORD dwStyle = GetWindowLong( hWnd, GWL_STYLE );
if ( ( dwStyle & UDS_ALIGNRIGHT || dwStyle & UDS_ALIGNLEFT ) &&
SendMessage( hWnd, UDM_GETBUDDY, 0, 0L ) == (LONG)m_hWnd )
{
RECT rc;
GetWindowRect( hWnd, &rc );
const int nEdge = GetSystemMetrics( SM_CXEDGE );
if ( dwStyle & UDS_ALIGNRIGHT )
rect.right += ( rc.right - rc.left ) - nEdge;
else // UDS_ALIGNLEFT
rect.left -= ( rc.right - rc.left ) - nEdge;
HDC hDC = GetDC( hWnd ); // We must draw the lines onto spin control DC
COLORREF clr = GetSysColor( m_nState & dsHoverMask ? COLOR_3DDKSHADOW : COLOR_3DHIGHLIGHT );
if ( !IsWindowEnabled( m_hWnd ) )
clr = GetSysColor( COLOR_3DFACE );
FillSolidRect( hDC, 1, 1, rc.right - rc.left - nEdge - 1, 1, clr );
if ( dwStyle & UDS_ALIGNLEFT )
FillSolidRect( hDC, 1, 1, 1, rc.bottom - rc.top - nEdge - 1, clr );
ReleaseDC( hWnd, hDC );
}
}
}
if ( GetWindowLong( m_hWnd, GWL_STYLE ) & ES_READONLY )
m_nState |= dsDisabled;
else
m_nState &= ~dsDisabled;
CCMControl::DrawControl( hDC, rect );
}
LRESULT CCoolControlsManager::CCMEdit::WindowProc( UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch ( uMsg )
{
case WM_ENABLE:
{
CallWindowProc( m_oldWndProc, m_hWnd, uMsg, wParam, lParam );
DrawBorder();
HWND hWnd = GetNextWindow( m_hWnd, GW_HWNDNEXT );
if ( hWnd )
{
TCHAR szBuf[MAX_CLASSNAME];
// Retrieve window class name
GetClassName( hWnd, szBuf, MAX_CLASSNAME );
if ( lstrcmpi( szBuf, _T( "msctls_updown32" ) ) == 0 && // Up-down is found
SendMessage( hWnd, UDM_GETBUDDY, 0, 0L ) == (LONG)m_hWnd )
SendMessage( hWnd, WM_PAINT, 0, 0L ); // Repaint up-down too
}
}
return 0;
default:
return CCMControl::WindowProc( uMsg, wParam, lParam );
}
}
//////////////////////////////////////////////////////////////////////////////
// CCMComboBox class
void CCoolControlsManager::CCMComboBox::DrawControl( HDC hDC, const RECT& rect )
{
// First, draw borders around the control
CCMControl::DrawControl( hDC, rect );
// Now, we have to draw borders around the drop-down arrow
RECT rc = rect;
InflateRect( &rc, -2, -2 );
rc.left = rc.right - GetSystemMetrics( SM_CXHSCROLL );
if ( IsWindowEnabled( m_hWnd ) == TRUE )
{
if ( m_nState & dsHoverMask )
Draw3dBorder( hDC, rc, COLOR_3DFACE, COLOR_3DDKSHADOW,
COLOR_3DHIGHLIGHT, COLOR_3DSHADOW );
else
Draw3dBorder( hDC, rc, COLOR_3DHIGHLIGHT, COLOR_3DSHADOW,
COLOR_3DFACE, COLOR_3DFACE );
}
else
Draw3dBorder( hDC, rc, COLOR_3DFACE, COLOR_3DFACE,
COLOR_3DFACE, COLOR_3DFACE );
}
BOOL CCoolControlsManager::CCMComboBox::IsFocused()
{
// Special case for drop-down and simple ComboBoxes
// which contain child edit control and focus always
// goes to that edit window
if ( ( GetWindowLong( m_hWnd, GWL_STYLE ) & 0x03 ) == CBS_DROPDOWN )
{
HWND hWnd = GetTopWindow( m_hWnd );
if ( hWnd && hWnd == GetFocus() )
return TRUE;
}
return CCMControl::IsFocused();
}
LRESULT CCoolControlsManager::CCMComboBox::WindowProc( UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch ( uMsg )
{
// Drop-down ComboBox receives neither WM_SETFOCUS nor WM_KILLFOCUS
// Instead, it receives these next two messages
case WM_LBUTTONUP: // For kill focus
if ( lParam == -1 )
DrawBorder();
break;
case WM_COMMAND:
if ( HIWORD( wParam ) == EN_SETFOCUS )
DrawBorder();
break;
default:
return CCMControl::WindowProc( uMsg, wParam, lParam );
}
return CallWindowProc( m_oldWndProc, m_hWnd, uMsg, wParam, lParam );
}
//////////////////////////////////////////////////////////////////////////////
// CCMDateTime class
void CCoolControlsManager::CCMDateTime::DrawControl( HDC hDC, const RECT& rc )
{
if ( GetWindowLong( m_hWnd, GWL_STYLE ) & DTS_UPDOWN )
CCMControl::DrawControl( hDC, rc );
else
CCMComboBox::DrawControl( hDC, rc );
}
//////////////////////////////////////////////////////////////////////////////
// CCMPushButton class
void CCoolControlsManager::CCMPushButton::DrawControl( HDC hDC, const RECT& rc )
{
BOOL bDefault = FALSE;
// Unfortunately BS_DEFPUSHBUTTON is defined as 0x00000001L,
// and BS_OWNERDRAW as 0x0000000BL (see winuser.h) so we cannot
// determine the default button for owner-draw controls
DWORD dwStyle = GetWindowLong( m_hWnd, GWL_STYLE ) & BS_OWNERDRAW;
if ( dwStyle != BS_OWNERDRAW )
{
if ( dwStyle == BS_DEFPUSHBUTTON && IsWindowEnabled( m_hWnd ) )
bDefault = TRUE;
}
int nCheck = SendMessage( m_hWnd, BM_GETCHECK, 0, 0 );
if ( m_nState & dsHoverMask )
{
if ( bDefault == TRUE )
{
Draw3dBorder( hDC, rc, COLOR_3DDKSHADOW, COLOR_3DDKSHADOW,
COLOR_3DHIGHLIGHT, COLOR_3DDKSHADOW,
COLOR_3DLIGHT, COLOR_3DSHADOW );
}
else
{
if ( nCheck )
Draw3dBorder( hDC, rc, COLOR_3DDKSHADOW, COLOR_3DHIGHLIGHT,
COLOR_3DSHADOW, COLOR_3DLIGHT );
else
Draw3dBorder( hDC, rc, COLOR_3DHIGHLIGHT, COLOR_3DDKSHADOW,
COLOR_3DLIGHT, COLOR_3DSHADOW,
COLOR_3DFACE, COLOR_3DFACE );
}
}
else
{
if ( bDefault == TRUE )
{
Draw3dBorder( hDC, rc, COLOR_3DDKSHADOW, COLOR_3DDKSHADOW,
COLOR_3DHIGHLIGHT, COLOR_3DSHADOW,
COLOR_3DFACE, COLOR_3DFACE );
}
else
{
if ( nCheck )
Draw3dBorder( hDC, rc, COLOR_3DSHADOW, COLOR_3DHIGHLIGHT,
COLOR_3DFACE, COLOR_3DFACE );
else
Draw3dBorder( hDC, rc, COLOR_3DHIGHLIGHT, COLOR_3DSHADOW,
COLOR_3DFACE, COLOR_3DFACE,
COLOR_3DFACE, COLOR_3DFACE );
}
}
}
LRESULT CCoolControlsManager::CCMPushButton::WindowProc( UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch ( uMsg )
{
// Button messages
case BM_SETCHECK:
case WM_SETTEXT:
CallWindowProc( m_oldWndProc, m_hWnd, uMsg, wParam, lParam );
DrawBorder();
return 0;
default:
return CCMControl::WindowProc( uMsg, wParam, lParam );
}
}
//////////////////////////////////////////////////////////////////////////////
// CCMCheckBox class
void CCoolControlsManager::CCMCheckBox::DrawControl( HDC hDC, const RECT& rect )
{
DWORD dwStyle = GetWindowLong( m_hWnd, GWL_STYLE );
if ( dwStyle & BS_PUSHLIKE )
{
CCMPushButton::DrawControl( hDC, rect );
return;
}
RECT rc;
// Checkmark square size, hard coded here because I couldn't find any
// method to obtain this value from the system.
// Maybe someone else knows how to do it? If so, please let me know!
const int nCheckSize = 13;
if ( ( dwStyle & BS_VCENTER ) == BS_VCENTER )
rc.top = rect.top + ( ( rect.bottom - rect.top ) - nCheckSize ) / 2;
else if ( dwStyle & BS_TOP )
rc.top = rect.top + 1;
else if ( dwStyle & BS_BOTTOM )
rc.top = rect.bottom - nCheckSize - 2;
else // Default
rc.top = rect.top + ( ( rect.bottom - rect.top ) - nCheckSize ) / 2;
if ( dwStyle & BS_LEFTTEXT )
rc.left = rect.right - nCheckSize;
else
rc.left = rect.left;
rc.right = rc.left + nCheckSize;
rc.bottom = rc.top + nCheckSize;
if ( m_nState & dsHoverMask )
{
Draw3dBorder( hDC, rc, COLOR_3DDKSHADOW, COLOR_3DHIGHLIGHT,
COLOR_3DSHADOW, COLOR_3DFACE );
}
else
{
if ( IsWindowEnabled( m_hWnd ) == TRUE )
{
int nState = SendMessage( m_hWnd, BM_GETCHECK, 0, 0L );
Draw3dBorder( hDC, rc, COLOR_3DSHADOW, COLOR_3DHIGHLIGHT,
nState == 2 ? COLOR_3DHIGHLIGHT : COLOR_WINDOW,
nState == 2 ? COLOR_3DHIGHLIGHT : COLOR_WINDOW );
}
else
Draw3dBorder( hDC, rc, COLOR_3DSHADOW, COLOR_3DHIGHLIGHT,
COLOR_3DFACE, COLOR_3DFACE );
}
}
//////////////////////////////////////////////////////////////////////////////
// CCMRadioButton class
void CCoolControlsManager::CCMRadioButton::DrawFrame( POINT* ptArr, int nColor,
HDC hDC, int xOff, int yOff )
{
for ( int i = 0; ; i++ )
{
if ( !ptArr[i].x && !ptArr[i].y )
return;
SetPixel( hDC, ptArr[i].x + xOff, ptArr[i].y + yOff, GetSysColor( nColor ) );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -