接前一篇数据的接收与处理,源码篇

1. 建一个数据处理线程类.CDataThread

 

#pragma  once

class  CDataThread
{
public:
    CDataThread(
void);
    
~CDataThread(void);
public:
    
void    InitData(CWnd *pOwner ,int iDataLen ) ;
    BOOL    StartMonitoring() ;
    BOOL    RestartMonitoring() ;
    BOOL    StopMonitoring() ;

protected:
    
static UINT    DataThread( LPVOID pParam) ;
    BOOL        GetData(
int *pData , int iLen ) ;//取出数据


    CWinThread
*        m_Thread ;

    HANDLE            m_hStopEvent ;


    CWnd            
*m_pOwner ;

    
int                *m_pData ;
    
int                m_iDataLen ;

    
int                m_iCurReadPos ;
    
int                m_iCurWritePos;

public:
    BOOL    KillMonitoring(
void) ;

public:
    
void    AddData( int iData ) ;    

}
;

 

 

#include  " StdAfx.h "
#include 
" .datathread.h "

CDataThread::CDataThread(
void )
{
    m_hStopEvent  
= NULL ;

    m_iCurReadPos 
= 0 ;
    m_iCurWritePos
= 0 ;

    m_pData 
= NULL ;
    m_Thread 
= NULL ;
    m_pOwner 
= NULL ;
}


CDataThread::
~ CDataThread( void )
{
    
if ( m_pData != NULL ) 
    
{
        delete [] m_pData ;
        m_pData 
= NULL ;
    }

}

void  CDataThread::InitData(CWnd  *  pOwner ,  int  iDataLen )
{

    
if ( m_hStopEvent != NULL )
    
{
        ResetEvent(m_hStopEvent ) ;
    }

    m_hStopEvent 
=  CreateEvent(NULL , TRUE , FALSE , NULL ) ;


    m_pOwner 
= pOwner ;

    m_iDataLen 
= iDataLen ;

    
if ( m_pData != NULL )
    
{
        delete [] m_pData ;
        m_pData 
= NULL ;
    }


    m_pData 
= new int[iDataLen] ;
}

