?? pc2pcview.cpp
字號:
// PC2PCView.cpp : implementation of the CPC2PCView class
//
#include "stdafx.h"
#include "PC2PC.h"
#include "PC2PCDoc.h"
#include "PC2PCView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
HANDLE hCom; //串口的句柄
HANDLE hThreadEvent; //事件線程句柄
DWORD ThreadProcEvent(LPVOID pParam); //事件響應函數
bool fEventRun; //事件線程函數執行標志
HWND hWnd; //窗口句柄
DWORD dwThreadID; //事件線程ID
OVERLAPPED Eol={0}; //事件線程使用的OVERLAPPED結構Eol
OVERLAPPED Wol={0}; //寫操作使用的OVERLAPPED結構Wol
OVERLAPPED Rol={0}; //讀操作使用的OVERLAPPED結構Rol
DWORD dwTimeoutValue; //定義接收超時時間,ms為單位,在事件線程中使用
/////////////////////////////////////////////////////////////////////////////
// CPC2PCView
IMPLEMENT_DYNCREATE(CPC2PCView, CEditView)
BEGIN_MESSAGE_MAP(CPC2PCView, CEditView)
//{{AFX_MSG_MAP(CPC2PCView)
ON_COMMAND(ID_SETUPCOM, OnSetupcom)
ON_COMMAND(ID_SENDFILE, OnSendfile)
ON_COMMAND(ID_OPENCOM, OnOpencom)
ON_COMMAND(ID_CLOSECOM, OnClosecom)
ON_UPDATE_COMMAND_UI(ID_SENDFILE, OnUpdateSendfile)
ON_UPDATE_COMMAND_UI(ID_SETUPCOM, OnUpdateSetupcom)
ON_UPDATE_COMMAND_UI(ID_OPENCOM, OnUpdateOpencom)
ON_UPDATE_COMMAND_UI(ID_CLOSECOM, OnUpdateClosecom)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_UPDATE_COMMAND_UI(ID_APP_EXIT, OnUpdateAppExit)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_MYMSG,OnReceiveEvent)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPC2PCView construction/destruction
CPC2PCView::CPC2PCView()
{
// TODO: add construction code here
myCom="COM4"; //默認設置
myBaudRate=CBR_4800;
myfParity=false;
myParity=NOPARITY;
}
CPC2PCView::~CPC2PCView()
{
}
BOOL CPC2PCView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
BOOL bPreCreated = CEditView::PreCreateWindow(cs);
cs.style &= ~(ES_AUTOHSCROLL|WS_HSCROLL); // Enable word-wrapping
return bPreCreated;
}
/////////////////////////////////////////////////////////////////////////////
// CPC2PCView drawing
void CPC2PCView::OnDraw(CDC* pDC)
{
CPC2PCDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CPC2PCView diagnostics
#ifdef _DEBUG
void CPC2PCView::AssertValid() const
{
CEditView::AssertValid();
}
void CPC2PCView::Dump(CDumpContext& dc) const
{
CEditView::Dump(dc);
}
CPC2PCDoc* CPC2PCView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPC2PCDoc)));
return (CPC2PCDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CPC2PCView message handlers
void CPC2PCView::OnSetupcom()
{
// TODO: Add your command handler code here
CString strStatus;
if(mySetupDlg.DoModal()==IDOK)
{
switch (mySetupDlg.m_Com)
{
case 0:
{
strStatus="COM1";
strStatus+=" ";
myCom="COM1";
break;
}
case 1:
{
strStatus="COM2";
strStatus+=" ";
myCom="COM2";
break;
}
case 2:
{
strStatus="COM3";
strStatus+=" ";
myCom="COM3";
break;
}
case 3:
{
strStatus="COM4";
strStatus+=" ";
myCom="COM4";
break;
}
case 4:
{
strStatus="COM5";
strStatus+=" ";
myCom="COM5";
}
break;
case 5:
{
strStatus="COM6";
strStatus+=" ";
myCom="COM6";
}
break;
}
switch(mySetupDlg.m_BaudRate)
{
case 0:
{
strStatus+="19200";
strStatus+=" ";
myBaudRate=CBR_19200;
break;
}
case 1:
{
strStatus+="9600";
strStatus+=" ";
myBaudRate=CBR_9600;
break;
}
case 2:
{
strStatus+="4800";
strStatus+=" ";
myBaudRate=CBR_4800;
break;
}
case 3:
{
strStatus+="2400";
strStatus+=" ";
myBaudRate=CBR_2400;
break;
}
}
switch(mySetupDlg.m_Parity)
{
case 0:
{
myfParity=false;
myParity=NOPARITY;
strStatus+="N";
strStatus+="-8-1";
break;
}
case 1:
{
myfParity=TRUE;
myParity=ODDPARITY;
strStatus+="O";
strStatus+="-8-1";
break;
}
case 2:
{
myfParity=true;
myParity=EVENPARITY;
strStatus+="E";
strStatus+="-8-1";
break;
}
}
CMainFrame* m_pGetFrame=(CMainFrame*) AfxGetApp()->m_pMainWnd ;
CStatusBar* m_pStatus=&m_pGetFrame->m_wndStatusBar;
m_pStatus->SetPaneText(1,strStatus); //將通信參數顯示在狀態條上
blnSeted=true;
}
}
void CPC2PCView::OnSendfile()
{
// TODO: Add your command handler code here
CFileDialog myFileDlg(true); //打開文件對話框
CEdit& myEdit=this->GetEditCtrl();
BYTE bytFileNameLen; //文件名字符串的長度
BYTE bytTemp;
DWORD dwTemp1,dwTemp2;
int i;
CString myStr,myFileName,myPathName;
CFileException e; //文件異常變量
bytActStatus=1; //置為發送態
if(myFileDlg.DoModal()==IDOK) //調出文件選擇對話框,選擇傳送的文件
{
myPathName=myFileDlg.GetPathName();
myFileName=myFileDlg.GetFileName();
if(myFileName.GetLength()>100)
{
AfxMessageBox("文件名長度應小于100!");
bytActStatus=10; //恢復為接收態
return;
}
else
{
bytFileNameLen=(BYTE)myFileName.GetLength();
}
}
else
{
bytActStatus=10; //恢復為接收態
return;
}
myPathName.Replace("\\","\\\\"); //將文件名中的單“\”替換成雙“\\”
//打開選定的文件
if(!myFile.Open(myPathName,CFile::modeRead|CFile::typeBinary|CFile::shareDenyWrite,&e))
{
myStr.Format("%02X",e.m_cause);//文件打開錯誤處理,錯誤代碼為m_cause
myStr+="error";
AfxMessageBox(myStr);
bytActStatus=10; //恢復為接收態
return;
}
dwFileLen=myFile.GetLength();
if(dwFileLen>=67108864)
{
AfxMessageBox("文件必須小于64MB!");//檢查文件尺寸<64MB
bytActStatus=10; //恢復為接收態
return;
}
arrSendData[0]=05; //ENQ
arrSendData[4]=(BYTE)(dwFileLen/16777216);
dwTemp1=dwFileLen%16777216;
arrSendData[3]=(BYTE)(dwTemp1/65536);
dwTemp2=dwTemp1%65536;
arrSendData[2]=(BYTE)(dwTemp2/256);
arrSendData[1]=(BYTE)(dwTemp2%256);
arrSendData[5]=bytFileNameLen;
for(i=6;i<=bytFileNameLen+5;i++) //保存文件名稱
{
arrSendData[i]=myFileName.GetAt(i-6);
}
bytTemp=0;
for(i=0;i<=bytFileNameLen+5;i++)
{
bytTemp^=arrSendData[i];
}
arrSendData[bytFileNameLen+6]=bytTemp;//計算出校驗位
bytSendStatus=1;
bytResendCount=0;
Write(arrSendData,bytFileNameLen+7);
myEdit.SetSel(1000000,1000000);
myEdit.ReplaceSel("發出傳輸請求。\15\12");
blnNoTimeout=false;
}
void CPC2PCView::OnOpencom()
{
// TODO: Add your command handler code here
//打開串口操作
hCom=CreateFile(myCom, //打開串口COM2
GENERIC_READ | GENERIC_WRITE, //使用讀寫方式
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //使用重疊方式
NULL);
if( hCom !=INVALID_HANDLE_VALUE)
{
SetupComm(hCom,1500,1500); //設置發送緩沖1500,接收緩沖區1500
DCB myDCB;
GetCommState( hCom, &myDCB ); //獲取當前串口參數
myDCB.BaudRate=myBaudRate;
myDCB.fBinary=TRUE;
myDCB.fParity=myfParity;
myDCB.ByteSize=8;
myDCB.Parity=myParity;
myDCB.StopBits=ONESTOPBIT;
SetCommState(hCom,&myDCB); //設置串口通信參數
blnOpened=true;
//創建并立即執行線程函數
DWORD dwParam;
if (!SetCommMask(hCom,EV_RXCHAR))// | EV_TXEMPTY))//設置允許的事件類型
{
AfxMessageBox("建立事件掩碼失敗!");
}
hThreadEvent=CreateThread(NULL, //創建事件線程
0,
(LPTHREAD_START_ROUTINE )ThreadProcEvent, //指定線程函數名稱
&dwParam,
0, //創建線程函數后,立即執行
&dwThreadID);
if (hThreadEvent==INVALID_HANDLE_VALUE)
{
AfxMessageBox("事件線程創建失敗!");
}
fEventRun=true; //允許事件函數執行循環體
bytActStatus=10;
bytSendStatus=0;
bytRcvStatus=0;
bytResendCount=0;
uintStxCurNo=0;
}
else
{
AfxMessageBox("創建串口失敗!");
}
}
void CPC2PCView::OnClosecom()
{
// TODO: Add your command handler code here
fEventRun=false; //停止事件線程循環體的操作
WaitForSingleObject(hThreadEvent, //等待事件線程函數退出
INFINITE); //無限時地等待,直到事件線程函數退出
CloseHandle(hThreadEvent); //關閉事件線程句柄
CloseHandle(hCom); //關閉串口句柄
blnOpened=false;
}
//事件線程函數
DWORD ThreadProcEvent(LPVOID pParam)
{
DWORD dwErrors;
COMSTAT Rcs;
DWORD dwEvtMask,dwRes;
Eol.hEvent=CreateEvent(NULL, //設置Eol.hEvent成員為無信號狀態
TRUE,
FALSE,
NULL);
while(fEventRun)
{
WaitCommEvent(hCom, //監視串口事件
&dwEvtMask, //存放事件掩碼組合值
&Eol); //OVERLAPPED結構
dwRes=WaitForSingleObject(Eol.hEvent, //等待的事件對象句柄
dwTimeoutValue); //超時時間(ms)
switch (dwRes)
{
case WAIT_OBJECT_0: //成功得到事件監視結果
{
switch (dwEvtMask)
{
case EV_RXCHAR: //接收到數據
{
//向主線程發送消息,接收到數據
ClearCommError(hCom, //串口句柄
&dwErrors, //存放出錯信息的掩碼組合
&Rcs); //COMSTAT類型結構變量
if(Rcs.cbInQue!=0)
{
::PostMessage(hWnd, //目的窗口句柄
WM_MYMSG, //消息名稱
0, //傳遞的參數1
(LPARAM)EV_RXCHAR ); //傳遞的參數2
}
break;
}
case EV_TXEMPTY: //發送緩沖區已空
{
//這里可加入發送緩沖區空的處理代碼,或向主線程發送消息
break;
}
}
break;
}
case WAIT_TIMEOUT:
{
//傳遞超時消息給主線程
::PostMessage(hWnd, //目的窗口句柄
WM_MYMSG, //消息名稱
0, //傳遞的參數1
(LPARAM)100 ); //傳遞的參數100
break;
}
}
}
return true;
}
//消息響應函數
LONG CPC2PCView::OnReceiveEvent(WPARAM wParam,LPARAM lParam)
{
CFileDialog myFileDlg(false); //保存文件對話框
BYTE myByte[1100];
BYTE bytTemp;
CString strDis,strDis1;
char *myChar; //獲取文件名時使用
char myName[300];
char myExt[5];
int i;
CEdit& myEdit=this->GetEditCtrl();
CMainFrame* m_pGetFrame=(CMainFrame*) AfxGetApp()->m_pMainWnd ;
CStatusBar* m_pStatus=&m_pGetFrame->m_wndStatusBar;
CFileException e;
switch(bytActStatus)
{
case 1://發送操作
{
switch(bytSendStatus)//發送的不同狀態
{
case 1://發送操作的1態
{
switch(lParam)
{
case EV_RXCHAR://lParam=EV_RXCHAR即1,說明讀線程收到數據
{
blnNoTimeout=true;
bytTimeoutCounter=0;
switch(Detect(1))
{
case 0://收到指定數量的字符
{
break;
}
case 4://超時錯誤
{
DisSend(4);
blnNoTimeout=false;
return -1;
break;
}
case 8://無效,輸入緩沖區中字符數量為0
{
blnNoTimeout=false;
return 0;
break;
}
}
switch(Read(myByte,1))
{
case 0:
{
//繼續后面的操作
break;
}
case 4://超時錯誤
{
DisSend(4);
return -1;
break;
}
case 16://讀操作失敗
{
DisSend(16);
return -1;
break;
}
}
switch(myByte[0])
{
case 6://響應是ACK
{
//發送當前序號的數據
uintStxCurNo=1;
myEdit.SetSel(1000000,1000000);
myEdit.ReplaceSel("正在傳送數據……\15\12");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -