如何獲取3狀態複選框以將不同狀態使用不同的位圖?MFC VC++自定義複選框圖片
我想改變我的三態複選框使用的圖像使用不同的;這些控件採用Win98風格,而且這種複選框的不確定狀態很難與禁用的複選框區分開來(這可能是他們爲什麼改變了WinXP風格控件的原因,但由於我的項目中有其他細節,我無法使用這些控件) 。
我正在使用Visual C++ 2010,並且在VS的資源編輯器中定義了一個8x8位圖。位圖的ID是IDB_INDET_CHECK
。
我不完全確定這樣的標準「技術」是什麼;我只是真的開始操縱Windows控件和MFC。
我的第一次嘗試是創建一個類,CTriButton
,派生自CButton
,覆蓋DrawItem
函數,並嘗試自己繪製它。然後,我使用SubclassDlgItem
將窗口中的其中一個複選框變成此類(我認爲?)。這種作品?複選框不再出現,如果我點擊它應該在的位置,會出現一個空的複選框框架,但沒有其他事情發生(並且我的代碼中的調試消息未被髮送)。
下面是相關的代碼,但我不確定任何這是正確的。首先,我的窗口的代碼是OnInitDialog
。
BOOL CAffixFilterDlg::OnInitDialog() // CAffixFilterDlg is my CDialog-derived window
{
CDialog::OnInitDialog(); // call basic version
// subclass a CButton-derived control with CTriButton
if (CBipedHead.SubclassDlgItem(IDC_HEAD, this)) // CBipedHead is a CTriButton member of CAffixFilterDlg, IDC_HEAD is a checkbox
SetWindowLong(CBipedHead.m_hWnd, GWL_STYLE, CBipedHead.GetStyle() | BS_OWNERDRAW); // set the ownerdraw style
else // subclassing didn't work
_ERROR("Subclassing failed."); // I do not see this error message, so SubclassDlgItem worked?
// initialization continues, but is not relevant...
UpdateWindow();
Invalidate();
return TRUE;
}
接下來,我的自定義按鈕的代碼爲DrawItem
。
void CTriButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
_DMESSAGE("Drawing TriButton"); // never see this message
CDC dc;
dc.Attach(lpDrawItemStruct->hDC); //Get device context object
int nWidth = GetSystemMetrics(SM_CXMENUCHECK);
int nMargin = (nWidth - 8)/2;
CRect textRt = lpDrawItemStruct->rcItem;
textRt.right = textRt.right - nWidth - nMargin;
CString text;
GetWindowText(text);
UINT textDrawState = DST_TEXT;
if (lpDrawItemStruct->itemState & ODS_DISABLED)
textDrawState |= DSS_DISABLED;
dc.DrawState(CPoint(textRt.left, textRt.top), textRt.Size(), text, textDrawState, TRUE, 0, (CBrush*)NULL);
CRect rt = lpDrawItemStruct->rcItem; // initial rect is for entire button
rt.left = rt.right - nWidth; // set left margin
LONG center = (rt.bottom + rt.top)/2;
rt.top = center - nWidth/2;
rt.bottom = center + nWidth/2;
UINT checkDrawState = DFCS_BUTTONCHECK;
if (lpDrawItemStruct->itemState & ODS_DISABLED)
checkDrawState |= DFCS_INACTIVE;
if (lpDrawItemStruct->itemState & ODS_CHECKED)
checkDrawState |= DFCS_CHECKED;
else if (GetCheck() == BST_INDETERMINATE) {
_VMESSAGE("Indeterminate; custom draw.");
CBitmap indet_check = CBitmap();
indet_check.LoadBitmap(IDB_INDET_CHECK);
CPoint pt = CPoint(rt.left + nMargin, rt.top + nMargin);
CSize sz = CSize(8, 8);
dc.DrawState(pt, sz, &indet_check, DST_BITMAP|DSS_NORMAL);
}
dc.DrawFrameControl(rt, DFC_BUTTON, checkDrawState);
}
你是在哪裏啓用了所有者繪製窗口樣式的? – paludarium
你的問題是什麼?您在哪裏設置了複選框以將三種樣式或設置按鈕的狀態設置爲中間狀態? – Ajay
@paludarium:謝謝,這有助於一些;我不知道這樣做。我更新了我的代碼,現在設置ownerdraw樣式;現在似乎並沒有被繪製出來,直到我點擊它應該在的位置,然後我纔得到一個空的複選框。我的繪圖代碼似乎沒有被調用(從來沒有看到調試信息)。我的問題已更新。感謝提到設置風格! – KRyan