home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
-
- 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);
-
- }
-