CHUITUDlg::CHUITUDlg(CWnd* pParent /*=NULL*/) : CDialog(CHUITUDlg::IDD, pParent) { //{{AFX_DATA_INIT(CHUITUDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_bConnected=FALSE; }void CHUITUDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CHUITUDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP }BEGIN_MESSAGE_MAP(CHUITUDlg, CDialog) //{{AFX_MSG_MAP(CHUITUDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_START, OnStart) //}}AFX_MSG_MAP ON_MESSAGE(WM_COMMNOTIFY,OnCommMsg) END_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////// // CHUITUDlg message handlersBOOL CHUITUDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. 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); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here m_hMsg=CreateEvent(NULL,TRUE,TRUE,NULL);
return TRUE; // return TRUE unless you set the focus to a control }void CHUITUDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } }// If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework.void CHUITUDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle 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; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } }// The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CHUITUDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; }void CHUITUDlg::OnStart() { //调用串口开启函数OpenSerial(); OpenSerial(); //GetDlgItem(IDC_START)->EnableWindow(FALSE); } BOOL CHUITUDlg::OpenSerial()//打开串口,创建接收线程; { //打开串口 COMMTIMEOUTS TimeOuts;//超时结构 if(m_bConnected) { //已经开启串口,出错返回; } m_hCom=CreateFile("COM1",//打开串口,得到串口句柄; GENERIC_READ|GENERIC_WRITE,0,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL); if(m_hCom==INVALID_HANDLE_VALUE) { //无效句柄,报错; } //////////设置超时结构//////////////// TimeOuts.ReadIntervalTimeout=0xFFFFFFFF; TimeOuts.ReadTotalTimeoutMultiplier=0; TimeOuts.ReadTotalTimeoutConstant=1000; TimeOuts.WriteTotalTimeoutMultiplier=0; TimeOuts.WriteTotalTimeoutConstant=1000; SetCommTimeouts(m_hCom,&TimeOuts); //设置串口参数,成功则创建接收线程,否则关闭串口; if(ConfigSerial()) { m_pThread=AfxBeginThread(CommProc,this,//创建接收线程并挂起 THREAD_PRIORITY_NORMAL, 0,CREATE_SUSPENDED,NULL); if(m_pThread==NULL)//接收线程句柄无效,关闭串口; { CloseHandle(m_hCom); return FALSE; } else { m_bConnected=TRUE;//接收线程句柄有效,激活接收线程; m_pThread->ResumeThread(); //AfxMessageBox("线程创建成功"); } } else { CloseHandle(m_hCom);//串口设置失败,出错返回; return FALSE; } return TRUE;//串叩开启并设置成功,接受线程成功创建,成功返回; }
//#include "stdafx.h"
#include "HUITU.h"
#include "HUITUDlg.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif///////////////全局函数//////////////////////////////////
///////////////接收线程函数/////////////
UINT CommProc(LPVOID lParam)
{
CHUITUDlg* pDlg=(CHUITUDlg*) lParam;//主窗口的指针;
OVERLAPPED os;//OVERLAPPED结构;
DWORD dwMask,dwErr,dwTrans;
COMSTAT ComStat;//串口状态结构; memset(&os,0,sizeof(OVERLAPPED));//初始化OVERLAPPED结构;
os.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);//创建OVERLAPPED结构事件;
if(os.hEvent==NULL)//如果创建事件失败,报错返回;
{
AfxMessageBox("Can't create event object!");
return(UINT)-1;
}
//AfxMessageBox("Received data!");
while(pDlg->m_bConnected)//无限循环,直到主线程断开连接;
{
//AfxMessageBox("Received A!");
ClearCommError(pDlg->m_hCom,&dwErr,&ComStat);//清除错误位,并返回串口状态;
if(ComStat.cbInQue)//如果输入缓冲有字符
{
WaitForSingleObject(pDlg->m_hMsg,INFINITE);//无限挂起,直到有信号
ResetEvent(pDlg->m_hMsg);//设置成无信号
//PostMessage((HWND)pDlg,WM_COMMNOTIFY,EV_RXCHAR,0);//通知主线程
pDlg->PostMessage(WM_COMMNOTIFY,EV_RXCHAR,0);//通知主窗口收到信息
AfxMessageBox("Received B!");
continue;
}
dwMask=0;
if(!WaitCommEvent(pDlg->m_hCom,&dwMask,&os))
{
if( GetLastError()==ERROR_IO_PENDING)
GetOverlappedResult(pDlg->m_hCom,&os,&dwTrans,TRUE);
else
{
CloseHandle(os.hEvent);
return (UINT)-1;
}
}
}//while结束,线程退出;
CloseHandle(os.hEvent);
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
IMPLEMENT_DYNCREATE(CHUITUDlg, CDialog)class CAboutDlg : public CDialog
{
public:
CAboutDlg();// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA // ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()////////////////////////////////////////////////////////////////////
: CDialog(CHUITUDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CHUITUDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_bConnected=FALSE;
}void CHUITUDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CHUITUDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}BEGIN_MESSAGE_MAP(CHUITUDlg, CDialog)
//{{AFX_MSG_MAP(CHUITUDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_START, OnStart)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_COMMNOTIFY,OnCommMsg)
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CHUITUDlg message handlersBOOL CHUITUDlg::OnInitDialog()
{
CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range.
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);
}
} // Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
m_hMsg=CreateEvent(NULL,TRUE,TRUE,NULL);
memset(&m_osRead,0,sizeof(OVERLAPPED));//初始化OVERLAPPED结构;
m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);//创建OVERLAPPED结构事件;
return TRUE; // return TRUE unless you set the focus to a control
}void CHUITUDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.void CHUITUDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle
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; // Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CHUITUDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}void CHUITUDlg::OnStart()
{
//调用串口开启函数OpenSerial();
OpenSerial();
//GetDlgItem(IDC_START)->EnableWindow(FALSE);
}
BOOL CHUITUDlg::OpenSerial()//打开串口,创建接收线程;
{
//打开串口
COMMTIMEOUTS TimeOuts;//超时结构
if(m_bConnected)
{
//已经开启串口,出错返回;
}
m_hCom=CreateFile("COM1",//打开串口,得到串口句柄;
GENERIC_READ|GENERIC_WRITE,0,NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
NULL);
if(m_hCom==INVALID_HANDLE_VALUE)
{
//无效句柄,报错;
}
//////////设置超时结构////////////////
TimeOuts.ReadIntervalTimeout=0xFFFFFFFF;
TimeOuts.ReadTotalTimeoutMultiplier=0;
TimeOuts.ReadTotalTimeoutConstant=1000;
TimeOuts.WriteTotalTimeoutMultiplier=0;
TimeOuts.WriteTotalTimeoutConstant=1000;
SetCommTimeouts(m_hCom,&TimeOuts);
//设置串口参数,成功则创建接收线程,否则关闭串口;
if(ConfigSerial())
{
m_pThread=AfxBeginThread(CommProc,this,//创建接收线程并挂起
THREAD_PRIORITY_NORMAL,
0,CREATE_SUSPENDED,NULL);
if(m_pThread==NULL)//接收线程句柄无效,关闭串口;
{
CloseHandle(m_hCom);
return FALSE;
}
else
{
m_bConnected=TRUE;//接收线程句柄有效,激活接收线程;
m_pThread->ResumeThread();
//AfxMessageBox("线程创建成功");
}
}
else
{
CloseHandle(m_hCom);//串口设置失败,出错返回;
return FALSE;
} return TRUE;//串叩开启并设置成功,接受线程成功创建,成功返回;
}
{
DCB dcb={0};
//dcb.DCBlength = sizeof(dcb);
if(!GetCommState(m_hCom,&dcb))
return FALSE;
dcb.BaudRate=2400;
dcb.ByteSize=8;
dcb.StopBits= ONESTOPBIT;
dcb.Parity=NOPARITY;
//BuildCommDCB("2400,n,8,1", &dcb);
return SetCommState(m_hCom,&dcb);
}
LRESULT CHUITUDlg::OnCommMsg(WPARAM wParam,LPARAM lParam)
{
//AfxMessageBox(Queue);
int nLen=0;
if(!m_bConnected||(wParam & EV_RXCHAR)!=EV_RXCHAR)
{
SetEvent(m_hMsg);
return 0L;
}
nLen=ReadComm(Queue,100);//从串口读数据并返回实际读到的字节数;
//AfxMessageBox(Queue);
if(nLen)
{
AfxMessageBox(" Read!");
//绘图;
}
SetEvent(m_hMsg);
m_bConnected=FALSE;//结束线程工作
return 0;
}
DWORD CHUITUDlg::ReadComm(char* buf,DWORD dwLength)
{
DWORD length=0;
COMSTAT ComStat;
DWORD dwErrorFlags;
ClearCommError(m_hCom,&dwErrorFlags,&ComStat);//返回输入缓冲里的字符数
length=min(dwLength,ComStat.cbInQue);//取最小值;
ReadFile(m_hCom,buf,length,&length,&m_osRead);
return length;
}
OnCommMsg()响应子线程消息后,调用ReadFile()读串口不能成功呢?我怕解释不明白,故将所有源玛上传,希望大家提点意见。我是东北人,平时说话从不说偶,偶大概是网上用语吧!
//dcb.DCBlength = sizeof(dcb);
if(!GetCommState(m_hCom,&dcb))
return FALSE;
dcb.BaudRate=2400;
dcb.ByteSize=8;
dcb.StopBits= ONESTOPBIT;
dcb.Parity=NOPARITY;
//BuildCommDCB("2400,n,8,1", &dcb);
return SetCommState(m_hCom,&dcb);仔细看清楚有没有错,确保线是好的,com口没问题,没插错(com1--com2)
m_hCom 不为 0x000000;
然后:建议用VXD虚拟串口,不过又有的累了。只是个建议
我编过串口程序的,粗看了一下你的码,没有明显的漏洞,再好好找找吧。
{
//AfxMessageBox("Received A!");
dwMask=0;
if(!WaitCommEvent(pDlg->m_hCom,&dwMask,&os))
{
if( GetLastError()==ERROR_IO_PENDING)
{
WaitForSingleObject(pDlg->m_hCom, INFINITE);
pDlg->PostMessage(WM_COMMNOTIFY,EV_RXCHAR,0);//通知主窗口收到信息
}
else
{
CloseHandle(os.hEvent);
return (UINT)-1;
}
}
}//while结束,线程退出;================================================================曾经有一碗热辣辣的烧猪手面放在我面前,我没有珍惜,等到晾凉了之后才后悔莫及。
。
。
AfxMessageBox("A");
。
。
AfxMessageBox("B");
。
。
。
结果程序正常,两个消息框都能先后出来,但是如果我把AfxMessageBox("A")注释掉,那么AfxMessageBox("B")就不出来,小弟实在不明白是怎么回事?问题没有完,所以还不能结贴,但我已经给各位捐分了,人人有分!!!
wwwllg 20
guojackey 30
qupd 20
zhuazhi 20
jerry529 30
wealth 20
小弟还有500多分可以捐,希望大家给我出注意,谢谢大家了!!!
7456!各位,请告诉我怎么才能给你们捐分???