📄 termw16.cpp
字号:
// ******************** START OF TERMW16.CPP ********************
//
// This is a simple demo program that exercises the Win16Port
// class under Windows 3.1. This program uses a subclassed
// edit control for display of incoming data. Any keystrokes
// sent to the subclassed control from the keyboard are
// intercepted and sent out the open comm port. Data that
// is read in from the comm port is sent to the edit control
// as if it were actual keyboard data, which then displays it.
//
// This is okay for a demo/test program, but it isn't robust
// enough for a real application. In particular, it will
// eventually run out of memory, as none of the input data is
// ever flushed from the edit control's buffer. Also, special
// characters sent to the control, such as arrow keys, will
// have results that cause the app to misbehave.
//
#include <windows.h>
#include "win16.h"
//
// Even though this is a C++ program, it operates
// under Win16, which is basically a C framework.
// So we end up with a few global variables, which
// would be frowned upon in some quarters.
//
FARPROC pDefaultEditProc = 0; // Pointer to the normal WinProc
// for the edit control.
HWND hEdit = 0; // Handle of the embedded edit
// control.
Win16Port *pCommPort = 0; // Pointer to the comm port, which
// is opened in WinMain and kept open.
//
// This is the subclassed edit control procedure. It only
// overrides one piece of behavior, which is the WM_CHAR
// message. When the user types a character from the keyboard,
// we don't want it to go into the edit control, we actually
// want to send it out the comm port. This guy takes care
// of it.
//
// The really important thing this control does is take care
// of displaying the data that is read in from the comm port.
// We send those to the edit control from the polling loop
// with a special value of lParam that indicates we need to
// deal with them.
//
long FAR PASCAL _export EditProc( HWND hwnd,
UINT message,
UINT wParam,
LONG lParam )
{
switch ( message ) {
case WM_CHAR :
if ( lParam == 0xffffffffl )
lParam = 0x1e0001L; /* A normal lParam */
else {
pCommPort->Write( (char) wParam );
return 1;
}
break;
}
//
// Here we use the default procedure to handle any message
// besides WM_CHAR. We also handle the special WM_CHAR sent
// in from the polling loop. The polling loop sends data to
// be displayed with a special lParam value of 0xffffffffl,
// which we then discard and replace with a value that
// gets sent with a 'normal' keystroke
//
return CallWindowProc( pDefaultEditProc,
hwnd,
message,
wParam,
lParam );
}
//
// The windows procedure for my frame window. This is
// a really simple window procedure, because we rely
// on the child edit control to do all the work. All
// we do of any significance in here is create the edit
// child when we are created, set up a timer to let us
// poll the serial port periodically, and resize the
// child control if we are resized.
//
long FAR PASCAL _export WndProc( HWND hwnd,
UINT message,
UINT wParam,
LONG lParam )
{
switch ( message ) {
//
// I want a unique frame without resizing handles, and
// I set it up here. I could have done it by calling
// CreateWindowEx() in Win Main, but this requires
// less typing.
//
case WM_NCCREATE:
{
LONG exstyle = GetWindowLong( hwnd, GWL_EXSTYLE );
exstyle |= WS_EX_DLGMODALFRAME;
SetWindowLong( hwnd, GWL_EXSTYLE, exstyle );
return 1 ;
}
//
// When the frame window is ready, I create the embedded
// child edit control, hook its procedure, and start up
// a 100 millisecond timer.
//
case WM_CREATE:
{
HANDLE hInstance = ( (LPCREATESTRUCT) lParam)->hInstance;
hEdit = CreateWindow( "edit",
NULL,
WS_CHILD | WS_VISIBLE |
WS_HSCROLL | WS_VSCROLL |
WS_BORDER | ES_LEFT |
ES_MULTILINE | ES_AUTOHSCROLL |
ES_AUTOVSCROLL,
0, 0, 0, 0,
hwnd, 1,
hInstance,
NULL ) ;
FARPROC pEditProc =
MakeProcInstance( (FARPROC) EditProc, hInstance );
pDefaultEditProc = (FARPROC) GetWindowLong( hEdit, GWL_WNDPROC );
SetWindowLong( hEdit, GWL_WNDPROC, (LONG) pEditProc );
SetTimer( hwnd, 1000, 100, 0 );
return 0 ;
}
//
// Every timer tick I read in all the characters I can handle from
// the serial port, and send them to the edit control which is
// tricked into thinking they are regular keystrokes. One thing
// I have to do as a bit of preprocessing is to through out CR
// characters and just process LFs. If don't do this every input
// line gets an extra LF.
//
case WM_TIMER :
{
char buf[ 256 ];
pCommPort->Read( buf, 255, 0 );
int count = pCommPort->ByteCount;
if ( count > 0 )
for ( int i = 0 ; i < count ; i++ )
if ( buf[ i ] != '\r' )
SendMessage( hEdit, WM_CHAR, buf[ i ], 0xffffffffL );
break;
}
//
// If the frame window gets the focus for some reason, we immediately
// delegate it to the child edit control.
//
case WM_SETFOCUS:
SetFocus( hEdit );
return 0;
//
// I only get resized on creation, but even so I have to deal with
// it by resizing the child edit control so that it fills the frame.
//
case WM_SIZE:
MoveWindow( hEdit,
0, 0,
LOWORD( lParam ), HIWORD( lParam ),
TRUE );
return 0 ;
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc( hwnd, message, wParam, lParam );
}
//
// WinMain is the same everywhere.
//
int PASCAL WinMain( HANDLE hInstance,
HANDLE hPrevInstance,
LPSTR /* lpszCmdLine */,
int nCmdShow )
{
pCommPort = new Win16Port( COM1, 19200L, 'N', 8, 1 );
if ( pCommPort == 0 || pCommPort->ErrorStatus() < 0 ) {
MessageBox( 0, "Error opening port!", "TERMW16 Error", MB_OK );
return 0;
}
if ( !hPrevInstance ) {
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wndclass.hCursor = LoadCursor ( NULL, IDC_ARROW );
wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = "TermClass";
RegisterClass (&wndclass) ;
}
HWND hwnd = CreateWindow( "TermClass",
"Term31",
WS_CAPTION |
WS_SYSMENU |
WS_MINIMIZEBOX,
CW_USEDEFAULT,
CW_USEDEFAULT,
600, 350,
NULL,
NULL,
hInstance,
NULL );
ShowWindow( hwnd, nCmdShow );
UpdateWindow( hwnd );
MSG msg;
while ( GetMessage ( &msg, NULL, 0, 0 ) ) {
TranslateMessage( &msg );
DispatchMessage( &msg );
}
delete pCommPort;
return msg.wParam;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -