📄 ttychic.c
字号:
//---------------------------------------------------------------------------
//
// Module: ttychic.c
//
// Purpose:
// This sample application demonstrates the usage of the COMM
// API. It implements the new Win32c API of Windows 95.
//
// This application demonstrates how to read data by Polling.
//
// NOTE: no escape sequences are translated, only
// the necessary control codes (LF, CR, BS, etc.)
//
// Description of functions:
// Descriptions are contained in the function headers.
//
//---------------------------------------------------------------------------
//
// Written by Microsoft Product Support Services, Windows Developer Support.
// Copyright (c) 1991 Microsoft Corporation. All Rights Reserved.
//
//---------------------------------------------------------------------------
#include "tty.h"
HINSTANCE ghInst; //global instance handle, for now.
HWND hTTYWnd ; //global window handle
BOOL bReading;
PTTYINFO pTTYInfo ;
COMMCONFIG cc;
DCB dcb;
COMMTIMEOUTS to;
COMMPROP cp;
HANDLE hComm, hThread;
LPCSTR lpszCommName = "COM2"; //global variable to define the serial
// COM port you will be using
DWORD ReadThread (LPDWORD lpdwParam1);
void locProcessCommError (DWORD dwError);
void locProcessBytes (LPBYTE buf, DWORD dwBytes);
#if !defined(_WIN32)
#include <ver.h>
#endif
// Windows NT defines APIENTRY, but 3.x doesn't
#if !defined (APIENTRY)
#define APIENTRY far pascal
#endif
// Windows 3.x uses a FARPROC for dialogs
#if !defined(_WIN32)
#define DLGPROC FARPROC
#endif
char szDebug[100];
//
// FUNCTION: WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
//
// PURPOSE: calls initialization function, processes message loop
//
// COMMENTS:
//
// Windows recognizes this function by name as the initial entry point
// for the program. This function calls the application initialization
// routine, if no other instance of the program is running, and always
// calls the instance initialization routine. It then executes a
// message retrieval and dispatch loop that is the top-level control
// structure for the remainder of execution. The loop is terminated
// when a WM_QUIT message is received, at which time this function
// exits the application instance by returning the value passed by
// PostQuitMessage().
//
// If this function must abort before entering the message loop, it
// returns the conventional value NULL.
//
int APIENTRY WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
MSG msg;
DWORD id;
BOOL bOldState = FALSE;
OutputDebugString ("TTY Demo Program\n");
// Other instances of app running?
if (!hPrevInstance) {
// Initialize shared things
if (!InitApplication(hInstance)) {
return (FALSE); // Exits if unable to initialize
}
}
if (NULL == (hTTYWnd = InitInstance( hInstance, nCmdShow )))
return ( FALSE ) ;
ghInst = hInstance;
CreateTTYInfo( hTTYWnd );
if (NULL == (pTTYInfo =
(PTTYINFO) GetWindowLong( hTTYWnd,GWL_PTTYINFO )))
return ( FALSE ) ;
/* open COM port #2 for reading and writing */
if ((hComm=CreateFile (lpszCommName, GENERIC_READ|GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) {
/* handle error */
MessageBox (NULL, "Error opening COM port","",MB_OK);
return FALSE;
} /* end if (error creating read thread) */
/* get comm properties */
cp.wPacketLength = sizeof(COMMPROP);
GetCommProperties (hComm, &cp);
/* create the thread for reading bytes */
bReading = TRUE;
if ((hThread=CreateThread (NULL /*def security */, 0 /* def stack size */,
(LPTHREAD_START_ROUTINE)ReadThread, NULL /* param to pass to thread */,
0, &id)) == INVALID_HANDLE_VALUE) {
/* handle error */
MessageBox (NULL, "Error creating READ thread","",MB_OK);
CloseHandle (hComm);
return FALSE;
} /* end if (error creating read thread) */
while (GetMessage(&msg, NULL, 0, 0)) {
if (!TranslateAccelerator (msg.hwnd, ghAccel, &msg)) {
TranslateMessage(&msg);// Translates virtual key codes
DispatchMessage(&msg); // Dispatches message to window
}
} /* end while (not a quit message) */
/* kill the read thread */
bReading = FALSE;
/* in case the thread is not running, resume it now */
ResumeThread (hThread);
/* wait for thread to die... */
while (GetExitCodeThread(hThread, &id)) {
if (id == STILL_ACTIVE)
continue;
else
break;
} /* end while (no error reading thread exit code) */
CloseHandle (hThread);
/* close COM port */
CloseHandle (hComm);
/* clean up */
DestroyTTYInfo( hTTYWnd ) ;
// Returns the value from PostQuitMessage
return (msg.wParam);
// This will prevent 'unused formal parameter' warnings
lpCmdLine;
}
//---------------------------------------------------------------------------
// BOOL NEAR InitApplication( HANDLE hInstance )
//
// Description:
// First time initialization stuff. This registers information
// such as window classes.
//
// Parameters:
// HANDLE hInstance
// Handle to this instance of the application.
//
//---------------------------------------------------------------------------
BOOL NEAR InitApplication( HANDLE hInstance )
{
WNDCLASS wndclass ;
// register tty window class
wndclass.style = 0 ;
wndclass.lpfnWndProc = TTYWndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = sizeof( DWORD ) ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( TTYICON ) );
wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ) ;
wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1) ;
wndclass.lpszMenuName = MAKEINTRESOURCE( TTYMENU ) ;
wndclass.lpszClassName = gszTTYClass ;
return( RegisterClass( &wndclass ) ) ;
} // end of InitApplication()
//---------------------------------------------------------------------------
// HWND NEAR InitInstance( HANDLE hInstance, int nCmdShow )
//
// Description:
// Initializes instance specific information.
//
// Parameters:
// HANDLE hInstance
// Handle to instance
//
// int nCmdShow
// How do we show the window?
//
//---------------------------------------------------------------------------
HWND NEAR InitInstance( HANDLE hInstance, int nCmdShow )
{
HWND hTTYWnd ;
// load accelerators
ghAccel = LoadAccelerators( hInstance, MAKEINTRESOURCE( TTYACCEL ) ) ;
// create the TTY window
hTTYWnd = CreateWindow( gszTTYClass, gszAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL ) ;
if (NULL == hTTYWnd)
return ( NULL ) ;
ShowWindow( hTTYWnd, nCmdShow ) ;
UpdateWindow( hTTYWnd ) ;
return ( hTTYWnd ) ;
} // end of InitInstance()
//---------------------------------------------------------------------------
// LRESULT FAR PASCAL TTYWndProc( HWND hWnd, UINT uMsg,
// WPARAM wParam, LPARAM lParam )
//
// Description:
// This is the TTY Window Proc. This handles ALL messages
// to the tty window.
//
// Parameters:
// As documented for Window procedures.
//
//---------------------------------------------------------------------------
LRESULT FAR PASCAL TTYWndProc( HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam )
{
LONG lrc;
switch (uMsg)
{
case WM_CREATE:
break;
case WM_COMMAND:
{
switch ((DWORD) wParam)
{
case ID_SETTINGS_CONFIGURE:
/* get current port settings */
lrc = sizeof(COMMCONFIG);
GetCommConfig (hComm, &cc, &lrc);
/* display dialog to modify settings */
if (!CommConfigDialog(lpszCommName, hWnd, &cc))
break;
/* write new settings */
if (!SetCommState (hComm, &cc.dcb))
break;
break;
case IDM_ABOUT:
GoModalDialogBoxParam ( GETHINST( hWnd ),
MAKEINTRESOURCE( ABOUTDLGBOX ),
hWnd,
AboutDlgProc, 0 ) ;
break;
case IDM_EXIT:
PostMessage( hWnd, WM_CLOSE, 0, 0L ) ;
break ;
}
}
break ;
case WM_PAINT:
PaintTTY( hWnd ) ;
break ;
case WM_SIZE:
SizeTTY( hWnd, HIWORD( lParam ), LOWORD( lParam ) ) ;
break ;
case WM_HSCROLL:
ScrollTTYHorz( hWnd, (WORD) wParam, LOWORD( lParam ) ) ;
break ;
case WM_VSCROLL:
ScrollTTYVert( hWnd, (WORD) wParam, LOWORD( lParam ) ) ;
break ;
case WM_CHAR:
/* echo to local window if echo turned on */
if (LOCALECHO (pTTYInfo)) {
WriteTTYBlock(hWnd, (LPBYTE)&wParam, 1 );
}
/* write out the character to the COM Port */
if (!WriteFile(hComm, (LPBYTE)&wParam, 1, &lrc, NULL)) {
/* handle error */
locProcessCommError(GetLastError ());
} /* end if (error reading bytes) */
break ;
case WM_SETFOCUS:
SetTTYFocus( hWnd ) ;
break ;
case WM_KILLFOCUS:
KillTTYFocus( hWnd ) ;
break ;
case WM_DESTROY:
PostQuitMessage( 0 ) ;
break ;
case WM_CLOSE:
if (IDOK != MessageBox( hWnd, "OK to close window?", "TTY Sample",
MB_ICONQUESTION | MB_OKCANCEL ))
break ;
// fall through
default:
return( DefWindowProc( hWnd, uMsg, wParam, lParam ) ) ;
}
return 0L ;
} // end of TTYWndProc()
//---------------------------------------------------------------------------
// DWORD ReadThread(LPDWORD lpdwParam1)
//
// Description:
// Thread dedicated to reading bytes from the COM port
//
//
// Parameters:
// LPDWORD lpdwParam1
// Thread data (not used)
//
//---------------------------------------------------------------------------
DWORD ReadThread (LPDWORD lpdwParam1)
{
BYTE inbuff[100];
DWORD nBytesRead;
/* The next two lines check to make sure that interval
timeouts are supported by the port */
if (!(cp.dwProvCapabilities & PCF_INTTIMEOUTS))
return 1L; /* error; can抰 set interval timeouts */
/* the next three lines tell the read function to return
immediately when there are no bytes waiting in the
port抯 receive queue */
memset (&to, 0, sizeof(to));
to.ReadIntervalTimeout = MAXDWORD;
SetCommTimeouts (hComm, &to);
/* this loop polls the port reading bytes until the
control variable bReading is set to FALSE by the
controlling process */
while (bReading) {
/* poll the port and read bytes if available */
if (!ReadFile(hComm, inbuff, 100, &nBytesRead, NULL)) {
/* handle error */
locProcessCommError(GetLastError ());
} /* end if (error reading bytes) */
else {
/* if there were bytes waiting,
display them in TTY window */
if (nBytesRead)
locProcessBytes(inbuff, nBytesRead);
}
} /* end while (thread active) */
/* clean out any pending bytes in the receive buffer */
PurgeComm(hComm, PURGE_RXCLEAR);
return 0L;
} /* end function (ReadThread) */
// local function to process COM errors - fill in your own error handler
void locProcessCommError (DWORD dwError)
{
DWORD lrc;
COMSTAT cs;
/* clear error */
ClearCommError (hComm, &lrc, &cs);
} /* end function (locProcessCommError) */
// local function to process bytes read from the COM port - just displays them in the terminal window;
// put your own handler code here
void locProcessBytes (LPBYTE buf, DWORD dwBytes)
{
WriteTTYBlock(hTTYWnd, buf, dwBytes);
} /* end function (locProcessBytes) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -