📄 chapt12dlg.cpp
字号:
// Chapt12Dlg.cpp : implementation file
//
#include <afxwin.h>
#include <process.h>
#include <cassert>
#include <sstream>
#include <mcx.h>
#include "Chapt12.h"
#include "Chapt12Dlg.h"
#include "MyWin32Port.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CChapt12Dlg dialog
CChapt12Dlg::CChapt12Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CChapt12Dlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CChapt12Dlg)
//}}AFX_DATA_INIT
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_hConsoleOutput = INVALID_HANDLE_VALUE;
m_hConsoleInput = INVALID_HANDLE_VALUE;
m_hCloseConsoleEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
m_pPort = 0;
}
void CChapt12Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CChapt12Dlg)
DDX_Control(pDX, IDC_SPEW, m_SpewButton);
DDX_Control(pDX, IDC_FLUSH_TX, m_FlushTxButton);
DDX_Control(pDX, IDC_FLUSH_RX, m_FlushRxButton);
DDX_Control(pDX, IDC_PEEK_BUFFER, m_PeekBufferButton);
DDX_Control(pDX, IDC_SEND_BREAK, m_SendBreakButton);
DDX_Control(pDX, IDC_DUMP_STATUS, m_DumpStatusButton);
DDX_Control(pDX, IDC_SEND_BUFFER, m_SendBufferButton);
DDX_Control(pDX, IDC_READ_CHAR, m_ReadCharButton);
DDX_Control(pDX, IDC_UPDATE, m_UpdateButton);
DDX_Control(pDX, IDC_PORT, m_PortComboBox);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CChapt12Dlg, CDialog)
//{{AFX_MSG_MAP(CChapt12Dlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_OPEN_OR_CLOSE, OnOpenOrClose)
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_SEND_BUFFER, OnSendBuffer)
ON_BN_CLICKED(IDC_UPDATE, OnUpdate)
ON_CBN_EDITUPDATE(IDC_BAUD_RATE, OnEditupdateBaudRate)
ON_CBN_SELCHANGE(IDC_BAUD_RATE, OnSelchangeBaudRate)
ON_CBN_EDITCHANGE(IDC_PARITY, OnEditchangeParity)
ON_CBN_SELCHANGE(IDC_PARITY, OnSelchangeParity)
ON_CBN_EDITUPDATE(IDC_STOP_BITS, OnEditupdateStopBits)
ON_CBN_SELCHANGE(IDC_STOP_BITS, OnSelchangeStopBits)
ON_CBN_EDITUPDATE(IDC_WORD_SIZE, OnEditupdateWordSize)
ON_CBN_SELCHANGE(IDC_WORD_SIZE, OnSelchangeWordSize)
ON_BN_CLICKED(IDC_RTS, OnRts)
ON_BN_CLICKED(IDC_DTR, OnDtr)
ON_BN_CLICKED(IDC_DTR_DSR, OnDtrDsr)
ON_BN_CLICKED(IDC_XON_XOFF, OnXonXoff)
ON_BN_CLICKED(IDC_RTS_CTS, OnRtsCts)
ON_MESSAGE( WM_SERIAL_RX_NOTIFY,OnRxNotify)
ON_MESSAGE( WM_FRAMING_ERROR_NOTIFY,OnFramingErrorNotify)
ON_MESSAGE( WM_PARITY_ERROR_NOTIFY,OnParityErrorNotify)
ON_MESSAGE( WM_HARDWARE_OVERRUN_ERROR_NOTIFY,OnHardwareOverrunErrorNotify)
ON_MESSAGE( WM_SOFTWARE_OVERRUN_ERROR_NOTIFY,OnSoftwareOverrunErrorNotify)
ON_MESSAGE( WM_BREAK_DETECT_NOTIFY,OnBreakDetectNotify)
ON_MESSAGE( WM_CTS_NOTIFY,OnCtsNotify)
ON_MESSAGE( WM_DSR_NOTIFY,OnDsrNotify)
ON_MESSAGE( WM_CD_NOTIFY,OnCdNotify)
ON_MESSAGE( WM_RI_NOTIFY,OnRiNotify)
ON_MESSAGE( WM_TX_NOTIFY,OnTxNotify)
ON_BN_CLICKED(IDC_READ_CHAR, OnReadChar)
ON_BN_CLICKED(IDC_DUMP_STATUS, OnDumpStatus)
ON_BN_CLICKED(IDC_ERROR_NOTIFICATION, OnErrorNotification)
ON_BN_CLICKED(IDC_SEND_BREAK, OnSendBreak)
ON_CBN_SELCHANGE(IDC_READ_TYPE, OnSelchangeReadType)
ON_BN_CLICKED(IDC_PEEK_BUFFER, OnPeekBuffer)
ON_BN_CLICKED(IDC_FLUSH_RX, OnFlushRx)
ON_BN_CLICKED(IDC_FLUSH_TX, OnFlushTx)
ON_BN_CLICKED(IDC_SPEW, OnSpew)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CChapt12Dlg message handlers
BOOL CChapt12Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
SetDlgItemText( IDC_PORT, "COM1" );
SetDlgItemText( IDC_BAUD_RATE, "9600" );
SetDlgItemText( IDC_PARITY, "None" );
SetDlgItemText( IDC_WORD_SIZE, "8" );
SetDlgItemText( IDC_STOP_BITS, "1" );
SetDlgItemText( IDC_BREAK_DURATION, "250" );
SendDlgItemMessage( IDC_DTR, BM_SETCHECK, BST_CHECKED, 0 );
SendDlgItemMessage( IDC_RTS, BM_SETCHECK, BST_CHECKED, 0 );
m_eReading = READ_BYTES;
SendDlgItemMessage( IDC_READ_TYPE, CB_SETCURSEL, 1, 0 );
m_bErrorNotification = true;
SendDlgItemMessage( IDC_ERROR_NOTIFICATION, BM_SETCHECK, BST_CHECKED, 0 );
return TRUE; // return TRUE unless you set the focus to a control
}
// 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 CChapt12Dlg::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();
}
}
HCURSOR CChapt12Dlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CChapt12Dlg::OnOpenOrClose()
{
if ( m_hConsoleOutput == INVALID_HANDLE_VALUE ) {
CString port_name;
GetDlgItemText( IDC_PORT, port_name );
int baud_rate = GetDlgItemInt( IDC_BAUD_RATE );
int word_size = GetDlgItemInt( IDC_WORD_SIZE );
int stop_bits = GetDlgItemInt( IDC_STOP_BITS );
int xon_xoff = SendDlgItemMessage( IDC_XON_XOFF, BM_GETCHECK, 0, 0 ) == BST_CHECKED;
int rts_cts = SendDlgItemMessage( IDC_RTS_CTS, BM_GETCHECK, 0, 0 ) == BST_CHECKED;
int dtr_dsr = SendDlgItemMessage( IDC_DTR_DSR, BM_GETCHECK, 0, 0 ) == BST_CHECKED;
m_iFramingErrorCount = 0;
m_iParityErrorCount = 0;
m_iHardwareOverrunErrorCount = 0;
m_iSoftwareOverrunErrorCount = 0;
m_iBreakDetectCount = 0;
m_iTxNotifyCount = 0;
m_bSpewing = false;
SetDlgItemInt( IDC_FRAMING_ERROR_COUNT, 0 );
SetDlgItemInt( IDC_PARITY_ERROR_COUNT, 0 );
SetDlgItemInt( IDC_HARDWARE_OVERRUN_ERROR_COUNT, 0 );
SetDlgItemInt( IDC_SOFTWARE_OVERRUN_ERROR_COUNT, 0 );
SetDlgItemInt( IDC_BREAK_DETECT_COUNT, 0 );
SetDlgItemInt( IDC_TX_EMPTY_COUNT, 0 );
CString parity;
GetDlgItemText( IDC_PARITY, parity );
m_pPort = new MyWin32Port( this->m_hWnd,
(const char *) port_name,
baud_rate,
parity[ 0 ],
word_size,
stop_bits,
UNCHANGED,
UNCHANGED,
xon_xoff,
rts_cts,
dtr_dsr );
if ( m_pPort->ErrorStatus() == RS232_SUCCESS ) {
m_PortComboBox.EnableWindow( FALSE );
SetDlgItemText( IDC_OPEN_OR_CLOSE, "Close" );
m_SendBufferButton.EnableWindow( TRUE );
m_ReadCharButton.EnableWindow( TRUE );
m_PeekBufferButton.EnableWindow( TRUE );
m_SendBreakButton.EnableWindow( TRUE );
m_SpewButton.EnableWindow( TRUE );
m_SpewButton.SetWindowText( "Start Spew" );
m_DumpStatusButton.EnableWindow( TRUE );
m_FlushRxButton.EnableWindow( TRUE );
m_FlushTxButton.EnableWindow( TRUE );
m_iRingCount = -1;
SetDlgItemText( IDC_CTS, "" );
SetDlgItemText( IDC_DSR, "" );
SetDlgItemText( IDC_CD, "" );
SetDlgItemText( IDC_RI, "" );
int check_state = BST_INDETERMINATE;
switch ( m_pPort->Dtr() ) {
case 0 : check_state = BST_UNCHECKED; break;
case 1 : check_state = BST_CHECKED; break;
}
SendDlgItemMessage( IDC_DTR, BM_SETCHECK, check_state, 0 );
check_state = BST_INDETERMINATE;
switch ( m_pPort->Rts() ) {
case 0 : check_state = BST_UNCHECKED; break;
case 1 : check_state = BST_CHECKED; break;
}
SendDlgItemMessage( IDC_RTS, BM_SETCHECK, check_state, 0 );
AllocConsole();
m_hConsoleOutput = GetStdHandle( STD_OUTPUT_HANDLE );
m_hConsoleInput = GetStdHandle( STD_INPUT_HANDLE );
SetWindowPos( &wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
SetConsoleMode( m_hConsoleInput, 0 );
ResetEvent( m_hCloseConsoleEvent );
_beginthread( ConsoleInputThread, 0, (void *) this );
} else {
string msg = "Port Error: ";
msg += m_pPort->ErrorName( m_pPort->ErrorStatus() );
AfxMessageBox( msg.c_str() );
delete m_pPort;
m_pPort = 0;
}
} else {
m_SendBufferButton.EnableWindow( FALSE );
m_ReadCharButton.EnableWindow( FALSE );
m_PeekBufferButton.EnableWindow( FALSE );
m_SendBreakButton.EnableWindow( FALSE );
m_SpewButton.EnableWindow( FALSE );
m_DumpStatusButton.EnableWindow( FALSE );
m_FlushRxButton.EnableWindow( FALSE );
m_FlushTxButton.EnableWindow( FALSE );
delete m_pPort;
m_pPort = 0;
m_hConsoleInput = INVALID_HANDLE_VALUE;
m_hConsoleOutput = INVALID_HANDLE_VALUE;
SetEvent( m_hCloseConsoleEvent );
FreeConsole();
m_PortComboBox.EnableWindow( TRUE );
m_UpdateButton.EnableWindow( FALSE );
SetDlgItemText( IDC_OPEN_OR_CLOSE, "Open" );
}
}
void CChapt12Dlg::ConsoleInputThread(void * arglist)
{
CChapt12Dlg *obj = (CChapt12Dlg *) arglist;
TRACE( "Entering console input thread\n" );
HANDLE handles[ 2 ] = { obj->m_hConsoleInput, obj->m_hCloseConsoleEvent };
for ( ; ; ) {
DWORD wait_result = WaitForMultipleObjects( 2,
handles,
FALSE,
INFINITE );
if ( wait_result == 1 )
break;
DWORD result;
INPUT_RECORD record;
BOOL ret_val = ReadConsoleInput( obj->m_hConsoleInput,
&record,
1,
&result );
if ( record.EventType == KEY_EVENT ) {
if ( record.Event.KeyEvent.bKeyDown && record.Event.KeyEvent.uChar.AsciiChar ) {
char c = record.Event.KeyEvent.uChar.AsciiChar;
obj->m_pPort->Write( c );
if ( c == '\r' )
obj->m_pPort->Write( '\n' );
}
}
}
TRACE( "Exiting console input thread, error = %x\n", GetLastError() );
}
void CChapt12Dlg::OnDestroy()
{
CDialog::OnDestroy();
if ( m_hConsoleOutput != INVALID_HANDLE_VALUE ) {
m_hConsoleInput = INVALID_HANDLE_VALUE;
m_hConsoleOutput = INVALID_HANDLE_VALUE;
SetEvent( m_hCloseConsoleEvent );
FreeConsole();
}
if ( m_pPort ) {
delete m_pPort;
m_pPort = 0;
}
}
void CChapt12Dlg::OnSendBuffer()
{
m_pPort->Write( "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\r\n", 38 );
}
void CChapt12Dlg::OnUpdate()
{
int baud_rate = GetDlgItemInt( IDC_BAUD_RATE );
int word_size = GetDlgItemInt( IDC_WORD_SIZE );
int stop_bits = GetDlgItemInt( IDC_STOP_BITS );
CString parity;
GetDlgItemText( IDC_PARITY, parity );
RS232Error err = m_pPort->Set( baud_rate, parity[ 0 ], word_size, stop_bits );
if ( err < RS232_SUCCESS ) {
string msg = "Port Error: ";
msg += m_pPort->ErrorName( err );
AfxMessageBox( msg.c_str() );
}
}
void CChapt12Dlg::OnEditupdateBaudRate()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -