hur.cn - 华软网

 热门搜索

【重载ListBox】自绘DrawItem、排序CompareItem参数总是不对

  作者:未知    来源:网络    更新时间:2011/9/29
下面是代码
C++">
int CMyListBox::CompareItem(LPCOMPAREITEMSTRUCT lpCIS)
{
// TODO:  用您的消息处理程序代码替换下一行
DWORD item1,item2;
item1 = lpCIS->itemData1;
item2 = lpCIS->itemData2;
if (item1 < item2)
{
return -1;
}
else
{
return 1;
}
return 0;
}

C++">
void CMyListBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
// TODO: 在此处添加消息处理程序代码
CDC dc;
dc.Attach(lpDIS->hDC);

CRect rect = lpDIS->rcItem;
UINT  nIndex = lpDIS->itemID;

CBrush* pBrush = new CBrush(
::GetSysColor((lpDIS->itemState&ODS_SELECTED)?COLOR_HIGHLIGHT:COLOR_WINDOW));
dc.FillRect(&rect,pBrush);

if (lpDIS->itemState&ODS_FOCUS)
{
dc.DrawFocusRect(rect);
}

if (nIndex != (UINT)-1)
{
//  CString str;
//  GetText(nIndex,str);

in_addr addr;
addr.S_un.S_addr = (DWORD)(lpDIS->itemData);

dc.SetBkMode(TRANSPARENT);
dc.DrawText(inet_ntoa(addr),-1,&rect,DT_LEFT|DT_SINGLELINE|DT_VCENTER);
}

dc.Detach();
}


问题是这样的,我想将添加到ListBox的各个项目按照他们的ItemData排序
但是发现只重载CompareItem函数会报莫名其妙的错误

于是又重载了DrawItem、MeasureItem来启动自绘

目前的问题就是CompareItem、DrawItem、MeasureItem三个函数传入的结构
(LPCOMPAREITEMSTRUCT、LPDRAWITEMSTRUCT、LPMEASUREITEMSTRUCT)
里面的itemData项都不正确

推断是因为AddString就会触发排序和重绘,这时还没有调用到SetItemData,
所以上述三个结构的itemData项在第一遍调用的时候总是一个固定的初始化值

但是又没有办法在AddString之前就把ItemData设置好,所以一直都得不到想要的结果
ListBox没有按预期的顺序排序,重绘的第一个List项也会是一个固定的错误值(取决于初始的ItemData)

我已经调了一天了,实在没办法了,大家给点建议把。。。
---华软 网友回答---
自己顶
---华软网友回复---
http://blog.csdn.net/visualeleven/article/details/5935430
参考一下这个
---华软网友回复---
请参考这个,代码简介明了
http://download.csdn.net/detail/gameslq/3648385
---华软网友回复---
引用 3 楼 gameslq 的回复:
请参考这个,代码简介明了
http://download.csdn.net/detail/gameslq/3648385

我的问题是ListBox不是ListCtrl,
ListBox里面的排序是在AddString的时候完成的,没有用户事件去触发他(是父窗口的WM_COMPAREITEM消息调用它的回调)

还是谢谢你的示例,很不错的ListCtrl
---华软网友回复---
引用 2 楼 visualeleven 的回复:
http://blog.csdn.net/visualeleven/article/details/5935430
参考一下这个


VisualEleven你好
我参考你的博文写了下我的DrawItem,但是也不能正常工作
C++">
void CMyListBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
// TODO: 在此处添加消息处理程序代码
ASSERT(lpDIS->CtlType == ODT_LISTBOX); 
CDC dc;
dc.Attach(lpDIS->hDC);

CRect rect = lpDIS->rcItem;
UINT nIndex = lpDIS->itemID;
COLORREF bkClr;
COLORREF frClr = RGB(0,0,0);

// 若为焦点项则前、背景色高亮
if (lpDIS->itemState&ODS_SELECTED)
{
bkClr = RGB(100,100,255);
frClr = GetSysColor(COLOR_HIGHLIGHTTEXT);
}
else
{
// 不为焦点项,背景色浅蓝与白色交替
if ((lpDIS->itemID)%2)
{
bkClr = RGB(220,220,255);
}
else
{
bkClr = RGB(255,255,255);
}
}
// 设置前景色
dc.SetTextColor(frClr);
dc.SetBkMode(TRANSPARENT);
// 填充背景色
CBrush* pBrush = new CBrush(bkClr);
dc.FillRect(&rect,pBrush);

if (lpDIS->itemState&ODS_FOCUS)
{
dc.DrawFocusRect(rect);
}

if (nIndex != (UINT)-1)
{
in_addr addr;
addr.S_un.S_addr = (DWORD)lpDIS->itemData;
dc.DrawText(inet_ntoa(addr),-1,&rect,DT_LEFT|DT_SINGLELINE|DT_VCENTER);

/*  dc.DrawText((LPCTSTR)lpDIS->itemData,-1,&rect,DT_LEFT|DT_SINGLELINE|DT_VCENTER);*/
//这里被注释掉的这行,如果将itemData当做LPCSTR使用的话会报其他地方的错误
//将itemData当做我设置的IP使用的话则可以得到正确结果。。。
}

dc.Detach();
}


---华软网友回复---
然后就是我的CompareItem函数传入的结构体总有一项的ID是-1

int CMyListBox::CompareItem(LPCOMPAREITEMSTRUCT lpCIS)
{
// TODO:  用您的消息处理程序代码替换下一行
if (lpCIS->itemID1 == -1 || lpCIS->itemID2 == -1)
{
return 0;//总会命中这里
}
     
华软声明:本内容来自网络,如有侵犯您版权请来信指出,本站立即删除。