📄 oper_int.cpp
字号:
//*************************************************************************************
// OPER_INT.CPP
// This file contains definitions of classes and functions used the generic
// character-mode real-time operator interface.
//
// The current version has been modified from a regular-C application for Windows
// into a C++-style program. It is designed to use control keys rather than
// function keys so that it will be as portable as possible between platforms.
//
// FILES: To make an operator window package you need this file and its
// associated HPP file. It is designed to fit neatly with the TranRun3
// or CTL_EXEC scheduler packages; these are necessary for compilation
// whether or not the scheduler is to be used. See TranRun4.hpp for a
// list of all the header files which need to be made available.
//
// Version
// Original: copyright 1993, DM Auslander
// Modified: 1-94 JR non-C++ version added
// 2-94 JR Screen Manager stuff added
// 2-7-94 JR Went with op_xxxxx names only
// 8-94 JR Ported to Visual C++ DOS/QuickWin
// 9-94 JR Version done for Visual C++ running under Windows
// 12-94 JR C++ interface added to Windows app. in C version
// 1-95 JR Class structure modified, file OPER_WIN.CPP split up
// 6-95 JR Modified DOS version into EasyWin version; changed
// use of function keys (F1-F8) to use of control keys
// 9-95 JR Merged contents of OPI_EZWN and OPI_MAIN to this file
// 10-95 JR Eliminated TranRun3 dependency; now uses BASE_OBJ only
// 8-96 JR Changed delete calls for arrays to DELETE_ARRAY macro
// 10-96 DMA Added SelectedInput line in Display()
// 8-97 JR Added code to run in console from WinNT GUI application
//*************************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if !defined (TR4_COMP_HPP)
#define bool int
#define true 1
#define false 0
#define DELETE_ARRAY delete
#endif
#if defined (__WIN32__) && !defined (__CONSOLE__)
#include <windows.h>
extern HANDLE hStdin, hStdout; // Handles to console's standard I/O
extern HANDLE hSchedulerWindow; // Handle of scheduler's GUI window
DWORD dDummy; // Holds unused information
COORD conxy; // Coordinates of text on console
#define OPI_print(x) WriteConsole (hStdout, (x), strlen (x), &dDummy, NULL);
#define gotoxy(x,y) conxy.X = (x); conxy.Y = ((y) - 1); \
SetConsoleCursorPosition (hStdout, conxy)
#define clrscr() // There's no convenient replacement for consoles
//---------------------------------------------------------------------------------
// Function: kbhit
// This function must be redefined for use with a console which has been
// added to a Windows GUI application. It checks for the number of console
// input events (these may be key events) which are ready to be read.
bool kbhit (void)
{
DWORD NumEvents; // Number of console events not yet read
GetNumberOfConsoleInputEvents (hStdin, &NumEvents);
if (NumEvents > 0) return true;
else return false;
}
//---------------------------------------------------------------------------------
// Function: getch
// This function must also be redefined for use with a console. It reads a
// console input event. If the event is a key press, it returns the ASCII
// code of the key which was pressed; if not it discards the event.
int getch (void)
{
INPUT_RECORD EventBuffer; // Holds a console input event record
KEY_EVENT_RECORD KeyEvent; // Holds a record of what key was pressed
if (ReadConsoleInput (hStdin, &EventBuffer, 1, &dDummy) == false)
MessageBox (hSchedulerWindow, "Unable to read console input",
"Interface Error", MB_OK | MB_ICONSTOP);
// If the event isn't a key event, ignore it
if (EventBuffer.EventType != KEY_EVENT) return 0;
// Get key event record; make sure it's a key down, not a key up
KeyEvent = (KEY_EVENT_RECORD)EventBuffer.Event.KeyEvent;
if (KeyEvent.bKeyDown == false) return 0;
return ((int)(KeyEvent.uChar.AsciiChar));
}
#else
#include <conio.h> // kbhit() and getch() are defined here
#include <dos.h>
#define OPI_print(x) printf ("%s", (x))
#endif
#include <oper_int.hpp> // This file #includes <base_obj.hpp>
//=====================================================================================
// Global Variables
// Those variables which absolutely have to be made global are instantiated here.
COperatorWindow* CurrentOpWin = NULL; // Pointer to operator window in use
CDataItem* SelectedInput = NULL; // Pointer to selected screen input item
static int NeedToDrawKeys = 0; // Tells Update() to write key legend
static int NeedToDrawTitle = 0; // Tells Update() it must write title
//=====================================================================================
// Class: CDataItem
// This class represents one input or output item. Deriving it from CBaseObj
// makes it easy to keep DataItems in a list. A DataItem has member functions
// which allow it to update and return its contents and label. It can also print
// itself on the screen; the code for that is in operating environment specific
// files, though, not here.
//=====================================================================================
//-------------------------------------------------------------------------------------
// Constructor: CDataItem
// This constructor creates a CDataItem object. The parameters we have to give
// it are: type of data, input or output item, label text, pointer to data, and
// the number of this item in the list (which determines Y coordinate on screen).
CDataItem::CDataItem (DataType aType, IO_Type aIO, const char* aLabel, void* aData,
int aNum)
{
Label = new char[128]; // Allocate string for item label
strcpy (Label, aLabel); // Copy the data's name into this string
Type = aType; // Set data type
pData = aData; // Set pointer to data, whatever data it is
InOrOut = aIO; // Save choice of input or output item
NumberInList = aNum; // Save number in the list of items
// Get the coordinates of the rectangle in which to display the item. The Y
// coordinates depend on the number of the item in the list (static member data
// called NumberInList holds this). This is for character, not pixel, mode
ScreenRect.left = (InOrOut == DATA_INPUT) ? COL_INTITLE : COL_OUTTITLE;
ScreenRect.top = (NumberInList + TOP_BORDER);
ScreenRect.right = (InOrOut == DATA_INPUT) ? COL_OUTTITLE : 80;
ScreenRect.bottom = ScreenRect.top + 1;
}
//-------------------------------------------------------------------------------------
// Destructor: ~CDataItem
// This destructor is here to free up the memory used by the CDataItem object.
CDataItem::~CDataItem (void)
{
DELETE_ARRAY Label;
}
//-------------------------------------------------------------------------------------
// Function: SetValue
// When the user has typed in a string, the value of the data item must be set
// to equal whatever the data is in the string. Here's a function to do that:
// it's sort of an assignment, pData = (what's in UserString).
void CDataItem::SetValue (const char *UserString)
{
switch (Type)
{
case DT_INT:
sscanf (UserString, "%d", (int*)pData);
break;
case DT_LONG:
sscanf (UserString, "%ld", (long*)pData);
break;
case DT_FLOAT:
sscanf (UserString, "%g", (float*)pData);
break;
case DT_DOUBLE:
sscanf (UserString, "%lg", (double*)pData);
break;
case DT_LONG_DBL:
sscanf (UserString, "%Lg", (long double*)pData);
break;
case DT_STRING:
if (strlen (UserString) > 0)
strcpy ((char*)pData, UserString);
break;
default:
break;
}
}
//-------------------------------------------------------------------------------------
// Function: GetLabel
// This function returns a pointer to the character string containing the label
// of this data item.
const char* CDataItem::GetLabel (void)
{
return Label;
}
//-------------------------------------------------------------------------------------
// Function: GetData
// This function returns the data of the item in the form of a character string,
// which makes it easier for the COperatorWindow to display it on the screen. As
// the pointer returned points to a static character array, the data will be
// valid until the next time this function is called.
const char* CDataItem::GetData (void)
{
static char aString[48]; // Allocate ample space for the returned string
// Call function to convert data from its native form into a string
Data2String (pData, aString, Type);
return aString;
}
//-------------------------------------------------------------------------------------
// Function: Data2String
// In order to facilitate the display of numbers and such on the screen, this
// function converts numbers or whatever into character strings.
void CDataItem::Data2String (void* data, char* string, DataType aType)
{
switch (aType)
{
case DT_INT:
sprintf (string, "%d", *(int*)data);
break;
case DT_LONG:
sprintf (string, "%ld", *(long*)data);
break;
case DT_FLOAT:
sprintf (string, "%g", (double)(*(float*)data));
break;
case DT_DOUBLE:
sprintf (string, "%lg", *(double*)data);
break;
case DT_LONG_DBL:
sprintf (string, "%Lg", *(long double*)data);
break;
case DT_STRING:
sprintf (string, "%s", (char*)data);
break;
default:
sprintf (string, "**Data Error**");
break;
}
}
//-------------------------------------------------------------------------------------
// Function: Paint
// This function displays the data item on the screen. It's to be called by some
// function such as Paint() or Update().
void CDataItem::Paint (void)
{
int Twid; // Width of text area on screen
int Length; // Length of a text string
char OutString[128]; // Stores text to be shown
int X; // Stores X coord., other stuff
// Make sure there's a current operator window active in which to paint
if (CurrentOpWin == NULL)
return;
// If this is the input item which is selected, write label in white on gray
if (InOrOut == DATA_INPUT)
{
// Begin by filling the OutString string with the data label, plus extra
// spaces so that it erases anything which might be in the typein area
strcpy (OutString, GetLabel ());
Twid = COL_INDATA - COL_INTITLE;
Length = strlen (OutString);
while (Length++ < Twid)
strcat (OutString, " ");
if (this == SelectedInput) // If this is the input
{ // which accepts type-ins,
gotoxy (COL_INTITLE, ScreenRect.top); // signify it with a little
OPI_print (OutString); // arrow "->" to the left of
gotoxy (COL_TYPEIN, ScreenRect.top); // the type-in area; it
OPI_print ("->"); // looks kinda like a prompt
OPI_print (CurrentOpWin->InputBuffer);
}
else // Else it's not highlighted,
{ // so write the label alone
gotoxy (COL_INTITLE, ScreenRect.top);
OPI_print (OutString);
}
}
else // This else means it's
{ // not an input item but
gotoxy (COL_OUTTITLE, ScreenRect.top); // and output item; the
OPI_print (GetLabel ()); // label goes over here
}
// Now display the data for the item in the appropriate column
strcpy (OutString, GetData ());
// Pad length: 'Twid' is length of string which just fills the data area, and
// 'Length' is length of the output string. Pad output string until it's just
// long enough to fill the data area
Twid = (InOrOut == DATA_INPUT) ? (COL_OUTTITLE - COL_INDATA) : (80 - COL_OUTDATA);
Length = strlen (OutString);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -