home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Shareware GOLD
/
NuclearComputingVol3No1.cdr
/
other
/
f1490
/
stdio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-29
|
14KB
|
537 lines
/*****************************************************************************
Stdio.c
Main Program file.
This file contains all the code to provide basic text communication
for another windows application.
This programs operation is described in winpipe.wri.
*****************************************************************************/
#include <windows.h>
#include <stdio.h>
#include "winpipe.h"
#include "Stdio.h"
/* circular difference , First, Last, Count */
#define CIRDIF(F, L, C) (L >= F) ? (L - F): (C - (F - L))
#define MAX_ROWS 50 /* upto 50 rows of text on window */
#define MAX_COLS 100 /* up to 100 characters per row */
#define TAB_SIZE 8 /* Tab expansion size */
#define BUFFER_SIZE 2048 /* Buffer size, same as default pipe size */
FILE *logfile; /* "redirection" file */
char ScrBuf[MAX_ROWS][MAX_COLS];/* screen buffer */
char szFname[]="\\stdio.log"; /* default Log file name */
char *szAppName = "stdio"; /* Application name */
char *szPosition = "Pos"; /* Position entry in win.ini */
char *szError = "Error"; /* String for error */
static int FirstRow=0; /* first entry into circular buffer */
static int LastRow=0; /* last entry into circular buffer */
static int CurrentCol=0; /* Current row being worked on */
static int WinRow=0; /* reletive Windows row */
static int NumRows; /* Number of rows avaialable */
static int CharHeight; /* height of a character */
static int CharWidth; /* average Width of a character */
RECT rect; /* Window rectangle */
HANDLE hBrush; /* Generic brush to paint window with */
HANDLE hInstance; /* This programs instance */
HANDLE hMainWnd; /* This programs window */
static HDC ScrhDC; /* internal copy of device context */
/* Quick'n easy dialog routine */
BOOL PopupDLG( hParentWnd, lpszTemplate, lpfnDlgProc )
HWND hParentWnd;
LPSTR lpszTemplate;
FARPROC lpfnDlgProc;
{
BOOL bResult;
FARPROC lpProc;
HANDLE hParentInst;
hParentInst = GetWindowWord(hParentWnd,GWW_HINSTANCE);
lpProc = MakeProcInstance( lpfnDlgProc, hParentInst);
bResult = DialogBox( hParentInst, lpszTemplate, hParentWnd, lpProc );
FreeProcInstance( lpProc );
return( bResult );
}
/* Aboutbox proc */
BOOL FAR PASCAL About(hDlg, message, wParam, lParam) /* About box */
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
switch (message) {
case WM_INITDIALOG:
return (TRUE);
case WM_COMMAND:
switch(wParam){
case IDOK:
EndDialog(hDlg, TRUE);
break;
case IDCANCEL:
EndDialog(hDlg, TRUE);
break;
default:
break;
}
}
return (FALSE);
}
/* Draw single line */
UpdateLine()
{
TextOut(ScrhDC, 0, CharHeight * WinRow, (LPSTR) ScrBuf[LastRow], CurrentCol);
}
/* Redraw whole window */
void RepaintScr()
{
int i, y, numrows;
int len = CurrentCol;
int row = LastRow;
numrows = CIRDIF(FirstRow, LastRow, MAX_ROWS); /* number of displayable lines */
WinRow = (NumRows <= numrows) ? (NumRows-1) : numrows; /* starting row */
y = WinRow * CharHeight; /* Last line in window */
FillRect(ScrhDC, (LPRECT) &rect, hBrush); /* Clear window */
for(i=WinRow; i >= 0; i--){ /* count down to last displayable */
TextOut(ScrhDC, 0, y, (LPSTR)ScrBuf[row], lstrlen((LPSTR)ScrBuf[row]));
y -= CharHeight;
row = (--row < 0) ? (MAX_ROWS -1) : row;
}
}
/* Point to next row */
void IncRow()
{
int difference;
ScrBuf[LastRow][CurrentCol] = (char) 0; /* make a Z string */
if(logfile){
fputs(ScrBuf[LastRow], logfile); /* string */
fputc('\n', logfile); /* plus new line */
}
UpdateLine();
CurrentCol=0;
LastRow++;
LastRow = (LastRow >= MAX_ROWS) ? 0 : LastRow;
if(FirstRow == LastRow){
FirstRow ++;
FirstRow = (FirstRow >= MAX_ROWS) ? 0 : FirstRow;
}
WinRow++;
WinRow = (WinRow >= NumRows) ? (NumRows-1) : WinRow;
ScrBuf[LastRow][CurrentCol] = 0;
difference = CIRDIF(FirstRow, LastRow, MAX_ROWS);
if(NumRows <= difference)
RepaintScr();
}
/* Interpret and optionally add character to window buffer */
void AddChar(int c)
{
int i;
RECT rCell;
DWORD dwStrSpec;
switch(c){
case 9: /* Tab */
if((CurrentCol + TAB_SIZE) >= MAX_COLS)
DrawChar('\n');
for(i=0; i < TAB_SIZE; i++)
ScrBuf[LastRow][CurrentCol++] = ' ';
break;
case 10: /* Line feed */
IncRow();
break;
case 11: /* Vertical tab */
IncRow();
break;
case 12: /* Form feed (ignore) */
break;
case 13: /* enter key */
CurrentCol=0;
break;
case 8: /* Back Space */
rCell.left = 0; /* left side of window */
rCell.top = CharHeight * WinRow; /* Top of text */
/* Width of all characters */
dwStrSpec=GetTextExtent(ScrhDC, (LPSTR)ScrBuf[LastRow], CurrentCol);
rCell.right = LOWORD(dwStrSpec);
rCell.bottom = rCell.top + HIWORD(dwStrSpec);
/* Clear Cell */
FillRect(ScrhDC, (LPRECT) &rCell, hBrush);
/* Clear cell position */
CurrentCol = (--CurrentCol <= 0) ? 0 : CurrentCol;
/* repaint text minus character */
TextOut(ScrhDC, 0, CharHeight * WinRow, (LPSTR) ScrBuf[LastRow], CurrentCol);
/* cap off ScrBuf to be an 'Z' string */
ScrBuf[LastRow][CurrentCol] = (char) 0;
break;
default: /* just draw characters */
ScrBuf[LastRow][CurrentCol++] = (char) c;
ScrBuf[LastRow][CurrentCol] = (char) 0;
break;
}
}
/* Draw character on window */
DrawChar(int c)
{
AddChar(c);
UpdateLine();
}
/* Draw string on window */
void DrawBuffer(LPSTR szString, int num)
{
int i;
for(i=0; i < num && szString[i] != 0; i++)
AddChar(szString[i]);
UpdateLine();
}
/* Clear screen */
void ClearScr()
{
if(ScrhDC = GetDC(hMainWnd)){
FirstRow=LastRow=0; /* zero circular buffer */
CurrentCol=0; /* Set pos to zero */
ScrBuf[LastRow][CurrentCol]=0; /* Kill string */
RepaintScr();
ReleaseDC(hMainWnd, ScrhDC);
}
}
/* Winproc for stdio */
long FAR PASCAL WndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
PAINTSTRUCT ps;
int i;
HMENU hMenu;
char Buffer[BUFFER_SIZE];
switch (message) {
case WM_COMMAND:
switch(wParam){
case IDM_ABOUT: /* Show about box */
PopupDLG(hWnd, "AboutBox", About);
break;
case IDM_SAVE: /* Save data */
logfile=fopen(szFname, "w");
if(logfile){
hMenu=GetMenu(hWnd);
EnableMenuItem(hMenu, IDM_CLOSE, MF_ENABLED);
EnableMenuItem(hMenu, IDM_SAVE, MF_GRAYED);
}
break;
case IDM_CLEAR: /* Clear "screen" */
ClearScr();
break;
case IDM_CLOSE: /* Close log file */
if(!fclose(logfile)){
hMenu=GetMenu(hWnd);
EnableMenuItem(hMenu, IDM_CLOSE, MF_GRAYED);
EnableMenuItem(hMenu, IDM_SAVE, MF_ENABLED);
}
break;
case IDM_DEFAULT: /* Set default position in win.ini */
{
RECT rect;
char buffer[25];
GetWindowRect(hWnd, &rect); /* get size */
wsprintf((LPSTR)buffer,
(LPSTR)"%d,%d,%d,%d", rect.left, rect.top, rect.right, rect.bottom);
WriteProfileString((LPSTR)szAppName, (LPSTR)szPosition, (LPSTR)buffer);
}
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
break;
case WM_USER:
if(wParam == 11){
ScrhDC = GetDC(hWnd);
#ifdef BY_THE_BOOK
i = Pgets((LPSTR) Buffer, LOWORD(lParam), Stdout);
DrawBuffer(Buffer, i);
#else
while((i=QueryPipe(Stdout))){
i = Pgets((LPSTR) Buffer, LOWORD(lParam), Stdout);
DrawBuffer(Buffer, i);
}
#endif
/*
* This is done to fix a phasing error. If testapp is started before
* stdio, stdio will be a number of read messages behind. So - I have
* Changed the code to empty the pipe after a read message. Your code
* Should either do this also or assure correct phasing of read and
* write messages.
*/
ReleaseDC(hWnd, ScrhDC);
}
break;
case WM_CHAR:
if(wParam == 13)
Pputc(10, Stdin);
else
Pputc((char) wParam, Stdin);
break;
case WM_DESTROY:
ReleasePipe(Stdin);
ReleasePipe(Stdout);
PostQuitMessage(0);
break;
case WM_CREATE:
{
TEXTMETRIC tm;
if(OpenPipe(hWnd, (LPSTR) "Stdout", PIPE_READ, 11) < 0)
PostQuitMessage(0);
logfile=NULL;
hBrush = GetStockObject(WHITE_BRUSH);
LastRow=0;
CurrentCol=0;
ScrhDC = GetDC(hWnd);
GetTextMetrics(ScrhDC, (LPTEXTMETRIC) &tm);
CharHeight = tm.tmHeight;
CharWidth = tm.tmWeight;
ReleaseDC(hWnd, ScrhDC);
GetClientRect(hWnd, &rect);
NumRows = (rect.bottom - rect.top) / CharHeight;
}
break;
case WM_PAINT:
ScrhDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
NumRows = (rect.bottom - rect.top) /CharHeight;
RepaintScr();
EndPaint(hWnd, &ps);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (NULL);
}
/* routine to create window sized by parameters in win.ini */
HWND SetWindow()
{
char Buffer[25];
char *szString;
int i;
int startx, starty, sizex, sizey;
szString=Buffer;
GetProfileString((LPSTR)szAppName, (LPSTR)szPosition, (LPSTR)szError,
(LPSTR)szString, 25);
if(lstrcmpi((LPSTR)szError, (LPSTR)szString)){ /* if default set */
while(*szString && !isdigit(*szString))
szString++;
startx=atoi(szString);
while(*szString && isdigit(*szString))
szString++; /* skip start x number */
while(*szString && !isdigit(*szString))
szString++; /* Skip non numbers */
starty=atoi(szString);
while(*szString && isdigit(*szString))
szString++; /* skip start y number */
while(*szString && !isdigit(*szString))
szString++; /* skip non numbers */
sizex=atoi(szString);
while(*szString && isdigit(*szString))
szString++; /* skip start y number */
while(*szString && !isdigit(*szString))
szString++; /* skip non numbers */
sizey=atoi(szString);
sizex = sizex - startx; /* Get size, not coords. */
sizey = sizey - starty;
}
else{
startx = 0;
sizex = GetSystemMetrics(SM_CXSCREEN); /* All across the bottom */
i=GetSystemMetrics(SM_CYSCREEN); /* Get Height of screen */
starty = i - (i * .3); /* 1/4 of the screen */
sizey = i - starty;
}
return(CreateWindow (szAppName,"Stdio Window", WS_OVERLAPPEDWINDOW,
startx, starty, sizex, sizey, NULL, NULL, hInstance, NULL));
}
/* Winmain routine for stdio */
int PASCAL WinMain(hInst, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE hInst;
HANDLE hPrevInstance;
LPSTR lpszCmdLine;
int nCmdShow;
{
MSG msg;
BOOL bStat;
hInstance = hInst;
if(!hPrevInstance){
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(hInst,"StdioIcon");
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = szAppName;
wc.lpszClassName = szAppName;
if(!RegisterClass(&wc))
return(FALSE);
}
hMainWnd = SetWindow();
ShowWindow(hMainWnd, nCmdShow);
UpdateWindow(hMainWnd);
while(GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return(msg.wParam);
}