Как получить флажок с 3 состояниями, чтобы использовать другое растровое изображение для состояния неопределенности?
Я хочу изменить изображение, используемое моими флажками с 3 состояниями, чтобы использовать другое; элементы управления выполнены в стиле Win98, и неопределенное состояние таких флажков трудно отличить от отключенных флажков (вероятно, поэтому они изменили это для элементов управления в стиле WinXP, но я не могу использовать их из-за других деталей в моем проекте) . * * 1003
Я использую Visual C ++ 2010 и определил растровое изображение 8x8 в редакторе ресурсов VS. Идентификатор растрового изображения 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);
}