我正在制作MFC自定义列表控件(内部绘制单选按钮)
但是它很奇怪。 单选按钮显示为闪烁或擦除。
我该如何解决这个问题?
这是我的代码
- > vfcxxx是xxx相同的东西
- > cell struct有string,row,btn data
#include "checklistctrl.h"
IMPLEMENT_DYNAMIC(CCheckListCtrl, CListCtrl)
CCheckListCtrl::CCheckListCtrl(): CListCtrl()
{
visibleMaxRow = visibleMinRow = 0;
}
CCheckListCtrl::~CCheckListCtrl()
{
}
BEGIN_MESSAGE_MAP(CCheckListCtrl, CListCtrl)
ON_WM_DRAWITEM()
END_MESSAGE_MAP()
void CCheckListCtrl::DrawItem(_In_ LPDRAWITEMSTRUCT lpDrawItemStruct)
{
static int tmp = 1;
int cnt = lpDrawItemStruct->itemID;
VfcLong tmpnum = -1;
LONG prev_left = lpDrawItemStruct->rcItem.left;
LV_COLUMN column_data;
memset(&column_data, 0, sizeof(LV_COLUMN));
column_data.mask = LVCF_WIDTH | LVCF_FMT;
for(int column_index = 0; GetColumn(column_index, &column_data); column_index++)
{
RECT tempRC;
{
tempRC.top = lpDrawItemStruct->rcItem.top;
tempRC.bottom = lpDrawItemStruct->rcItem.bottom;
tempRC.left = (prev_left);
tempRC.right = (prev_left += column_data.cx);
}
LV_ITEM tempLI;
wchar_t buffer[256];
{
tempLI.mask = LVIF_TEXT | LVIF_PARAM;
tempLI.iItem = lpDrawItemStruct->itemID;
tempLI.iSubItem = column_index;
tempLI.pszText = buffer;
tempLI.cchTextMax = sizeof(buffer);
VERIFY(GetItem(&tempLI));
}
CString tmpChk = buffer;
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
if( (tmpnum = isInsert(defaultGroup, cnt)) != -1)
{
pDC->FillSolidRect(&tempRC, RGB(255, 255, 255));
pDC->SetTextColor(RGB(0, 0, 0));
tempRC.left += 2;
pDC->DrawText(buffer, wcslen(buffer), &tempRC, DT_LEFT);
}
else if( (tmpnum = isInsert(radioGroup, cnt)) != -1)
{
radioCell cell = radioGroup[tmpnum];
pDC->FillSolidRect(&tempRC, RGB(cell.color[0], cell.color[1], cell.color[2]));
pDC->SetTextColor(RGB(125, 125, 125));
tempRC.left += 2;
pDC->DrawText(buffer, wcslen(buffer), &tempRC, DT_LEFT);
}
else
{
pDC->FillSolidRect(&tempRC, RGB(255, 255, 255));
pDC->SetTextColor(RGB(0, 0, 0));
tempRC.left += 2;
pDC->DrawText(buffer, wcslen(buffer), &tempRC, DT_LEFT);
}
}
setVisibleRowNumber();
setVisibleAttrRadioButton(prev_left);
}
VfcLong CCheckListCtrl::isInsert(VfcArray<radioCell> arr, VfcLong row)
{
for(int i = 0; i < arr.size(); i++)
{
if( arr[i].row == row)
return i;
}
return -1;
}
VfcLong CCheckListCtrl::isInsert(VfcArray<baseCell> arr, VfcLong row)
{
for(int i = 0; i < arr.size(); i++)
{
if( arr[i].row == row)
return i;
}
return -1;
}
VfcVoid CCheckListCtrl::insertRadioCell
(VfcLong groupId, VfcLong row, VfcString layName, VfcString data, VfcShort color[3], VfcBool isStart)
{
USES_CONVERSION;
InsertItem(row, A2W(layName.c_str()));
SetItem(row, 1, LVIF_TEXT, A2W(data.c_str()), 0, 0, 0, NULL );
//SetItem(row, 2, LVIF_TEXT, _T(""), 0, 0, 0, NULL );
radioCell cell = { row, layName, data, groupId, color[0], color[1], color[2], new CButton()};
radioGroup.pushTail(cell);
CRect tmp;
tmp.top = 0;
tmp.bottom = 19;
tmp.left = 280;
tmp.right = 350;
if (isStart)
{
cell.btn->Create(_T("select"), WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_GROUP | BS_OWNERDRAW, tmp, this, row);
}
else
{
cell.btn->Create(_T("select"), WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | BS_OWNERDRAW, tmp, this, row);
}
}
VfcVoid CCheckListCtrl::insertSingleCell(VfcLong row, VfcString layName, VfcString data)
{
baseCell cell = { row, layName, data};
singleGrop.pushTail(cell);
USES_CONVERSION;
InsertItem(row, A2W(layName.c_str()));
SetItem(row, 1, LVIF_TEXT, A2W(data.c_str()), 0, 0, 0, NULL );
}
VfcVoid CCheckListCtrl::insertDefaultCell(VfcLong row, VfcString data)
{
baseCell cell = { row, "default", data};
singleGrop.pushTail(cell);
InsertItem(row, _T("default"));
USES_CONVERSION;
SetItem(row, 1, LVIF_TEXT, A2W(data.c_str()), 0, 0, 0, NULL );
}
VfcVoid CCheckListCtrl::setVisibleRowNumber()
{
visibleMinRow = GetScrollPos(SB_VERT);
visibleMaxRow = visibleMinRow + 12;
}
VfcVoid CCheckListCtrl::setVisibleAttrRadioButton(VfcLong left)
{
VfcLong row, cnt = 0, cnt2 = 0;
for(int i = 0; i < radioGroup.size(); i++)
{
row = radioGroup[i].row;
if( row >= visibleMinRow && row <= visibleMaxRow)
{
radioGroup[i].btn->ShowWindow(SW_SHOW);
radioGroup[i].btn->SetWindowPos(NULL, left, (row - visibleMinRow + 1) * 19 + 5, 0, 0, SWP_NOSIZE);
radioGroup[i].btn->RedrawWindow();
}
else
{
radioGroup[i].btn->ShowWindow(SW_HIDE);
}
}
}