home *** CD-ROM | disk | FTP | other *** search
/ Windows Shareware GOLD / NuclearComputingVol3No1.cdr / other / f1490 / stdio.c < prev    next >
C/C++ Source or Header  |  1990-12-29  |  14KB  |  537 lines

  1. /*****************************************************************************
  2.  
  3.     Stdio.c
  4.  
  5.     Main Program file.
  6.  
  7.     This file contains all the code to provide basic text communication
  8.     for another windows application.
  9.  
  10.     This programs operation is described in winpipe.wri.
  11.  
  12.  
  13. *****************************************************************************/
  14.  
  15. #include <windows.h>
  16. #include <stdio.h>
  17. #include "winpipe.h"
  18. #include "Stdio.h"
  19.  
  20.  
  21. /*  circular difference , First, Last, Count    */
  22.  
  23. #define CIRDIF(F, L, C) (L >= F) ? (L - F): (C - (F - L))
  24.  
  25. #define MAX_ROWS     50         /*  upto 50 rows of text on window  */
  26. #define MAX_COLS     100        /*  up to 100 characters per row    */
  27. #define TAB_SIZE      8         /*  Tab expansion size              */
  28. #define BUFFER_SIZE 2048        /*  Buffer size, same as default pipe size  */
  29.  
  30. FILE *logfile;                  /*  "redirection" file              */
  31.  
  32. char ScrBuf[MAX_ROWS][MAX_COLS];/*  screen buffer                   */
  33.  
  34. char szFname[]="\\stdio.log";   /*  default Log file name               */
  35. char *szAppName = "stdio";      /*  Application name                    */
  36. char *szPosition = "Pos";       /*  Position entry in win.ini           */
  37. char *szError = "Error";        /*  String for error                    */
  38.  
  39. static int  FirstRow=0;     /*  first entry into circular buffer    */
  40. static int  LastRow=0;        /*  last entry into circular buffer    */
  41.  
  42. static int CurrentCol=0;    /*  Current row being worked on        */
  43. static int WinRow=0;        /*  reletive Windows row        */
  44.  
  45. static int NumRows;        /*  Number of rows avaialable        */
  46. static int CharHeight;        /*  height of a character        */
  47. static int CharWidth;           /*  average Width of a character        */
  48.  
  49.  
  50. RECT    rect;                   /*  Window rectangle                    */
  51. HANDLE  hBrush;                 /*  Generic brush to paint window with  */
  52.  
  53. HANDLE  hInstance;              /*  This programs instance              */
  54. HANDLE    hMainWnd;               /*  This programs window                */
  55. static HDC ScrhDC;              /*  internal copy of device context     */
  56.  
  57. /*  Quick'n easy dialog routine */
  58.  
  59. BOOL PopupDLG( hParentWnd, lpszTemplate, lpfnDlgProc )
  60. HWND        hParentWnd;
  61. LPSTR       lpszTemplate;
  62. FARPROC     lpfnDlgProc;
  63. {
  64.     BOOL           bResult;
  65.     FARPROC        lpProc;
  66.     HANDLE         hParentInst;
  67.  
  68.     hParentInst = GetWindowWord(hParentWnd,GWW_HINSTANCE);
  69.  
  70.     lpProc = MakeProcInstance( lpfnDlgProc, hParentInst);
  71.  
  72.     bResult = DialogBox( hParentInst, lpszTemplate, hParentWnd, lpProc );
  73.  
  74.     FreeProcInstance( lpProc );
  75.  
  76.     return( bResult );
  77.  
  78. }
  79.  
  80. /*  Aboutbox proc   */
  81.  
  82. BOOL FAR PASCAL About(hDlg, message, wParam, lParam)    /*  About box   */
  83. HWND hDlg;
  84. unsigned message;
  85. WORD wParam;
  86. LONG lParam;
  87. {
  88.     switch (message) {
  89.         case WM_INITDIALOG:
  90.       return (TRUE);
  91.  
  92.         case WM_COMMAND:
  93.             switch(wParam){
  94.                 case IDOK:
  95.                     EndDialog(hDlg, TRUE);
  96.                     break;
  97.  
  98.                 case IDCANCEL:
  99.                     EndDialog(hDlg, TRUE);
  100.                     break;
  101.  
  102.                 default:
  103.                     break;
  104.  
  105.             }
  106.  
  107.     }
  108.     return (FALSE);
  109. }
  110.  
  111.  
  112.  
  113.       /*  Draw single line    */
  114.  
  115. UpdateLine()
  116. {
  117.     TextOut(ScrhDC, 0, CharHeight * WinRow, (LPSTR) ScrBuf[LastRow], CurrentCol);
  118. }
  119.  
  120.  
  121.      /*  Redraw whole window */
  122.  
  123. void RepaintScr()
  124. {
  125.     int i, y, numrows;
  126.     int len = CurrentCol;
  127.     int row = LastRow;
  128.  
  129.     numrows = CIRDIF(FirstRow, LastRow, MAX_ROWS);  /* number of displayable lines */
  130.  
  131.     WinRow = (NumRows <= numrows) ? (NumRows-1) : numrows; /* starting row     */
  132.  
  133.     y = WinRow * CharHeight;                        /*  Last line in window     */
  134.  
  135.     FillRect(ScrhDC, (LPRECT) &rect, hBrush);       /*  Clear window            */
  136.  
  137.     for(i=WinRow; i >= 0; i--){                /* count down to last displayable    */
  138.     TextOut(ScrhDC, 0, y, (LPSTR)ScrBuf[row], lstrlen((LPSTR)ScrBuf[row]));
  139.     y -= CharHeight;
  140.     row = (--row < 0) ? (MAX_ROWS -1) : row;
  141.  
  142.     }
  143.  
  144. }
  145.  
  146.  
  147.       /*  Point to next row   */
  148.  
  149. void IncRow()
  150. {
  151.     int difference;
  152.  
  153.     ScrBuf[LastRow][CurrentCol] = (char) 0;    /* make a Z string  */
  154.  
  155.     if(logfile){
  156.         fputs(ScrBuf[LastRow], logfile);        /*  string          */
  157.         fputc('\n', logfile);                   /*  plus new line   */
  158.     }
  159.  
  160.     UpdateLine();
  161.  
  162.     CurrentCol=0;
  163.  
  164.     LastRow++;
  165.     LastRow = (LastRow >= MAX_ROWS) ? 0 : LastRow;
  166.  
  167.     if(FirstRow == LastRow){
  168.     FirstRow ++;
  169.     FirstRow = (FirstRow >= MAX_ROWS) ? 0 : FirstRow;
  170.     }
  171.  
  172.     WinRow++;
  173.     WinRow = (WinRow >= NumRows) ? (NumRows-1) : WinRow;
  174.  
  175.     ScrBuf[LastRow][CurrentCol] = 0;
  176.     difference = CIRDIF(FirstRow, LastRow, MAX_ROWS);
  177.  
  178.     if(NumRows <= difference)
  179.     RepaintScr();
  180. }
  181.  
  182.     /*  Interpret and optionally add character to window buffer */
  183.  
  184. void AddChar(int c)
  185. {
  186. int     i;
  187. RECT    rCell;
  188. DWORD   dwStrSpec;
  189.  
  190.     switch(c){
  191.  
  192.     case    9:              /*  Tab                 */
  193.             if((CurrentCol + TAB_SIZE) >= MAX_COLS)
  194.                 DrawChar('\n');
  195.  
  196.         for(i=0; i < TAB_SIZE; i++)
  197.             ScrBuf[LastRow][CurrentCol++] = ' ';
  198.         break;
  199.  
  200.     case    10:             /*  Line feed           */
  201.         IncRow();
  202.         break;
  203.  
  204.     case    11:             /*  Vertical tab        */
  205.         IncRow();
  206.         break;
  207.  
  208.     case    12:             /* Form feed (ignore)   */
  209.         break;
  210.  
  211.     case    13:             /* enter key            */
  212.         CurrentCol=0;
  213.         break;
  214.  
  215.         case    8:              /*  Back Space          */
  216.             rCell.left = 0;                             /*  left side of window     */
  217.             rCell.top  = CharHeight * WinRow;           /*  Top of text             */
  218.  
  219.             /*  Width of all characters */
  220.             dwStrSpec=GetTextExtent(ScrhDC, (LPSTR)ScrBuf[LastRow], CurrentCol);
  221.             rCell.right = LOWORD(dwStrSpec);
  222.             rCell.bottom = rCell.top + HIWORD(dwStrSpec);
  223.  
  224.             /*  Clear Cell  */
  225.             FillRect(ScrhDC, (LPRECT) &rCell, hBrush);
  226.  
  227.             /*  Clear cell position  */
  228.             CurrentCol = (--CurrentCol <= 0) ? 0 : CurrentCol;
  229.  
  230.             /*  repaint text minus character    */
  231.         TextOut(ScrhDC, 0, CharHeight * WinRow, (LPSTR) ScrBuf[LastRow], CurrentCol);
  232.  
  233.             /*  cap off ScrBuf to be an 'Z' string  */
  234.         ScrBuf[LastRow][CurrentCol] = (char) 0;
  235.             break;
  236.  
  237.     default:    /*  just draw characters  */
  238.  
  239.         ScrBuf[LastRow][CurrentCol++] = (char) c;
  240.             ScrBuf[LastRow][CurrentCol] = (char) 0;
  241.             break;
  242.     }
  243.  
  244.  
  245. }
  246.  
  247.      /*  Draw character on window    */
  248.  
  249. DrawChar(int c)
  250. {
  251.     AddChar(c);
  252.     UpdateLine();
  253. }
  254.  
  255.  
  256.     /*  Draw string on window   */
  257.  
  258. void DrawBuffer(LPSTR szString, int num)
  259. {
  260.     int i;
  261.     for(i=0; i < num && szString[i] != 0; i++)
  262.     AddChar(szString[i]);
  263.  
  264.     UpdateLine();
  265. }
  266.  
  267.     /*  Clear screen    */
  268.  
  269. void ClearScr()
  270. {
  271.     if(ScrhDC = GetDC(hMainWnd)){
  272.         FirstRow=LastRow=0;                     /*  zero circular buffer    */
  273.         CurrentCol=0;                           /*  Set pos to zero         */
  274.         ScrBuf[LastRow][CurrentCol]=0;          /*  Kill string             */
  275.         RepaintScr();
  276.         ReleaseDC(hMainWnd, ScrhDC);
  277.  
  278.     }
  279.  
  280. }
  281.  
  282. /*  Winproc for stdio */
  283.  
  284. long FAR PASCAL WndProc(hWnd, message, wParam, lParam)
  285. HWND hWnd;
  286. unsigned message;
  287. WORD wParam;
  288. LONG lParam;
  289. {
  290. PAINTSTRUCT       ps;
  291. int           i;
  292. HMENU           hMenu;
  293. char           Buffer[BUFFER_SIZE];
  294.  
  295.  
  296.     switch (message) {
  297.         case WM_COMMAND:
  298.             switch(wParam){
  299.         case    IDM_ABOUT:      /*  Show about box  */
  300.             PopupDLG(hWnd, "AboutBox", About);
  301.             break;
  302.  
  303.         case    IDM_SAVE:       /*  Save data       */
  304.             logfile=fopen(szFname, "w");
  305.  
  306.             if(logfile){
  307.                 hMenu=GetMenu(hWnd);
  308.             EnableMenuItem(hMenu, IDM_CLOSE, MF_ENABLED);
  309.             EnableMenuItem(hMenu, IDM_SAVE, MF_GRAYED);
  310.                     }
  311.  
  312.             break;
  313.  
  314.         case    IDM_CLEAR:      /*  Clear "screen"  */
  315.                     ClearScr();
  316.             break;
  317.  
  318.         case    IDM_CLOSE:      /*  Close log file  */
  319.             if(!fclose(logfile)){
  320.             hMenu=GetMenu(hWnd);
  321.             EnableMenuItem(hMenu, IDM_CLOSE, MF_GRAYED);
  322.             EnableMenuItem(hMenu, IDM_SAVE, MF_ENABLED);
  323.             }
  324.             break;
  325.  
  326.                 case    IDM_DEFAULT:    /*  Set default position in win.ini */
  327.                     {
  328.                         RECT    rect;
  329.                         char buffer[25];
  330.                         GetWindowRect(hWnd, &rect); /*  get size    */
  331.                         wsprintf((LPSTR)buffer,
  332.                         (LPSTR)"%d,%d,%d,%d", rect.left, rect.top, rect.right, rect.bottom);
  333.                         WriteProfileString((LPSTR)szAppName, (LPSTR)szPosition, (LPSTR)buffer);
  334.                     }
  335.                     break;
  336.  
  337.  
  338.                 default:
  339.                     return (DefWindowProc(hWnd, message, wParam, lParam));
  340.             }
  341.         break;
  342.  
  343.     case    WM_USER:
  344.         if(wParam == 11){
  345.                 ScrhDC = GetDC(hWnd);
  346.  
  347. #ifdef BY_THE_BOOK
  348.                 i = Pgets((LPSTR) Buffer, LOWORD(lParam), Stdout);
  349.                 DrawBuffer(Buffer, i);
  350. #else
  351.                 while((i=QueryPipe(Stdout))){
  352.                     i = Pgets((LPSTR) Buffer, LOWORD(lParam), Stdout);
  353.                     DrawBuffer(Buffer, i);
  354.                 }
  355. #endif
  356.  
  357. /*
  358.  *  This is done to fix a phasing error. If testapp is started before
  359.  *  stdio, stdio will be a number of read messages behind. So - I have
  360.  *  Changed the code to empty the pipe after a read message. Your code
  361.  *  Should either do this also or assure correct phasing of read and
  362.  *  write messages.
  363.  */
  364.  
  365.             ReleaseDC(hWnd, ScrhDC);
  366.         }
  367.         break;
  368.  
  369.     case    WM_CHAR:
  370.         if(wParam == 13)
  371.         Pputc(10, Stdin);
  372.         else
  373.         Pputc((char) wParam, Stdin);
  374.         break;
  375.  
  376.     case WM_DESTROY:
  377.         ReleasePipe(Stdin);
  378.         ReleasePipe(Stdout);
  379.         PostQuitMessage(0);
  380.         break;
  381.  
  382.  
  383.     case    WM_CREATE:
  384.         {
  385.         TEXTMETRIC    tm;
  386.  
  387.         if(OpenPipe(hWnd, (LPSTR) "Stdout", PIPE_READ, 11) < 0)
  388.         PostQuitMessage(0);
  389.  
  390.         logfile=NULL;
  391.         hBrush = GetStockObject(WHITE_BRUSH);
  392.         LastRow=0;
  393.         CurrentCol=0;
  394.         ScrhDC = GetDC(hWnd);
  395.         GetTextMetrics(ScrhDC, (LPTEXTMETRIC) &tm);
  396.         CharHeight = tm.tmHeight;
  397.             CharWidth = tm.tmWeight;
  398.         ReleaseDC(hWnd, ScrhDC);
  399.         GetClientRect(hWnd, &rect);
  400.         NumRows = (rect.bottom - rect.top) / CharHeight;
  401.         }
  402.         break;
  403.  
  404.     case    WM_PAINT:
  405.         ScrhDC = BeginPaint(hWnd, &ps);
  406.         GetClientRect(hWnd, &rect);
  407.         NumRows = (rect.bottom - rect.top) /CharHeight;
  408.         RepaintScr();
  409.         EndPaint(hWnd, &ps);
  410.         break;
  411.  
  412.  
  413.         default:
  414.         return (DefWindowProc(hWnd, message, wParam, lParam));
  415.     }
  416.     return (NULL);
  417.  
  418. }
  419.  
  420.  
  421.     /*  routine to create window sized by parameters in win.ini */
  422.  
  423.  
  424. HWND SetWindow()
  425. {
  426.     char Buffer[25];
  427.     char *szString;
  428.     int i;
  429.     int startx, starty, sizex, sizey;
  430.  
  431.     szString=Buffer;
  432.  
  433.     GetProfileString((LPSTR)szAppName, (LPSTR)szPosition, (LPSTR)szError,
  434.         (LPSTR)szString, 25);
  435.  
  436.     if(lstrcmpi((LPSTR)szError, (LPSTR)szString)){    /* if default set  */
  437.         while(*szString && !isdigit(*szString))
  438.             szString++;
  439.  
  440.         startx=atoi(szString);
  441.  
  442.         while(*szString && isdigit(*szString))
  443.             szString++;     /* skip start x number  */
  444.  
  445.         while(*szString && !isdigit(*szString))
  446.             szString++;     /*  Skip non numbers    */
  447.  
  448.         starty=atoi(szString);
  449.  
  450.         while(*szString && isdigit(*szString))
  451.             szString++;  /* skip start y number  */
  452.  
  453.         while(*szString && !isdigit(*szString))
  454.             szString++; /*  skip non numbers    */
  455.  
  456.         sizex=atoi(szString);
  457.  
  458.         while(*szString && isdigit(*szString))
  459.             szString++;  /* skip start y number  */
  460.  
  461.         while(*szString && !isdigit(*szString))
  462.             szString++; /*  skip non numbers    */
  463.  
  464.         sizey=atoi(szString);
  465.  
  466.         sizex = sizex - startx; /*  Get size, not coords.   */
  467.         sizey = sizey - starty;
  468.  
  469.  
  470.     }
  471.     else{
  472.  
  473.         startx = 0;
  474.         sizex  = GetSystemMetrics(SM_CXSCREEN); /*  All across the bottom   */
  475.  
  476.         i=GetSystemMetrics(SM_CYSCREEN);        /*  Get Height of screen    */
  477.         starty = i - (i * .3);                  /*  1/4 of the screen       */
  478.         sizey = i - starty;
  479.  
  480.     }
  481.  
  482.     return(CreateWindow (szAppName,"Stdio Window", WS_OVERLAPPEDWINDOW,
  483.         startx, starty, sizex, sizey, NULL, NULL, hInstance, NULL));
  484.  
  485.  
  486.  
  487. }
  488.  
  489.  
  490.  
  491.     /*  Winmain routine for stdio   */
  492.  
  493. int PASCAL WinMain(hInst, hPrevInstance, lpszCmdLine, nCmdShow)
  494.     HANDLE  hInst;
  495.     HANDLE  hPrevInstance;
  496.     LPSTR   lpszCmdLine;
  497.     int     nCmdShow;
  498.     {
  499.         MSG         msg;
  500.         BOOL        bStat;
  501.  
  502.         hInstance = hInst;
  503.  
  504.         if(!hPrevInstance){
  505.             WNDCLASS    wc;
  506.             wc.style            =   CS_HREDRAW | CS_VREDRAW;
  507.             wc.lpfnWndProc      =   WndProc;
  508.             wc.cbClsExtra       =   0;
  509.             wc.cbWndExtra       =   0;
  510.             wc.hInstance        =   hInst;
  511.         wc.hIcon        =   LoadIcon(hInst,"StdioIcon");
  512.             wc.hCursor          =   LoadCursor (NULL, IDC_ARROW);
  513.             wc.hbrBackground    =   GetStockObject(WHITE_BRUSH);
  514.         wc.lpszMenuName    =   szAppName;
  515.         wc.lpszClassName    =   szAppName;
  516.  
  517.             if(!RegisterClass(&wc))
  518.                 return(FALSE);
  519.  
  520.             }
  521.  
  522.  
  523.     hMainWnd = SetWindow();
  524.  
  525.     ShowWindow(hMainWnd, nCmdShow);
  526.     UpdateWindow(hMainWnd);
  527.  
  528.  
  529.     while(GetMessage(&msg, NULL, 0, 0)){
  530.     TranslateMessage(&msg);
  531.         DispatchMessage(&msg);
  532.         }
  533.  
  534.     return(msg.wParam);
  535.  
  536. }
  537.