我要实现一功能,当我点某个项时,会变大。基本已经OK了,却发现了一个问题,只有在特定情况下产生。
这个情况是这样的:比如说我有四个项,列表框刚好容的下,但因为我的功能是点击后会变大,列表框就会自动产生滚动条,之后就会有问题,DrawItem的lpDrawItemStruct->itemData这个数据不能用,一用就内存错误,就点击第0项的时候会内存错误,点击其它项没事。
代码在下面,请指点一二,谢谢。
void CIWRListBox::OnLbnSelchange()
{
// TODO: 在此添加控件通知处理程序代码
SetSelect();

}void CIWRListBox::SetSelect()
{
m_bRealDelete=FALSE;

int iIndex;
iIndex=GetCurSel();
if (m_iLastSelect==iIndex)  return;
if (m_iLastSelect!=-1)
{
UpdateItemState(m_iLastSelect,FALSE); }
UpdateItemState(iIndex,TRUE);
SetCurSel(iIndex);
m_bSetSelect=false;
m_iLastSelect=iIndex;
m_bRealDelete=TRUE;
return;
}void CIWRListBox::UpdateItemState(int iIndex,BOOL bSelect)
{
m_bSetSelect=bSelect;
DWORD_PTR dp=GetItemData(iIndex);
DeleteString(iIndex);
InsertString(iIndex,_T(""));
SetItemData(iIndex,dp);
return;
}
void CIWRListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{ // TODO:  添加您的代码以绘制指定项
CIWRListBox::DrawItem(lpDrawItemStruct);
CDC dc;
int iSaveDC;
dc.Attach(lpDrawItemStruct->hDC);
iSaveDC=dc.SaveDC();
dc.SetTextColor(colListBoxName);
dc.SetBkMode(TRANSPARENT);
CRect rt;
rt=lpDrawItemStruct->rcItem;
CString* s=(CString*)lpDrawItemStruct->itemData;
CString ss;
dc.DrawText(*s,rt,DT_CENTER|DT_SINGLELINE|DT_VCENTER);
dc.RestoreDC(iSaveDC);
dc.Detach();

}
void CIWRLBTest::DeleteItem(LPDELETEITEMSTRUCT lpDeleteItemStruct)
{
// TODO: 在此添加专用代码和/或调用基类

if (!m_bRealDelete)
{
return;
}
TRACE(_T("REAL:%d\r\n"),lpDeleteItemStruct->itemID);
delete (CString*)(lpDeleteItemStruct->itemData);
CIWRListBox::DeleteItem(lpDeleteItemStruct);

}

解决方案 »

  1.   

    没遇到过这种问题
    想个替代的方案
    如果在这种情况下点击0行不去访问lpDrawItemStruct->itemData呢?
      

  2.   

    试试这样CString s = (LPCTSTR)lpDrawItemStruct->itemData;
    dc.DrawText(s,rt,DT_CENTER|DT_SINGLELINE|DT_VCENTER);    
    dc.RestoreDC(iSaveDC);
    dc.Detach();
    作为指针来访问,的首选保证其有效性,否则容易产生非法访问错误
      

  3.   

    CString* s=(CString*)lpDrawItemStruct->itemData;
    CString ss;
    dc.DrawText(*s,rt,DT_CENTER|DT_SINGLELINE|DT_VCENTER); 没这样用过,会不会是这里的问题,这样改行不行呢LPCTSTR s = (LPCTSTR)(lpDrawItemStruct->itemData);
    dc.DrawText(s,-1,DT_CENTER|DT_SINGLELINE|DT_VCENTER); 
      

  4.   

    CString* s=(CString*)lpDrawItemStruct->itemData; 这个代码的确有问题,#4 说得对,windows 的消息、结构不可能只为 MFC 设计的
      

  5.   

    http://blog.csdn.net/VisualEleven/archive/2010/10/12/5935430.aspx
      

  6.   

    我setitemdata的时候传进去的就是cstring啊,然后再用还原成cstring这样有问题吗?
      

  7.   

    itemData必须是全局生命域的指针。
      

  8.   


    for (int i=0;i<10;i++)
    {
    CString* cs=new CString();
    cs->Format(_T("test:%d"),i);
    m_lbFriend.AddString(_T(""));
    m_lbFriend.SetItemData(i,(DWORD_PTR)cs);
    }这是在对话框初始化的时候向listbox添加项目的代码。然后在drawitem的时候把这个指针拿出来。
    像这样有问题吗?
      

  9.   

    他们提示是CString问题,你何不试试char
      

  10.   

    用wchar_t没有问题。
    但是不明白,cstring无非是一个类而已。为什么其他的可以,cstring就不可以?
      

  11.   

    使用(LPSTR)(LPCSTR)cs可能就好了,&cs可能不是字符串本身。
      

  12.   

    cs本来就不是字符串本身啊,他是一个cstring类。cstring类不单单是一个字符串。
    我现在就是想把这个cstring传进去,没有办法吗?
      

  13.   

    First off, if you're not using CStrings, shame on you! Come on guys, the year 2000 is almost upon us! No more character arrays, strcpy, strdup, and all that rot. CStrings are easy, lightweight, overwrite-proof, and provide useful functions for manipulating strings. There's even a Format function that works like printf! Not to mention that CStrings go from English to International (ASCII to Unicode) with the flip of a compiler switch. There's just no excuse for writing char[256] any more unless you're dealing with legacy code written in COBOL. Now that I got that off my chest, let's do something about Ian's code. First, it's always better to instantiate CString objects directly as inline class members or on the stack instead of allocating them from the heap. A CString is very small; it contains only one member (m_pchData, a pointer to the actual character data) so a CString is only four bytes, the same as an int. It makes no sense to allocate CStrings individually unless you have some truly bizarre situation at hand. In general, you should think of CString as a primitive type like int or long or double. You wouldn't allocate space to store one int, would you? So the first thing you should do is make m_str an actual CString instead of a pointer to one.
      

  14.   

     you should think of CString as a primitive type like int or long or double. You wouldn't allocate space to store one int, would you? So the first thing you should do is make m_str an actual CString instead of a pointer to one.他说可以把cstring看作像int这样的基础类型,不用特意为cstring分配空间,像使用int类型用cstring。他说的是在一般情况下吧,如果我的程序不用new,在drawitem的时候肯定会出错,因为cstring在for语句结束后就会被析构掉。
      

  15.   

     you should think of CString as a primitive type like int or long or double. You wouldn't allocate space to store one int, would you? So the first thing you should do is make m_str an actual CString instead of a pointer to one.他说可以把cstring看作像int这样的基础类型,不用特意为cstring分配空间,像使用int类型用cstring。他说的是在一般情况下吧,如果我的程序不用new,在drawitem的时候肯定会出错,因为cstring在for语句结束后就会被析构掉。