home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / ircd4652.zip / ircd-df-4.6.5-os2 / src / cio_main.c < prev    next >
C/C++ Source or Header  |  1997-12-28  |  17KB  |  836 lines

  1. #include <windows.h>
  2. #include <memory.h>
  3. #include <stdio.h>
  4. #include <crtdbg.h>
  5. #include "Cio.h"
  6. #include "CioFunc.h"
  7.  
  8.  
  9. CioLine    *CioMakeLine(CioLine *Prev, CioLine *Next)
  10. {
  11.     CioLine    *Line;
  12.  
  13.     Line = LocalAlloc(LPTR, sizeof(CioLine));
  14.     _ASSERT(Line);
  15.     if ( Prev )
  16.         {
  17.         Prev->Next = Line;
  18.         Line->Prev = Prev;
  19.         }
  20.     if ( Next )
  21.         {
  22.         Next->Prev = Line;
  23.         Line->Next = Next;
  24.         }
  25.  
  26.     return Line;
  27. }
  28.  
  29.  
  30. void    CioRemoveLine(CioWndInfo *CWI, CioLine *Line)
  31. {
  32.     if ( Line->Next )
  33.         Line->Next->Prev = Line->Prev;
  34.     if ( Line->Prev )
  35.         Line->Prev->Next = Line->Next;
  36.     else
  37.         CWI->FirstLine = Line->Next;
  38.  
  39.     if ( Line->Data )
  40.         LocalFree(Line->Data);
  41.     LocalFree(Line);
  42. }
  43.  
  44.  
  45.  
  46. //
  47. //   FUNCTION: Cio_Create(HANDLE, HWND, DWORD, int, int, int, int)
  48. //
  49. //   PURPOSE: Creates main CIO window
  50. //
  51. HWND Cio_Create(HINSTANCE hInstance, HWND hParent, DWORD Style, int X, int Y, int W, int H)
  52. {
  53.     HWND    hWnd;
  54.  
  55.     if ( hParent == NULL )
  56.         return NULL;
  57.  
  58.     hWnd = CreateWindow(CIOCLASS, NULL, WS_CHILD | WS_VSCROLL | Style,
  59.         X, Y, W, H, hParent, NULL, hInstance, NULL);
  60.  
  61.     return hWnd;
  62. }
  63.  
  64.  
  65. //
  66. //  FUNCTION: Cio_WndProc(HWND, unsigned, WORD, LONG)
  67. //
  68. //  PURPOSE:  Processes messages for a CIO window.
  69. //
  70. LRESULT CALLBACK Cio_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  71. {
  72.     DWORD    Style;
  73.  
  74.     switch (message)
  75.         {
  76.         case WM_CREATE:
  77.             return Cio_WndCreate(hWnd);
  78.  
  79.         case WM_RBUTTONDOWN: // RightClick in windows client area...
  80.             return 0;
  81.  
  82.         case WM_PAINT:
  83.             return Cio_WndPaint(hWnd);
  84.  
  85.         case WM_SIZE:
  86.             Style = GetWindowLong(GetParent(hWnd), GWL_STYLE);
  87.             if ( Style & WS_MINIMIZE )
  88.                 return 0;
  89.             return Cio_WndSize(hWnd, lParam);
  90.  
  91.         case WM_VSCROLL:
  92.             return Cio_WndScroll(hWnd, wParam);
  93.  
  94.         case WM_DESTROY:
  95.             return Cio_WndDestroy(hWnd);
  96.  
  97.         case WM_SETFONT:
  98.             return Cio_SetFont(hWnd, wParam);
  99.  
  100.         case CIO_ADDSTRING:
  101.             return Cio_WndAddString(hWnd, wParam, (char *)lParam);
  102.  
  103.         default:
  104.             return (DefWindowProc(hWnd, message, wParam, lParam));
  105.         }
  106.     return (0);
  107. }
  108.  
  109.  
  110. BOOL Cio_WndCreate(HWND hWnd)
  111. {
  112.     CioWndInfo    *CWI;
  113.     LOGFONT        lfFont;
  114.     TEXTMETRIC    tm;
  115.     HDC    hdc;
  116.  
  117.     CWI = LocalAlloc(LPTR, sizeof(CioWndInfo));
  118.     _ASSERT(CWI);
  119.     lfFont.lfHeight =         12;
  120.     lfFont.lfWidth =          0;
  121.     lfFont.lfEscapement =     0;
  122.     lfFont.lfOrientation =    0;
  123.     lfFont.lfWeight =         400;
  124.     lfFont.lfItalic =         0;
  125.     lfFont.lfUnderline =      0;
  126.     lfFont.lfStrikeOut =      0;
  127.     lfFont.lfCharSet =        ANSI_CHARSET;
  128.     lfFont.lfOutPrecision =   OUT_STRING_PRECIS;
  129.     lfFont.lfClipPrecision =  CLIP_STROKE_PRECIS;
  130.     lfFont.lfQuality =        DRAFT_QUALITY;
  131.     lfFont.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
  132.     wsprintf(lfFont.lfFaceName, "FixedSys");
  133.  
  134.     CWI->hFont = CreateFontIndirect(&lfFont);
  135.  
  136.     hdc = GetDC(hWnd);
  137.     SelectObject(hdc, CWI->hFont);
  138.     GetTextMetrics(hdc, &tm);
  139.     ReleaseDC(hWnd, hdc);
  140.  
  141.     CWI->XChar = tm.tmAveCharWidth;
  142.     CWI->YChar = tm.tmHeight + tm.tmExternalLeading;
  143.  
  144.     CWI->FirstLine = CWI->CurLine = CioMakeLine(NULL, NULL);
  145.     CWI->Lines=0;
  146.  
  147.     SetWindowLong(hWnd, GWL_USER, (DWORD)CWI);
  148.  
  149.     return 0;
  150. }
  151.  
  152.  
  153. BOOL Cio_WndPaint(HWND hWnd)
  154. {
  155.     PAINTSTRUCT    ps;
  156.     CioWndInfo    *CWI;
  157.     HDC    hdc;
  158.     HFONT    hOldFont;
  159.     CioLine    *Line;
  160.     RECT    rect;
  161.     int    nCol, nEndCol, nMaxCol, nRow, nEndRow, nBegCol, nCount, i=0;
  162.     int    nVertPos, nHorzPos, nOff, nBegOff, NewColorAt=0;
  163.     BYTE    Red, Green, Blue, NewColor=0, UnderLine=0;
  164.     HPEN    hpen;
  165.  
  166.  
  167.     CWI = (CioWndInfo *)GetWindowLong(hWnd, GWL_USER);
  168.     hdc = BeginPaint(hWnd, &ps);
  169.  
  170.     hOldFont = SelectObject(hdc, CWI->hFont);
  171.     rect = ps.rcPaint;
  172.     nCol    = max(0, rect.left / CWI->XChar);
  173.     nEndCol = rect.right / CWI->XChar;
  174.     nEndCol = min(CWI->Width, nEndCol+1);
  175.     nEndRow = max(0, rect.top / CWI->YChar);
  176.     nRow    = rect.bottom / CWI->YChar;
  177.     nRow    = min(CWI->Height, nRow+1);
  178.  
  179.     nBegOff = nCol;
  180.     nBegCol = nCol;
  181.  
  182.     /*
  183.      * Find the first line to use, and work up from there.
  184.      */
  185.     Line = CWI->FirstLine;
  186.     while ( Line && i < CWI->Scroll )
  187.         {
  188.         if ( Line->Data )
  189.             i++;
  190.         Line = Line->Next;
  191.         }
  192.     i = 0;
  193.     while ( Line && i < (CWI->Height-nRow) )
  194.         {
  195.         if ( Line->Data )
  196.             i++;
  197.         Line = Line->Next;
  198.         }    
  199.  
  200.     for ( ; nRow >= nEndRow; nRow-- )
  201.         {
  202.         UnderLine=0;
  203.         while ( Line && !Line->Data )
  204.             Line = Line->Next;
  205.         if ( !Line )
  206.             continue;
  207.  
  208.         nMaxCol = Line->Len;
  209.         nOff = nBegOff;
  210.         nCol = 0;
  211.         nCount = 0;
  212.         for ( i = 0; i < Line->Len; i++ )
  213.             {
  214.             if ( Line->Data[i] == 0 )
  215.                 {
  216.                 Red   = Line->Data[i+1];
  217.                 Green = Line->Data[i+2];
  218.                 Blue  = Line->Data[i+3];
  219.                 SetTextColor(hdc, RGB(Red, Green, Blue));
  220.                 SetBkColor(hdc, RGB(255, 255, 255));
  221.                 i += 3;
  222.                 nCol += 4;
  223.                 continue;
  224.                 }
  225.             if ( nCount >= nBegCol )
  226.                 break;
  227.             nCol++;
  228.             nCount++;
  229.             }
  230.         if ( i >= Line->Len )
  231.             continue;
  232.  
  233.         for ( ; nCol <= nMaxCol; nCol++ )
  234.             {
  235.             nCount = nMaxCol-nCol;
  236.             for ( i = 0; i < (nMaxCol-nCol); i++ )
  237.                 {
  238.                 if ( Line->Data[nCol+i] == 0x1F )
  239.                     {
  240.                     nCount = i;
  241.                     if ( UnderLine == 0 )
  242.                         {
  243.                         UnderLine = 1;
  244.                         break;
  245.                         }
  246.                     if ( UnderLine == 1 )
  247.                         {
  248.                         UnderLine = 2;
  249.                         break;
  250.                         }
  251.                     break;
  252.                     }
  253.                 if ( Line->Data[nCol+i] == 0x0F )
  254.                     {
  255.                     nCount = i;
  256.                     UnderLine = 0;
  257.                     break;
  258.                     }
  259.                 if ( Line->Data[nCol+i] == 0 )
  260.                     {
  261.                     NewColor = 1;
  262.                     NewColorAt = nCol+i;
  263.                     nCount = i;
  264.                     i += 3;
  265.                     break;
  266.                     }
  267.                 }
  268.  
  269.             if ( nCount )
  270.                 {
  271.                 nVertPos = nRow * CWI->YChar - CWI->YChar +
  272.                     CWI->YJunk;
  273.                 nHorzPos = nOff * CWI->XChar;
  274.                 rect.top    = nVertPos;
  275.                 rect.bottom = nVertPos + CWI->YChar;
  276.                 rect.left   = nHorzPos;
  277.                 rect.right  = nHorzPos + (CWI->XChar*nCount);
  278.                 SetBkMode(hdc, OPAQUE);
  279.  
  280.                 ExtTextOut(hdc, nHorzPos, nVertPos, ETO_OPAQUE,
  281.                     &rect, (LPSTR) Line->Data+nCol,
  282.                     nCount, NULL);
  283.                 nOff += nCount;
  284.  
  285.                 if ( UnderLine == 2 )
  286.                     {
  287.                     hpen = CreatePen(PS_SOLID, 0,
  288.                         RGB(Red, Green, Blue));
  289.                     SelectObject(hdc, hpen);
  290.                     MoveToEx(hdc, (int)rect.left,
  291.                         (int)rect.bottom-1,
  292.                         (LPPOINT)NULL);
  293.                     LineTo(hdc, (int)rect.right,
  294.                         (int)rect.bottom-1);
  295.                     DeleteObject(hpen);
  296.                     UnderLine = 0;
  297.                     }
  298.                 }
  299.             if ( UnderLine == 1 )
  300.                 UnderLine = 2;
  301.  
  302.             nCol += i;
  303.             if ( NewColor )
  304.                 {
  305.                 Red   = Line->Data[NewColorAt+1];
  306.                 Green = Line->Data[NewColorAt+2];
  307.                 Blue  = Line->Data[NewColorAt+3];
  308.                 SetTextColor(hdc, RGB(Red, Green, Blue));
  309.                 SetBkColor(hdc, RGB(255, 255, 255));
  310.                 NewColor = 0;
  311.                 }
  312.             }
  313.         Line = Line->Next;
  314.         }
  315.     
  316.     SelectObject(hdc, hOldFont);
  317.     EndPaint(hWnd, &ps);
  318.     return 0;
  319. }
  320.  
  321.  
  322. BOOL Cio_WndDestroy(HWND hWnd)
  323. {
  324.     CioWndInfo  *CWI;
  325.  
  326.     CWI = (CioWndInfo *)GetWindowLong(hWnd, GWL_USER);
  327.     while ( CWI->FirstLine )
  328.         CioRemoveLine(CWI, CWI->FirstLine);
  329.  
  330.     DeleteObject(CWI->hFont);
  331.     LocalFree(CWI);
  332.  
  333.     return 0;
  334. }
  335.  
  336.  
  337. int Cio_WndAddString(HWND hWnd, int Len, char *Buffer)
  338. {
  339.     CioWndInfo    *CWI;
  340.     CioLine    *Line;
  341.     int    TLen=0, DLen=0, Loop=0, LastSpace=0, Scrolled=0, Pad=0;
  342.     BYTE    Red=0, Grn=0, Blu=0;
  343.  
  344.  
  345.     CWI = (CioWndInfo *)GetWindowLong(hWnd, GWL_USER);
  346.  
  347.     if ( CWI->ScrollMe == TRUE )
  348.         {
  349.         Cio_Scroll(hWnd, CWI, 1);
  350.         Scrolled++;
  351.         CWI->ScrollMe = FALSE;
  352.         }
  353.     if ( Buffer[Len-1] == '\r' )
  354.         {
  355.         CWI->ScrollMe = TRUE;
  356.         Len-=1;
  357.         }
  358.  
  359.     while ( Len )
  360.         {
  361.         /*
  362.          * Check the current line to see if we have room to tack
  363.          * on our string to the end of.  If not, put as much as
  364.          * possible on, then scroll up a new line.
  365.          */
  366.         TLen=DLen=0;
  367.         Line = CWI->FirstLine;
  368.         while ( TLen < Line->Len )
  369.             {
  370.             if ( Line->Data[TLen] == 0 )
  371.                 {
  372.                 TLen+=4;
  373.                 continue;
  374.                 }
  375.             TLen+=1;
  376.             DLen+=1;
  377.             }
  378.         Loop=TLen=0;
  379.         while ( TLen < Len )
  380.             {
  381.             if ( Buffer[TLen] == 0 )
  382.                 {
  383.                 TLen+=4;
  384.                 continue;
  385.                 }
  386.             TLen+=1;
  387.             Loop+=1;
  388.             }
  389.         if ( DLen+Loop > CWI->Width )
  390.             {
  391.             Cio_Scroll(hWnd, CWI, 1);
  392.             Scrolled++;
  393.             Loop=TLen=0;
  394.             do
  395.                 {
  396.                 if ( Buffer[TLen] == 0 )
  397.                     {
  398.                     Red = Buffer[TLen+1];
  399.                     Grn = Buffer[TLen+2];
  400.                     Blu = Buffer[TLen+3];
  401.                     TLen+=4;
  402.                     continue;
  403.                     }            
  404.                 if ( TLen >= Len || DLen+Loop >= CWI->Width )
  405.                     break;
  406.                 if ( Buffer[TLen] == ' ' )
  407.                     LastSpace = TLen;
  408.                 TLen+=1;
  409.                 Loop+=1;
  410.                 } while ( TLen < Len && DLen+Loop < CWI->Width );
  411.  
  412.             if ( TLen != Len && Buffer[TLen] != ' ' &&
  413.                  LastSpace && (LastSpace-TLen) < 16 )
  414.                 TLen = LastSpace;
  415.  
  416.             if ( Line->Data != NULL )
  417.                 {
  418.                 Line->Data = LocalReAlloc(Line->Data,
  419.                     Line->Len+TLen+Pad, LMEM_MOVEABLE);
  420.                 _ASSERT(Line->Data);
  421.                 memset(Line->Data, ' ', Pad);
  422.                 memmove(Line->Data+Line->Len+Pad, Buffer, TLen);
  423.                 Line->Len += TLen + Pad;
  424.                 }
  425.             else
  426.                 {
  427.                 if ( Buffer[0] == 0 )
  428.                     {
  429.                     Line->Data = LocalAlloc(LPTR, TLen+Pad);
  430.                     _ASSERT(Line->Data);
  431.                     memset(Line->Data, ' ', Pad);
  432.                     memmove(Line->Data+Pad, Buffer, TLen);
  433.                     Line->Len = TLen + Pad;
  434.                     }
  435.                 else
  436.                     {
  437.                     Line->Data = LocalAlloc(LPTR, TLen+4+Pad);
  438.                     _ASSERT(Line->Data);
  439.                     memset(Line->Data+4, ' ', Pad);
  440.                     memmove(Line->Data+4+Pad, Buffer, TLen);
  441.                     Line->Len = TLen+4+Pad;
  442.                     Line->Data[0] = 0;
  443.                     Line->Data[1] = Red;
  444.                     Line->Data[2] = Grn;
  445.                     Line->Data[3] = Blu;
  446.                     }
  447.                 }
  448.  
  449.             if ( TLen == LastSpace )
  450.                 TLen++;
  451.             Pad = 3;
  452.             Len -= TLen;
  453.             memmove(Buffer, Buffer+TLen, Len);
  454.             if ( Buffer[0] == '\r' && Len == 1 )
  455.                 Len=0;
  456.             continue;
  457.             } /* if ( DLen+Loop > CWI->Width ) */
  458.  
  459.         Line = CWI->FirstLine;
  460.         if ( Line->Data != NULL )
  461.             {
  462.             Line->Data = LocalReAlloc(Line->Data, Line->Len+TLen+Pad,
  463.                 LMEM_MOVEABLE);
  464.             _ASSERT(Line->Data);
  465.             memset(Line->Data, ' ', Pad);
  466.             memmove(Line->Data+Line->Len+Pad, Buffer, Len);
  467.             Line->Len += Len + Pad;
  468.             }
  469.         else
  470.             {
  471.             if ( Buffer[0] == 0 )
  472.                 {
  473.                 Line->Data = LocalAlloc(LPTR, Len+Pad);
  474.                 _ASSERT(Line->Data);
  475.                 memset(Line->Data, ' ', Pad);
  476.                 memmove(Line->Data+Pad, Buffer, Len);
  477.                 Line->Len = Len + Pad;
  478.                 }
  479.             else
  480.                 {
  481.                 Line->Data = LocalAlloc(LPTR, Len+4+Pad);
  482.                 _ASSERT(Line->Data);
  483.                 memset(Line->Data+4, ' ', Pad);
  484.                 memmove(Line->Data+4+Pad, Buffer, Len);
  485.                 Line->Len = Len+4+Pad;
  486.                 Line->Data[0] = 0;
  487.                 Line->Data[1] = Red;
  488.                 Line->Data[2] = Grn;
  489.                 Line->Data[3] = Blu;
  490.                 }
  491.             }
  492.  
  493.         break;
  494.         } /* while (Len) */
  495.  
  496.     if ( !CWI->Scroll )
  497.         {
  498.         RECT    rc;
  499.  
  500.         rc.left = rc.top = 0;
  501.         rc.right = CWI->Width*CWI->XChar;
  502.         rc.bottom = CWI->Height*CWI->YChar+CWI->YJunk;
  503.         ScrollWindow(hWnd, 0, -(Scrolled*CWI->YChar), &rc, NULL);
  504.         rc.top = (CWI->Height-Scrolled)*CWI->YChar+CWI->YJunk;
  505.         if ( rc.top < 0 )
  506.             rc.top = 0;
  507.         return Scrolled;
  508.         }
  509.     return 0;
  510. }
  511.  
  512.  
  513. BOOL Cio_WndSize(HWND hWnd, LPARAM lParam)
  514. {
  515.     CioWndInfo    *CWI;
  516.     SCROLLINFO    si;
  517.  
  518.     CWI = (CioWndInfo *)GetWindowLong(hWnd, GWL_USER);
  519.  
  520.     CWI->Scroll = 0;
  521.     CWI->Width = LOWORD(lParam) / CWI->XChar;
  522.     CWI->Height = HIWORD(lParam) / CWI->YChar;
  523.     CWI->YJunk = HIWORD(lParam) - (CWI->Height * CWI->YChar);
  524.  
  525.     InvalidateRect(hWnd, NULL, TRUE);
  526.  
  527.     /* Set the Scroll Bar information. */
  528.  
  529.     si.cbSize = sizeof(si);
  530.     si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_DISABLENOSCROLL;
  531.     si.nMin   = 1;
  532.     si.nMax   = CWI->Lines;
  533.     si.nPage  = CWI->Height-1;
  534.     si.nPos   = si.nMax;
  535.     SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
  536.  
  537.     return 0;
  538. }
  539.  
  540.  
  541. BOOL Cio_WndScroll(HWND hWnd, WPARAM wParam)
  542. {
  543.     CioWndInfo    *CWI;
  544.     SCROLLINFO    si;
  545.     int    Amnt=0, nPos=0;
  546.  
  547.     CWI = (CioWndInfo *)GetWindowLong(hWnd, GWL_USER);
  548.     si.cbSize = sizeof(si);
  549.     si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS;
  550.     GetScrollInfo(hWnd, SB_VERT, &si);
  551.  
  552.     si.nMax-=si.nPage;
  553.     si.nMax+=si.nMin;
  554.     nPos = si.nPos;
  555.  
  556.     switch(LOWORD (wParam))
  557.         {
  558.         case SB_PAGEUP:
  559.             Amnt = -(int)si.nPage;
  560.             break;
  561.  
  562.         case SB_PAGEDOWN:
  563.             Amnt = si.nPage;
  564.             break;
  565.  
  566.         case SB_LINEUP:
  567.             Amnt = -(int)1;
  568.             break;
  569.  
  570.         case SB_LINEDOWN:
  571.             Amnt = 1;
  572.             break;
  573.  
  574.         case SB_THUMBTRACK:
  575.             break;
  576.         }
  577.  
  578.     if ( Amnt )
  579.         {
  580.         nPos += Amnt;
  581.  
  582.         if ( nPos < si.nMin )
  583.             {
  584.             Amnt -= nPos - si.nMin;
  585.             nPos = si.nMin;
  586.             }
  587.  
  588.         if ( nPos > si.nMax )
  589.             {
  590.             Amnt -= nPos - si.nMax;
  591.             nPos = si.nMax;
  592.             }
  593.  
  594.         if ( Amnt )
  595.             {
  596.             SetScrollPos(hWnd, SB_VERT, nPos, TRUE);
  597.             CWI->Scroll = si.nMax-nPos;
  598.             InvalidateRect(hWnd, NULL, TRUE);
  599.             }
  600.         }
  601.  
  602.     return 0;
  603. }
  604.  
  605.  
  606. void Cio_Scroll(HWND hWnd, CioWndInfo *CWI, int Scroll)
  607. {
  608.     int    i=0, KillAmt=0, StopAt=0;
  609.     SCROLLINFO    si;
  610.     CioLine    *Line, *Next;
  611.  
  612.     if ( CWI->Lines+Scroll > 500 && !CWI->Scroll )
  613.         {
  614.         Line = CWI->FirstLine;
  615.         KillAmt = max((CWI->Lines+Scroll)-500, 20);
  616.         for ( i = 0; Line && i < (CWI->Lines-KillAmt); i++ )
  617.             Line = Line->Next;
  618.  
  619.         while ( Line )
  620.         {
  621.             Next = Line->Next;
  622.             CioRemoveLine(CWI, Line);
  623.             Line = Next;
  624.         }
  625.         CWI->Lines -= KillAmt;
  626.         }
  627.  
  628.     for ( i = 0; i < Scroll; i++ )
  629.         CWI->FirstLine = CioMakeLine(NULL, CWI->FirstLine);
  630.  
  631.     CWI->Lines+=Scroll;
  632.     if ( CWI->Scroll )
  633.         CWI->Scroll += Scroll;
  634.     
  635.     /* Set the Scroll Bar information. */
  636.     si.cbSize = sizeof(si);
  637.     si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_DISABLENOSCROLL;
  638.     GetScrollInfo(hWnd, SB_VERT, &si);
  639.  
  640.     si.cbSize = sizeof(si);
  641.     si.fMask  = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_DISABLENOSCROLL;
  642.     si.nMin   = 1;
  643.     si.nMax   = CWI->Lines;
  644.     si.nPage  = CWI->Height-1;
  645.     si.nPos   = CWI->Lines - si.nPage - CWI->Scroll;
  646.     SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
  647. }
  648.  
  649.  
  650. BOOL Cio_PrintF(HWND hWnd, char *InBuf, ...)
  651. {
  652.     CioWndInfo    *CWI;
  653.     va_list    argptr;
  654.     char    *Buffer=NULL, *Ptr = NULL;
  655.     DWORD    Len=0, TLen, Off;
  656.     int    Scrolled=0;
  657.     RECT    rc;
  658.  
  659.  
  660.     if ( (Buffer = LocalAlloc(LPTR, 16384)) == NULL )
  661.         return FALSE;
  662.  
  663.     va_start(argptr, InBuf);
  664.     Len = vsprintf(Buffer, InBuf, argptr);
  665.     va_end(argptr);
  666.     if ( Len == 0 )
  667.         {
  668.         LocalFree(Buffer);
  669.         return FALSE;
  670.         }
  671.  
  672.     CWI = (CioWndInfo *)GetWindowLong(hWnd, GWL_USER);
  673.     Ptr = memchr(Buffer, 0, TLen=Len);
  674.     while ( Ptr != NULL )
  675.         {
  676.         Off = Ptr-Buffer;
  677.         
  678.         CWI->FR = Buffer[Off+1];
  679.         CWI->FG = Buffer[Off+2];
  680.         CWI->FB = Buffer[Off+3];
  681.  
  682.         Off += 4;
  683.         TLen = Len-Off;
  684.         if ( TLen == 0 )
  685.             break;
  686.         Ptr = memchr(Buffer+Off, 0, TLen);
  687.         }
  688.     if ( Buffer[0] != 0 )
  689.         {
  690.         memmove(Buffer+4, Buffer, Len);
  691.         Len+=4;
  692.         Buffer[0] = 0;
  693.         Buffer[1] = CWI->FR;
  694.         Buffer[2] = CWI->FG;
  695.         Buffer[3] = CWI->FB;
  696.         }
  697.  
  698.     rc.left = 0;
  699.     rc.right = CWI->Width*CWI->XChar;
  700.     rc.top = rc.bottom = CWI->Height*CWI->YChar;
  701.  
  702.     do
  703.         {
  704.         Ptr = memchr(Buffer, '\r', Len);
  705.         if ( Ptr )
  706.             TLen = (Ptr-Buffer)+1;
  707.         else
  708.             TLen = Len;
  709.         if ( Buffer[0] != '\r' || CWI->ScrollMe == FALSE )
  710.             {
  711.             Scrolled = Cio_WndAddString(hWnd, TLen, Buffer);
  712.             rc.top -= Scrolled*CWI->YChar;
  713.             }
  714.         Len -= TLen;
  715.         memmove(Buffer, Buffer+TLen, Len);
  716.         } while ( Len );
  717.  
  718.     if ( rc.top < rc.bottom )
  719.         {
  720.         if ( rc.top < 0 )
  721.             rc.top = 0;
  722.         InvalidateRect(hWnd, &rc, TRUE);
  723.         UpdateWindow(hWnd);
  724.         }
  725.     LocalFree(Buffer);
  726.     return TRUE;
  727. }
  728.  
  729.  
  730. BOOL Cio_Puts(HWND hWnd, char *InBuf, DWORD Len)
  731. {
  732.     CioWndInfo    *CWI;
  733.     char    *Buffer = NULL, *Ptr = NULL;
  734.     DWORD    TLen, Off;
  735.     int    Scrolled=0;
  736.     RECT    rc;
  737.  
  738.  
  739.     if ( !Len )
  740.         return FALSE;
  741.  
  742.     if ( (Buffer = LocalAlloc(LPTR, 16384)) == NULL )
  743.         return FALSE;
  744.     memmove(Buffer, InBuf, Len);
  745.  
  746.     CWI = (CioWndInfo *)GetWindowLong(hWnd, GWL_USER);
  747.     Ptr = memchr(Buffer, 0, TLen=Len);
  748.     while ( Ptr != NULL )
  749.         {
  750.         Off = Ptr-Buffer;
  751.         
  752.         CWI->FR = Buffer[Off+1];
  753.         CWI->FG = Buffer[Off+2];
  754.         CWI->FB = Buffer[Off+3];
  755.  
  756.         Off += 4;
  757.         TLen = Len-Off;
  758.         if ( TLen == 0 )
  759.             break;
  760.         Ptr = memchr(Buffer+Off, 0, TLen);
  761.         }
  762.     if ( Buffer[0] != 0 )
  763.         {
  764.         memmove(Buffer+4, Buffer, Len);
  765.         Len+=4;
  766.         Buffer[0] = 0;
  767.         Buffer[1] = CWI->FR;
  768.         Buffer[2] = CWI->FG;
  769.         Buffer[3] = CWI->FB;
  770.         }
  771.  
  772.     rc.left = 0;
  773.     rc.right = CWI->Width*CWI->XChar;
  774.     rc.top = rc.bottom = CWI->Height*CWI->YChar;
  775.  
  776.     do
  777.         {
  778.         Ptr = memchr(Buffer, '\r', Len);
  779.         if ( Ptr )
  780.             TLen = (Ptr-Buffer)+1;
  781.         else
  782.             TLen = Len;
  783.         if ( Buffer[0] != '\r' || CWI->ScrollMe == FALSE )
  784.             {
  785.             Scrolled = Cio_WndAddString(hWnd, TLen, Buffer);
  786.             rc.top -= Scrolled*CWI->YChar;
  787.             }
  788.         Len -= TLen;
  789.         memmove(Buffer, Buffer+TLen, Len);
  790.         } while ( Len );
  791.  
  792.     if ( rc.top < rc.bottom )
  793.         {
  794.         if ( rc.top < 0 )
  795.             rc.top = 0;
  796.         InvalidateRect(hWnd, &rc, TRUE);
  797.         UpdateWindow(hWnd);
  798.         }
  799.     LocalFree(Buffer);
  800.     return TRUE;
  801. }
  802.  
  803.  
  804. BOOL Cio_SetFont(HWND hWnd, WPARAM wParam)
  805. {
  806.     CioWndInfo    *CWI;
  807.     TEXTMETRIC    tm;
  808.     HFONT    hFont = (HFONT)wParam;
  809.     HDC    hdc;
  810.     RECT    rc;
  811.  
  812.  
  813.     CWI = (CioWndInfo *)GetWindowLong(hWnd, GWL_USER);
  814.  
  815.     if ( CWI->hFont )
  816.         DeleteObject(CWI->hFont);
  817.     CWI->hFont = hFont;
  818.     hdc = GetDC(hWnd);
  819.     SelectObject(hdc, CWI->hFont);
  820.     GetTextMetrics(hdc, &tm);
  821.     ReleaseDC(hWnd, hdc);
  822.  
  823.     CWI->XChar = tm.tmAveCharWidth;
  824.     CWI->YChar = tm.tmHeight + tm.tmExternalLeading;
  825.  
  826.     /*
  827.      * Send resize message so it will pick up the new font size.
  828.      */
  829.     GetClientRect(hWnd, &rc);
  830.     SendMessage(hWnd, WM_SIZE, 0, MAKELPARAM(rc.right-rc.left, rc.bottom-rc.top));
  831.     InvalidateRect(hWnd, NULL, TRUE);
  832.  
  833.     return TRUE;
  834. }
  835.  
  836.