我寫了一個CButton,當主題在Windows中使用時,它將使用ownerdraw(當使用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;
}
'CMFCButton'不能顯示覆選框或單選按鈕,即使方法'器isChecked()'返回TRUE時的風格'BS_CHECKBOX'用來。有趣。 –
當閱讀關於'CMFCButton'的文章時,我遇到了函數'CMFCVisualManager :: GetInstance() - > DrawCheckBox'和'CMFCVisualManager :: GetInstance() - > DrawRadioButton' –