home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / winsock / wvnsc926 / wvcodewn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  15.5 KB  |  555 lines

  1. /********************************************************************
  2.  *                                                                  *
  3.  *  MODULE    :  WVCODEWN.C                                         *
  4.  *                                                                  *
  5.  *  PURPOSE   : This file contains the window proc for coding       *
  6.  *        status windows                                      *                                 
  7.  *                                                                  *
  8.  * Author: John S. Cooper (jcooper@netcom.com)                      *
  9.  *   Date: Sept 30, 1993                                            *
  10.  ********************************************************************/
  11. /* 
  12.  * $Id: wvcodewn.c 1.7 1994/09/18 22:45:21 jcooper Exp $
  13.  * $Log: wvcodewn.c $
  14.  * Revision 1.7  1994/09/18  22:45:21  jcooper
  15.  * Better handling of status window.
  16.  *
  17.  * Revision 1.6  1994/09/16  00:58:09  jcooper
  18.  * always-on-top option, and general cleanup for 92.6
  19.  * 
  20.  * Revision 1.5  1994/08/11  00:09:17  jcooper
  21.  * Enhancements to Mime and article encoding/encoding
  22.  *
  23.  * Revision 1.4  1994/07/25  20:13:40  jcooper
  24.  * execution of decoded files
  25.  *
  26.  * Revision 1.3  1994/02/24  21:36:10  jcoop
  27.  * jcoop changes
  28.  *
  29.  * Revision 1.2  1994/01/24  17:40:28  jcoop
  30.  * 90.2 changes
  31.  *
  32.  * Revision 1.1  1994/01/16  12:10:59  jcoop
  33.  * Initial revision
  34.  *
  35.  */ 
  36. #include <windows.h>
  37. #include <windowsx.h>
  38. #include "wvglob.h"
  39. #include "winvn.h"
  40. #pragma hdrstop
  41. #include <string.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44.  
  45. /* ------------------------------------------------------------------------
  46.  *     Window Proc for block coding status window
  47.  *    Simple fixed text display 
  48.  *    Associated with TypCoded  (always currentCoded)
  49.  *    Fixed size, only ever one on screen, destroyed on block coding complete
  50.  *    To avoid redrawing the entire status window on each update,
  51.  *    wParam in association with WM_PAINT decides what to draw this time:
  52.  */
  53. long FAR PASCAL
  54. WinVnCodedBlockWndProc (hWnd, message, wParam, lParam)
  55.     HWND hWnd;
  56.     UINT message;
  57.     WPARAM wParam;
  58.     LPARAM lParam;
  59. {
  60.     HDC          hDC;
  61.     HMENU        hMenu;
  62.     PAINTSTRUCT  ps;
  63.     void    DrawStatusFrame (HDC hDC);
  64.     void    DrawStatusName (HDC hDC);
  65.     void    DrawStatusLines (HDC hDC);
  66.     void    DrawStatusBytes (HDC hDC);
  67.     void    DrawStatusSeq (HDC hDC);
  68.     void    DrawStatusActivity (HDC hDC);
  69.  
  70.     switch (message)
  71.     {
  72.     case WM_CREATE:
  73.         hMenu = GetSystemMenu(hWnd, FALSE);
  74.         AppendMenu(hMenu, MF_SEPARATOR, 0, (LPSTR) NULL);
  75.         AppendMenu(hMenu, MF_STRING, IDM_ALWAYSONTOP, "Always On Top");
  76.         if (BlockCodingStatusAlwaysOnTop) {
  77.                 SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
  78.             CheckMenuItem(hMenu, IDM_ALWAYSONTOP, MF_BYCOMMAND|MF_CHECKED);
  79.         } else {
  80.                 SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
  81.             CheckMenuItem(hMenu, IDM_ALWAYSONTOP, MF_BYCOMMAND|MF_UNCHECKED);
  82.         }
  83.         break;
  84.  
  85.     case WM_SYSCOMMAND:
  86.         if (wParam == IDM_ALWAYSONTOP) 
  87.         {
  88.             hMenu = GetSystemMenu(hWnd, FALSE);
  89.             BlockCodingStatusAlwaysOnTop = !(GetMenuState(hMenu, IDM_ALWAYSONTOP, 
  90.                 MF_BYCOMMAND) & MF_CHECKED);
  91.             if (BlockCodingStatusAlwaysOnTop) {
  92.                     SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
  93.                 CheckMenuItem(hMenu, IDM_ALWAYSONTOP, MF_BYCOMMAND|MF_CHECKED);
  94.             } else {
  95.                     SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
  96.                 CheckMenuItem(hMenu, IDM_ALWAYSONTOP, MF_BYCOMMAND|MF_UNCHECKED);
  97.             }
  98.         }
  99.         else
  100.             return (DefWindowProc (hWnd, message, wParam, lParam));
  101.  
  102.     case WM_SIZE:
  103.     {
  104.         RECT client;
  105.         if (wParam != SIZE_MINIMIZED)
  106.         {
  107.             GetWindowRect (hWnd, &client);
  108.                 MoveWindow (hWnd, client.left, client.top, STATUSWIDTH,
  109.                                STATUSHEIGHT, TRUE);
  110.         }
  111.               break;
  112.     }
  113.             
  114.     case WM_PAINT:
  115.         hDC = BeginPaint (hWnd, &ps);
  116.         SetBkColor (hDC, StatusBackgroundColor);
  117.         SetTextColor (hDC, StatusTextColor);
  118.         SelectObject (hDC, hStatusFont);
  119.         if (currentCoded == NULL)
  120.             DrawStatusFrame (hDC);
  121.         else
  122.         {
  123.             DrawStatusFrame (hDC);
  124.             DrawStatusName (hDC);        
  125.             DrawStatusLines (hDC);        
  126.             DrawStatusBytes (hDC);        
  127.             DrawStatusSeq (hDC);        
  128.             DrawStatusActivity (hDC);        
  129.                 }
  130.         EndPaint (hWnd, &ps);
  131.         break;
  132.  
  133.     case WM_CLOSE:
  134.         if (CodingState)
  135.            MessageBox (hWnd,
  136.              "Please wait until en/decoding is complete",
  137.              "Cannot close status window", MB_OK|MB_ICONSTOP);
  138.         else                             
  139.            DestroyWindow (hWnd);
  140.  
  141.         break;
  142.     
  143.     default:
  144.         return (DefWindowProc (hWnd, message, wParam, lParam));
  145.     }
  146.     
  147.     return (0);
  148. }
  149.  
  150. /* ------------------------------------------------------------------------
  151.  *   Routines for drawing coding block status window
  152.  *   2 columns, 3 lines
  153.  *
  154.  *   HTITLE1       HTEXT1        HTITLE2  HTEXT2
  155.  *   !             !             !        !
  156.  *   Retrieving    ___________   Sequence ___________   <- YOFFSET
  157.  *   Lines Read    __________    Activity ___________   <- YOFFSET+YSPACE
  158.  *   Bytes Decoded __________                           <- YOFFSET+2*YSPACE
  159.  */
  160. #define HTITLE1 (3*StatusCharWidth)
  161. #define HTITLE2 (45*StatusCharWidth)
  162. #define HTEXT1    (22*StatusCharWidth)
  163. #define HTEXT2    (57*StatusCharWidth)
  164. #define YOFFSET (StatusLineHeight)
  165. #define YSPACE    (int)(StatusLineHeight*1.5)
  166.  
  167. void
  168. DrawStatusFrame (HDC hDC)
  169. {
  170.     if (CodingState >= ATTACH_PROCESSING)
  171.     {
  172.       TextOut (hDC, HTITLE1, YOFFSET, "Reading file", 12);
  173.       if (CodingState == ATTACH_PROCESSING)
  174.         TextOut (hDC, HTITLE1, YOFFSET + YSPACE, "Lines encoded", 13);
  175.       else
  176.         TextOut (hDC, HTITLE1, YOFFSET + YSPACE, "Lines posted", 12);
  177.       TextOut (hDC, HTITLE1, YOFFSET + 2*YSPACE, "Bytes read", 10);
  178.       if (CodingState == ATTACH_POSTING)
  179.         TextOut (hDC, HTITLE2, YOFFSET, "Sequence", 8);
  180.     } 
  181.     else
  182.     {
  183.       TextOut (hDC, HTITLE1, YOFFSET, "Retrieving", 10);
  184.       TextOut (hDC, HTITLE1, YOFFSET + YSPACE, "Lines Read", 10);
  185.       TextOut (hDC, HTITLE1, YOFFSET + 2*YSPACE, "Bytes Decoded", 13);
  186.       TextOut (hDC, HTITLE2, YOFFSET, "Sequence", 8);
  187.     } 
  188.     TextOut (hDC, HTITLE2, YOFFSET + YSPACE, "Activity", 8);
  189. }
  190.  
  191. void
  192. DrawStatusName (HDC hDC)
  193. {
  194.     char temp[MAXINTERNALLINE];
  195.     RECT aRect;
  196.         
  197.     if (currentCoded->name[0] == '\0' && currentCoded->ident[0] == '\0')
  198.         strcpy (temp, "Name unknown");
  199.     else
  200.     {
  201.         if (currentCoded->name[0] != '\0')    // len must be <= 20    
  202.         {
  203.             NameWithoutPath (str, currentCoded->name);// cut off any path
  204.             sprintf(temp, "%s", str);
  205.         }
  206.         else
  207.         {
  208.             NameWithoutPath (str, currentCoded->ident);//cut off any path
  209.             sprintf(temp, "%s", str); 
  210.         }
  211.     }
  212.  
  213.     // be sure to erase old name 
  214.     SetRect (&aRect, HTEXT1, YOFFSET, HTITLE2-1, YOFFSET+YSPACE-1);
  215.     ExtTextOut (hDC, HTEXT1, YOFFSET, ETO_OPAQUE|ETO_CLIPPED, &aRect, 
  216.                 temp, lstrlen(temp), (LPINT)NULL); 
  217. }
  218. void
  219. DrawStatusLines (HDC hDC)
  220. {
  221.     int len;
  222.     RECT aRect;
  223.     
  224.     len = sprintf (str, "%lu", currentCoded->numLines);
  225.     SetRect (&aRect, HTEXT1, YOFFSET+YSPACE, HTITLE2-1, YOFFSET+2*YSPACE-1);
  226.     ExtTextOut (hDC, HTEXT1, YOFFSET+YSPACE, ETO_OPAQUE|ETO_CLIPPED, 
  227.                 &aRect, str, len, (LPINT)NULL); 
  228. }
  229. void
  230. DrawStatusBytes (HDC hDC)
  231. {
  232.     int len;
  233.     RECT aRect;
  234.     
  235.     len = sprintf (str, "%lu", currentCoded->numBytes);
  236.     TextOut (hDC, HTEXT1, YOFFSET + 2*YSPACE, str, len);
  237.     SetRect (&aRect, HTEXT1, YOFFSET+2*YSPACE, HTITLE2-1, YOFFSET+3*YSPACE-1);
  238.     ExtTextOut (hDC, HTEXT1, YOFFSET+2*YSPACE, ETO_OPAQUE|ETO_CLIPPED, 
  239.                 &aRect, str, len, (LPINT)NULL); 
  240. }
  241. void
  242. DrawStatusSeq (HDC hDC)
  243. {
  244.     int len;
  245.     RECT aRect;
  246.     
  247.     if (CodingState == ATTACH_PROCESSING)
  248.         return;
  249.         
  250.     if (currentCoded->sequence == -1)
  251.         len = sprintf (str, "%s", "Unknown");
  252.     else    
  253.         len = sprintf (str, "%d", currentCoded->sequence);
  254.         
  255.     SetRect (&aRect, HTEXT2, YOFFSET, STATUSWIDTH-1, YOFFSET+YSPACE-1);
  256.     ExtTextOut (hDC, HTEXT2, YOFFSET, ETO_OPAQUE|ETO_CLIPPED, 
  257.                 &aRect, str, len, (LPINT)NULL); 
  258. }
  259.  
  260. void
  261. DrawStatusActivity (HDC hDC)
  262. {
  263. //    static int prevState = -1;
  264.     COLORREF backColor;
  265.     int len;
  266.     SIZE size;
  267.     RECT aRect;
  268. //    if (CodingState == prevState)
  269. //        return;
  270.     
  271.     switch (CodingState)
  272.     {
  273.     case DECODE_SKIPPING:
  274.          backColor = RGB(128, 0, 0);             // red
  275.         strcpy (str, "Skipping");
  276.         break;
  277.         
  278.     case DECODE_GET_TABLE:
  279.          backColor = RGB(0, 128, 128);           // purple?
  280.         strcpy (str, "Getting table");
  281.         break;                                                     
  282.         
  283.     case DECODE_PROCESSING:
  284.          backColor = RGB(0, 128, 0);             // green
  285.         strcpy (str, "Decoding");
  286.         break;
  287.  
  288.     case ATTACH_PROCESSING:
  289.          backColor = RGB(0, 128, 0);        // green
  290.         strcpy (str, "Encoding");
  291.         break;
  292.  
  293.     case ATTACH_POSTING:    
  294.          backColor = RGB(128, 128, 0);        // yellow
  295.         if (ReviewAttach)
  296.            strcpy (str, "Creating review");
  297.         else
  298.            strcpy (str, "Posting");
  299.         break;
  300.  
  301.     case ATTACH_READFILE:
  302.          backColor = RGB(0, 128, 0);        // green
  303.         strcpy (str, "Reading file");
  304.         break;
  305.     }
  306.  
  307.     len = lstrlen(str);
  308.     // Create colored rectangle behind text
  309.     SetRect (&aRect, HTEXT2, YOFFSET+YSPACE, HTEXT2 + 20*StatusCharWidth, 
  310.              YOFFSET+YSPACE + StatusLineHeight+1);
  311.     
  312.     SetTextColor (hDC, RGB(0,0,0));
  313.     SetBkColor (hDC, backColor);
  314.  
  315.     // center the text in the rectangle
  316.     GetTextExtentPoint (hDC, str, len, &size);
  317.     ExtTextOut (hDC, HTEXT2 + (20*StatusCharWidth - size.cx)/2,
  318.                 YOFFSET+YSPACE, ETO_OPAQUE|ETO_CLIPPED, &aRect, 
  319.                 str, len, (LPINT)NULL); 
  320.  
  321.     SetTextColor (hDC, StatusTextColor);
  322.     SetBkColor (hDC, StatusBackgroundColor);
  323.  
  324. //    prevState = CodingState;
  325. }
  326.  
  327. /* ------------------------------------------------------------------------
  328.  *     Window Proc for Coding status window
  329.  *    Simple text display window w/ scroll bars
  330.  *    Associated with TypDecodeThread
  331.  *    One per decode thread, variable size, user must delete it
  332.  *
  333.  *    Mostly copied from Petzold
  334.  */
  335. long FAR PASCAL
  336. WinVnCodingWndProc  (hWnd, message, wParam, lParam)
  337.      HWND hWnd;
  338.      UINT message;
  339.      WPARAM wParam;
  340.      LPARAM lParam;
  341. {
  342.     static int   cxClient, cyClient, nVscrollPos, nVscrollMax,
  343.              nHscrollPos, nHscrollMax;
  344.     int rangeTemp;
  345.     RECT         client;
  346.     HDC          hDC;
  347.     int          i, x, y, nPaintBeg, nPaintEnd, nVscrollInc, nHscrollInc;
  348.     PAINTSTRUCT  ps;
  349.     TypTextBlock *ThisText;
  350.     int      ThisTextNum;
  351.     int       CtrlState;
  352.     
  353.     for (ThisTextNum = 0; ThisTextNum < NumStatusTexts; ThisTextNum++)
  354.         if (CodingStatusText[ThisTextNum]->hTextWnd == hWnd)
  355.             break;
  356.     
  357.     if (ThisTextNum == NumStatusTexts)
  358.         ThisTextNum = NumStatusTexts - 1;    // new status window
  359.  
  360.     ThisText = CodingStatusText[ThisTextNum];
  361.  
  362.     switch (message)
  363.     {
  364.     case WM_CREATE:
  365. //        nVscrollPos = nHscrollPos = 0;
  366.                 break;
  367.  
  368.     case WM_SIZE:
  369.         GetClientRect (hWnd, &client);
  370.         cxClient = client.right - client.left;
  371.         cyClient = client.bottom - client.top;
  372.         // nVscrollMax is # lines that won't fit in client y area
  373.         rangeTemp = ((int)(ThisText->numLines + 2) * (int)StatusLineHeight - cyClient) / (int)StatusLineHeight;
  374.         nVscrollMax = max (0, rangeTemp);
  375.         nVscrollPos = min (nVscrollPos, nVscrollMax);
  376.  
  377.         SetScrollRange (hWnd, SB_VERT, 0, nVscrollMax, FALSE);
  378.         SetScrollPos   (hWnd, SB_VERT, nVscrollPos, TRUE);
  379.  
  380.         // nHscrollMax is # chars that won't fit in client x area
  381.         rangeTemp = ((int)(ThisText->maxLineLen + 2) * (int)StatusCharWidth - cxClient) / (int)StatusCharWidth;
  382.         nHscrollMax = max (0, rangeTemp);
  383.         nHscrollPos = min (nHscrollPos, nHscrollMax);
  384.  
  385.         SetScrollRange (hWnd, SB_HORZ, 0, nHscrollMax, FALSE);
  386.         SetScrollPos   (hWnd, SB_HORZ, nHscrollPos, TRUE);
  387.         break;
  388.      
  389.     case WM_VSCROLL:
  390.         switch (wParam)
  391.         {
  392.         case SB_TOP:
  393.             nVscrollInc = -nVscrollPos;
  394.             break;
  395.     
  396.         case SB_BOTTOM:
  397.             nVscrollInc = nVscrollMax - nVscrollPos;
  398.             break;
  399.  
  400.         case SB_LINEUP:
  401.             nVscrollInc = -1;
  402.             break;
  403.     
  404.         case SB_LINEDOWN:
  405.             nVscrollInc = 1;
  406.             break;
  407.  
  408.         case SB_PAGEUP:
  409.             nVscrollInc = min (-1, -cyClient / (int)StatusLineHeight);
  410.             break;
  411.  
  412.         case SB_PAGEDOWN:
  413.             nVscrollInc = max (1, cyClient / (int)StatusLineHeight);
  414.             break;
  415.  
  416.         case SB_THUMBTRACK:
  417.             nVscrollInc = LOWORD (lParam) - nVscrollPos;
  418.             break;
  419.  
  420.         default:
  421.             nVscrollInc = 0;
  422.         }
  423.         nVscrollInc = max (-nVscrollPos,
  424.                   min (nVscrollInc, nVscrollMax - nVscrollPos));
  425.  
  426.         if (nVscrollInc != 0)
  427.         {
  428.             nVscrollPos += nVscrollInc;
  429.             ScrollWindow (hWnd, 0, -1 * (int)StatusLineHeight * nVscrollInc, NULL, NULL);
  430.             SetScrollPos (hWnd, SB_VERT, nVscrollPos, TRUE);
  431.         
  432.             UpdateWindow (hWnd);
  433.         }
  434.         break;
  435.  
  436.     case WM_HSCROLL:
  437.         switch (wParam)
  438.         {
  439.         case SB_LINEUP:
  440.             nHscrollInc = -1;
  441.             break;
  442.  
  443.         case SB_LINEDOWN:
  444.             nHscrollInc = 1;
  445.             break;
  446.  
  447.         case SB_PAGEUP:
  448.             nHscrollInc = -8;
  449.             break;            
  450.  
  451.         case SB_PAGEDOWN:
  452.             nHscrollInc = 8;
  453.             break;
  454.  
  455.         case SB_THUMBPOSITION:
  456.             nHscrollInc = LOWORD (lParam) - nHscrollPos;
  457.             break;
  458.         default:
  459.             nHscrollInc = 0;
  460.         }
  461.         nHscrollInc = max (-nHscrollPos,
  462.             min (nHscrollInc, nHscrollMax - nHscrollPos));
  463.  
  464.         if (nHscrollInc != 0)
  465.         {
  466.              nHscrollPos += nHscrollInc;
  467.              ScrollWindow (hWnd, -1 * (int)StatusCharWidth * nHscrollInc, 0, NULL, NULL);
  468.              SetScrollPos (hWnd, SB_HORZ, nHscrollPos, TRUE);
  469.  
  470.         }
  471.         break;
  472.  
  473.           case WM_PAINT:
  474.         if (ThisText->numLines == 0)
  475.             break;
  476.        
  477.         hDC = BeginPaint (hWnd, &ps);
  478.         SetBkColor (hDC, StatusBackgroundColor);
  479.         SetTextColor (hDC, StatusTextColor);
  480.         SelectObject (hDC, hStatusFont);
  481.  
  482.         nPaintBeg = max (0, (nVscrollPos + ps.rcPaint.top / (int)StatusLineHeight - 1));
  483.         nPaintEnd = min ((int)ThisText->numLines,
  484.             (nVscrollPos + ps.rcPaint.bottom / (int)StatusLineHeight));
  485.  
  486.         SetTextAlign (hDC, TA_LEFT | TA_TOP);
  487.  
  488.         for (i = nPaintBeg; i < nPaintEnd; i++)
  489.         {
  490.             x = (int)StatusCharWidth * (1 - nHscrollPos);
  491.             y = (int)StatusLineHeight * (1 - nVscrollPos + i);
  492.  
  493.             TextOut (hDC, x, y, TextBlockLine (ThisText, i), 
  494.                 lstrlen (TextBlockLine (ThisText, i)));
  495.         }
  496.  
  497. /*        GetClientRect (hWnd, &client);
  498.         cyClient = client.bottom - client.top;
  499.         cxClient = client.right - client.left;
  500. */
  501.         // nVscrollMax is # lines that won't fit in client y area
  502.         rangeTemp = ((int)(ThisText->numLines + 2) * (int)StatusLineHeight - cyClient) / (int)StatusLineHeight;
  503.         nVscrollMax = max (0, rangeTemp);
  504.         SetScrollRange (hWnd, SB_VERT, 0, nVscrollMax, TRUE);
  505.         // nHscrollMax is # chars that won't fit in client x area
  506.         rangeTemp = ((int)(ThisText->maxLineLen + 2) * (int)StatusCharWidth - cxClient) / (int)StatusCharWidth;
  507.         nHscrollMax = max (0, rangeTemp);
  508.         SetScrollRange (hWnd, SB_HORZ, 0, nHscrollMax, TRUE);
  509.  
  510.         EndPaint (hWnd, &ps);
  511.         break;
  512.  
  513.           case WM_KEYDOWN:
  514.         /* See if this key should be mapped to a scrolling event
  515.         * for which we have programmed the mouse.  If so,
  516.         * construct the appropriate mouse call and call the mouse code.
  517.         */
  518.     
  519.         CtrlState = GetKeyState (VK_CONTROL) < 0;
  520.         for (i = 0; i < NUMKEYS; i++)
  521.         {
  522.            if (wParam == key2scroll[i].wVirtKey &&
  523.             CtrlState == key2scroll[i].CtlState)
  524.            {
  525.             SendMessage (hWnd, key2scroll[i].iMessage,
  526.             key2scroll[i].wRequest, 0L);
  527.            }
  528.         }
  529.         break;
  530.  
  531.     case WM_CLOSE:
  532.         if (CodingState && ThisText->IsBusy)
  533.            MessageBox (hWnd,
  534.              "Please wait until en/decoding is complete",
  535.              "Cannot close status window", MB_OK|MB_ICONSTOP);
  536.         else
  537.            DestroyWindow (hWnd);
  538.         break;
  539.         
  540.     case WM_DESTROY:
  541.         for (i = ThisTextNum; i < NumStatusTexts; i++)
  542.             CodingStatusText[i] = CodingStatusText[i+1];
  543.         FreeTextBlock (ThisText);
  544.         NumStatusTexts--;
  545.         break;
  546.     
  547.     default:
  548.         return (DefWindowProc (hWnd, message, wParam, lParam));
  549.     }
  550.     
  551.     return (0);
  552. }
  553.  
  554.  
  555.