我需要从txt文档读取大量测量数据到程序处理和显示,如果都在主线程实现,程序界面在读数和处理的时候界面就出现假死。觉得很不舒服。
    现在我采用用户界面线程,主线程启动子线程后,在子线程完成txt数据读取,然后将数据传递到主线程显示。   现在问题是,数据量很大,怎么从子线程传递到主线程呢?
   看网上说公共变量可以,但是不建议用。
   MFC传递指针又不允许。。
   应该怎样才能传递呢?请大家帮帮忙。最好有具体详细点的代码示例。谢谢啦
MFC用户界面线程数据传递

解决方案 »

  1.   

    怎么不允许传递指针呢? 后台程序读取,开辟空间,填入消息,将空间起始地址作为消息参数发给UI对话框,UI显示后删除空间。。
      

  2.   


    我就是觉得在主线程读txt文档数据有假死的现象,所以让子线程读。
    如果子线程读完存到文件,再主线程读。哪还不如主线程直接读呢?
      

  3.   

    我现在这么做的:float* pTxtDate; 
    pTxtDate=new float[mTotalOpenNum];
    //mTotalOpenNum是要读取数据的总数
    .....
    .....
    //将数据都读取到pTxtDate后
    PostMessage(GetMainWnd()->m_hWnd,WM_MYMESSAGE,(WPARAM)pTxtDate,0);
    ];这样的话我能够紧跟着delete [] pTxtDate;吗?
    还有在我的消息函数中:CString str;
    str.Format("%.2f",wParam);怎么没有传过来数据呢?请大家帮我看看,谢谢!
      

  4.   

    咋没有回复呢?等了一整天。是因为我用MFC  用户界面线程的原因吗?怎么没有回复呢?谢谢啦
      

  5.   


    思路没错,写法上楼主搞错了。
    直接开个char数组读取,读完后发消息(数组指针,内容长度),窗口里收到消息后,直接赋值给CString就可以了。
      

  6.   

    str.Format("%.2f",wParam);---->仅仅是打印了wParam本身的地址,而不是它所指向的内存内容。
      

  7.   

    float* pTxtDate; 
    -->是从文本文件中加载内容,那么内容应该当作字符串来处理,即使内容是一些浮点数,此时也是字符串表达方式,所以不用float来保存文本文件内容,用char *更合适一些,当然用void *也行,只要有内存来保存内容即可。
      

  8.   

    用一个结构体全局变量,里面开一个buffer,作保存数据的地方,线程之间传结构体的地址,是安全的,因为这个结构体不是MFC中自带的,只要你自己负责线程安全就可以了
      

  9.   


    你好,我想问下,我在线程中定义了
    struct sTxtData
    {
    CString strDate;
    CString strTime;
    float mValue;
    };
    sTxtData* myData;然后每次我读上来的数据都赋给
    myData->strDate=strToShow;
    myData->strTime=strToShow;
    myData->mValue=atof(strToShow);
    后,我再发消息:
    SendMessage(GetMainWnd()->m_hWnd,WM_MYMESSAGE,WPARAM(myData),0);
    问题1:这样发消息对吗?
    问题2:在主线程的消息函数中我该怎样接收呢?
    谢谢啦,我基础不行。
      

  10.   

    似乎需要用WM_COPYDATA消息。。
    大家帮我出出注意啦!!!!!!!
      

  11.   


    你好,我想问下,我在线程中定义了
    struct sTxtData
    {
    CString strDate;
    CString strTime;
    float mValue;
    };
    sTxtData* myData;然后每次我读上来的数据都赋给
    myData->strDate=strToShow;
    myData->strTime=strToShow;
    myData->mValue=atof(strToShow);
    后,我再发消息:
    SendMessage(GetMainWnd()->m_hWnd,WM_MYMESSAGE,WPARAM(myData),0);
    问题1:这样发消息对吗?
    问题2:在主线程的消息函数中我该怎样接收呢?
    谢谢啦,我基础不行。
    如果你用 SendMessage,那这样写代码是可以的:发送线程不需要new,接收线程也不需要delete,比较简单。
    接收线程使用强制转换 (sTxtData*)myData但是,使用SendMessage的话,会使得接收线程在没有处理完WM_MYMESSAGE消息之前,发送线程会一直等待。
    如果程序运行速度正常,那就使用SendMessage。如果觉得程序运行速度不理想,可以改用PostMessage,或者WM_COPYDATA消息。
      

  12.   


    你好,我想问下,我在线程中定义了
    struct sTxtData
    {
    CString strDate;
    CString strTime;
    float mValue;
    };
    sTxtData* myData;然后每次我读上来的数据都赋给
    myData->strDate=strToShow;
    myData->strTime=strToShow;
    myData->mValue=atof(strToShow);
    后,我再发消息:
    SendMessage(GetMainWnd()->m_hWnd,WM_MYMESSAGE,WPARAM(myData),0);
    问题1:这样发消息对吗?
    问题2:在主线程的消息函数中我该怎样接收呢?
    谢谢啦,我基础不行。1.这么发送时可以的
    2.在处理线程那边做个消息映射
    BEGIN_MESSAGE_MAP(CDlgRightView, CDialog)
        ON_MESSAGE(WM_MYMESSAGE,M_ProcFun)//M_ProcFun是你的处理函数 
    END_MESSAGE_MAP()
    M_ProcFun函数中定义myData的对象 mydata
    memcpy( &mydata, (myData)wParam, sizeof(myData) );
    直接拷贝 取出数据就是了
      

  13.   


    你好,我想问下,我在线程中定义了
    struct sTxtData
    {
    CString strDate;
    CString strTime;
    float mValue;
    };
    sTxtData* myData;然后每次我读上来的数据都赋给
    myData->strDate=strToShow;
    myData->strTime=strToShow;
    myData->mValue=atof(strToShow);
    后,我再发消息:
    SendMessage(GetMainWnd()->m_hWnd,WM_MYMESSAGE,WPARAM(myData),0);
    问题1:这样发消息对吗?
    问题2:在主线程的消息函数中我该怎样接收呢?
    谢谢啦,我基础不行。1.这么发送时可以的
    2.在处理线程那边做个消息映射
    BEGIN_MESSAGE_MAP(CDlgRightView, CDialog)
        ON_MESSAGE(WM_MYMESSAGE,M_ProcFun)//M_ProcFun是你的处理函数 
    END_MESSAGE_MAP()
    M_ProcFun函数中定义myData的对象 mydata
    memcpy( &mydata, (myData)wParam, sizeof(myData) );
    直接拷贝 取出数据就是了
    memcpy( &mydata, (myData)wParam, sizeof(myData) );
    这一句报错cannot convert from 'unsigned int' to 'struct sTxtData'
    什么情况呢?
      

  14.   

     MFC传递指针又不允许。。你确定说的是线程,不是进程么?怎么不能传了?WM_COPYDATA是跨进程的。
      

  15.   

    我自己是这么使用的
    发送时myData用对象
    SendMessage(GetMainWnd()->m_hWnd,WM_MYMESSAGE,(WPARAM)(&myData),0);
    拷贝时就能直接拷贝对象内存地址
      

  16.   

    结贴之前,总结下解决过程及结果。
    真心话,像我们这样半道出家的,真的需要好好学习MSDN上的实例。最后解决办法也是MSDN的实例。
    第一步:定义结构体(在头文件中)#pragma pack(1)
    struct sTxtData
    {
    CString strDate;
    CString strTime;
    CString strValue;
    };
    #pragma  pack;定义结构体对象和COPYDATASTRUCT对象sTxtData* pData=new sTxtData();
    COPYDATASTRUCT cpdsTruct;将每行从txt文档读来的数据赋给pData的对应变量:
    pData->strDate=strToShow;
    pData->strTime=strToShow;
    pData->strValue=strToShow;
    然后将结构体信息赋给消息准备传递的cpdsTruct
    cpdsTruct.dwData=0;
    cpdsTruct.cbData=sizeof(sTxtData);
    cpdsTruct.lpData=(PVOID)pData;
    然后发送消息WM_COPYDATA
    SendMessage(GetMainWnd()->m_hWnd,WM_COPYDATA,NULL,(LPARAM)&cpdsTruct);第二步:重载WM_COPYDATA消息
    然后在BOOL ***::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 
    中添加:
    CString mDate,mTime,mValue;
    sTxtData* myRData=(sTxtData*)(pCopyDataStruct->lpData);
    mDate=myRData->strDate;
    mTime=myRData->strTime;
    mValue=myRData->strValue;至此,利用界面线程打开txt文件中一行数据就都传递到主线程了。
    提醒:没有安装MSDN的孩纸们,赶紧安装。没有那玩意,痛苦着呢……………………