在主对话框上有一个CListCtrl控件,用于显示数据库中的记录
我在一个线程中,向数据库中插入一些记录
然后通过 PostMessage 向主线程发送一个消息,在消息函数(OnFreshList)中重新读取数据库中的记录并列表显示;但是问题是:新的数据增加啦,消息也发送成功了,可是CListCtrl中的记录始终不会改变;如果在OnFreshList函数中增加一个MessageBox(),弹出一个消息框后,CListCtrl 就能正常刷新,请问这个是什么原因呢?要如何修正?谢谢。

解决方案 »

  1.   

    在主对话框上UpdateData(FALSE);//刷新控件控件
      

  2.   

    可能是线程同步的问题,你可以在OnFreshList函数里使用WaitForSingleObject()函数等待线程结束后,在执行刷新操作试试。
      

  3.   

    还在 OnFreshList 中,重新设置了一个BTN的标题,这个都执行成功了的。就是List不行。
      

  4.   

    能把你的线程实现函数和OnFreshList函数的代码贴上来看看吗?
      

  5.   


    void CPayClientDlg::FreshList()
    {
    UpdateData(); GetFocus();
    m_list.Invalidate();
    UpdateWindow(); CAdoHelper db;
    if(!db.OpenAccess())return; CTime stime,etime;
    CString f_date;
    m_sdate_ctrl.GetTime(stime);
    m_edate_ctrl.GetTime(etime);
    CString strTime1,strTime2;
    strTime1=stime.Format("%Y-%m-%d 00:00:00");
    strTime2=etime.Format("%Y-%m-%d 23:59:59");
    f_date.Format(" and ordertime between #%s# and #%s#",strTime1,strTime2); CString f_type;
    if(m_search_type==1)
    {
    f_type=" and orderFrom=1";
    }
    else if(m_search_type==2)
    {
    f_type=" and orderFrom=2";
    } CString sql="select * from orders where id>0 "+f_date+f_type+" order by id desc";
    _RecordsetPtr rs=db.Query(sql);
    if(rs==NULL){db.Close();return;}
    m_list.DeleteAllItems();
    while(!rs->adoEOF)
    {
    CString orderid=(char*)(_bstr_t)rs->GetCollect("orderid");
    CString orderFrom=(char*)(_bstr_t)rs->GetCollect("orderFrom");
    CString orderType=(char*)(_bstr_t)rs->GetCollect("orderType");
    CString ordername=(char*)(_bstr_t)rs->GetCollect("ordername");
    CString account=(char*)(_bstr_t)rs->GetCollect("account");
    CString price=(char*)(_bstr_t)rs->GetCollect("price");
    CString num=(char*)(_bstr_t)rs->GetCollect("num");
    CString total_fee=(char*)(_bstr_t)rs->GetCollect("total_fee");
    CString myiid=(char*)(_bstr_t)rs->GetCollect("myiid");
    CString ordertime=(char*)(_bstr_t)rs->GetCollect("ordertime"); if(orderFrom=="1")
    orderFrom="淘宝";
    else
    orderFrom="拍拍"; int nItem=m_list.GetItemCount();
    m_list.InsertItem(nItem,orderid);
    m_list.SetItemText(nItem,1,orderFrom);
    m_list.SetItemText(nItem,2,orderType);
    m_list.SetItemText(nItem,3,ordername);
    m_list.SetItemText(nItem,4,account);
    m_list.SetItemText(nItem,5,price);
    m_list.SetItemText(nItem,6,num);
    m_list.SetItemText(nItem,7,total_fee);
    m_list.SetItemText(nItem,8,myiid);
    m_list.SetItemText(nItem,9,ordertime);

    rs->MoveNext();
    }
    rs->Close();
    rs.Release();
    db.Close();
    UpdateData(FALSE);
    }
    线程中的SaveOrder(db,order);
    Sleep(1);
    ::SendMessage(AfxGetApp()->m_pMainWnd->m_hWnd,ID_REFRESH_LIST,0,0);
      

  6.   

    SaveOrder()是怎么实现的,代码贴上来看看。顺便,试一下,把SendMessage改为PostMessage可不可以!
      

  7.   

    就是保存数据,没有操作任何UI。
    我原来就是用的 PostMessage,后来才改send的
      

  8.   

    直接掉就不是不更新的问题了,搞不好会直接挂掉,建议你有空看下win32多线程程序设计楼主不妨在刷新列表操作里加句m_list.invalidate()试试。
      

  9.   

    SaveOrder(db,order);
    Sleep(1);
    ::SendMessage(AfxGetApp()->m_pMainWnd->m_hWnd,ID_REFRESH_LIST,0,0);
    -----------
    线程中不要搞,AfxGetApp()->m_pMainWnd->m_hWnd,创建线程的时候直接将窗口句柄HWND作为线程函数的参数传递给线程即可。
      

  10.   

    数据插入结束后,主动调用 m_list.UpdateWindow(); 试试
      

  11.   


    请大侠指点下,为何不能那样搞啊?
    另外,消息是发送成功了的,就是更新了list,list不刷新,郁闷死
      

  12.   

    在线程参数中传递句柄是最好的。如果你传递的是对象,通过对象调用封装后的MFC类函数,有些函数进行断言测试对象指针,线程不属于对象的成员,故断言失败,导致程序终断。
      

  13.   

    谢谢楼上的兄弟,但是AfxGetApp()->m_pMainWnd->m_hWnd这个用法好像是没有问题的。
      

  14.   


    这个只是说直接这样的引用,在你现在的情况下是没什么问题,但是如果这段代码放在不同的线程里的时候,比如主窗口销毁了,但这个线程依然存活时,使用代码的地方又没判断m_hWnd是否有效,直接拿来发送消息了,可能就会崩溃了。好一点的习惯就是传入参数,增加判断这样的,而且也方便你以后转而传入个其他窗口,就方便了。数据库这个会不会是数据库插入有延时呢?你使用弹出窗口没问题的话,你试试把弹出消息框的代码替换成不同的sleep时间长度。再不行的话看下数据库插入的文档,看有没有一些相关的内容提示。