关闭

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

405人阅读 评论(0) 收藏 举报

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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:47959次
    • 积分:598
    • 等级:
    • 排名:千里之外
    • 原创:15篇
    • 转载:9篇
    • 译文:1篇
    • 评论:16条
    文章分类
    文章存档
    最新评论