Я написал CButton, который будет использовать ownerdraw, когда тематика активна в Windows (это не тот случай, когда используется Windows Classic), и будет делать это динамически.Этот пример кода не является полным, но он демонстрирует все необходимое для получения результатов.
Сложная часть заключается в том, что вам необходимо представлять выделенные и нажатые состояния, см. Параметры для DrawCheckBox
.Я игнорирую их, поскольку они не будут полностью пропущены в моем приложении.
IMPLEMENT_DYNAMIC(mycheckbox, CButton)
mycheckbox::mycheckbox()
: mv_bIsChecked( false )
{
m_brush.CreateSolidBrush( RGB( 0,0,255) );
}
mycheckbox::~mycheckbox()
{
}
BEGIN_MESSAGE_MAP(mycheckbox, CButton)
ON_WM_CTLCOLOR_REFLECT()
ON_WM_PAINT()
ON_CONTROL_REFLECT(BN_CLICKED, &mycheckbox::OnBnClicked)
END_MESSAGE_MAP()
HBRUSH mycheckbox::CtlColor(CDC* pDC, UINT nCtlColor)
{
pDC->SetBkColor( RGB( 255, 0, 0 ) ); // text background color
pDC->SetTextColor( RGB( 0, 255, 0 ) ); // text foreground color
return m_brush; // control background
}
void mycheckbox::DrawItem(LPDRAWITEMSTRUCT)
{
}
void mycheckbox::OnPaint()
{
if( ( GetStyle() & BS_OWNERDRAW ) == BS_OWNERDRAW )
{
CPaintDC dc( this );
RECT rect;
GetClientRect( & rect );
rect.right = rect.left + 20;
CMFCVisualManager::GetInstance()->DrawCheckBox(
& dc
, rect
, false // highlighted
, mv_bIsChecked ? 1 : 0 // state
, true // enabled
, false // pressed
);
// draw text next to the checkbox if you like
}
else
__super::OnPaint();
}
// when BS_OWNERDAW is active,
// GetCheck() is reporting a wrong value
// so we have to do a little bookkeeping ourselves
void mycheckbox::OnBnClicked()
{
mv_bIsChecked = ! mv_bIsChecked;
}
BOOL mycheckbox::PreCreateWindow( CREATESTRUCT & cs )
{
CString lv_szValue;
CSettingsStore lv_Registry( FALSE, TRUE );
lv_Registry.Open( _T("Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager") );
lv_Registry.Read( _T("ThemeActive"), lv_szValue );
lv_Registry.Close();
if( lv_szValue == _T("1") )
cs.style |= BS_OWNERDRAW;
return CButton::PreCreateWindow(cs);
}
Я даже пробовал переключать темы во время выполнения, однако это дает нежелательный эффект при переключении с темы Windows 7
на Windows Classic
(установите флажок тогдавыглядит как обычная кнопка).Так что я не пользуюсь этим, но, возможно, интересно поделиться:
void mycheckbox::OnNMThemeChanged( NMHDR * pNMHDR, LRESULT * pResult )
{
CString lv_szValue;
CSettingsStore lv_Registry( FALSE, TRUE );
lv_Registry.Open( _T("Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager") );
lv_Registry.Read( _T("ThemeActive"), lv_szValue );
lv_Registry.Close();
ModifyStyle( BS_OWNERDRAW, 0 ); // turn off
if( lv_szValue == _T("1") )
ModifyStyle( 0, BS_OWNERDRAW ); // turn on
// This feature requires Windows XP or greater.
// The symbol _WIN32_WINNT must be >= 0x0501.
// TODO: Add your control notification handler code here
*pResult = 0;
}