UINT CDataThread::DataThread(LPVOID pParam )
{
    CDataThread 
*pThread = (CDataThread*)pParam ;

    DWORD Event 
= 0xffffffff ;

    
int data[10] ;

    memset(
&data , 0 , sizeof(int*10 ) ;

    BOOL bRunning 
= TRUE ;

    
while ( bRunning )
    
{
        Event 
= WaitForSingleObject(pThread->m_hStopEvent , 1 ) ;

        
switch(Event)
        
{
        
case WAIT_OBJECT_0:
            bRunning 
= FALSE ;
            
break ;
        
case WAIT_TIMEOUT:
            
//写读的数据
            if( pThread->GetData(data , 10 ) == TRUE )
            
{
                TRACE(
"得到10个数据 ")  ;
            }

            
break ;
        }

    }


    
return 0 ;
}


BOOL CDataThread::RestartMonitoring()
{

    TRACE(
"Thread resumed " ) ;
    m_Thread
->SuspendThread() ;

    
return TRUE ;
}

BOOL    CDataThread::StartMonitoring()
{
    
if ( ! ( m_Thread = AfxBeginThread(DataThread , this)))
        
return FALSE ;
    TRACE(
"Thread started ") ;

    
return TRUE ;
}


BOOL CDataThread::KillMonitoring()
{
    SetEvent(m_hStopEvent) ;

    
return 0 ;
}


void  CDataThread::AddData( int  iData )
{
    
if ( m_pData == NULL ) return ;

    
if ( m_iCurWritePos < m_iDataLen )
    
{
        m_pData[m_iCurWritePos] 
= iData ;
        m_iCurWritePos
++ ;

        
if ( m_iCurWritePos == m_iDataLen ) 
        
{
            m_iCurWritePos 
= 0 ;
        }

    }

}


BOOL  CDataThread::GetData(
int   * pGetData ,  int  iLen )
{    
    
    
if ( m_iCurReadPos > m_iCurWritePos ) 
    
{
        m_iCurReadPos 
= m_iCurWritePos ;
    }
    
    
    
if ( m_iCurWritePos - m_iCurReadPos < iLen ) return FALSE ;
        
    memcpy(pGetData , 
&m_pData[m_iCurReadPos] , sizeof(int* iLen ) ;

    m_iCurReadPos 
+= iLen ;

    
if ( m_iCurReadPos >= m_iDataLen )
    
{
        m_iCurReadPos 
= 0 ;
    }


    
return TRUE ;
}

 

 2.建立一个对话框程序进行测试,用定时器模拟加数据.1毫秒加一个点,比如程序中加入一个数10,达到10个数取一次点,就像从串口取十个数据,然后取出绘制一样.

 

//  TestMultiThreadDlg.h : 头文件
//

#pragma  once
#include  
" DataThread.h "

//  CTestMultiThreadDlg 对话框
class  CTestMultiThreadDlg :  public  CDialog
{
// 构造
public:
    CTestMultiThreadDlg(CWnd
* pParent = NULL);    // 标准构造函数

// 对话框数据
    enum { IDD = IDD_TESTMULTITHREAD_DIALOG };

    
protected:
    
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持


// 实现
protected:
    HICON m_hIcon;

    
// 生成的消息映射函数
    virtual BOOL OnInitDialog();
    afx_msg 
void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg 
void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
public:
    CDataThread DataThread ;

    
virtual BOOL DestroyWindow();
    afx_msg 
void OnBnClickedButton1();
    afx_msg 
void OnTimer(UINT nIDEvent);
}
;

 

 

//  TestMultiThreadDlg.cpp : 实现文件
//

#include 
" stdafx.h "
#include 
" TestMultiThread.h "
#include 
" TestMultiThreadDlg.h "
#include 
" . estmultithreaddlg.h "

#ifdef _DEBUG
#define  new DEBUG_NEW
#endif


//  用于应用程序“关于”菜单项的 CAboutDlg 对话框

class  CAboutDlg :  public  CDialog
{
public:
    CAboutDlg();

// 对话框数据
    enum { IDD = IDD_ABOUTBOX };

    
protected:
    
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
    DECLARE_MESSAGE_MAP()
}
;

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}


void  CAboutDlg::DoDataExchange(CDataExchange *  pDX)
{
    CDialog::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


//  CTestMultiThreadDlg 对话框



CTestMultiThreadDlg::CTestMultiThreadDlg(CWnd
*  pParent  /*=NULL*/ )
    : CDialog(CTestMultiThreadDlg::IDD, pParent)
{
    m_hIcon 
= AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}


void  CTestMultiThreadDlg::DoDataExchange(CDataExchange *  pDX)
{
    CDialog::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CTestMultiThreadDlg, CDialog)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    
// }}AFX_MSG_MAP
    ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
    ON_WM_TIMER()
END_MESSAGE_MAP()


//  CTestMultiThreadDlg 消息处理程序

BOOL CTestMultiThreadDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    
// 将“关于...”菜单项添加到系统菜单中。

    
// IDM_ABOUTBOX 必须在系统命令范围内。
    ASSERT((IDM_ABOUTBOX & 0xFFF0== IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX 
< 0xF000);

    CMenu
* pSysMenu = GetSystemMenu(FALSE);
    
if (pSysMenu != NULL)
    
{
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        
if (!strAboutMenu.IsEmpty())
        
{
            pSysMenu
->AppendMenu(MF_SEPARATOR);
            pSysMenu
->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }

    }


    
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
    
//  执行此操作
    SetIcon(m_hIcon, TRUE);            // 设置大图标
    SetIcon(m_hIcon, FALSE);        // 设置小图标

    
// TODO: 在此添加额外的初始化代码

    
    
return TRUE;  // 除非设置了控件的焦点,否则返回 TRUE
}


void  CTestMultiThreadDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    
if ((nID & 0xFFF0== IDM_ABOUTBOX)
    
{
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }

    
else
    
{
        CDialog::OnSysCommand(nID, lParam);
    }

}


//  如果向对话框添加最小化按钮,则需要下面的代码
//   来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//   这将由框架自动完成。

void  CTestMultiThreadDlg::OnPaint() 
{
    
if (IsIconic())
    
{
        CPaintDC dc(
this); // 用于绘制的设备上下文

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast
<WPARAM>(dc.GetSafeHdc()), 0);

        
// 使图标在工作矩形中居中
        int cxIcon = GetSystemMetrics(SM_CXICON);
        
int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(
&rect);
        
int x = (rect.Width() - cxIcon + 1/ 2;
        
int y = (rect.Height() - cyIcon + 1/ 2;

        
// 绘制图标
        dc.DrawIcon(x, y, m_hIcon);
    }

    
else
    
{
        CDialog::OnPaint();
    }

}


// 当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CTestMultiThreadDlg::OnQueryDragIcon()
{
    
return static_cast<HCURSOR>(m_hIcon);
}


BOOL CTestMultiThreadDlg::DestroyWindow()
{
    
// TODO: 在此添加专用代码和/或调用基类
    KillTimer(1) ;
    DataThread.KillMonitoring() ;

    
return CDialog::DestroyWindow();
}


void  CTestMultiThreadDlg::OnBnClickedButton1()
{
    
// TODO: 在此添加控件通知处理程序代码
    DataThread.InitData(this10000) ;
    DataThread.StartMonitoring() ;

    SetTimer(
1,10 , NULL ) ;
}


void  CTestMultiThreadDlg::OnTimer(UINT nIDEvent)
{
    
// TODO: 在此添加消息处理程序代码和/或调用默认值
    DataThread.AddData(10) ;
    CDialog::OnTimer(nIDEvent);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tangxingbin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值