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

  1. head     1.53;
  2. branch   ;
  3. access   ;
  4. symbols  test:1.51 V80:1.11 V76d:1.2;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.53
  10. date     94.09.18.22.46.50;  author jcooper;  state Exp;
  11. branches ;
  12. next     1.52;
  13.  
  14. 1.52
  15. date     94.09.16.00.41.22;  author jcooper;  state Exp;
  16. branches ;
  17. next     1.51;
  18.  
  19. 1.51
  20. date     94.09.02.23.50.26;  author rushing;  state Exp;
  21. branches ;
  22. next     1.50;
  23.  
  24. 1.50
  25. date     94.08.23.23.17.34;  author martin;  state Exp;
  26. branches ;
  27. next     1.49;
  28.  
  29. 1.49
  30. date     94.08.12.01.39.21;  author dumoulin;  state Exp;
  31. branches ;
  32. next     1.48;
  33.  
  34. 1.48
  35. date     94.08.11.21.41.41;  author rushing;  state Exp;
  36. branches ;
  37. next     1.47;
  38.  
  39. 1.47
  40. date     94.08.11.20.28.11;  author rushing;  state Exp;
  41. branches ;
  42. next     1.46;
  43.  
  44. 1.46
  45. date     94.08.11.00.14.26;  author jcooper;  state Exp;
  46. branches ;
  47. next     1.45;
  48.  
  49. 1.45
  50. date     94.08.04.05.51.13;  author dumoulin;  state Exp;
  51. branches ;
  52. next     1.44;
  53.  
  54. 1.44
  55. date     94.08.03.00.55.24;  author dumoulin;  state Exp;
  56. branches ;
  57. next     1.43;
  58.  
  59. 1.43
  60. date     94.07.27.21.09.33;  author gardnerd;  state Exp;
  61. branches ;
  62. next     1.42;
  63.  
  64. 1.42
  65. date     94.07.25.18.51.03;  author jcooper;  state Exp;
  66. branches ;
  67. next     1.41;
  68.  
  69. 1.41
  70. date     94.07.12.19.50.52;  author cnolan;  state Exp;
  71. branches ;
  72. next     1.40;
  73.  
  74. 1.40
  75. date     94.07.12.19.15.49;  author rushing;  state Exp;
  76. branches ;
  77. next     1.39;
  78.  
  79. 1.39
  80. date     94.06.30.21.30.41;  author gardnerd;  state Exp;
  81. branches ;
  82. next     1.38;
  83.  
  84. 1.38
  85. date     94.06.30.16.36.23;  author dumoulin;  state Exp;
  86. branches ;
  87. next     1.37;
  88.  
  89. 1.37
  90. date     94.06.08.21.01.45;  author gardnerd;  state Exp;
  91. branches ;
  92. next     1.36;
  93.  
  94. 1.36
  95. date     94.06.06.22.06.13;  author gardnerd;  state Exp;
  96. branches ;
  97. next     1.35;
  98.  
  99. 1.35
  100. date     94.06.06.21.23.37;  author mrr;  state Exp;
  101. branches ;
  102. next     1.34;
  103.  
  104. 1.34
  105. date     94.06.01.20.48.43;  author rushing;  state Exp;
  106. branches ;
  107. next     1.33;
  108.  
  109. 1.33
  110. date     94.05.27.01.29.29;  author rushing;  state Exp;
  111. branches ;
  112. next     1.32;
  113.  
  114. 1.32
  115. date     94.05.25.22.53.26;  author dumoulin;  state Exp;
  116. branches ;
  117. next     1.31;
  118.  
  119. 1.31
  120. date     94.05.23.18.36.00;  author jcooper;  state Exp;
  121. branches ;
  122. next     1.30;
  123.  
  124. 1.30
  125. date     94.05.19.02.04.54;  author rushing;  state Exp;
  126. branches ;
  127. next     1.29;
  128.  
  129. 1.29
  130. date     94.05.02.20.38.53;  author rushing;  state Exp;
  131. branches ;
  132. next     1.28;
  133.  
  134. 1.28
  135. date     94.04.19.18.35.23;  author rushing;  state Exp;
  136. branches ;
  137. next     1.27;
  138.  
  139. 1.27
  140. date     94.02.24.21.35.08;  author jcoop;  state Exp;
  141. branches ;
  142. next     1.26;
  143.  
  144. 1.26
  145. date     94.02.09.18.01.08;  author cnolan;  state Exp;
  146. branches ;
  147. next     1.25;
  148.  
  149. 1.25
  150. date     94.01.24.17.41.01;  author jcoop;  state Exp;
  151. branches ;
  152. next     1.24;
  153.  
  154. 1.24
  155. date     94.01.16.12.04.33;  author jcoop;  state Exp;
  156. branches ;
  157. next     1.23;
  158.  
  159. 1.23
  160. date     94.01.12.19.27.32;  author mrr;  state Exp;
  161. branches ;
  162. next     1.22;
  163.  
  164. 1.22
  165. date     93.12.08.01.28.01;  author rushing;  state Exp;
  166. branches ;
  167. next     1.21;
  168.  
  169. 1.21
  170. date     93.12.07.20.24.43;  author rushing;  state Exp;
  171. branches ;
  172. next     1.20;
  173.  
  174. 1.20
  175. date     93.10.12.17.47.26;  author rushing;  state Exp;
  176. branches ;
  177. next     1.19;
  178.  
  179. 1.19
  180. date     93.09.12.20.26.52;  author rushing;  state Exp;
  181. branches ;
  182. next     1.18;
  183.  
  184. 1.18
  185. date     93.08.25.18.54.36;  author mbretherton;  state Exp;
  186. branches ;
  187. next     1.17;
  188.  
  189. 1.17
  190. date     93.08.18.21.49.21;  author rushing;  state Exp;
  191. branches ;
  192. next     1.16;
  193.  
  194. 1.16
  195. date     93.08.17.21.46.49;  author DUMOULIN;  state Exp;
  196. branches ;
  197. next     1.15;
  198.  
  199. 1.15
  200. date     93.07.06.21.09.50;  author cnolan;  state Exp;
  201. branches ;
  202. next     1.14;
  203.  
  204. 1.14
  205. date     93.06.28.17.51.39;  author rushing;  state Exp;
  206. branches ;
  207. next     1.13;
  208.  
  209. 1.13
  210. date     93.06.24.17.13.14;  author riordan;  state Exp;
  211. branches ;
  212. next     1.12;
  213.  
  214. 1.12
  215. date     93.06.14.18.52.00;  author rushing;  state Exp;
  216. branches ;
  217. next     1.11;
  218.  
  219. 1.11
  220. date     93.06.11.00.10.35;  author rushing;  state Exp;
  221. branches ;
  222. next     1.10;
  223.  
  224. 1.10
  225. date     93.06.10.18.24.41;  author rushing;  state Exp;
  226. branches ;
  227. next     1.9;
  228.  
  229. 1.9
  230. date     93.05.24.23.55.25;  author rushing;  state Exp;
  231. branches ;
  232. next     1.8;
  233.  
  234. 1.8
  235. date     93.05.20.18.12.31;  author rushing;  state Exp;
  236. branches ;
  237. next     1.7;
  238.  
  239. 1.7
  240. date     93.04.29.20.23.06;  author rushing;  state Exp;
  241. branches ;
  242. next     1.6;
  243.  
  244. 1.6
  245. date     93.04.27.20.11.38;  author rushing;  state Exp;
  246. branches ;
  247. next     1.5;
  248.  
  249. 1.5
  250. date     93.04.27.18.53.17;  author rushing;  state Exp;
  251. branches ;
  252. next     1.4;
  253.  
  254. 1.4
  255. date     93.03.30.21.07.15;  author DUMOULIN;  state Exp;
  256. branches ;
  257. next     1.3;
  258.  
  259. 1.3
  260. date     93.03.30.20.46.07;  author DUMOULIN;  state Exp;
  261. branches ;
  262. next     1.2;
  263.  
  264. 1.2
  265. date     93.02.25.03.08.52;  author rushing;  state Exp;
  266. branches ;
  267. next     1.1;
  268.  
  269. 1.1
  270. date     93.02.16.20.54.22;  author rushing;  state Exp;
  271. branches ;
  272. next     ;
  273.  
  274.  
  275. desc
  276. @winvn version 0.76 placed into RCS
  277. @
  278.  
  279.  
  280. 1.53
  281. log
  282. @New Window menu item, etc
  283. @
  284. text
  285. @/********************************************************************
  286.  *                                                                  *
  287.  *  MODULE    :  WVUSENET.C                                         *
  288.  *                                                                  *
  289.  *  PURPOSE   : This file contains the window procedure and support *
  290.  *              routines for WinVn's main window                    *
  291.  *                                                                  *
  292.  ********************************************************************/
  293.  
  294. /*
  295.  * $Id: wvusenet.c 1.52 1994/09/16 00:41:22 jcooper Exp $
  296.  *
  297.  */
  298. #include <windows.h>
  299. #include <windowsx.h>
  300. #include "wvglob.h"
  301. #include "winvn.h"
  302. #pragma hdrstop
  303. #include <stdlib.h>
  304.  
  305. // This is for the special case where the user invoked the
  306. // program with dolist=0, then turned it on.  Without checking
  307. // this condition, the newsrc will be truncated to only those
  308. // groups read.  SMR 930224
  309.  
  310. int started_with_no_dolist;
  311.  
  312. void show_version_strings(HWND);
  313. void SetGroupActiveLines(void);
  314. void AbortAllComm();
  315.  
  316. /*--- FUNCTION: WinVnConfWndProc ---------------------------------------
  317.  *
  318.  *    Window procedure for the "Net" window.
  319.  *    This window displays the names of the newsgroups, one per line.
  320.  *
  321.  *    Entry    The usual parameters for any window function.
  322.  *
  323.  *    Note:    We don't do anything until "Initialized" is TRUE.
  324.  *             This way, the user won't try to perform functions
  325.  *             while the communications are still being set up.
  326.  */
  327.  
  328. long WINAPI WinVnConfWndProc (hWnd, message, wParam, lParam)
  329.      HWND hWnd;
  330.      unsigned message;
  331.      WPARAM wParam;
  332.      LPARAM lParam;
  333. {
  334.  
  335.   DLGPROC lpProcAbout;
  336.   HMENU hMenu, hSubMenu;
  337.  
  338.   PAINTSTRUCT ps;               /* paint structure          */
  339.   POINT ptCursor;
  340.  
  341.   HDC hDC;                      /* handle to display context */
  342.   HWND hWndView;
  343.   RECT myRect;                                    /* selection rectangle                */
  344.  
  345.   int j, idoc;
  346.   int found;
  347.   char far *lpsz;
  348.   TypLine far *LinePtr, far * GroupLinePtr;
  349.   TypBlock far *BlockPtr, far * GroupBlockPtr;
  350.   HANDLE hBlock;
  351.   TypDoc *MyDoc;
  352.   unsigned int Offset;
  353.   BOOL looping = TRUE;
  354.   BOOL continueFind;
  355.   TypGroup far *MyGroup;
  356.   
  357.   int X, Y;
  358.   int docnum;
  359.   int newdoc;
  360.   char mybuf[MAXINTERNALLINE];
  361.   int OldSel = FALSE;
  362.   int CtrlState;
  363.   TypLineID MyLineID;
  364.  
  365.   switch (message)
  366.     {
  367.  
  368.     case WM_SYSCOMMAND:
  369.       if (wParam == ID_ABOUT)
  370.    {
  371.      lpProcAbout = (DLGPROC)MakeProcInstance ((FARPROC)About, hInst);
  372.      DialogBox (hInst, "AboutBox", hWnd, lpProcAbout);
  373.      FreeProcInstance ((FARPROC)lpProcAbout);
  374.      break;
  375.    }
  376.       else
  377.    return (DefWindowProc (hWnd, message, wParam, lParam));
  378.  
  379.     case WM_CREATE:
  380.       MailInit (hWnd) ;
  381.  
  382.       /* Get handle to the hourglass cursor */
  383.  
  384.       hHourGlass = LoadCursor (hInst, IDC_WAIT);
  385.  
  386.       /* Add the "About" option to the system menu.            */
  387.  
  388.       hMenu = GetSystemMenu (hWnd, FALSE);
  389.       ChangeMenu (hMenu, NULL, NULL, NULL, MF_APPEND | MF_SEPARATOR);
  390.       ChangeMenu (hMenu, NULL, "A&bout WinVn...", ID_ABOUT,
  391.         MF_APPEND | MF_STRING);
  392.  
  393.       /* Fill in the Net document's window handle that we
  394.        * were unable to fill in in the call to InitDoc.
  395.        */
  396.       NetDoc.hDocWnd = hWnd;
  397.       InitBitmaps();
  398.       break;
  399.  
  400.     case WM_INITMENU:
  401.       hMenu = GetMenu (hWnd);
  402.       hSubMenu = GetSubMenu (hMenu, 2);    /* Utilities menu */
  403.       EnableMenuItem (GetSubMenu (hSubMenu, 3), IDM_SEND_ALL_POST, NumPostWnds ? MF_ENABLED : MF_DISABLED|MF_GRAYED);
  404.       EnableMenuItem (GetSubMenu (hSubMenu, 3), IDM_SEND_ALL_MAIL, NumMailWnds ? MF_ENABLED : MF_DISABLED|MF_GRAYED);
  405.         
  406.       hSubMenu = GetSubMenu (hMenu, 4);    /* Window menu */
  407.       EnableMenuItem (GetSubMenu (hSubMenu, 1), IDM_CLOSE_ALL_ARTICLE, NumArticleWnds ? MF_ENABLED : MF_DISABLED|MF_GRAYED);
  408.       EnableMenuItem (GetSubMenu (hSubMenu, 1), IDM_CLOSE_ALL_GROUP, NumGroupWnds ? MF_ENABLED : MF_DISABLED|MF_GRAYED);
  409.       EnableMenuItem (GetSubMenu (hSubMenu, 1), IDM_CLOSE_ALL_STATUS, NumStatusTexts ? MF_ENABLED : MF_DISABLED|MF_GRAYED);
  410.       EnableMenuItem (GetSubMenu (hSubMenu, 1), IDM_CLOSE_ALL, (NumArticleWnds||NumGroupWnds||NumStatusTexts) ? MF_ENABLED : MF_DISABLED|MF_GRAYED);
  411.       break;
  412.     
  413.     case WM_CHAR:
  414.       /* Hitting CR on a group name is the same as double-clicking
  415.        * on the name.
  416.        */
  417.       if (!Initializing)
  418.    {
  419.      if (wParam == '\r')
  420.        {
  421.  
  422.          GetCursorPos (&ptCursor);
  423.          ScreenToClient (hWnd, &ptCursor);
  424.          X = ptCursor.x;
  425.          Y = ptCursor.y;
  426.          goto getgroup;
  427.        }
  428.    }
  429.       break;
  430.  
  431.     case WM_KEYDOWN:
  432.       /* See if this key should be mapped to a scrolling event
  433.        * for which we have programmed the mouse.  If so,
  434.        * construct the appropriate mouse call and call the mouse code.
  435.        * Also, F6 means switch to next window.
  436.        * (This latter should also be table-driven.)
  437.        */
  438.       if (!Initializing)
  439.    {
  440.      if (wParam == VK_F6)
  441.        {
  442.          NextWindow (&NetDoc);
  443.        }
  444.      else
  445.        {
  446.          /* Based on the state of the Control key and the value
  447.           * of the key just pressed, look up in the array
  448.           * key2scroll to see if we should process this keystroke
  449.           * as if it were a mouse event.  If so, simulate the
  450.           * mouse event by sending the appropriate message.
  451.           */
  452.  
  453.          CtrlState = GetKeyState (VK_CONTROL) < 0;
  454.          for (j = 0; j < NUMKEYS; j++)
  455.       {
  456.         if (wParam == key2scroll[j].wVirtKey &&
  457.             CtrlState == key2scroll[j].CtlState)
  458.           {
  459.             SendMessage (hWnd, key2scroll[j].iMessage,
  460.                key2scroll[j].wRequest, 0L);
  461.             break;
  462.           }
  463.       }
  464.  
  465.        }
  466.    }
  467.       break;
  468.  
  469.     case WM_LBUTTONDOWN:
  470.       /*  Clicking the left button on a group name toggles the
  471.        *  selected/not selected status of that group.
  472.        *  Currently selected groups are displayed in reverse video.
  473.        */
  474.    
  475.       DragMouseAction = DRAG_NONE;
  476.       if (!Initializing)
  477.    {
  478.           BOOL status;
  479.      X = LOWORD (lParam);
  480.      Y = HIWORD (lParam);
  481.  
  482.      // make this behave more like a multi-select listbox (jlg)
  483.      // if click,       make the line the only one selected
  484.      // if ctrl-click,  add the line to the selection
  485.      // if shift-click, select from previously selected to current
  486.      if (GroupMultiSelect) {                                 
  487.         if ( !(wParam & MK_CONTROL) && !(wParam & MK_SHIFT) ) {
  488.            ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
  489.            }
  490.         }
  491.      if (CursorToTextLine (X, Y, &NetDoc, &BlockPtr, &LinePtr))
  492.        {
  493.          status = ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
  494.                      ->Selected ^= TRUE;
  495.          if (GroupMultiSelect) {                                 
  496.             if ( wParam & MK_SHIFT ) {
  497.                do {
  498.                   looping = PrevLine (&BlockPtr, &LinePtr);
  499.                   MyGroup = (TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine));
  500.                   if (MyGroup->Selected)
  501.                      looping = FALSE;
  502.                   else
  503.                      MyGroup->Selected = TRUE;   
  504.                   } 
  505.                   while (looping);
  506.                }
  507.             }
  508.          DragMouseAction = status ? DRAG_SELECT : DRAG_DESELECT;
  509.          GlobalUnlock (BlockPtr->hCurBlock);
  510.          SetCapture(hWnd); // release capture on button up
  511.        }
  512.  
  513.      InvalidateRect (hWnd, NULL, FALSE);
  514.    }
  515.       break;
  516.  
  517.     case WM_LBUTTONUP:
  518.       /*  Letting up on the left button on a group name 
  519.        *  gets us out of Dragging mode   */
  520.  
  521.       ReleaseCapture();
  522.       DragMouseAction = DRAG_NONE;
  523.       break;
  524.  
  525.     case WM_MOUSEMOVE:
  526.       /*  Code to drag the mouse and change the select/not selected
  527.        *  status of that group.
  528.        */
  529.  
  530.       if ((!Initializing) && (DragMouseAction != DRAG_NONE))
  531.       {
  532.         X = LOWORD (lParam);
  533.         Y = HIWORD (lParam);
  534.  
  535.         GetClientRect (hWnd, &myRect);
  536.         if (CursorToTextLine (X, Y, &NetDoc, &BlockPtr, &LinePtr))
  537.         {
  538.               switch (DragMouseAction)
  539.               {
  540.                case DRAG_SELECT:
  541.                  ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
  542.                     ->Selected = TRUE;
  543.                  break;
  544.                case DRAG_DESELECT:
  545.                  ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
  546.                     ->Selected = FALSE;
  547.                break;
  548.               }
  549.              GlobalUnlock (BlockPtr->hCurBlock);
  550.           }
  551.           InvalidateRect (hWnd, NULL, FALSE);
  552.       }
  553.       break;
  554.  
  555.     case WM_LBUTTONDBLCLK:
  556.       /*  Double-clicking on a group name creates a "Group"
  557.        *  window, whose purpose is to display the subjects
  558.        *  of the articles in the group.
  559.        */
  560.       if (!Initializing)
  561.    {
  562.      X = LOWORD (lParam);
  563.      Y = HIWORD (lParam);
  564.    getgroup:;
  565.  
  566.  
  567.      if (CursorToTextLine (X, Y, &NetDoc, &GroupBlockPtr, &GroupLinePtr))
  568.        {
  569.          if (MyDoc = (((TypGroup far *)
  570.       (((char far *) GroupLinePtr) + sizeof (TypLine)))->SubjDoc))
  571.       {
  572.  
  573.         /* We already have a document containing the subjects */
  574.         /* of this group, so just activate it.                */
  575.  
  576.         SetActiveWindow (MyDoc->hDocWnd);
  577.         SetFocus (MyDoc->hDocWnd);
  578.         GlobalUnlock (GroupBlockPtr->hCurBlock);
  579.         break;
  580.       }
  581.       if (TestCommBusy(hWnd, "Can't request info on group"))
  582.    {
  583.      GlobalUnlock (GroupBlockPtr->hCurBlock);
  584.      break;
  585.    }
  586.  
  587.          /* At this point, we've determined that the subjects for
  588.           * this newsgroup are not in memory, and that it's OK
  589.           * to fetch them from the server.  (Comm line not busy.)
  590.           * Figure out whether a new window/document should be
  591.           * created for this group & set "newdoc" accordingly.
  592.           */
  593.          newdoc = FALSE;
  594.          if (ViewNew || !ActiveGroupDoc || !(ActiveGroupDoc->InUse))
  595.       {
  596.         found = FALSE;
  597.         for (docnum = 0; docnum < MAXGROUPWNDS; docnum++)
  598.           {
  599.             if (!GroupDocs[docnum].InUse)
  600.          {
  601.            found = TRUE;
  602.            newdoc = TRUE;
  603.            CommDoc = &(GroupDocs[docnum]); 
  604.            CommDoc->LongestLine = 0;
  605.            CommDoc->ScXOffset = 0;
  606.            break;
  607.          }
  608.           }
  609.         if (!found)
  610.           {
  611.             MessageBox (hWnd, "You have too many group windows \
  612. active;\nClose one or select 'Reuse Old Window'.", "Can't open new window", MB_OK | MB_ICONASTERISK);
  613.             UnlockLine (GroupBlockPtr, GroupLinePtr, &hBlock, &Offset, &MyLineID);
  614.             break;
  615.           }
  616.       }
  617.          else
  618.       {
  619.         /* Must reuse old window for this group.           */  
  620.         ActiveGroupDoc->LongestLine = 0;
  621.         ActiveGroupDoc->ScXOffset = 0;
  622.         CommDoc = ActiveGroupDoc;
  623.     UpdateSeenArts (CommDoc);
  624.         UnlinkArtsInGroup (CommDoc);
  625.         LockLine (CommDoc->hParentBlock, CommDoc->ParentOffset, CommDoc->ParentLineID, &BlockPtr, &LinePtr);
  626.         ((TypGroup far *)
  627.          (((char far *) LinePtr) + sizeof (TypLine)))->SubjDoc = (TypDoc *) NULL;
  628.         UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
  629.         /* clear out contents of this document for reuse */
  630.         FreeDoc (CommDoc);
  631.       }
  632.  
  633.          /* Create window title indicating we are retrieving text. */
  634.  
  635.          CommDoc->InUse = TRUE;
  636.          lpsz = (char far *) (((char far *) GroupLinePtr) +
  637.                sizeof (TypLine) + sizeof (TypGroup));
  638.          strcpy (mybuf, "Retrieving ");
  639.          lstrcat (mybuf, lpsz);
  640.  
  641.          /* If necessary, create a new window.              */
  642.  
  643.          if (newdoc)
  644.       {
  645.         int x,y,width,height;
  646.         char poschars[MAXINTERNALLINE];
  647.  
  648.         /* Compute default screen position. */
  649.         x = 1;
  650.         y = 0;
  651.         width = (int) xScreen;
  652.         height = (int) (yScreen * 1 / 2);
  653.  
  654.         /* If the screen position has been saved, use that instead. */
  655.         GetPrivateProfileString (szAppName, "GroupWindowPos", "!",
  656.           poschars,MAXINTERNALLINE,szAppProFile);
  657.         if(poschars[0] != '!') {
  658.           sscanf(poschars,"%d,%d,%d,%d",&x,&y,&width,&height);
  659.         }
  660.         hWndView = CreateWindow ("WinVnView",
  661.                   mybuf,
  662.                   WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
  663.                   x + (int) docnum * CharWidth,/* Initial X pos */
  664.                   y + (int) docnum * LineHeight,
  665.                   width,           /* Initial X Width */
  666.                   height,
  667.                   NULL,
  668.                   NULL,
  669.                   hInst,
  670.                   NULL);
  671.  
  672.         if (!hWndView)
  673.           return (0); /* ??? */
  674.  
  675.     SetHandleBkBrush (hWndView, hListBackgroundBrush);
  676.    ShowWindow (hWndView, SW_SHOWNORMAL);
  677.       }
  678.          else
  679.       {
  680.         hWndView = CommDoc->hDocWnd;
  681.         SetWindowText (hWndView, mybuf);
  682.       }
  683.          RcvLineCount = 0;
  684.          TimesWndUpdated = 0;
  685.  
  686.          /* Do some housekeeping:  Set group as selected,
  687.           * initialize empty document to hold subject lines,
  688.           * set focus to this document, set pointers linking
  689.           * this document and the subject line.
  690.           */
  691.          ((TypGroup far *) (((char far *) GroupLinePtr) +
  692.              sizeof (TypLine)))->Selected = TRUE;
  693.          InitDoc (CommDoc, hWndView, &NetDoc, DOCTYPE_GROUP);
  694.          PtrToOffset (GroupBlockPtr, GroupLinePtr, &(CommDoc->hParentBlock),
  695.          &(CommDoc->ParentOffset), &(CommDoc->ParentLineID));
  696.          SetActiveWindow (hWndView);
  697.          SetFocus (hWndView);
  698.  
  699.          ((TypGroup far *) (((char far *) GroupLinePtr) + sizeof (TypLine)))
  700.       ->SubjDoc = CommDoc;
  701.          GlobalUnlock (GroupBlockPtr->hCurBlock);
  702.          InvalidateRect (hWndView, NULL, FALSE);
  703.  
  704.          UpdateWindow (hWndView);
  705.  
  706.          InvalidateRect (NetDoc.hDocWnd, NULL, FALSE);
  707.  
  708.          /* Deal with Comm-related stuff:  set FSA variables,
  709.           * send the GROUP command to NNTP.
  710.           */
  711.  
  712.          CommLinePtr = CommLineIn;
  713.          CommBusy = TRUE;
  714.          CommState = ST_GROUP_RESP;
  715.          hSaveCursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
  716.          ShowCursor (TRUE);
  717.  
  718. /* capture the mouse to the usenet window, so that we keep the hourglass */
  719.  
  720. //       SetCapture (hWnd);
  721.          strcpy (mybuf, "GROUP ");
  722.          lpsz = (char far *) GroupLinePtr + sizeof (TypLine) + sizeof (TypGroup);
  723.          lstrcat (mybuf, lpsz);
  724.          mylstrncpy (CurrentGroup, lpsz, MAXFINDSTRING);
  725.          PutCommLine (mybuf);
  726.        }
  727.    }
  728.       break;
  729.  
  730. // If we've lost the connection for some reason, kill the timer
  731. // that's banging on the socket.
  732.     case WM_TIMER:
  733.      if ((CommState == ST_CLOSED_COMM) && (!Initializing))
  734.        {
  735.      KillTimer(hWnd,ID_TIMER) ;
  736.        }
  737.      else 
  738.        {
  739.     if (CommState != ST_CLOSED_COMM)
  740.       DoCommInput ();
  741.        };
  742.       break;
  743.  
  744.     case WM_SIZE:
  745.       /* Store the new size of the window.                     */
  746.       GetClientRect (hWnd, &myRect);
  747.       NetDoc.ScXWidth = myRect.right;
  748.       NetDoc.ScYHeight = myRect.bottom;
  749.       NetDoc.ScYLines = (myRect.bottom - myRect.top - TopSpace) / LineHeight;
  750.       NetDoc.ScXChars = (myRect.right - myRect.left - SideSpace) / CharWidth;
  751.       break;
  752.  
  753.     case WM_VSCROLL:
  754.       if (!Initializing)
  755.    {
  756.      ScrollIt (&NetDoc, wParam, lParam);
  757.    }
  758.       break;
  759.  
  760.     case WM_HSCROLL:
  761.       if (!Initializing)
  762.       {
  763.         HScrollIt (&NetDoc, wParam, lParam);
  764.       }
  765.       break;
  766.  
  767.     case WM_COMMAND:
  768.       switch (LOWORD(wParam))
  769.    {
  770.                                                            
  771.    case IDM_QUIT:
  772.      SaveNewsrc = SaveConfig = FALSE;
  773.      DestroyWindow (hWnd);
  774.      break;
  775.  
  776.    case IDM_EXIT: 
  777.       SendMessage(hWnd, WM_CLOSE, 0, 0L);
  778.       break;
  779.  
  780.    case IDM_VIEW_SEL_GROUP:
  781.      break;
  782.  
  783.    case IDM_SHOW_SUBSCR:
  784.    case IDM_SHOW_ALL_GROUP:
  785.    case IDM_SEL_SUBSCR:
  786.    case IDM_SELECTALL:
  787.      MessageBox (hWnd, "Command not implemented",
  788.             "Sorry", MB_OK);
  789.      break;
  790.  
  791.    case IDM_UNSEL_ALL:
  792.      ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
  793.      InvalidateRect (hWnd, NULL, FALSE);
  794.      break;
  795.  
  796.    case IDM_SUBSCRIBE:
  797.      InitGroupTable ();
  798.      ForAllLines (&NetDoc, GroupAction, GROUP_ACTION_SUBSCRIBE, TRUE);
  799.      BuildPtrList ();
  800.      MergeGroups (ADD_SUBSCRIBED_END_OF_SUB);
  801.      CleanUpGroupTable ();
  802.      ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
  803.      NetDoc.LongestLine = 0;
  804.      SetGroupActiveLines();
  805.      ScreenToTop (&NetDoc);
  806.      SetNetDocTitle ();
  807.      InvalidateRect (hWnd, NULL, FALSE);
  808.      break;
  809.  
  810.    case IDM_UNSUBSCRIBE:
  811.      InitGroupTable ();
  812.      ForAllLines (&NetDoc, GroupAction, GROUP_ACTION_UNSUBSCRIBE, FALSE);
  813.      BuildPtrList ();
  814.      ShellSort (NewGroupTable,
  815.         (size_t) nNewGroups,
  816.         (size_t) sizeof (void far *),
  817.         GroupCompare);
  818.      MergeGroups (ADD_SUBSCRIBED_END_OF_SUB);
  819.      CleanUpGroupTable ();
  820.      ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
  821.      NetDoc.LongestLine = 0;
  822.      SetGroupActiveLines();
  823.      ScreenToTop (&NetDoc);
  824.      SetNetDocTitle ();
  825.      InvalidateRect (hWnd, NULL, FALSE);
  826.      break;
  827.  
  828.    case IDM_GROUP_TOP:
  829.      InitGroupTable ();
  830.      ForAllLines (&NetDoc, GroupAction, GROUP_ACTION_SUBSCRIBE, TRUE);
  831.      BuildPtrList ();
  832.      MergeGroups (ADD_SUBSCRIBED_TOP_OF_DOC);
  833.      CleanUpGroupTable ();
  834.      ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
  835.      ScreenToTop (&NetDoc);
  836.      InvalidateRect (hWnd, NULL, FALSE);
  837.      break;
  838.  
  839. #if 0 // This code not used anywhere (JSC 1/12/94)
  840.    case IDM_NEW_WIN_GROUP:
  841.      ViewNew = !ViewNew;
  842.      CheckView (hWnd);
  843.      break;
  844.  
  845.    case IDM_NEW_WIN_ARTICLE:
  846.      NewArticleWindow = !NewArticleWindow;
  847.      CheckView (hWnd);
  848.      break;
  849. #endif
  850.  
  851.    case IDM_COMMOPTIONS:
  852.  
  853.      if (DialogBox (hInst, "WinVnComm", hWnd, lpfnWinVnCommDlg))
  854.        {
  855.          InvalidateRect (hWnd, NULL, TRUE);
  856.        }
  857.  
  858.      break;
  859.  
  860.    case IDM_CONFIG_PERSONAL:
  861.  
  862.      DialogBox (hInst, "WinVnPersonal", hWnd, lpfnWinVnPersonalInfoDlg);
  863.      break;
  864.  
  865.    case IDM_CONFIG_MISC:
  866.  
  867.      DialogBox (hInst, "WinVnMisc", hWnd, lpfnWinVnMiscDlg);
  868.  
  869.      break;
  870.  
  871.    case IDM_CONFIG_LOG:
  872.  
  873.      DialogBox (hInst, "WinVnLogOpts", hWnd, lpfnWinVnLogOptDlg);
  874.  
  875.      break;
  876.  
  877.    case IDM_CONFIG_SIGFILE:
  878.      if (DialogBox (hInst, "WinVnSigFile", hWndConf, lpfnWinVnSigFileDlg))
  879.        {
  880.          InvalidateRect (hWnd, NULL, TRUE);
  881.        }
  882.  
  883.      break;
  884.  
  885.    case IDM_CONFIG_SMART_FILER:
  886.      DialogBox(hInst, "WinvnSmartFiler", hWndConf, lpfnWinVnSmartFilerDlg);
  887.      break;
  888.  
  889.    case IDM_FONT_GROUPLIST:
  890.      if (AskForFont (hWndConf, ListFontFace, &ListFontSize, ListFontStyle)) 
  891.        break;
  892.      InitListFonts();
  893.      SendMessage (hWndConf, WM_SIZE, 0, 0L);
  894.      InvalidateRect (hWndConf, NULL, TRUE);
  895.      RefreshGroupWnds();
  896.      break;
  897.  
  898.    case IDM_FONT_ARTICLE_TEXT:
  899.      if (AskForFont (hWndConf, ArticleFontFace, &ArticleFontSize, ArticleFontStyle)) 
  900.        break;
  901.      InitArticleFonts();
  902.      RefreshArticleWnds();
  903.      break;
  904.  
  905.    case IDM_FONT_STATUS_TEXT:
  906.     askStatusFont:;
  907.      if (AskForFont (hWndConf, StatusFontFace, &StatusFontSize, StatusFontStyle)) 
  908.         break;
  909.      InitStatusFonts();
  910.      if (STATUSWIDTH > xScreen)
  911.      {
  912.        MessageBox (hWndConf,"The status window will not fit on your screen with this font.\nPlease select a smaller font",
  913.                        "Font too big", MB_OK|MB_ICONSTOP);
  914.        goto askStatusFont;
  915.      }
  916.      RefreshStatusWnds();
  917.      break;
  918.  
  919.    case IDM_FONT_PRINT_TEXT:
  920.      if (AskForFont (hWndConf, PrintFontFace, &PrintFontSize, "Printer")) 
  921.        break;
  922.      InitPrintFonts();
  923.      InvalidateRect (hWndConf, NULL, TRUE);
  924.      break;
  925.  
  926.    case IDM_COLOR_SUBSCRIBED:
  927.      if (AskForColor (hWndConf, &NetSubscribedColor))
  928.        break;
  929.      InvalidateRect (hWndConf, NULL, TRUE);
  930.      break;
  931.  
  932.    case IDM_COLOR_UNSUBSCRIBED:
  933.      if (AskForColor (hWndConf, &NetUnSubscribedColor))
  934.        break;
  935.      InvalidateRect (hWndConf, NULL, TRUE);
  936.      break;
  937.  
  938.    case IDM_COLOR_SEEN:
  939.      if (AskForColor (hWndConf, &ArticleSeenColor))
  940.        break;
  941.      RefreshGroupWnds();
  942.      break;
  943.  
  944.    case IDM_COLOR_UNSEEN:
  945.      if (AskForColor (hWndConf, &ArticleUnSeenColor))
  946.        break;
  947.      RefreshGroupWnds();
  948.      break;
  949.  
  950.    case IDM_COLOR_ARTICLE_TEXT:
  951.      if (AskForColor (hWndConf, &ArticleTextColor))
  952.        break;
  953.      RefreshArticleWnds();
  954.      break;
  955.  
  956.    case IDM_COLOR_STATUS_TEXT:
  957.      if (AskForColor (hWndConf, &StatusTextColor))
  958.        break;
  959.      RefreshStatusWnds();
  960.      break;
  961.  
  962.    case IDM_COLOR_LIST_BACKGROUND:
  963.      if (AskForColor (hWndConf, &ListBackgroundColor))
  964.        break;
  965.      DeleteObject (hListBackgroundBrush);
  966.      hListBackgroundBrush = CreateSolidBrush (ListBackgroundColor);
  967.      SetHandleBkBrush (hWnd, hListBackgroundBrush);
  968.  
  969.      RefreshGroupWnds();
  970.      InvalidateRect (hWndConf, NULL, TRUE);
  971.      break;
  972.  
  973.    case IDM_COLOR_ARTICLE_BACKGROUND:
  974.      if (AskForColor (hWndConf, &ArticleBackgroundColor))
  975.         break;
  976.       DeleteObject (hArticleBackgroundBrush);
  977.       hArticleBackgroundBrush = CreateSolidBrush (ArticleBackgroundColor);
  978.       RefreshArticleWnds();
  979.       break;
  980.  
  981.    case IDM_COLOR_STATUS_BACKGROUND:
  982.      if (AskForColor (hWndConf, &StatusBackgroundColor))
  983.        break;
  984.      DeleteObject (hStatusBackgroundBrush);
  985.      hStatusBackgroundBrush = CreateSolidBrush (StatusBackgroundColor);
  986.      RefreshStatusWnds();
  987.      break;
  988.  
  989.  
  990.    case IDM_WINDOW_CASCADE:
  991.      CascadeWindows();
  992.      break;
  993.    
  994.    case IDM_CLOSE_ALL:
  995.      if (ConfirmBatchOps)
  996.        if (MessageBox (hWndConf, "Are you sure you wish to close all open windows?", 
  997.                        "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO)
  998.          break;
  999.      CloseArticleWnds();
  1000.      CloseGroupWnds();
  1001.      CloseStatusWnds();
  1002.      break;
  1003.  
  1004.    case IDM_CLOSE_ALL_ARTICLE:
  1005.      if (ConfirmBatchOps)
  1006.        if (MessageBox (hWndConf, "Are you sure you wish to close all open article windows?", 
  1007.                        "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO)
  1008.          break;
  1009.      CloseArticleWnds();
  1010.      break;
  1011.  
  1012.    case IDM_CLOSE_ALL_GROUP:
  1013.      if (ConfirmBatchOps)
  1014.        if (MessageBox (hWndConf,"Are you sure you wish to close all open group windows?", 
  1015.                        "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO)
  1016.          break;
  1017.      CloseGroupWnds();
  1018.      break;
  1019.  
  1020.    case IDM_CLOSE_ALL_STATUS:
  1021.      if (ConfirmBatchOps)
  1022.        if (MessageBox (hWndConf, "Are you sure you wish to close all open status windows?", 
  1023.                        "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO)
  1024.          break;
  1025.      CloseStatusWnds();
  1026.      break;
  1027.  
  1028.    case IDM_SEND_ALL_POST:
  1029.      if (ConfirmBatchOps)
  1030.        if (MessageBox (hWndConf, "Are you sure you wish to send all open post windows?", 
  1031.                        "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO)
  1032.          break;
  1033.      BatchSend(DOCTYPE_POSTING);
  1034.      break;
  1035.  
  1036.    case IDM_SEND_ALL_MAIL:
  1037.      if (ConfirmBatchOps)
  1038.        if (MessageBox (hWndConf, "Are you sure you wish to send all open mail windows?", 
  1039.                        "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO)
  1040.          break;
  1041.      BatchSend(DOCTYPE_MAIL);
  1042.      break;
  1043.  
  1044.    case IDM_DECODE_FILE:
  1045.      if (TestDecodeBusy(hWndConf, "Can't decode file"))
  1046.        break;
  1047.  
  1048.      if (!DialogBoxParam (hInst, "WinVnDecodeArts", hWndConf, lpfnWinVnDecodeArtsDlg, 0))
  1049.         InvalidateRect (hWndConf, NULL, TRUE);
  1050.      else
  1051.         DecodeFile(hWnd);
  1052.      break;
  1053.  
  1054.    case IDM_ENCODE_FILE:
  1055.       if (TestDecodeBusy(hWndConf, "Can't encode file"))
  1056.         break;
  1057.       if (!DialogBox (hInst, "WinVnEncode", hWndConf, lpfnWinVnEncodeDlg))
  1058.          InvalidateRect (hWndConf, NULL, TRUE);
  1059.       else
  1060.          EncodeToFile (hWndConf, AttachFileName);
  1061.       break;
  1062.  
  1063.    case IDM_RESET:
  1064.      AbortAllComm();
  1065.      break;
  1066.  
  1067.    case IDM_CONNECT:
  1068.      Connect (); // menus are enabled in WM_PAINT once connection is established
  1069.      break;
  1070.  
  1071.    case IDM_DISCONNECT:
  1072.      /* If the NNTP server disconnected, then Initializing == INIT_NOT_CONNECTED */
  1073.      if ((Initializing != INIT_NOT_CONNECTED)
  1074.         && (MessageBox (hWndConf, 
  1075.                    "Are you sure you wish to disconnect from the server?\n"
  1076.                    "All active windows will be closed.",
  1077.                         "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO))
  1078.         break;
  1079.  
  1080.    //  PutCommLine ("QUIT\r\n");      // breaks Pathworks stack 
  1081.        PutCommData ("QUIT\r\n",6);
  1082.      KillTimer(hWnd, ID_TIMER);
  1083.  
  1084.      Initializing = INIT_NOT_CONNECTED;
  1085.      SetUserMenus (hWnd, DISABLE);
  1086.      InvalidateRect (hWnd, NULL, TRUE);
  1087.      UpdateWindow (hWnd);
  1088.  
  1089.      MRRCloseComm();     // blammo
  1090.  
  1091.      if (Decoding)
  1092.      {
  1093.          CompleteThisDecode();
  1094.          DecodeDone();
  1095.      }
  1096.      else if (Attaching)
  1097.          FinishAttachment (ABORT);
  1098.  
  1099.      CommDoc = NULL;
  1100.      CloseArticleWnds();
  1101.      CloseGroupWnds();
  1102.      CloseStatusWnds();
  1103.     
  1104.      break;
  1105.  
  1106.    case IDM_SAVE_CONFIG:
  1107.      WriteWinvnProfile();
  1108.      MessageBox (hWndConf, "WinVn Configuration Saved", "WinVn Configuration", MB_OK);
  1109.      break;
  1110.  
  1111.    case IDM_SAVE_WINDOW:
  1112.      {
  1113.      RECT rect;
  1114.  
  1115.      /* Save position and size of Usenet window. */
  1116.      GetWindowRect(hWndConf,&rect);
  1117.      sprintf(mybuf,"%d,%d,%d,%d",rect.left,rect.top,
  1118.        rect.right-rect.left,rect.bottom-rect.top);
  1119.      WritePrivateProfileString
  1120.       (szAppName, "UsenetWindowPos", mybuf, szAppProFile);
  1121.  
  1122.  
  1123.      /* Save position and size of first Group window */
  1124.  
  1125.      for(found=FALSE,idoc=0; !found && idoc<MAXGROUPWNDS; idoc++) {
  1126.        if(GroupDocs[idoc].InUse) {
  1127.          GetWindowRect(GroupDocs[idoc].hDocWnd,&rect);
  1128.          found = TRUE;
  1129.          sprintf(mybuf,"%d,%d,%d,%d",rect.left,rect.top,
  1130.             rect.right-rect.left,rect.bottom-rect.top);
  1131.          WritePrivateProfileString
  1132.            (szAppName, "GroupWindowPos", mybuf, szAppProFile);
  1133.        }
  1134.      }
  1135.  
  1136.      /* Save position and size of first Article window */
  1137.  
  1138.      for(found=FALSE,idoc=0; !found && idoc<MAXARTICLEWNDS; idoc++) {
  1139.        if(ArticleDocs[idoc].InUse) {
  1140.          GetWindowRect(ArticleDocs[idoc].hDocWnd,&rect);
  1141.          found = TRUE;
  1142.          sprintf(mybuf,"%d,%d,%d,%d",rect.left,rect.top,
  1143.             rect.right-rect.left,rect.bottom-rect.top);
  1144.          WritePrivateProfileString
  1145.            (szAppName, "ArticleWindowPos", mybuf, szAppProFile);
  1146.        }
  1147.      }
  1148.  
  1149.      break;
  1150.      }
  1151.  
  1152.    case IDM_FIND:
  1153.      FindDoc = &NetDoc;
  1154.      if (!(FindDoc->SearchStr[0]) && LastGroupNameFind[0]) 
  1155.         strcpy(FindDoc->SearchStr, LastGroupNameFind);
  1156.  
  1157.      if (DialogBox (hInst, "WinVnFind", hWnd, lpfnWinVnFindDlg))
  1158.        {
  1159.          found = DoFind (TRUE);
  1160.          if (!found)
  1161.       {
  1162.         strcpy (mybuf, "\"");
  1163.         strcat (mybuf, NetDoc.SearchStr);
  1164.         strcat (mybuf, "\" not found.");
  1165.         MessageBox (hWnd, mybuf, "Not found", MB_OK);
  1166.       }
  1167.       else
  1168.           strcpy(LastGroupNameFind, FindDoc->SearchStr);
  1169.  
  1170.        }
  1171.      break;
  1172.  
  1173.    case IDM_FIND_NEXT_SAME:
  1174.      FindDoc = &NetDoc;
  1175.    
  1176.      continueFind = TRUE;
  1177.      if (!FindDoc->SearchStr[0]) {
  1178.        if (!(FindDoc->SearchStr[0]) && LastGroupNameFind[0]) 
  1179.           strcpy(FindDoc->SearchStr, LastGroupNameFind);
  1180.        continueFind = DialogBox (hInst, "WinVnFind", hWnd, lpfnWinVnFindDlg);
  1181.      }
  1182.  
  1183.      if (continueFind && FindDoc->SearchStr[0])
  1184.        {
  1185.          found = DoFind (!FindDoc->hFindBlock && !FindDoc->FindLineID);
  1186.          if (!found)
  1187.       {
  1188.         strcpy (mybuf, "\"");
  1189.         strcat (mybuf, NetDoc.SearchStr);
  1190.         strcat (mybuf, "\" not found.");
  1191.         MessageBox (hWnd, mybuf, "No more occurrences", MB_OK);
  1192.       }
  1193.        }
  1194.      break;
  1195.  
  1196.    case ID_ABOUT:
  1197.      lpProcAbout = (DLGPROC)MakeProcInstance ((FARPROC)About, hInst);
  1198.      DialogBox (hInst, "AboutBox", hWnd, lpProcAbout);
  1199.      FreeProcInstance ((FARPROC)lpProcAbout);
  1200.      break;
  1201.  
  1202.    case IDM_HELP:
  1203.      MakeHelpPathName (mybuf, MAXINTERNALLINE);
  1204.      WinHelp (hWndConf, mybuf, HELP_INDEX, 0L);
  1205.      break;
  1206.  
  1207.    case IDM_MAIL:
  1208.      (MailCtrl.fnMlWinCreate)(hWnd, (TypDoc *) NULL, DOCTYPE_MAIL);
  1209.      break;
  1210.  
  1211.    case IDM_LOGOUT:
  1212.      (MailCtrl.fnMlLogout)(hWnd);
  1213.      break;
  1214.  
  1215.    case IDM_SHOW_VERSION:
  1216.      show_version_strings(hWnd);
  1217.      break;
  1218.  
  1219.    case IDM_POST:
  1220.      DialogBoxParam (hInst, "WinVnGeneric", hWnd,
  1221.            lpfnWinVnGenericDlg, (LPARAM) (char far *) "Newsgroup(s):");
  1222.      NewsgroupsPtr = DialogString;
  1223.      CreatePostingWnd (hWnd, (TypDoc *) NULL, DOCTYPE_POSTING);
  1224.      break;
  1225.  
  1226.    }
  1227.       break;
  1228.  
  1229.     case WM_PAINT:
  1230.       {
  1231.    HANDLE hBlock;
  1232.    SIZE sz;
  1233.    unsigned int Offset, MyLen, indicatorwidth;
  1234.    int VertLines, HorzChars;
  1235.    int EndofDoc = FALSE;
  1236.    int RangeHigh, CurPos;
  1237.    int Xtext;
  1238.    char far *textptr;
  1239.    char *cptr, *cptr2;
  1240.    char indicator;
  1241.    char indcptr[128];
  1242.    char group_name[MAXINTERNALLINE];
  1243.    char init_msg[60];
  1244.    TypGroup far *MyGroup;
  1245.    TypRange far *RangePtr;
  1246.    unsigned long int   HighestRead;
  1247.    COLORREF MyColors[4], MyBack[4];
  1248. // DWORD Rop;
  1249.    RECT myRect, aRect;
  1250.    int MyColorMask = 1, PrevColorMask = MyColorMask;
  1251. #define SUBSCR_MASK 1
  1252. #define SELECT_MASK 2
  1253.  
  1254.    hDC = BeginPaint (hWnd, &ps); 
  1255.    SetBkColor (hDC, ListBackgroundColor);
  1256.    if (ListBackgroundColor == RGB(0,0,0))
  1257.       SetTextColor(hDC, RGB(200,200,200));     // if background is black, make text white
  1258.    else
  1259.       SetTextColor(hDC, RGB(0,0,0));        // otherwise text is black
  1260.  
  1261.    GetClientRect (hWnd, &myRect);
  1262.    SelectObject (hDC, hListFont);
  1263.  
  1264.    /* If still initializing comm link, put out a message    */
  1265.    /* to that effect.                                       */
  1266.  
  1267.    switch (Initializing)
  1268.      {
  1269.      case INIT_NOT_CONNECTED:
  1270.        cptr = "Not connected";
  1271.        cptr2 = "to news server";
  1272.  
  1273.        goto display_msg;
  1274.  
  1275.      case INIT_ESTAB_CONN:
  1276.        cptr = "Establishing link";
  1277.        cptr2 = "to news server...";
  1278.  
  1279.        goto display_msg;
  1280.  
  1281.      case INIT_READING_NEWSRC:
  1282.        cptr = "Reading your log";
  1283.        cptr2 = "(\"newsrc\")...";
  1284.        goto display_msg;
  1285.  
  1286.      case INIT_SCANNING_NETDOC:
  1287.        cptr = "Creating hash table";
  1288.        cptr2 = "from current groups...";
  1289.        goto display_msg;
  1290.  
  1291.      case INIT_GETTING_LIST:
  1292.        sprintf (mybuf, "Receiving %uth newsgroup", RcvLineCount);
  1293.        cptr = mybuf;
  1294.        cptr2 = "name from server...";
  1295.  
  1296.      display_msg:;
  1297.        X = SideSpace + CharWidth;
  1298.        Y = StartPen + 2 * LineHeight;
  1299.        strcpy (init_msg, cptr);
  1300.        strcat (init_msg, "    ");
  1301.        j = strlen (init_msg);
  1302.        TextOut (hDC, X, Y, init_msg, j);
  1303.        strcpy (init_msg, cptr2);
  1304.        strcat (init_msg, "    ");
  1305.        j = strlen (init_msg);
  1306.        TextOut (hDC, X, Y + LineHeight, init_msg, j);
  1307.        break;
  1308.  
  1309.      case INIT_READY:
  1310.         /* this state happens when all connection prep is finished 
  1311.          * and we are ready to begin normal WinVn user operation
  1312.          */
  1313.          SetUserMenus (hWnd, ENABLE);
  1314.         Initializing = INIT_DONE;
  1315.         // fall into INIT_DONE
  1316.  
  1317.      case INIT_DONE:
  1318.  
  1319.        VertLines = NetDoc.ScYLines;
  1320.        HorzChars = NetDoc.ScXChars;
  1321.        MyColors[0] = NetUnSubscribedColor;      // unseen/unselected    
  1322.        MyColors[1] = NetSubscribedColor;     // seen/unselected
  1323.        MyColors[2] = MyColors[0];         // unseen/selected
  1324.        MyColors[3] = ListBackgroundColor;    // seen/selected
  1325.  
  1326.        MyBack[0] = MyColors[3];
  1327.        MyBack[1] = MyBack[0];
  1328.        if (ListBackgroundColor == RGB(0,0,0))
  1329.          MyBack[2] = RGB(200,200,200);    // selected = white background
  1330.        else
  1331.          MyBack[2] = RGB(0,0,0);       // selected = black background
  1332. //       MyBack[2] = MyColors[1];
  1333.        MyBack[3] = MyBack[2];
  1334.  
  1335.        SetTextColor (hDC, MyColors[MyColorMask]);
  1336.        SetBkColor (hDC, MyBack[MyColorMask]);
  1337.  
  1338.        GetTextExtentPoint (hDC, "*", 2, &sz);             
  1339.        indicatorwidth = sz.cx*7*7;                        
  1340.  
  1341.        LockLine (NetDoc.hCurTopScBlock, NetDoc.TopScOffset, NetDoc.TopScLineID,
  1342.             &BlockPtr, &LinePtr);
  1343.  
  1344.        /* Update the scroll bar thumb position.                 */
  1345.  
  1346.        CurPos = NetDoc.TopLineOrd;
  1347.        if (CurPos < 0)
  1348.          CurPos = 0;   
  1349.        RangeHigh = NetDoc.ActiveLines - VertLines;;
  1350.        if (RangeHigh < 0)
  1351.          RangeHigh = 0;
  1352.        SetScrollRange (hWnd, SB_VERT, 0, RangeHigh, FALSE);
  1353.        SetScrollPos (hWnd, SB_VERT, CurPos, TRUE);
  1354.  
  1355.        RangeHigh = NetDoc.LongestLine - NetDoc.ScXChars; 
  1356.        if (RangeHigh < 0) 
  1357.        {
  1358.          RangeHigh = 0;
  1359.          NetDoc.ScXOffset = 0;
  1360.        }
  1361.        SetScrollRange (hWnd, SB_HORZ, 0, RangeHigh, FALSE);
  1362.        SetScrollPos (hWnd, SB_HORZ, NetDoc.ScXOffset, TRUE); 
  1363.  
  1364.        /* Loop through the lines, painting them on the screen. */
  1365.  
  1366.        X = SideSpace - NetDoc.ScXOffset * (CharWidth+1);
  1367.        Xtext = X + indicatorwidth;
  1368.        Y = StartPen;
  1369.        if (LinePtr->length != END_OF_BLOCK)
  1370.          do
  1371.        {                               
  1372.         MyGroup = ((TypGroup far *)
  1373.               ((char far *) LinePtr + sizeof (TypLine)));
  1374.         MyLen = MyGroup->NameLen;
  1375.         textptr = (char far *) LinePtr + sizeof (TypLine) +
  1376.           sizeof (TypGroup); 
  1377.           
  1378.         /* Display this line only if it is active. */  
  1379.         if(LinePtr->active) {
  1380.  
  1381.         /* Figure out the color of this line.                 */
  1382.  
  1383.         if (MyGroup->Subscribed)
  1384.           {
  1385.             MyColorMask |= SUBSCR_MASK;
  1386.           }
  1387.         else
  1388.           {
  1389.             MyColorMask &= (0xff - SUBSCR_MASK);
  1390.           }
  1391.         if (MyGroup->Selected)
  1392.           {
  1393.             MyColorMask |= SELECT_MASK;
  1394.           }
  1395.         else
  1396.           {
  1397.             MyColorMask &= 0xff - SELECT_MASK;
  1398.           }
  1399.         if (MyColorMask != PrevColorMask)
  1400.           {
  1401.             SetTextColor (hDC, MyColors[MyColorMask]);
  1402.             SetBkColor (hDC, MyBack[MyColorMask]);
  1403.             PrevColorMask = MyColorMask;
  1404.           }
  1405.  
  1406.         /* Figure out what indicator character to use. */
  1407.  
  1408.         indicator = ' ';
  1409.         if (NetDoc.FindLineID == LinePtr->LineID)
  1410.           {
  1411.             indicator = '>';
  1412.           }
  1413.         else if (MyGroup->HighestPrevSeen)
  1414.           {
  1415.             if (MyGroup->ServerLast > MyGroup->HighestPrevSeen)
  1416.             {
  1417.               indicator = '*';
  1418.             }
  1419.             else {
  1420.               /* check if there are unread articles - jlg 4/9/94 */
  1421.               RangePtr = (TypRange far *) ((char far *) MyGroup + RangeOffset (MyGroup->NameLen));
  1422.               if (MyGroup->nRanges) {
  1423.                  HighestRead = RangePtr[MyGroup->nRanges-1].Last;
  1424.                  if (MyGroup->ServerLast > HighestRead && MyGroup->ServerEstNum > 0)
  1425.                    indicator = '*';
  1426.                  }
  1427.             }
  1428.           }
  1429.  
  1430.         mylstrncpy (group_name, textptr, MyGroup->NameLen + 1);
  1431.  
  1432.         if (MyGroup->Determined == FALSE)
  1433.            strcpy(str, "-");
  1434.         else
  1435.            sprintf(str, "%5lu", MyGroup->ServerEstNum); 
  1436.         
  1437.         sprintf (indcptr, "%c %5s %s ", indicator, str, group_name);
  1438.  
  1439.         /* Now write out the line.                            */
  1440.  
  1441.         MyLen = strlen (indcptr);
  1442.  
  1443.         SetRect (&aRect, 0, Y, myRect.right, Y+LineHeight);
  1444.         
  1445.         ExtTextOut (hDC, X, Y, ETO_OPAQUE|ETO_CLIPPED, &aRect,
  1446.                     indcptr, MyLen, (LPINT)NULL);
  1447.        
  1448.         Y += LineHeight;
  1449.         --VertLines;
  1450.         }  /* end if LinePtr->active */  
  1451.        }
  1452.        while (VertLines > 0 && NextLine (&BlockPtr, &LinePtr));
  1453.  
  1454. //       SetTextColor (hDC, MyColors[1]);
  1455. //       SetBkColor (hDC, MyBack[1]);
  1456. //       SelectObject (hDC, UnSelectedBrush);
  1457.  
  1458.        /* Blank out bottom and top of screen */
  1459.        SelectObject (hDC, hListBackgroundBrush);
  1460.        PatBlt (hDC, 0, Y, myRect.right-1, myRect.bottom - Y, PATCOPY);
  1461.        PatBlt (hDC, 0, 0, myRect.right-1, TopSpace, PATCOPY);
  1462.  
  1463.        UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
  1464.      }
  1465.      EndPaint (hWnd, &ps);
  1466.      break;
  1467.     }
  1468.  
  1469.     case WM_ENDSESSION:
  1470.  
  1471.       WinHelp (hWndConf, LFN_HELP, HELP_QUIT, 0L);
  1472.       //CloseComm (CommDevice);
  1473.  
  1474.       break;
  1475.  
  1476.     case WM_CLOSE:
  1477.       if (!ConfirmExit) {
  1478.         SaveNewsrc = SaveConfig = TRUE;
  1479.       } else {
  1480.         // WinVnExitDlg sets SaveNewsrc and SaveConfig
  1481.         if (!DialogBox (hInst, "WinVnExit", hWnd, lpfnWinVnExitDlg))
  1482.         {
  1483.           InvalidateRect (hWnd, NULL, TRUE);
  1484.           break;
  1485.         }
  1486.       } 
  1487.       DestroyWindow (hWnd);
  1488.       break;
  1489.  
  1490.     case WM_DESTROY:
  1491. #if 0    /* happens as each group window is destroyed by CloseGroupWnds (jsc) */
  1492.       for (idoc = 0; idoc < MAXGROUPWNDS; idoc++)
  1493.    {
  1494.      if (GroupDocs[idoc].InUse)
  1495.        {
  1496.          UpdateSeenArts (&(GroupDocs[idoc]));
  1497.        }
  1498.    }
  1499. #endif
  1500.       if (Initializing != INIT_NOT_CONNECTED) {
  1501.   //       PutCommLine ("QUIT\r\n");                // breaks pathworks 
  1502.            PutCommData ("QUIT\r\n",6);
  1503.          MRRCloseComm ();
  1504.       }
  1505.  
  1506.       MailClose(hWnd);
  1507.  
  1508.       AbortAllComm();
  1509.  
  1510.       /* force client wnds to close before doing WriteNewsrc */
  1511.       CloseArticleWnds();    
  1512.       CloseGroupWnds();    
  1513.       CloseStatusWnds();
  1514.  
  1515.       if (SaveNewsrc)    /* do we need  && !Initializing? */
  1516.         WriteNewsrc();
  1517.       
  1518.       if (SaveConfig)
  1519.           WriteWinvnProfile();
  1520.  
  1521.       /* Remove resources before exiting program */
  1522.       FreeTextBlock (Signature);
  1523.       if (MailList)
  1524.         FreeTextBlock (MailList);
  1525.       
  1526.       DestroyFonts();
  1527.       DestroyBitmaps();
  1528.       // deselect the brush from the DC, or we can't free it
  1529.      SetHandleBkBrush (hWndConf, GetStockObject (WHITE_BRUSH));
  1530.       if (hListBackgroundBrush) DeleteObject(hListBackgroundBrush);
  1531.       if (hArticleBackgroundBrush) DeleteObject(hArticleBackgroundBrush);
  1532.       if (hStatusBackgroundBrush) DeleteObject(hStatusBackgroundBrush);
  1533.  
  1534.       PostQuitMessage (0);
  1535.       break;
  1536.  
  1537.     default:
  1538.       return (DefWindowProc (hWnd, message, wParam, lParam));
  1539.     }
  1540.   return (0);
  1541. }
  1542.  
  1543. void
  1544. SetConnectMenuItem (HWND hWnd, int enable)
  1545. {
  1546.     HMENU hMenu, hSubMenu;
  1547.     UINT mode;
  1548.     
  1549.     if (enable == ENABLE)    
  1550.         mode = MF_BYCOMMAND|MF_ENABLED;
  1551.     else
  1552.         mode = MF_BYCOMMAND|MF_DISABLED|MF_GRAYED;
  1553.     
  1554.     hMenu = GetMenu (hWnd);
  1555.     hSubMenu = GetSubMenu (hMenu, 0);    // config menu
  1556.     EnableMenuItem (hSubMenu, IDM_CONNECT, mode);
  1557. }
  1558.  
  1559. void
  1560. SetMainMailMenu (HWND hWnd)
  1561. {
  1562.     HMENU hMenu, hSubMenu;
  1563.     
  1564.     hMenu = GetMenu (hWnd);
  1565.     hSubMenu = GetSubMenu (hMenu, 0);    // network menu
  1566.       EnableMenuItem (hSubMenu, IDM_LOGOUT, MailCtrl.enableLogout) ;    
  1567.  
  1568.     hSubMenu = GetSubMenu (hMenu, 2);    // utilities menu
  1569.     EnableMenuItem (hSubMenu, IDM_MAIL, MailCtrl.enableMail) ;    
  1570. }
  1571.  
  1572. void
  1573. SetUserMenus (HWND hWnd, int enable)
  1574. {
  1575.     HMENU hMenu, hSubMenu;
  1576.     UINT mode;
  1577.     
  1578.     if (enable == ENABLE)    
  1579.         mode = MF_BYCOMMAND|MF_ENABLED;
  1580.     else
  1581.         mode = MF_BYCOMMAND|MF_DISABLED|MF_GRAYED;
  1582.     
  1583.     hMenu = GetMenu (hWnd);
  1584.     hSubMenu = GetSubMenu (hMenu, 1);    // group menu
  1585.     EnableMenuItem (hSubMenu, IDM_FIND, mode);
  1586.     EnableMenuItem (hSubMenu, IDM_FIND_NEXT_SAME, mode);
  1587.     EnableMenuItem (hSubMenu, IDM_SUBSCRIBE, mode);
  1588.     EnableMenuItem (hSubMenu, IDM_UNSUBSCRIBE, mode);
  1589.     EnableMenuItem (hSubMenu, IDM_GROUP_TOP, mode);
  1590.     EnableMenuItem (hSubMenu, IDM_UNSEL_ALL, mode);
  1591.  
  1592.     hSubMenu = GetSubMenu (hMenu, 2);    // utilities menu
  1593.     EnableMenuItem (hSubMenu, IDM_POST, mode);
  1594.     EnableMenuItem (hSubMenu, 3, mode|MF_BYPOSITION ) ;      // batch submenu
  1595.     
  1596.     hSubMenu = GetSubMenu (hMenu, 0);    // network menu
  1597.     EnableMenuItem (hSubMenu, IDM_RESET, mode);
  1598.     EnableMenuItem (hSubMenu, IDM_DISCONNECT, mode);
  1599.  
  1600.     SetConnectMenuItem (hWnd, !enable);        // connect item has reverse attributes
  1601.     SetMainMailMenu (hWnd);
  1602. }
  1603.  
  1604.  
  1605. /*---  FUNCTION: AbortAllComm -------------------------------------------
  1606.  *
  1607.  *  Kills all active comm stuff
  1608.  *  jsc 9/12/94
  1609.  */
  1610.  
  1611. void
  1612. AbortAllComm()
  1613. {
  1614.    if (Decoding) {
  1615.      CompleteThisDecode();
  1616.      DecodeDone();
  1617.    }
  1618.    else if (Attaching)
  1619.      FinishAttachment(ABORT);
  1620.     
  1621.    if (PostEdit)    /* !NULL if posting */
  1622.      CompletePost(PostEdit, ABORT);
  1623.  
  1624.    CommDoc = (TypDoc *)NULL;
  1625.    CommBusy = FALSE;
  1626.    CommState = ST_NONE;
  1627. }
  1628.  
  1629.      
  1630. /*---  FUNCTION: About ---------------------------------------------------
  1631.  *
  1632.  *  Process messages for "About" dialog box
  1633.  */
  1634.  
  1635. BOOL WINAPI About (hDlg, message, wParam, lParam)
  1636.      HWND hDlg;
  1637.      unsigned message;
  1638.      WORD wParam;
  1639.      LONG lParam;
  1640. {
  1641.   switch (message)
  1642.     {
  1643.     case WM_INITDIALOG:
  1644.       return (TRUE);
  1645.  
  1646.     case WM_COMMAND:
  1647.       if (wParam == IDOK)
  1648.    {
  1649.      EndDialog (hDlg, TRUE);
  1650.      return (TRUE);
  1651.    }
  1652.       break;
  1653.     }
  1654.   return (FALSE);
  1655. }
  1656.  
  1657. #if 0 // This code not used anywhere (JSC 1/12/94)
  1658. /* Function CheckView -----------------------------
  1659.  *
  1660.  *  This function handles checking and unchecking menu items.
  1661.  *
  1662.  *    Entry    hWnd     is the window whose menu is to be altered.
  1663.  *                      Currently works only for the Net window.
  1664.  *
  1665.  *    Exit     The appropriate items on the menu have been checked or
  1666.  *             unchecked.
  1667.  */
  1668.  
  1669. VOID 
  1670. CheckView (hWnd)
  1671.      HWND hWnd;
  1672. {
  1673.   HMENU hMenu;
  1674.   int CheckIt;
  1675.  
  1676.   if (ViewNew)
  1677.     {
  1678.       CheckIt = MF_CHECKED | MF_BYCOMMAND;
  1679.     }
  1680.   else
  1681.     {
  1682.       CheckIt = MF_UNCHECKED | MF_BYCOMMAND;
  1683.     }
  1684.   hMenu = GetMenu (hWnd);
  1685.  
  1686.   CheckMenuItem (hMenu, IDM_NEW_WIN_GROUP, CheckIt);
  1687.  
  1688.   if (NewArticleWindow)
  1689.     {
  1690.       CheckIt = MF_CHECKED | MF_BYCOMMAND;
  1691.     }
  1692.   else
  1693.     {
  1694.       CheckIt = MF_UNCHECKED | MF_BYCOMMAND;
  1695.     }
  1696.   CheckMenuItem (hMenu, IDM_NEW_WIN_ARTICLE, CheckIt);
  1697. }
  1698. #endif
  1699. /* --- function CrackGroupLine --------------------------------------
  1700.  *
  1701.  *  Given a line from a .newsrc file, create a text line containing
  1702.  *  a structure of type TypGroup containing the same information.
  1703.  *  The line is zero-terminated upon input.
  1704.  *
  1705.  *    Entry    buf      points to a zero-terminated line from .newsrc.
  1706.  *             lineptr  points to a place to put the converted textline.
  1707.  *
  1708.  *    Exit     The line pointed to by "lineptr" now is a TypLine textline
  1709.  *             containing a structure of type TypGroup, containing the
  1710.  *             information in the input line from .newsrc.
  1711.  *
  1712.  *  Returns TRUE iff group was subscribed to.
  1713.  */
  1714. BOOL
  1715. CrackGroupLine (buf, lineptr)
  1716.      char *buf;
  1717.      TypLine *lineptr;
  1718. {
  1719.   char *grname = (char *) lineptr + sizeof (TypLine) + sizeof (TypGroup);
  1720.   TypGroup *group = (TypGroup *) ((char *) lineptr + sizeof (TypLine));
  1721.   TypRange *RangePtr;
  1722.   BOOL MoreNums;
  1723.   unsigned int MyLength;
  1724.  
  1725.   group->Subscribed = FALSE;
  1726.   group->Selected = FALSE;
  1727.   group->Determined = FALSE;
  1728.   group->NameLen = 0;
  1729.   group->SubjDoc = (TypDoc *) NULL;
  1730.   group->ServerEstNum = 0;
  1731.   group->ServerFirst = 0;
  1732.   group->ServerLast = 0;
  1733.   group->HighestPrevSeen = 0;
  1734.   group->nRanges = 0;
  1735.   group->header_handle = (HANDLE) NULL;
  1736.  
  1737.   /* Copy group name to output line.                               */
  1738.  
  1739.   while (*buf && *buf != ':' && *buf != '!')
  1740.     {
  1741.       *(grname++) = *(buf++);
  1742.       (group->NameLen)++;
  1743.     }
  1744.   *(grname++) = '\0';
  1745.  
  1746.   if (!(*buf))
  1747.     {
  1748.       /* Ran off end of line without seeing ':' or '!'.  Error.      */
  1749.     }
  1750.   else
  1751.     {
  1752.       if (*buf == ':')
  1753.    {
  1754.      group->Subscribed = TRUE;
  1755.    }
  1756.       buf++;
  1757.     }
  1758.  
  1759.   /* Look for the highest article number previously seen, in an
  1760.    * entry of form "s" followed by a number.
  1761.    */
  1762.  
  1763.   while (*buf && *buf == ' ' && *buf != '\n')
  1764.     buf++;
  1765.   if (*buf == 's')
  1766.     {
  1767.       buf++;
  1768.       GetNum (&buf, &(group->HighestPrevSeen));
  1769.     }
  1770.  
  1771.   /* Convert the article number ranges to the internal numeric
  1772.    * form we use in WinVN.
  1773.    */
  1774.  
  1775.   RangePtr = (TypRange *) ((char *) lineptr + sizeof (TypLine) +
  1776.             RangeOffset (group->NameLen));
  1777.  
  1778.   RangePtr->Last = RangePtr->First = 0;
  1779.  
  1780.   // allow lines like this, with no range data:
  1781.   // news.group: 
  1782.   //
  1783.   MoreNums = ( (*buf)=='\n' ? FALSE : TRUE);
  1784.   while (MoreNums)
  1785.     {
  1786.       while (*buf && (*buf == ' ' || *buf == ','))
  1787.    buf++;
  1788.       if (GetNum (&buf, &(RangePtr->First)))
  1789.    {
  1790.      /* We have the first number in a range.                     */
  1791.      (group->nRanges)++;
  1792.      RangePtr->Last = RangePtr->First;
  1793.      if (*buf == '-')
  1794.        {
  1795.          buf++;
  1796.          if (GetNum (&buf, &(RangePtr->Last)))
  1797.       {
  1798.         RangePtr++;
  1799.         /* at this point, we are positioned just after a range */
  1800.       }
  1801.          else
  1802.       {
  1803.         RangePtr->Last = RangePtr->First;
  1804.         MoreNums = FALSE;
  1805.       }
  1806.        }
  1807.      else if (*buf == ',')
  1808.        {
  1809.          /* We have a single number "n"; interpret as the range "n-n".
  1810.           */
  1811.          RangePtr++;
  1812.        }
  1813.      else
  1814.        {
  1815.          /* That must have been the last number.                  */
  1816.          MoreNums = FALSE;
  1817.        }
  1818.    }
  1819.       else
  1820.    {
  1821.      MoreNums = FALSE;
  1822.    }
  1823.     }
  1824.   if (group->nRanges == 0)
  1825.     (group->nRanges)++;
  1826.  
  1827.   MyLength = sizeof (TypLine) + RangeOffset (group->NameLen) +
  1828.     sizeof (TypRange) * (group->nRanges) + sizeof (int);
  1829.  
  1830.   lineptr->length = MyLength;
  1831.   lineptr->LineID = NextLineID++;
  1832.   *(int *) ((char *) lineptr + MyLength - sizeof (int)) = MyLength;
  1833.  
  1834.   return (group->Subscribed);
  1835. }
  1836.  
  1837. /*-- function CursorToTextLine ----------------------------------------
  1838.  *
  1839.  *   Routine to locate a text line in a document, based on the
  1840.  *   cursor position.  Used to figure out which line is being selected
  1841.  *   when a user clicks a mouse button.
  1842.  *
  1843.  *   Entry    X, Y    are the position of the cursor.
  1844.  *            DocPtr  points to the current document.
  1845.  *
  1846.  *   Exit     *LinePtr points to the current line, if one was found.
  1847.  *            *BlockPtr points to the current block, if found.
  1848.  *            Function returns TRUE iff a line was found that corresponds
  1849.  *              to the cursor position.
  1850.  */
  1851. BOOL
  1852. CursorToTextLine (X, Y, DocPtr, BlockPtr, LinePtr)
  1853.      int X;
  1854.      int Y;
  1855.      TypDoc *DocPtr;
  1856.      TypBlock far **BlockPtr;
  1857.      TypLine far **LinePtr;
  1858. {
  1859.   int found;
  1860.   int SelLine;
  1861.  
  1862.   if (Y < TopSpace || (unsigned) Y > TopSpace + DocPtr->ScYLines * LineHeight ||
  1863.       X < SideSpace)
  1864.     {
  1865.       /* Cursor is in no-man's-land at edge of window.               */
  1866.       found = FALSE;
  1867.     }
  1868.   else
  1869.     {
  1870.       found = TRUE;
  1871.       SelLine = (Y - TopSpace) / LineHeight;
  1872.  
  1873.       LockLine (DocPtr->hCurTopScBlock, DocPtr->TopScOffset, DocPtr->TopScLineID,
  1874.       BlockPtr, LinePtr);
  1875.       AdvanceToActive(BlockPtr,LinePtr);
  1876.  
  1877.       for (found = TRUE, il = 0; il < SelLine; )
  1878.    {
  1879.      if (!NextLine (BlockPtr, LinePtr))
  1880.        {
  1881.          found = FALSE;    /* ran off end of document */
  1882.          break;
  1883.        } else if((*LinePtr)->active){
  1884.          il++;
  1885.        }
  1886.    }
  1887.     }
  1888.   return (found);
  1889. }
  1890.  
  1891. /*-- function ReadNewsrc ----------------------------------------------
  1892.  *
  1893.  *    Reads NEWSRC into the Net document.
  1894.  *    This routine opens NEWSRC, reads & parses the lines into the NetDoc
  1895.  *    document, and closes the file.  One call does it all.
  1896.  *
  1897.  *    Entry    The NetDoc document is assumed to be initialized.
  1898.  *
  1899.  *    Exit     Returns TRUE if all went well, else zero.
  1900.  */
  1901. int
  1902. ReadNewsrc ()
  1903. {
  1904.   TypBlock far *BlockPtr;
  1905.   TypLine *LocalLinePtr, far * GroupPtr;
  1906.   HANDLE hLine;
  1907.   HANDLE hBlock;
  1908.   HFILE hRetCode;
  1909.   unsigned int Offset;
  1910.   TypLineID MyLineID;
  1911.   char mybuf[TEMPBUFSIZE];
  1912.   TypMRRFile *MRRFile;
  1913.   int returned;
  1914.  
  1915.   LockLine (NetDoc.hCurAddBlock, NetDoc.AddOffset, NetDoc.AddLineID, &BlockPtr, &GroupPtr);
  1916.   NetDoc.hDocWnd = hWndConf;
  1917.  
  1918.   hLine = LocalAlloc (LMEM_MOVEABLE, TEMPBUFSIZE);
  1919.   LocalLinePtr = (TypLine *) LocalLock (hLine);
  1920.  
  1921. #if 0
  1922.   env_var = getenv ("WINVN");           /* get path to winvn.ini */
  1923.   if (lstrlen (env_var))
  1924.    {
  1925.      lstrcpy (newsrc_filename, env_var);
  1926.      if (*(newsrc_filename + lstrlen (newsrc_filename) - 1) == '\\')
  1927.        lstrcat (newsrc_filename, "newsrc");
  1928.      else
  1929.        lstrcat (newsrc_filename, "\\newsrc");
  1930.    }
  1931.   else
  1932.    {
  1933.      MessageBox (hWndConf,"Environment variable WINVN not set.","Fatal Error", MB_OK | MB_ICONEXCLAMATION);
  1934.      return (0);
  1935.    }
  1936.  
  1937. #endif
  1938.  
  1939.  
  1940.   hRetCode = MRROpenFile (szNewsSrc, OF_READ, &MRRFile);
  1941.   if ((int) hRetCode <= 0)
  1942.     {
  1943.       return FALSE;
  1944.     }
  1945.   else
  1946.     {
  1947.       /* Loop to read lines, convert them to internal format, and
  1948.        * insert them into the NetDoc document.
  1949.        */
  1950.       
  1951.       LinesInRC = 0;
  1952.       while ((returned = MRRReadLine (MRRFile, mybuf, TEMPBUFSIZE)) > (-1))
  1953.    {
  1954.      mybuf[returned] = '\0';
  1955.      if (CrackGroupLine (mybuf, LocalLinePtr))
  1956.        {
  1957.          NetDoc.CountedLines++;
  1958.        }
  1959.      AddLine (LocalLinePtr, &BlockPtr, &GroupPtr);
  1960.      LinesInRC++;
  1961.    }
  1962.       MRRCloseFile (MRRFile);
  1963.     }
  1964.  
  1965.   /* Change the title of the Net document.  I suppose that,
  1966.    * strictly speaking, this oughtn't be done in this routine.
  1967.    */
  1968.   SetNetDocTitle ();
  1969.   UnlockLine (BlockPtr, GroupPtr, &hBlock, &Offset, &MyLineID);
  1970.  
  1971.   NetDoc.hCurTopScBlock = NetDoc.hFirstBlock;
  1972.   NetDoc.TopScOffset = sizeof (TypBlock);
  1973.   NetDoc.TopScLineID = 0L;
  1974.   NetDoc.LongestLine = 0;
  1975.   /* Mark lines active or inactive according to ShowUnsubscribed. */                                        
  1976.   SetGroupActiveLines();                                          
  1977.   // we'll check this during WriteNewsrc(). SMR 930224
  1978.   started_with_no_dolist = !DoList;
  1979.   LocalUnlock (hLine);
  1980.   LocalFree (hLine);
  1981.  
  1982.   return (TRUE);
  1983. }
  1984.  
  1985. char *ltoa ();
  1986.  
  1987. /*--- function WriteNewsrc ---------------------------------------------
  1988.  *
  1989.  *  Write out a NEWSRC file, based on the information in the
  1990.  *  NetDoc document.  Use the standard Unix "rn" format for .newsrc.
  1991.  *
  1992.  *    Entry    no parameters
  1993.  *             NetDoc   has the group information.
  1994.  *
  1995.  *    Exit     The NEWSRC file has been written.
  1996.  */
  1997. void
  1998. WriteNewsrc ()
  1999. {
  2000.   TypBlock far *BlockPtr;
  2001.   TypLine far *LinePtr;
  2002.   HANDLE hLine;
  2003.   HANDLE hBlock;
  2004.   unsigned int Offset;
  2005.   TypLineID MyLineID;
  2006.   char mes[60], mybuf[60];
  2007.   char far *fromptr;
  2008.   char *toptr;
  2009.   char *NewsLine;
  2010.   HFILE hRetCode;
  2011.   TypMRRFile *MRRFile;
  2012.   int nranges;
  2013.   TypGroup far *Group;
  2014.   TypRange far *RangePtr;
  2015.   BOOL firstrange;
  2016.  
  2017.   LockLine (NetDoc.hFirstBlock, sizeof (TypBlock), 0L, &BlockPtr, &LinePtr);
  2018.  
  2019.   hLine = LocalAlloc (LMEM_MOVEABLE, BLOCK_SIZE);
  2020.   NewsLine = (char *) LocalLock (hLine);
  2021.  
  2022.   hRetCode = MRROpenFile (szNewsSrc, OF_CREATE, &MRRFile);
  2023.   if ((int) hRetCode < 0)
  2024.     {
  2025.       sprintf (mes, "MRROpenFile returned %d", hRetCode);
  2026.       MessageBox (hWndConf, mes, mybuf, MB_OK);
  2027.     }
  2028.   else
  2029.     {
  2030.       do
  2031.    {
  2032.      toptr = NewsLine;
  2033.      Group = (TypGroup far *) ((char far *) LinePtr + sizeof (TypLine));
  2034.  
  2035.      /* Remove groups only if we performed a LIST command and */
  2036.      /* the server did not have them.  Otherwise if !did_list, the */
  2037.      /* newsrc will be practically empty! */
  2038.  
  2039.      /* Jeeeeez!!  I'm fixing this AGAIN! */
  2040.      /* DoList is not a boolean. SMR 930610 */
  2041.  
  2042.      if ((Group->ServerFirst || Group->ServerEstNum) || !did_list ) {
  2043.      /* Copy group name                                          */
  2044.      fromptr = (char far *) LinePtr + sizeof (TypLine) + sizeof (TypGroup);
  2045.      while (*(toptr++) = *(fromptr++));
  2046.      toptr--;
  2047.  
  2048.      /* Affix : or ! depending upon whether subscribed.          */
  2049.      *(toptr++) = (char) (Group->Subscribed ? ':' : '!');
  2050.      *(toptr++) = ' ';
  2051.  
  2052.      /* If we know the highest article number on the server,
  2053.       * output it preceded by an "s".
  2054.       */
  2055.      if (Group->ServerLast || Group->HighestPrevSeen)
  2056.        {
  2057.          *(toptr++) = 's';
  2058.          if (Group->ServerLast)
  2059.              ltoa ((unsigned long) Group->ServerLast, toptr, 10);
  2060.          else
  2061.              ltoa ((unsigned long) Group->HighestPrevSeen, toptr, 10);
  2062.  
  2063.          while (*toptr)
  2064.       toptr++;
  2065.          *(toptr++) = ' ';
  2066.        }
  2067.  
  2068.      /* Affix ranges of articles read.                          */
  2069.      firstrange = TRUE;
  2070.      nranges = Group->nRanges;
  2071.      RangePtr = (TypRange far *) ((char far *) Group + RangeOffset (Group->NameLen));
  2072.  
  2073.      while ((nranges--) > 0)
  2074.        {
  2075.          /* Write out ',' if not first range of articles.         */
  2076.  
  2077.          if (!firstrange)
  2078.       {
  2079.         *(toptr++) = ',';
  2080.       }
  2081.          else
  2082.       {
  2083.         firstrange = FALSE;
  2084.       }
  2085.          /* Write out first article in a range.                   */
  2086.  
  2087.          ltoa ((unsigned long) RangePtr->First, toptr, 10);
  2088.          while (*toptr)
  2089.       toptr++;
  2090.  
  2091.          /* If the range is of form "n-n", just put out "n"       */
  2092.  
  2093.          if (RangePtr->First != RangePtr->Last)
  2094.       {
  2095.         /* Put out the hyphen in middle of range.                */
  2096.         *(toptr++) = '-';
  2097.         /* Put out the last article in a range.                  */
  2098.         ltoa ((unsigned long) RangePtr->Last, toptr, 10);
  2099.         while (*toptr)
  2100.           toptr++;
  2101.       }
  2102.          RangePtr++;
  2103.        }
  2104.      MRRWriteLine (MRRFile, NewsLine, toptr - NewsLine);
  2105.      }
  2106.    }
  2107.       while (NextLine (&BlockPtr, &LinePtr));
  2108.       UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
  2109.       MRRCloseFile (MRRFile);
  2110.     }
  2111.     LocalUnlock (hLine);
  2112.     LocalFree (hLine);
  2113.     
  2114. }
  2115.  
  2116. /*--- function SetNetDocTitle -------------------------------------------
  2117.  *
  2118.  */
  2119. void
  2120. SetNetDocTitle ()
  2121. {
  2122.   char mybuf[120];
  2123.  
  2124.   sprintf (mybuf, "WinVN:  %u groups; %u subscribed", NetDoc.TotalLines,
  2125.       NetDoc.CountedLines);
  2126.   SetWindowText (hWndConf, mybuf);
  2127.  
  2128. }
  2129.  
  2130. /*--- function SetLineFlag --------------------------------------------
  2131.  *
  2132.  *  Set some flag in a line in a document.
  2133.  *
  2134.  *  Entry   Doc      points to the document.
  2135.  *          LinePtr  points to th line.
  2136.  *
  2137.  *  Exit    lFlag    says what to do.
  2138.  */
  2139. void
  2140. SetLineFlag (TypDoc * Doc, TypBlock far ** BlockPtr, TypLine far ** LinePtr, int wFlag, int wValue)
  2141. {
  2142.   switch (wFlag)
  2143.     {
  2144.       case LINE_FLAG_SET:
  2145.       ((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
  2146.       ->Selected = wValue;
  2147.       break;
  2148.     }
  2149. }
  2150.  
  2151.  
  2152. /*--- function GroupAction --------------------------------------------
  2153.  *
  2154.  *  Perform some action on a group that is specified by a pointer
  2155.  *  to a line in the Net document.
  2156.  *  Typically called for each line in the Net document by
  2157.  *  ForAllLines.
  2158.  *
  2159.  *  Entry   Doc      points to NetDoc
  2160.  *          LinePtr  points to a line in that document.
  2161.  *          lFlag    indicates what to do with that line.
  2162.  */
  2163. void
  2164. GroupAction (TypDoc * Doc, TypBlock far ** BlockPtr, TypLine far ** LinePtr, int wFlag, int wValue)
  2165. {
  2166.  
  2167.   switch (wFlag)
  2168.     {
  2169.       case GROUP_ACTION_SUBSCRIBE:
  2170.       case GROUP_ACTION_UNSUBSCRIBE:
  2171.       if (((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
  2172.      ->Selected)
  2173.    {
  2174.      ((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
  2175.      ->Subscribed = wValue;
  2176.      AddGroupToTable ((char far *) *LinePtr);
  2177.      DeleteLine (BlockPtr, LinePtr);
  2178.    }
  2179.       break;
  2180.       
  2181.       case GROUP_ACTION_CHECK_ACTIVE:
  2182.          if(((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
  2183.             ->Subscribed || ShowUnsubscribed ) {
  2184.             (*LinePtr)->active = TRUE;
  2185.             (*BlockPtr)->NumActiveLines++;
  2186.             NetDoc.ActiveLines++;
  2187.             NetDoc.LongestLine = max(NetDoc.LongestLine,(unsigned)
  2188.                                     ((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
  2189.                                     ->NameLen+GROUP_NAME_OFFSET);
  2190.             if(((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
  2191.             ->Subscribed) NetDoc.CountedLines++;
  2192.          } else {
  2193.             (*LinePtr)->active = FALSE;
  2194.          }
  2195.          break;
  2196.  
  2197.     }
  2198. }
  2199.  
  2200. /****************************************************************************
  2201.  
  2202.    FUNCTION:   MakeHelpPathName
  2203.  
  2204.    PURPOSE:    HelpEx assumes that the .HLP help file is in the same
  2205.           directory as the HelpEx executable.This function derives
  2206.           the full path name of the help file from the path of the
  2207.           executable.
  2208.  
  2209.    Taken from HELPEX.C, from the MS Windows SDK.
  2210.  
  2211. ****************************************************************************/
  2212.  
  2213. void 
  2214. MakeHelpPathName (szFileName, maxchars)
  2215.      char *szFileName;
  2216.      int maxchars;
  2217. {
  2218.   char *pcFileName;
  2219.   int nFileNameLen;
  2220.  
  2221.   nFileNameLen = GetModuleFileName (hInst, szFileName, maxchars);
  2222.   pcFileName = szFileName + nFileNameLen;
  2223.  
  2224.   while (pcFileName > szFileName)
  2225.     {
  2226.       if (*pcFileName == '\\' || *pcFileName == ':')
  2227.    {
  2228.      *(++pcFileName) = '\0';
  2229.      break;
  2230.    }
  2231.       nFileNameLen--;
  2232.       pcFileName--;
  2233.     }
  2234.  
  2235.   if ((nFileNameLen + 13) < maxchars)
  2236.     {
  2237.       lstrcat (szFileName, LFN_HELP);
  2238.     }
  2239.  
  2240.   else
  2241.     {
  2242.       lstrcat (szFileName, "?");
  2243.     }
  2244.  
  2245.   return;
  2246. }
  2247.  
  2248.  
  2249. int
  2250. cursor_to_char_number (X, Y, DocPtr, BlockPtr, LinePtr)
  2251.      int X;
  2252.      int Y;
  2253.      TypDoc *DocPtr;
  2254.      TypBlock far **BlockPtr;
  2255.      TypLine far **LinePtr;
  2256. {
  2257.   int SelLine;
  2258.   int charnum = -1;
  2259.   SIZE extent;
  2260.                                                                                       
  2261.   char far * textptr;
  2262.   int textlen;
  2263.   HDC display_context;
  2264.   int iTopSpace, iSideSpace, iLineHeight, iCharWidth;
  2265.   
  2266.   if (DocPtr->DocType == DOCTYPE_ARTICLE)
  2267.   {
  2268.     iTopSpace = ArtTopSpace;
  2269.     iSideSpace = ArtSideSpace;
  2270.     iLineHeight = ArtLineHeight;                    
  2271.     iCharWidth = ArtCharWidth;
  2272.   }
  2273.   else
  2274.   {
  2275.     iTopSpace = TopSpace;
  2276.     iSideSpace = SideSpace;
  2277.     iLineHeight = LineHeight;
  2278.     iCharWidth = CharWidth;  
  2279.   }
  2280.     
  2281.   if (Y < iTopSpace || (unsigned) Y > iTopSpace + DocPtr->ScYLines * iLineHeight ||
  2282.       X < iSideSpace)
  2283.     {
  2284.    return (-1);
  2285.     }
  2286.   else
  2287.     {
  2288.       SelLine = (Y - iTopSpace) / iLineHeight;
  2289.  
  2290.       LockLine (DocPtr->hCurTopScBlock, DocPtr->TopScOffset, DocPtr->TopScLineID,
  2291.       BlockPtr, LinePtr);
  2292.  
  2293.       for (il = 0; il < SelLine; il++)
  2294.    {
  2295.      if (!NextLine (BlockPtr, LinePtr))
  2296.        {
  2297.          return (-1);  
  2298.          break;
  2299.        }
  2300.    }
  2301.     }
  2302.  
  2303.   /* find the right character on the text line */
  2304.   textlen = ((TypText far *) ((char far *) (*LinePtr) +
  2305.                sizeof (TypLine)))->NameLen;
  2306.  
  2307.  
  2308.   if (textlen) {
  2309.     textptr = (char far *) ((char far *) (*LinePtr) + sizeof (TypLine) + sizeof (TypText) );
  2310.     display_context = GetDC (DocPtr->hDocWnd);
  2311.  
  2312.     if (isLineQuotation(textptr))
  2313.       {  /* prepare to print a quotation Line */
  2314.         SelectObject (display_context, hFontArtQuote);
  2315.       }
  2316.     else
  2317.       {  /* prepare to print a normal line */
  2318.         SelectObject (display_context, hFontArtNormal);
  2319.       }
  2320.  
  2321.     for (charnum = 1; charnum < textlen; charnum++)
  2322.       {
  2323.     GetTextExtentPoint(display_context, (LPSTR) textptr, charnum, &extent); 
  2324.     if (extent.cx > (X + (int)DocPtr->ScXOffset * (iCharWidth + 1)- iSideSpace)) break;                                 
  2325.       }
  2326.     ReleaseDC (DocPtr->hDocWnd, display_context);
  2327.     return (charnum - 1);
  2328.   }
  2329.  
  2330. }
  2331.  
  2332. /*--- function SetGroupActiveLines --------------------------------------
  2333.  *
  2334.  *  Go through all the lines in the Net document, marking each
  2335.  *  as active or inactive according to whether the corresponding
  2336.  *  group is subscribed and whether we are displaying unsubscribed
  2337.  *  groups.
  2338.  *
  2339.  *  Entry:  NetDoc and ShowUnsubscribed are set properly.
  2340.  *
  2341.  *  Exit:   Each of the lines in NetDoc has had its "active" field
  2342.  *          set properly.
  2343.  */
  2344. void
  2345. SetGroupActiveLines() {
  2346.    NetDoc.ActiveLines = 0; 
  2347.    NetDoc.CountedLines = 0;
  2348.    ForAllBlocks (&NetDoc, SetForBlock, BLOCK_ACTION_SET_ACTIVE, 0);
  2349.    ForAllLines (&NetDoc, GroupAction, GROUP_ACTION_CHECK_ACTIVE, 0);
  2350. }                 
  2351.  
  2352.  
  2353. /* stuff for showing version numbers of the files */
  2354.  
  2355. #include "version.h"
  2356. #include "version.c"
  2357.  
  2358. /*-- function VerListDlgProc ---------------------------------------
  2359.  *
  2360.  *  Dialog function to handle selection of Version List
  2361.  *                                  JD 8/3/94
  2362.  */
  2363.  
  2364. LRESULT CALLBACK VerListDlgProc (HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)                  
  2365.                           
  2366. {
  2367.   int j;
  2368.   char far *cptr;
  2369.   char    szVersion[64];
  2370.  
  2371.   switch (iMessage)
  2372.     {
  2373.     case WM_INITDIALOG: 
  2374.          sprintf(szVersion,"Version %s",(LPSTR) WINVN_VERSION);    
  2375.          SetDlgItemText ((HWND) hDlg, IDD_VERSION_NUMBER, (LPSTR)szVersion);         
  2376.            hVerDlgList = GetDlgItem (hDlg, IDD_VERSION_LISTBOX);          
  2377.            SendMessage (hVerDlgList, WM_SETREDRAW, FALSE, 0L);
  2378.                    
  2379.          cptr = 0;
  2380.       for (j = 0; j < (sizeof(version_string) / sizeof version_string[0]); j++)
  2381.           {
  2382.             cptr = version_string[j];
  2383.             SendMessage (hVerDlgList, LB_ADDSTRING, 0, (LONG) cptr);
  2384.        }
  2385.           SendMessage (hVerDlgList, WM_SETREDRAW, TRUE, 0L);
  2386.           return TRUE;
  2387.           break;
  2388.  
  2389.     case WM_COMMAND:
  2390.       switch (wParam)
  2391.        {
  2392.        case IDOK:
  2393.               EndDialog (hDlg, TRUE);
  2394.              break;
  2395.  
  2396.         case IDCANCEL:
  2397.              EndDialog (hDlg, FALSE);
  2398.              break;
  2399.  
  2400.         default:
  2401.              return FALSE;
  2402.        }
  2403.       break;
  2404.  
  2405.     case WM_DESTROY:
  2406.       break;
  2407.  
  2408.     default:
  2409.       return FALSE;
  2410.       break;
  2411.     }
  2412.   return TRUE;
  2413. }
  2414.           
  2415. /*  Display Dialog Box to show version info   JD 8/4/94 */
  2416. void show_version_strings(HWND hWnd)
  2417. {
  2418.   lpfnWinVnVersionListDlg = (DLGPROC) MakeProcInstance((FARPROC) VerListDlgProc, (HINSTANCE) hInst);
  2419.   DialogBox (hInst, "WINVNVERSIONLIST", hWnd, lpfnWinVnVersionListDlg);  
  2420.   FreeProcInstance((FARPROC) lpfnWinVnVersionListDlg);
  2421.  
  2422. }
  2423.  
  2424. /* Last line of WVUSENET.C */
  2425. @
  2426.  
  2427.  
  2428. 1.52
  2429. log
  2430. @massive cleanup for 92.6
  2431. @
  2432. text
  2433. @d11 1
  2434. a11 1
  2435.  * $Id: wvusenet.c 1.51 1994/09/02 23:50:26 rushing Exp $
  2436. d52 1
  2437. a52 1
  2438.   HMENU hMenu;
  2439. d116 13
  2440. d705 15
  2441. d725 1
  2442. a725 1
  2443.      CloseArticleWnds();    // don't force the close
  2444. d733 1
  2445. a733 1
  2446.      CloseGroupWnds();        // don't force the close
  2447. d741 1
  2448. a741 1
  2449.      CloseStatusWnds();     // don't force the close
  2450. d764 1
  2451. a764 1
  2452.      if (!DialogBox (hInst, "WinVnDecodeArts", hWndConf, lpfnWinVnDecodeArtsDlg))
  2453. @
  2454.  
  2455.  
  2456. 1.51
  2457. log
  2458. @call huge shellsort correctly
  2459. @
  2460. text
  2461. @d11 1
  2462. a11 1
  2463.  * $Id: wvusenet.c 1.50 1994/08/23 23:17:34 martin Exp rushing $
  2464. d14 5
  2465. a18 2
  2466.  
  2467. #include "windows.h"
  2468. a19 2
  2469. #include "WVglob.h"
  2470. #include "WinVn.h"
  2471. a20 3
  2472. #include <stdlib.h>   /* for getenv */
  2473.  
  2474.  
  2475. d30 1
  2476. d39 1
  2477. a39 1
  2478.  *    Note:    We don't do anything until "Initialized" is true.
  2479. d51 1
  2480. a51 1
  2481.   FARPROC lpProcAbout;
  2482. d70 1
  2483. d87 1
  2484. a87 1
  2485.      lpProcAbout = MakeProcInstance (About, hInst);
  2486. d89 1
  2487. a89 1
  2488.      FreeProcInstance (lpProcAbout);
  2489. d113 1
  2490. a115 5
  2491. /*    case WM_INITMENUPOPUP :
  2492.       EnableMenuItem(GetMenu(hWnd),IDM_LOGOUT,MailCtrl.enableLogout) ;    // moved to SetUserMenus
  2493.       EnableMenuItem(GetMenu(hWnd),IDM_MAIL,MailCtrl.enableMail) ;
  2494.       break ;
  2495. */
  2496. d475 1
  2497. d480 1
  2498. a480 19
  2499.       // from exit menu always query exit options
  2500.       // to quit without asking, uncheck "Always confirm save on exit" in MiscDlg
  2501.       // and double click upper-left corner
  2502.  
  2503.       if (ConfirmExit)
  2504.       { // if confirming, actual writes occur in lpfnWinVnExitDlg
  2505.         if (!DialogBox (hInst, "WinVnExit", hWnd, lpfnWinVnExitDlg))
  2506.         {
  2507.           InvalidateRect (hWnd, NULL, TRUE);
  2508.           break;
  2509.         }
  2510.       }
  2511.       else
  2512.       { // not confirming, so just write em
  2513.         WriteNewsrc ();
  2514.         WriteWinvnProfile();
  2515.       }
  2516.  
  2517.       DestroyWindow (hWnd);
  2518. d588 4
  2519. d697 1
  2520. a697 1
  2521.      CloseArticleWnds();
  2522. d705 1
  2523. a705 1
  2524.      CloseGroupWnds();
  2525. d713 1
  2526. a713 1
  2527.      CloseStatusWnds();
  2528. d752 1
  2529. a752 2
  2530.      CommBusy = FALSE;
  2531.      CommState = ST_NONE;
  2532. d842 2
  2533. d855 3
  2534. d863 9
  2535. a871 1
  2536.      if (strcmp (FindDoc->SearchStr, ""))
  2537. d873 1
  2538. a873 1
  2539.          found = DoFind (FALSE);
  2540. d885 1
  2541. a885 1
  2542.      lpProcAbout = MakeProcInstance (About, hInst);
  2543. d887 1
  2544. a887 1
  2545.      FreeProcInstance (lpProcAbout);
  2546. d944 5
  2547. d1120 6
  2548. a1125 4
  2549.         sprintf (indcptr, "%c %5lu %s ",
  2550.                   indicator,
  2551.                   MyGroup->ServerEstNum,
  2552.                   group_name);
  2553. d1165 4
  2554. a1168 2
  2555.       if (ConfirmExit)
  2556.       { // if confirming, actual writes occur in lpfnWinVnExitDlg
  2557. a1174 5
  2558.       else
  2559.       { // not confirming, so just write em
  2560.         WriteNewsrc ();
  2561.         WriteWinvnProfile();
  2562.       }
  2563. d1179 1
  2564. d1187 1
  2565. a1187 5
  2566. /*      if (SaveNewsrc && (!Initializing))
  2567.    {
  2568.      WriteNewsrc ();
  2569.    }
  2570. */
  2571. d1194 1
  2572. a1194 1
  2573.       MailClose(hWnd) ;
  2574. d1196 13
  2575. a1208 12
  2576.       if (Decoding)
  2577.       {
  2578.         CompleteThisDecode();
  2579.         DecodeDone();
  2580.       }
  2581.       else if (Attaching)
  2582.         FinishAttachment (ABORT);
  2583.     
  2584. // make sure all coding status windows are closed and resources freed
  2585.      while (numStatusTexts)
  2586.         DestroyWindow (codingStatusText[0]->hTextWnd);
  2587.       
  2588. d1214 2
  2589. a1217 8
  2590.       if (hListFont) DeleteObject(hListFont);
  2591.       if (hFontArtNormal) DeleteObject(hFontArtNormal);
  2592.       if (hFontArtQuote) DeleteObject(hFontArtQuote);
  2593.       if (hStatusFont) DeleteObject(hStatusFont);
  2594.       if (hFontPrint) DeleteObject(hFontPrint);
  2595.       if (hFontPrintB) DeleteObject(hFontPrintB);
  2596.       if (hFontPrintS) DeleteObject(hFontPrintS);
  2597.       if (hFontPrintI) DeleteObject(hFontPrintI);   
  2598. d1248 13
  2599. d1281 2
  2600. a1282 1
  2601.         EnableMenuItem (hSubMenu, IDM_POST, mode);
  2602. a1283 8
  2603.     if (enable == ENABLE) {
  2604. //        EnableMenuItem (hSubMenu, IDM_LOGOUT, MailCtrl.enableLogout) ;
  2605.         EnableMenuItem (hSubMenu, IDM_MAIL, MailCtrl.enableMail) ;    
  2606.     } else {
  2607. //        EnableMenuItem (hSubMenu, IDM_MAIL, mode);        // should we leave this as is??  Yes!! (CN)
  2608. //        EnableMenuItem (hSubMenu, IDM_LOGOUT, mode);
  2609.     }
  2610.         
  2611. a1286 5
  2612.     
  2613. if (enable == ENABLE)     
  2614.        EnableMenuItem (hSubMenu, IDM_LOGOUT, MailCtrl.enableLogout) ;    
  2615. else
  2616.     EnableMenuItem (hSubMenu, IDM_LOGOUT, mode);
  2617. d1289 19
  2618. d1309 6
  2619. a1314 7
  2620. // Batch is now off of Utilities menu
  2621. //    hSubMenu = GetSubMenu (hMenu, 3);    // batch menu
  2622. //    EnableMenuItem (hSubMenu, IDM_CLOSE_ALL_ARTICLE, mode);
  2623. //    EnableMenuItem (hSubMenu, IDM_CLOSE_ALL_GROUP, mode);
  2624. //    EnableMenuItem (hSubMenu, IDM_CLOSE_ALL_STATUS, mode);
  2625. //    EnableMenuItem (hSubMenu, IDM_SEND_ALL_POST, mode);
  2626. //    EnableMenuItem (hSubMenu, IDM_SEND_ALL_MAIL, mode);
  2627. d1317 1
  2628. a1317 1
  2629.     
  2630. d1415 1
  2631. d1596 1
  2632. a1596 1
  2633.   HANDLE hRetCode;
  2634. d1698 1
  2635. a1698 1
  2636.   HANDLE hRetCode;
  2637. d1743 1
  2638. a1743 1
  2639.      if (Group->ServerLast)
  2640. d1746 5
  2641. a1750 1
  2642.          ltoa ((unsigned long) Group->ServerLast, toptr, 10);
  2643. @
  2644.  
  2645.  
  2646. 1.50
  2647. log
  2648. @new hash table mechanism
  2649. @
  2650. text
  2651. @d11 1
  2652. a11 1
  2653.  * $Id: wvusenet.c 1.49 1994/08/12 01:39:21 dumoulin Exp $
  2654. d538 4
  2655. a541 4
  2656.      ShellSort ((void far *) NewGroupTable,
  2657.            (size_t) nNewGroups,
  2658.            (size_t) sizeof (void far *),
  2659.            GroupCompare);
  2660. @
  2661.  
  2662.  
  2663.  
  2664. 1.49
  2665. log
  2666. @Fix Quit option to not bomb pathworks upon exit
  2667. @
  2668. text
  2669. @d11 1
  2670. a11 1
  2671.  * $Id: wvusenet.c 1.48 1994/08/11 21:41:41 rushing Exp dumoulin $
  2672. d523 1
  2673. d530 1
  2674. d537 1
  2675. d548 1
  2676. d555 1
  2677. d1628 1
  2678. d1637 1
  2679. @
  2680.  
  2681.  
  2682.  
  2683. 1.48
  2684. log
  2685. @ensure quit command sent to server on exit/disconnect
  2686. @
  2687. text
  2688. @d11 1
  2689. a11 1
  2690.  * $Id: wvusenet.c 1.47 1994/08/11 20:28:11 rushing Exp rushing $
  2691. d781 2
  2692. a782 1
  2693.      PutCommLine ("QUIT\r\n");
  2694. d1188 2
  2695. a1189 1
  2696.          PutCommLine ("QUIT\r\n");
  2697. @
  2698.  
  2699.  
  2700.  
  2701. 1.47
  2702. log
  2703. @handle server-side disconnect quietly
  2704. @
  2705. text
  2706. @d11 1
  2707. a11 1
  2708.  * $Id: wvusenet.c 1.46 1994/08/11 00:14:26 jcooper Exp $
  2709. d494 1
  2710. a494 1
  2711.       } 
  2712. d500 1
  2713. d781 1
  2714. a781 1
  2715.      MRRCloseComm();     // blammo
  2716. d789 2
  2717. d1186 2
  2718. a1187 1
  2719.       if (Initializing != INIT_NOT_CONNECTED)
  2720. d1189 1
  2721. @
  2722.  
  2723.  
  2724.  
  2725. 1.46
  2726. log
  2727. @bug fixes to properly finish decoding before exiting
  2728. @
  2729. text
  2730. @d11 1
  2731. a11 1
  2732.  * $Id: wvusenet.c 1.45 1994/08/04 05:51:13 dumoulin Exp $
  2733. d772 6
  2734. a777 3
  2735.    
  2736.      if (MessageBox (hWndConf, "Are you sure you wish to disconnect from the server?\nAll active windows will be closed.", 
  2737.                        "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO)
  2738. @
  2739.  
  2740.  
  2741.  
  2742. 1.45
  2743. log
  2744. @Added support for scrollable version box
  2745. @
  2746. text
  2747. @d11 1
  2748. a11 1
  2749.  * $Id: wvusenet.c 1.44 1994/08/03 00:55:24 dumoulin Exp dumoulin $
  2750. d791 1
  2751. a791 1
  2752.          FinishAttachment ();
  2753. d1185 11
  2754. a1195 3
  2755.       // make sure all coding status windows are closed and resources freed
  2756.       while (numStatusTexts)
  2757.      DestroyWindow (codingStatusText[0]->hTextWnd);
  2758. @
  2759.  
  2760.  
  2761.  
  2762. 1.44
  2763. log
  2764. @Fixed bug cleaning up printer fonts even if someone doesn't
  2765. have a printer attached.
  2766. @
  2767. text
  2768. @d11 1
  2769. a11 1
  2770.  * $Id: wvusenet.c 1.43 1994/07/27 21:09:33 gardnerd Exp dumoulin $
  2771. d28 1
  2772. a28 1
  2773. int started_with_no_dolist;            
  2774. d30 1
  2775. a30 1
  2776. void show_version_strings(void);
  2777. d897 1
  2778. a897 1
  2779.      show_version_strings();
  2780. d2006 59
  2781. a2064 1
  2782. void show_version_strings(void)
  2783. d2066 4
  2784. a2069 5
  2785.   
  2786.   MessageBox (hWndConf,
  2787.          version_string,
  2788.          "WinVN Version Information",
  2789.          MB_OK);
  2790. @
  2791.  
  2792.  
  2793.  
  2794. 1.43
  2795. log
  2796. @copy to clipboard
  2797. @
  2798. text
  2799. @d11 1
  2800. a11 1
  2801.  * $Id: wvusenet.c 1.42 1994/07/25 18:51:03 jcooper Exp $
  2802. d904 1
  2803. a904 1
  2804.      CreatePosti.gWnd (hWnd, (TypDoc *) NULL, DOCTYPE_POSTING);
  2805. d1196 11
  2806. a1206 11
  2807.       DeleteObject(hListFont);
  2808.       DeleteObject(hFontArtNormal);
  2809.       DeleteObject(hFontArtQuote);
  2810.       DeleteObject(hStatusFont);
  2811.       DeleteObject(hFontPrint);
  2812.       DeleteObject(hFontPrintB);
  2813.       DeleteObject(hFontPrintS);
  2814.       DeleteObject(hFontPrintI);   
  2815.       DeleteObject(hListBackgroundBrush);
  2816.       DeleteObject(hArticleBackgroundBrush);
  2817.       DeleteObject(hStatusBackgroundBrush);
  2818. @
  2819.  
  2820.  
  2821.  
  2822. 1.42
  2823. log
  2824. @execution of decoded files
  2825. @
  2826. text
  2827. @d11 1
  2828. a11 1
  2829.  * $Id: wvusenet.c 1.41 1994/07/12 19:50:52 cnolan Exp $
  2830. d1908 1
  2831. a1908 1
  2832.  
  2833. d1912 19
  2834. a1930 3
  2835.  
  2836.   if (Y < TopSpace || (unsigned) Y > TopSpace + DocPtr->ScYLines * LineHeight ||
  2837.       X < SideSpace)
  2838. d1936 1
  2839. a1936 1
  2840.       SelLine = (Y - TopSpace) / ArtLineHeight;
  2841. d1945 1
  2842. a1945 1
  2843.          return (-1);
  2844. d1960 9
  2845. d1972 1
  2846. a1972 1
  2847.     if (extent.cx > (X - SideSpace)) break;                                 
  2848. @
  2849.  
  2850.  
  2851.  
  2852. 1.41
  2853. log
  2854. @menu fixes from cnolan
  2855. @
  2856. text
  2857. @d11 1
  2858. a11 1
  2859.  * $Id: wvusenet.c 1.40 1994/07/12 19:15:49 rushing Exp $
  2860. a755 2
  2861.       if (AskForExistingFileName (hWndConf, AttachFileName, "Open file to be encoded") == FAIL)
  2862.          break; 
  2863. @
  2864.  
  2865.  
  2866.  
  2867. 1.40
  2868. log
  2869. @UpdateSeenArts() when reusing a group window
  2870. @
  2871. text
  2872. @d11 1
  2873. a11 1
  2874.  * $Id: wvusenet.c 1.39 1994/06/30 21:30:41 gardnerd Exp rushing $
  2875. d774 1
  2876. d799 1
  2877. d1231 1
  2878. a1231 1
  2879.     hSubMenu = GetSubMenu (hMenu, 2);    // config menu
  2880. d1247 1
  2881. a1247 1
  2882.     hSubMenu = GetSubMenu (hMenu, 0);    // group menu
  2883. d1255 1
  2884. a1255 1
  2885.     hSubMenu = GetSubMenu (hMenu, 1);    // utilities menu
  2886. d1259 1
  2887. a1259 1
  2888.         EnableMenuItem (hSubMenu, IDM_LOGOUT, MailCtrl.enableLogout) ;
  2889. d1262 2
  2890. a1263 2
  2891.         EnableMenuItem (hSubMenu, IDM_MAIL, mode);        // should we leave this as is??
  2892.         EnableMenuItem (hSubMenu, IDM_LOGOUT, mode);
  2893. d1266 1
  2894. a1266 1
  2895.     hSubMenu = GetSubMenu (hMenu, 2);    // config menu
  2896. d1269 5
  2897. d1277 7
  2898. a1283 6
  2899.     hSubMenu = GetSubMenu (hMenu, 3);    // batch menu
  2900.     EnableMenuItem (hSubMenu, IDM_CLOSE_ALL_ARTICLE, mode);
  2901.     EnableMenuItem (hSubMenu, IDM_CLOSE_ALL_GROUP, mode);
  2902.     EnableMenuItem (hSubMenu, IDM_CLOSE_ALL_STATUS, mode);
  2903.     EnableMenuItem (hSubMenu, IDM_SEND_ALL_POST, mode);
  2904.     EnableMenuItem (hSubMenu, IDM_SEND_ALL_MAIL, mode);
  2905. @
  2906.  
  2907.  
  2908.  
  2909. 1.39
  2910. log
  2911. @Allow scrolling by pixels instead of characters
  2912. @
  2913. text
  2914. @d11 1
  2915. a11 1
  2916.  * $Id: wvusenet.c 1.38 1994/06/30 16:36:23 dumoulin Exp $
  2917. d330 1
  2918. @
  2919.  
  2920.  
  2921.  
  2922. 1.38
  2923. log
  2924. @Fixed Exit to check the Confirm-upon-Exit flag
  2925. @
  2926. text
  2927. @d11 1
  2928. a11 1
  2929.  * $Id: wvusenet.c 1.37 1994/06/08 21:01:45 gardnerd Exp dumoulin $
  2930. d476 1
  2931. a476 1
  2932.  
  2933. d1041 1
  2934. a1041 1
  2935.        X = SideSpace;
  2936. d1117 4
  2937. a1120 13
  2938.         if((int)MyLen - (int)NetDoc.ScXOffset < 0)
  2939.         {
  2940.           ExtTextOut (hDC, X, Y, ETO_OPAQUE|ETO_CLIPPED, &aRect,
  2941.                       " ", 1, (LPINT)NULL);
  2942.         }
  2943.         else
  2944.         {
  2945.           ExtTextOut (hDC, X, Y, ETO_OPAQUE|ETO_CLIPPED, &aRect, 
  2946.                       indcptr+NetDoc.ScXOffset, MyLen-NetDoc.ScXOffset,
  2947.                       (LPINT)NULL);
  2948.         }  
  2949.    
  2950.  
  2951. @
  2952.  
  2953.  
  2954.  
  2955. 1.37
  2956. log
  2957. @more scrolling changes...
  2958. @
  2959. text
  2960. @d11 1
  2961. a11 1
  2962.  * $Id: wvusenet.c 1.36 1994/06/06 22:06:13 gardnerd Exp $
  2963. d45 1
  2964. a45 2
  2965. long FAR PASCAL
  2966. WinVnConfWndProc (hWnd, message, wParam, lParam)
  2967. d485 13
  2968. a497 4
  2969.       if (!DialogBox (hInst, "WinVnExit", hWnd, lpfnWinVnExitDlg))
  2970.       {
  2971.          InvalidateRect (hWnd, NULL, TRUE);
  2972.          break;
  2973. d500 1
  2974. a500 1
  2975.      break;
  2976. d1160 1
  2977. a1160 1
  2978.       { // if confirming, acutal writes occur in lpfnWinVnExitDlg
  2979. d1292 1
  2980. a1292 2
  2981. BOOL FAR PASCAL 
  2982. About (hDlg, message, wParam, lParam)
  2983. @
  2984.  
  2985.  
  2986.  
  2987. 1.36
  2988. log
  2989. @horizontal scrolling support
  2990. @
  2991. text
  2992. @d11 1
  2993. a11 1
  2994.  * $Id: wvusenet.c 1.35 1994/06/06 21:23:37 mrr Exp $
  2995. d516 1
  2996. d532 1
  2997. d1621 1
  2998. a1621 1
  2999.   
  3000. d1830 3
  3001. @
  3002.  
  3003.  
  3004.  
  3005. 1.35
  3006. log
  3007. @fix subscribed-count bug
  3008. @
  3009. text
  3010. @d11 1
  3011. a11 1
  3012.  * $Id: $
  3013. d311 3
  3014. a313 1
  3015.            CommDoc = &(GroupDocs[docnum]);
  3016. d327 3
  3017. a329 1
  3018.         /* Must reuse old window for this group.           */
  3019. d369 1
  3020. a369 1
  3021.                   WS_OVERLAPPEDWINDOW | WS_VSCROLL,
  3022. d467 7
  3023. d1020 9
  3024. d1106 13
  3025. a1118 3
  3026.    SetRect (&aRect, 0, Y, myRect.right, Y+LineHeight);
  3027.    ExtTextOut (hDC, X, Y, ETO_OPAQUE|ETO_CLIPPED, &aRect,
  3028.                indcptr, MyLen, (LPINT)NULL);
  3029. d1597 1
  3030. a1597 1
  3031.  
  3032. @
  3033.  
  3034.  
  3035.  
  3036. 1.34
  3037. log
  3038. @rewrote GroupAction for debugging...
  3039. @
  3040. text
  3041. @d11 1
  3042. a11 2
  3043.  * Revision 1.30  1994/05/19  02:04:54  rushing
  3044.  * changes for gensock, version 0.91
  3045. a12 95
  3046.  * Revision 1.29  1994/05/02  20:38:53  rushing
  3047.  * changes from jody glasser
  3048.  *
  3049.  * Revision 1.28  1994/04/19  18:35:23  rushing
  3050.  * check for NULL MailList in FreeTextBlock
  3051.  *
  3052.  * Revision 1.27  1994/02/24  21:35:08  jcoop
  3053.  * jcoop changes
  3054.  *
  3055.  * Revision 1.26  1994/02/09  18:01:08  cnolan
  3056.  * cnolan 90.2 changes
  3057.  *
  3058.  * Revision 1.25  1994/01/24  17:41:01  jcoop
  3059.  * 90.2 changes
  3060.  *
  3061.  * Revision 1.24  1994/01/16  12:04:33  jcoop
  3062.  * Color/fonts, signatures, exit INI handling, general cleanup
  3063.  *
  3064.  * Revision 1.23  1994/01/12  19:27:32  mrr
  3065.  * mrr mods 4
  3066.  * 
  3067.  * Revision 1.22  1993/12/08  01:28:01  rushing
  3068.  * new version box and cr lf consistency
  3069.  *
  3070.  * Revision 1.21  1993/12/07  20:24:43  rushing
  3071.  * testing new ID.
  3072.  *
  3073.  * Revision 1.20  1993/10/12  17:47:26  rushing
  3074.  * make winvn grok servers that start article numbers at 0
  3075.  *
  3076.  * Revision 1.19  1993/09/12  20:26:52  rushing
  3077.  * handle can't connect condition
  3078.  *
  3079.  * Revision 1.18  1993/08/25  18:54:36  mbretherton
  3080.  * MRB merge, mail & post logging
  3081.  *
  3082.  *
  3083.  * MBretherton
  3084.  * remove vRef from MRROpenFile (Mac Stuff)
  3085.  *
  3086.  * Revision 1.17  1993/08/18  21:49:21  rushing
  3087.  * more 16-bit article number fixes.
  3088.  *
  3089.  * Revision 1.16  1993/08/17  21:46:49  DUMOULIN
  3090.  * Added support for Dragging mouse for selecting/deselecting Usenet groups
  3091.  *
  3092.  * Revision 1.15  1993/07/06  21:09:50  cnolan
  3093.  * win32 support
  3094.  *
  3095.  * Revision 1.14  1993/06/28  17:51:39  rushing
  3096.  * fixed compiler warnings
  3097.  *
  3098.  * Revision 1.13  1993/06/24  17:13:14  riordan
  3099.  * Save window positions between sessions.
  3100.  *
  3101.  * Revision 1.12  1993/06/14  18:52:00  rushing
  3102.  * 'New Posting' menu option added
  3103.  *
  3104.  * Revision 1.11  1993/06/11  00:10:35  rushing
  3105.  * second merge from Matt Bretherton sources
  3106.  *
  3107.  * Revision 1.10  1993/06/10  18:24:41  rushing
  3108.  * hopefully newsrc&dolist thing is fixed FOR GOOD.
  3109.  *
  3110.  * Revision 1.9  1993/05/24  23:55:25  rushing
  3111.  * Delete Fonts (cleanup before exiting) (MRB)
  3112.  *
  3113.  * Revision 1.8  1993/05/20  18:12:31  rushing
  3114.  * don't write out newsrc if Intializing is true
  3115.  *
  3116.  * Revision 1.7  1993/04/29  20:23:06  rushing
  3117.  * attempted support for WSAAsyncSelect
  3118.  *
  3119.  * Revision 1.6  1993/04/27  20:11:38  rushing
  3120.  * Fixed out-of-date code that killed the timer if
  3121.  * CommState was ST_NONE.
  3122.  *
  3123.  * Revision 1.5  1993/04/27  18:53:17  rushing
  3124.  * attempt to fix newsrc problems.  allow newsrc line with
  3125.  * no range data.
  3126.  *
  3127.  * Revision 1.4  1993/03/30  21:07:15  DUMOULIN
  3128.  * handle conflicting MAPI merge problem (with wvsck???.c)
  3129.  * use ST_NONE instead of ST_CLOSED_COMM
  3130.  *
  3131.  * Revision 1.3  1993/03/30  20:46:07  bretherton
  3132.  * MAPI
  3133.  *
  3134.  * Revision 1.2  1993/02/25  03:08:52  rushing
  3135.  * fixed newsrc truncation when DoList = 0.
  3136.  *
  3137.  * Revision 1.1  1993/02/16  20:54:22  rushing
  3138.  * Initial revision
  3139.  *
  3140.  *
  3141. d1573 1
  3142. a1573 1
  3143.          NetDoc.ActiveLines++;
  3144. d1735 2
  3145. a1736 5
  3146.   /* someone else is using activelines, reset it (SMR 940601) */
  3147.   SetGroupActiveLines();                                          
  3148.  
  3149.   sprintf (mybuf, "WinVN:  %d groups; %d subscribed", NetDoc.TotalLines,
  3150.       NetDoc.ActiveLines);
  3151. a1776 1
  3152.   TypGroup far * this_group = (TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine));
  3153. d1780 10
  3154. a1789 8
  3155.     case GROUP_ACTION_SUBSCRIBE:
  3156.     case GROUP_ACTION_UNSUBSCRIBE:
  3157.       if (this_group->Selected)
  3158.     {
  3159.       this_group->Subscribed = wValue;
  3160.       AddGroupToTable ((char far *) *LinePtr);
  3161.       DeleteLine (BlockPtr, LinePtr);
  3162.     }
  3163. d1792 13
  3164. a1804 9
  3165.     case GROUP_ACTION_CHECK_ACTIVE:
  3166.       if (this_group->Subscribed  || ShowUnsubscribed ) {
  3167.     (*LinePtr)->active = TRUE;
  3168.     (*BlockPtr)->NumActiveLines++;
  3169.     if (this_group->Subscribed) NetDoc.ActiveLines++;
  3170.       } else {
  3171.     (*LinePtr)->active = FALSE;
  3172.       }
  3173.       break;
  3174. d1929 2
  3175. a1930 1
  3176.    NetDoc.ActiveLines = 0;
  3177. @
  3178.  
  3179.  
  3180.  
  3181. 1.33
  3182. log
  3183. @unnecessary winundoc.h
  3184. @
  3185. text
  3186. @d1831 3
  3187. d1876 1
  3188. d1880 8
  3189. a1887 10
  3190.       case GROUP_ACTION_SUBSCRIBE:
  3191.       case GROUP_ACTION_UNSUBSCRIBE:
  3192.       if (((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
  3193.      ->Selected)
  3194.    {
  3195.      ((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
  3196.      ->Subscribed = wValue;
  3197.      AddGroupToTable ((char far *) *LinePtr);
  3198.      DeleteLine (BlockPtr, LinePtr);
  3199.    }
  3200. d1890 9
  3201. a1898 11
  3202.       case GROUP_ACTION_CHECK_ACTIVE:
  3203.          if(((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
  3204.             ->Subscribed || ShowUnsubscribed ) {
  3205.             (*LinePtr)->active = TRUE;
  3206.             (*BlockPtr)->NumActiveLines++;
  3207.             NetDoc.ActiveLines++;
  3208.          } else {
  3209.             (*LinePtr)->active = FALSE;
  3210.          }
  3211.          break;
  3212.  
  3213. @
  3214.  
  3215.  
  3216.  
  3217. 1.32
  3218. log
  3219. @Added support for the Quit option on the Network Menu
  3220. @
  3221. text
  3222. @a111 3
  3223.  
  3224.  
  3225. #include "winundoc.h"
  3226. a112 2
  3227.  
  3228.  
  3229. @
  3230.  
  3231.  
  3232.  
  3233. 1.31
  3234. log
  3235. @new attach code, session [dis]connect
  3236. @
  3237. text
  3238. @d568 4
  3239. a571 2
  3240. // case IDM_QUIT:
  3241. //   SaveNewsrc = FALSE;
  3242. d681 1
  3243. a681 1
  3244.      
  3245. d704 1
  3246. a704 1
  3247.      {   
  3248. d708 1
  3249. a708 1
  3250.      }                
  3251. d721 1
  3252. a721 1
  3253.        break;  
  3254. d724 1
  3255. a724 1
  3256.    
  3257. d736 1
  3258. a736 1
  3259.    
  3260. d754 1
  3261. a754 1
  3262.    
  3263. d761 1
  3264. a761 1
  3265.        
  3266. d773 1
  3267. a773 1
  3268.    
  3269. d789 1
  3270. a789 1
  3271.    
  3272. d856 1
  3273. a856 1
  3274.         
  3275. d864 1
  3276. a864 1
  3277.      
  3278. d872 1
  3279. a872 1
  3280.      
  3281. d970 1
  3282. a970 1
  3283.      
  3284. d1070 1
  3285. a1070 1
  3286.         // fall into INIT_DONE         
  3287. @
  3288.  
  3289.  
  3290.  
  3291. 1.30
  3292. log
  3293. @changes for gensock, version 0.91
  3294. @
  3295. text
  3296. @d11 3
  3297. a13 2
  3298.  * $Id: wvusenet.c 1.29 1994/05/02 20:38:53 rushing Exp rushing $
  3299.  * $Log: wvusenet.c $
  3300. a133 1
  3301.  
  3302. d217 2
  3303. a218 2
  3304.     case WM_INITMENUPOPUP :
  3305.       EnableMenuItem(GetMenu(hWnd),IDM_LOGOUT,MailCtrl.enableLogout) ;
  3306. d221 1
  3307. a221 1
  3308.  
  3309. d846 31
  3310. d1022 6
  3311. d1062 7
  3312. d1247 2
  3313. a1248 1
  3314.       MRRCloseComm ();
  3315. d1284 60
  3316. d1345 1
  3317. @
  3318.  
  3319.  
  3320.  
  3321. 1.29
  3322. log
  3323. @changes from jody glasser
  3324. @
  3325. text
  3326. @d11 1
  3327. a11 1
  3328.  * $Id: wvusenet.c 1.28 1994/04/19 18:35:23 rushing Exp $
  3329. d13 3
  3330. d303 1
  3331. a303 1
  3332.                      ->Selected = TRUE;
  3333. d529 1
  3334. a529 2
  3335.          lstrcat(mybuf,"\r");
  3336.          PutCommLine (mybuf, lstrlen (mybuf));
  3337. @
  3338.  
  3339.  
  3340.  
  3341. 1.28
  3342. log
  3343. @check for NULL MailList in FreeTextBlock
  3344. @
  3345. text
  3346. @d11 1
  3347. a11 1
  3348.  * $Id: wvusenet.c 1.27 1994/02/24 21:35:08 jcoop Exp rushing $
  3349. d13 3
  3350. d169 3
  3351. a171 1
  3352.  
  3353. d288 9
  3354. d300 14
  3355. a313 1
  3356.                      ->Selected ^= TRUE;
  3357. d316 1
  3358. a316 1
  3359.          SetCapture(hWnd);    // release capture on button up
  3360. d372 1
  3361. d388 4
  3362. a391 4
  3363.     {
  3364.       GlobalUnlock (GroupBlockPtr->hCurBlock);
  3365.       break;
  3366.     }
  3367. d477 1
  3368. a477 1
  3369.     ShowWindow (hWndView, SW_SHOWNORMAL);
  3370. d632 1
  3371. a632 1
  3372. #if 0    // This code not used anywhere (JSC 1/12/94)
  3373. d700 1
  3374. a700 1
  3375.      {    
  3376. d757 1
  3377. a757 1
  3378.         
  3379. d970 2
  3380. d1028 4
  3381. a1031 4
  3382.        MyColors[0] = NetUnSubscribedColor;        // unseen/unselected    
  3383.        MyColors[1] = NetSubscribedColor;        // seen/unselected
  3384.        MyColors[2] = MyColors[0];            // unseen/selected
  3385.        MyColors[3] = ListBackgroundColor;        // seen/selected
  3386. d1036 1
  3387. a1036 1
  3388.          MyBack[2] = RGB(200,200,200);        // selected = white background
  3389. d1038 1
  3390. a1038 1
  3391.          MyBack[2] = RGB(0,0,0);            // selected = black background
  3392. d1117 9
  3393. d1139 3
  3394. a1141 3
  3395.     SetRect (&aRect, 0, Y, myRect.right, Y+LineHeight);
  3396.     ExtTextOut (hDC, X, Y, ETO_OPAQUE|ETO_CLIPPED, &aRect,
  3397.                 indcptr, MyLen, (LPINT)NULL);
  3398. d1207 1
  3399. a1207 1
  3400.       DestroyWindow (codingStatusText[0]->hTextWnd);
  3401. d1215 1
  3402. a1215 1
  3403.       SetHandleBkBrush (hWndConf, GetStockObject (WHITE_BRUSH));
  3404. d1266 1
  3405. a1266 1
  3406. #if 0    // This code not used anywhere (JSC 1/12/94)
  3407. @
  3408.  
  3409.  
  3410.  
  3411. 1.27
  3412. log
  3413. @jcoop changes
  3414. @
  3415. text
  3416. @d11 1
  3417. a11 1
  3418.  * $Id: wvusenet.c 1.26 1994/02/09 18:01:08 cnolan Exp $
  3419. d13 3
  3420. d1172 2
  3421. a1173 1
  3422.       FreeTextBlock (MailList);
  3423. @
  3424.  
  3425.  
  3426.  
  3427. 1.26
  3428. log
  3429. @cnolan 90.2 changes
  3430. @
  3431. text
  3432. @a9 2
  3433.  
  3434.  
  3435. d11 1
  3436. a11 1
  3437.  * $Id: wvusenet.c 1.25 1994/01/24 17:41:01 jcoop Exp $
  3438. d13 3
  3439. d283 2
  3440. a284 2
  3441.       ->Selected ^= TRUE;
  3442.               DragMouseAction = status ? DRAG_SELECT : DRAG_DESELECT;
  3443. d286 1
  3444. d297 1
  3445. d307 3
  3446. a309 3
  3447.    {
  3448.      X = LOWORD (lParam);
  3449.      Y = HIWORD (lParam);
  3450. d311 3
  3451. a313 2
  3452.      if (CursorToTextLine (X, Y, &NetDoc, &BlockPtr, &LinePtr))
  3453.        {
  3454. d315 14
  3455. a328 16
  3456.                 {
  3457.        case DRAG_SELECT:
  3458.                        ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
  3459.                ->Selected = TRUE;
  3460.                       break;
  3461.        case DRAG_DESELECT:
  3462.                       ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
  3463.               ->Selected = FALSE;
  3464.                       break;
  3465.        }
  3466.          GlobalUnlock (BlockPtr->hCurBlock);
  3467.        }
  3468.  
  3469.      InvalidateRect (hWnd, NULL, FALSE);
  3470.         }
  3471.  
  3472. d538 9
  3473. a546 1
  3474.      goto closeWnd;
  3475. d664 1
  3476. d668 6
  3477. d927 1
  3478. a927 1
  3479.    unsigned int Offset, MyLen, width, indicatorwidth;
  3480. d931 1
  3481. a931 1
  3482.    int RestX, Xtext;
  3483. d941 1
  3484. a941 2
  3485.    HBRUSH hOldBr, SelectedBrush, UnSelectedBrush;
  3486.    RECT myRect;
  3487. d998 1
  3488. a998 1
  3489.        MyColors[3] = GetBkColor (hDC);        // seen/selected
  3490. a1008 2
  3491.        SelectedBrush = CreateSolidBrush (MyBack[2]);
  3492.        UnSelectedBrush = CreateSolidBrush (MyBack[0]);
  3493. a1010 1
  3494.        hOldBr = SelectObject (hDC, UnSelectedBrush);
  3495. a1058 1
  3496. //          Rop = BLACKNESS;
  3497. a1062 1
  3498. //          Rop = WHITENESS;
  3499. a1068 5
  3500.  
  3501.             if (MyColorMask >= SELECT_MASK)
  3502.               SelectObject (hDC, SelectedBrush);
  3503.             else
  3504.               SelectObject (hDC, UnSelectedBrush);
  3505. d1081 3
  3506. a1083 3
  3507.          {
  3508.            indicator = '*';
  3509.          }
  3510. a1095 5
  3511.      GetTextExtentPoint (hDC, indcptr, MyLen, &sz);    
  3512.      width = sz.cx;                                    
  3513.         TextOut (hDC, X, Y, indcptr, MyLen);
  3514.  
  3515.       // This section was strange.  Maybe guilty.
  3516. d1097 3
  3517. a1099 2
  3518.             RestX = X + width;
  3519.             PatBlt (hDC, RestX, Y, myRect.right - RestX, LineHeight, PATCOPY);
  3520. d1103 3
  3521. a1105 3
  3522.       }  /* end if LinePtr->active */  
  3523.       }
  3524.          while (VertLines > 0 && NextLine (&BlockPtr, &LinePtr));
  3525. d1107 3
  3526. a1109 3
  3527.        SetTextColor (hDC, MyColors[1]);
  3528.        SetBkColor (hDC, MyBack[1]);
  3529.        SelectObject (hDC, UnSelectedBrush);
  3530. d1112 1
  3531. a1116 3
  3532.        SelectObject (hDC, hOldBr);
  3533.        DeleteObject (SelectedBrush);
  3534.        DeleteObject (UnSelectedBrush);
  3535. d1118 3
  3536. a1120 3
  3537.    EndPaint (hWnd, &ps);
  3538.    break;
  3539.       }
  3540. d1130 8
  3541. a1137 3
  3542.      closeWnd:;
  3543.       if (!DialogBox (hInst, "WinVnExit", hWnd, lpfnWinVnExitDlg))
  3544.         InvalidateRect (hWnd, NULL, TRUE);
  3545. d1139 5
  3546. a1143 1
  3547.         DestroyWindow (hWnd);
  3548. d1169 2
  3549. d1670 3
  3550. @
  3551.  
  3552.  
  3553.  
  3554. 1.25
  3555. log
  3556. @90.2 changes
  3557. @
  3558. text
  3559. @d13 1
  3560. a13 1
  3561.  * $Id: wvusenet.c 1.24 1994/01/16 12:04:33 jcoop Exp $
  3562. d15 3
  3563. d443 1
  3564. a443 1
  3565.     SetClassWord (hWndView, GCW_HBRBACKGROUND, hListBackgroundBrush);
  3566. d708 1
  3567. a708 1
  3568.      SetClassWord (hWnd, GCW_HBRBACKGROUND, hListBackgroundBrush);
  3569. d1161 1
  3570. a1161 1
  3571.       SetClassWord (hWndConf, GCW_HBRBACKGROUND, GetStockObject (WHITE_BRUSH));
  3572. @
  3573.  
  3574.  
  3575.  
  3576. 1.24
  3577. log
  3578. @Color/fonts, signatures, exit INI handling, general cleanup
  3579. @
  3580. text
  3581. @d13 1
  3582. a13 1
  3583.  * $Id: wvusenet.c 1.24 1994/01/16 01:05:01 jcoop Exp $
  3584. d15 3
  3585. a182 5
  3586.       /* Set up the timer which will wake us up every so often
  3587.        * so we can check to see if new characters have arrived from
  3588.        * the server.
  3589.        */
  3590.  
  3591. a184 6
  3592.       idTimer = SetTimer (hWnd, ID_TIMER ,1000, (FARPROC) NULL);
  3593.  
  3594.       if (!idTimer) {
  3595.    MessageBox (hWnd, "Couldn't create timer!", "WinVN", MB_OK | MB_ICONASTERISK);
  3596.       }
  3597.  
  3598. d627 1
  3599. a627 1
  3600.      if (DialogBox (hInst, "WinVnSigFile", hWnd, lpfnWinVnSigFileDlg))
  3601. d727 40
  3602. d768 1
  3603. a768 1
  3604.      if (TestDecodeBusy(hWnd, "Can't decode file"))
  3605. d771 2
  3606. a772 2
  3607.      if (!DialogBox (hInst, "WinVnDecodeArts", hWnd, lpfnWinVnDecodeArtsDlg))
  3608.         InvalidateRect (hWnd, NULL, TRUE);
  3609. a774 1
  3610.      
  3611. d778 1
  3612. a778 1
  3613.       if (TestDecodeBusy(hWnd, "Can't encode file"))
  3614. d780 1
  3615. a780 1
  3616.       if (AskForExistingFileName (hWnd, AttachFileName, "Open file to be encoded") == FAIL)
  3617. d782 2
  3618. a783 2
  3619.       if (!DialogBox (hInst, "WinVnEncode", hWnd, lpfnWinVnEncodeDlg))
  3620.          InvalidateRect (hWnd, NULL, TRUE);
  3621. d785 1
  3622. a785 1
  3623.          EncodeToFile (hWnd, AttachFileName);
  3624. d795 1
  3625. a795 1
  3626.      MessageBox (hWnd, "WinVn Configuration Saved", "WinVn Configuration", MB_OK);
  3627. @
  3628.  
  3629.  
  3630.  
  3631. 1.23
  3632. log
  3633. @mrr mods 4
  3634. @
  3635. text
  3636. @d13 1
  3637. a13 1
  3638.  * $Id: wvusenet.c 1.22 1993/12/08 01:28:01 rushing Exp $
  3639. d15 3
  3640. d359 5
  3641. a363 7
  3642.          if (CommBusy)
  3643.       {
  3644.         GlobalUnlock (GroupBlockPtr->hCurBlock);
  3645.         MessageBox (hWnd, "Sorry, I am already busy retrieving information from the server.\n\
  3646. Try again in a little while.", "Can't request info on group", MB_OK | MB_ICONASTERISK);
  3647.         break;
  3648.       }
  3649. d448 2
  3650. a449 2
  3651.         ShowWindow (hWndView, SW_SHOWNORMAL);
  3652.  
  3653. d493 1
  3654. a493 1
  3655.          SetCapture (hWnd);
  3656. d538 4
  3657. a541 4
  3658.    case IDM_QUIT:
  3659.      SaveNewsrc = FALSE;
  3660.    case IDM_EXIT:
  3661.      DestroyWindow (hWnd);
  3662. d596 1
  3663. d606 1
  3664. d634 5
  3665. d640 117
  3666. d762 5
  3667. d888 3
  3668. a890 2
  3669.    DWORD MyColors[4], MyBack[4];
  3670.    DWORD Rop;
  3671. d896 2
  3672. a897 1
  3673.    hDC = BeginPaint (hWnd, &ps);
  3674. d899 1
  3675. a899 1
  3676.    SelectObject (hDC, hFont);
  3677. d945 4
  3678. a948 4
  3679.        MyColors[0] = NetUnSubscribedColor;
  3680.        MyColors[1] = GetTextColor (hDC);
  3681.        MyColors[2] = MyColors[0];
  3682.        MyColors[3] = GetBkColor (hDC);
  3683. d952 5
  3684. a956 1
  3685.        MyBack[2] = MyColors[1];
  3686. d959 6
  3687. d1012 1
  3688. a1012 1
  3689.             Rop = BLACKNESS;
  3690. d1017 1
  3691. a1017 1
  3692.             Rop = WHITENESS;
  3693. d1024 5
  3694. d1063 1
  3695. a1063 1
  3696.             PatBlt (hDC, RestX, Y, myRect.right - RestX, LineHeight, Rop);
  3697. d1073 1
  3698. d1076 2
  3699. a1077 2
  3700.        PatBlt (hDC, 0, Y, myRect.right, myRect.bottom - Y, PATCOPY);
  3701.        PatBlt (hDC, 0, 0, myRect.right, TopSpace, PATCOPY);
  3702. d1080 3
  3703. d1095 8
  3704. d1111 1
  3705. a1111 1
  3706.       if (SaveNewsrc && (!Initializing))
  3707. d1115 1
  3708. d1120 4
  3709. d1125 4
  3710. a1128 1
  3711.       DeleteObject(hFont);
  3712. d1131 1
  3713. d1136 3
  3714. d1178 1
  3715. d1219 1
  3716. a1219 1
  3717.  
  3718. a1430 1
  3719. #define  TEMPBUFSIZE   1240
  3720. d1497 2
  3721. @
  3722.  
  3723.  
  3724.  
  3725. 1.22
  3726. log
  3727. @new version box and cr lf consistency
  3728. @
  3729. text
  3730. @d13 1
  3731. a13 1
  3732.  * $Id: wvusenet.c 1.21 1993/12/07 20:24:43 rushing Exp rushing $
  3733. d15 3
  3734. d109 2
  3735. a110 1
  3736. int started_with_no_dolist;
  3737. d112 2
  3738. d167 6
  3739. a172 6
  3740.     {
  3741.       lpProcAbout = MakeProcInstance (About, hInst);
  3742.       DialogBox (hInst, "AboutBox", hWnd, lpProcAbout);
  3743.       FreeProcInstance (lpProcAbout);
  3744.       break;
  3745.     }
  3746. d174 1
  3747. a174 1
  3748.     return (DefWindowProc (hWnd, message, wParam, lParam));
  3749. d187 1
  3750. a187 1
  3751.     MessageBox (hWnd, "Couldn't create timer!", "WinVN", MB_OK | MB_ICONASTERISK);
  3752. d199 1
  3753. a199 1
  3754.           MF_APPEND | MF_STRING);
  3755. d217 11
  3756. a227 11
  3757.     {
  3758.       if (wParam == '\r')
  3759.         {
  3760.  
  3761.           GetCursorPos (&ptCursor);
  3762.           ScreenToClient (hWnd, &ptCursor);
  3763.           X = ptCursor.x;
  3764.           Y = ptCursor.y;
  3765.           goto getgroup;
  3766.         }
  3767.     }
  3768. d238 25
  3769. a262 25
  3770.     {
  3771.       if (wParam == VK_F6)
  3772.         {
  3773.           NextWindow (&NetDoc);
  3774.         }
  3775.       else
  3776.         {
  3777.           /* Based on the state of the Control key and the value
  3778.            * of the key just pressed, look up in the array
  3779.            * key2scroll to see if we should process this keystroke
  3780.            * as if it were a mouse event.  If so, simulate the
  3781.            * mouse event by sending the appropriate message.
  3782.            */
  3783.  
  3784.           CtrlState = GetKeyState (VK_CONTROL) < 0;
  3785.           for (j = 0; j < NUMKEYS; j++)
  3786.         {
  3787.           if (wParam == key2scroll[j].wVirtKey &&
  3788.               CtrlState == key2scroll[j].CtlState)
  3789.             {
  3790.               SendMessage (hWnd, key2scroll[j].iMessage,
  3791.                    key2scroll[j].wRequest, 0L);
  3792.               break;
  3793.             }
  3794.         }
  3795. d264 2
  3796. a265 2
  3797.         }
  3798.     }
  3799. d276 1
  3800. a276 1
  3801.     {
  3802. d278 2
  3803. a279 2
  3804.       X = LOWORD (lParam);
  3805.       Y = HIWORD (lParam);
  3806. d281 4
  3807. a284 4
  3808.       if (CursorToTextLine (X, Y, &NetDoc, &BlockPtr, &LinePtr))
  3809.         {
  3810.           status = ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
  3811.         ->Selected ^= TRUE;
  3812. d286 2
  3813. a287 2
  3814.           GlobalUnlock (BlockPtr->hCurBlock);
  3815.         }
  3816. d289 2
  3817. a290 2
  3818.       InvalidateRect (hWnd, NULL, FALSE);
  3819.     }
  3820. d306 3
  3821. a308 3
  3822.     {
  3823.       X = LOWORD (lParam);
  3824.       Y = HIWORD (lParam);
  3825. d310 2
  3826. a311 2
  3827.       if (CursorToTextLine (X, Y, &NetDoc, &BlockPtr, &LinePtr))
  3828.         {
  3829. d314 3
  3830. a316 3
  3831.          case DRAG_SELECT:
  3832.                         ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
  3833.                  ->Selected = TRUE;
  3834. d318 1
  3835. a318 1
  3836.          case DRAG_DESELECT:
  3837. d320 1
  3838. a320 1
  3839.                 ->Selected = FALSE;
  3840. d322 3
  3841. a324 3
  3842.          }
  3843.           GlobalUnlock (BlockPtr->hCurBlock);
  3844.         }
  3845. d326 1
  3846. a326 1
  3847.       InvalidateRect (hWnd, NULL, FALSE);
  3848. d337 23
  3849. a359 23
  3850.     {
  3851.       X = LOWORD (lParam);
  3852.       Y = HIWORD (lParam);
  3853.     getgroup:;
  3854.  
  3855.       if (CursorToTextLine (X, Y, &NetDoc, &GroupBlockPtr, &GroupLinePtr))
  3856.         {
  3857.           if (MyDoc = (((TypGroup far *)
  3858.         (((char far *) GroupLinePtr) + sizeof (TypLine)))->SubjDoc))
  3859.         {
  3860.  
  3861.           /* We already have a document containing the subjects */
  3862.           /* of this group, so just activate it.                */
  3863.  
  3864.           SetActiveWindow (MyDoc->hDocWnd);
  3865.           SetFocus (MyDoc->hDocWnd);
  3866.           GlobalUnlock (GroupBlockPtr->hCurBlock);
  3867.           break;
  3868.         }
  3869.           if (CommBusy)
  3870.         {
  3871.           GlobalUnlock (GroupBlockPtr->hCurBlock);
  3872.           MessageBox (hWnd, "Sorry, I am already busy retrieving information from the server.\n\
  3873. d361 2
  3874. a362 2
  3875.           break;
  3876.         }
  3877. d364 23
  3878. a386 23
  3879.           /* At this point, we've determined that the subjects for
  3880.            * this newsgroup are not in memory, and that it's OK
  3881.            * to fetch them from the server.  (Comm line not busy.)
  3882.            * Figure out whether a new window/document should be
  3883.            * created for this group & set "newdoc" accordingly.
  3884.            */
  3885.           newdoc = FALSE;
  3886.           if (ViewNew || !ActiveGroupDoc || !(ActiveGroupDoc->InUse))
  3887.         {
  3888.           found = FALSE;
  3889.           for (docnum = 0; docnum < MAXGROUPWNDS; docnum++)
  3890.             {
  3891.               if (!GroupDocs[docnum].InUse)
  3892.             {
  3893.               found = TRUE;
  3894.               newdoc = TRUE;
  3895.               CommDoc = &(GroupDocs[docnum]);
  3896.               break;
  3897.             }
  3898.             }
  3899.           if (!found)
  3900.             {
  3901.               MessageBox (hWnd, "You have too many group windows \
  3902. d388 24
  3903. a411 101
  3904.               UnlockLine (GroupBlockPtr, GroupLinePtr, &hBlock, &Offset, &MyLineID);
  3905.               break;
  3906.             }
  3907.         }
  3908.           else
  3909.         {
  3910.           /* Must reuse old window for this group.           */
  3911.           CommDoc = ActiveGroupDoc;
  3912.           UnlinkArtsInGroup (CommDoc);
  3913.           LockLine (CommDoc->hParentBlock, CommDoc->ParentOffset, CommDoc->ParentLineID, &BlockPtr, &LinePtr);
  3914.           ((TypGroup far *)
  3915.            (((char far *) LinePtr) + sizeof (TypLine)))->SubjDoc = (TypDoc *) NULL;
  3916.           UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
  3917.           /* clear out contents of this document for reuse */
  3918.           FreeDoc (CommDoc);
  3919.         }
  3920.  
  3921.           /* Create window title indicating we are retrieving text. */
  3922.  
  3923.           CommDoc->InUse = TRUE;
  3924.           lpsz = (char far *) (((char far *) GroupLinePtr) +
  3925.                    sizeof (TypLine) + sizeof (TypGroup));
  3926.           strcpy (mybuf, "Retrieving ");
  3927.           lstrcat (mybuf, lpsz);
  3928.  
  3929.           /* If necessary, create a new window.              */
  3930.  
  3931.           if (newdoc)
  3932.         {
  3933.           int x,y,width,height;
  3934.           char poschars[MAXINTERNALLINE];
  3935.  
  3936.           /* Compute default screen position. */
  3937.           x = 1;
  3938.           y = 0;
  3939.           width = (int) xScreen;
  3940.           height = (int) (yScreen * 1 / 2);
  3941.  
  3942.           /* If the screen position has been saved, use that instead. */
  3943.           GetPrivateProfileString (szAppName, "GroupWindowPos", "!",
  3944.              poschars,MAXINTERNALLINE,szAppProFile);
  3945.           if(poschars[0] != '!') {
  3946.              sscanf(poschars,"%d,%d,%d,%d",&x,&y,&width,&height);
  3947.           }
  3948.           hWndView = CreateWindow ("WinVnView",
  3949.                        mybuf,
  3950.                        WS_OVERLAPPEDWINDOW | WS_VSCROLL,
  3951.                         x + (int) docnum * CharWidth,/* Initial X pos */
  3952.                         y + (int) docnum * LineHeight,
  3953.                         width,           /* Initial X Width */
  3954.                         height,
  3955.                        NULL,
  3956.                        NULL,
  3957.                        hInst,
  3958.                        NULL);
  3959.  
  3960.           if (!hWndView)
  3961.             return (0); /* ??? */
  3962.  
  3963.           ShowWindow (hWndView, SW_SHOWNORMAL);
  3964.  
  3965.         }
  3966.           else
  3967.         {
  3968.           hWndView = CommDoc->hDocWnd;
  3969.           SetWindowText (hWndView, mybuf);
  3970.         }
  3971.           RcvLineCount = 0;
  3972.           TimesWndUpdated = 0;
  3973.  
  3974.           /* Do some housekeeping:  Set group as selected,
  3975.            * initialize empty document to hold subject lines,
  3976.            * set focus to this document, set pointers linking
  3977.            * this document and the subject line.
  3978.            */
  3979.           ((TypGroup far *) (((char far *) GroupLinePtr) +
  3980.                  sizeof (TypLine)))->Selected = TRUE;
  3981.           InitDoc (CommDoc, hWndView, &NetDoc, DOCTYPE_GROUP);
  3982.           PtrToOffset (GroupBlockPtr, GroupLinePtr, &(CommDoc->hParentBlock),
  3983.             &(CommDoc->ParentOffset), &(CommDoc->ParentLineID));
  3984.           SetActiveWindow (hWndView);
  3985.           SetFocus (hWndView);
  3986.  
  3987.           ((TypGroup far *) (((char far *) GroupLinePtr) + sizeof (TypLine)))
  3988.         ->SubjDoc = CommDoc;
  3989.           GlobalUnlock (GroupBlockPtr->hCurBlock);
  3990.           InvalidateRect (hWndView, NULL, FALSE);
  3991.  
  3992.           UpdateWindow (hWndView);
  3993.  
  3994.           InvalidateRect (NetDoc.hDocWnd, NULL, FALSE);
  3995.  
  3996.           /* Deal with Comm-related stuff:  set FSA variables,
  3997.            * send the GROUP command to NNTP.
  3998.            */
  3999.  
  4000.           CommLinePtr = CommLineIn;
  4001.           CommBusy = TRUE;
  4002.           CommState = ST_GROUP_RESP;
  4003.           hSaveCursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
  4004.           ShowCursor (TRUE);
  4005. d413 77
  4006. d492 9
  4007. a500 9
  4008.           SetCapture (hWnd);
  4009.           strcpy (mybuf, "GROUP ");
  4010.           lpsz = (char far *) GroupLinePtr + sizeof (TypLine) + sizeof (TypGroup);
  4011.           lstrcat (mybuf, lpsz);
  4012.           mylstrncpy (CurrentGroup, lpsz, MAXFINDSTRING);
  4013.           lstrcat(mybuf,"\r");
  4014.           PutCommLine (mybuf, lstrlen (mybuf));
  4015.         }
  4016.     }
  4017. d508 1
  4018. a508 1
  4019.       KillTimer(hWnd,ID_TIMER) ;
  4020. d512 2
  4021. a513 2
  4022.      if (CommState != ST_CLOSED_COMM)
  4023.        DoCommInput ();
  4024. d528 3
  4025. a530 3
  4026.     {
  4027.       ScrollIt (&NetDoc, wParam, lParam);
  4028.     }
  4029. d535 139
  4030. a673 1
  4031.     {
  4032. d675 2
  4033. a676 199
  4034.     case IDM_QUIT:
  4035.       SaveNewsrc = FALSE;
  4036.     case IDM_EXIT:
  4037.       DestroyWindow (hWnd);
  4038.       break;
  4039.  
  4040.     case IDM_VIEW_SEL_GROUP:
  4041.       break;
  4042.  
  4043.     case IDM_SHOW_SUBSCR:
  4044.     case IDM_SHOW_ALL_GROUP:
  4045.     case IDM_SEL_SUBSCR:
  4046.     case IDM_SELECTALL:
  4047.       MessageBox (hWnd, "Command not implemented",
  4048.               "Sorry", MB_OK);
  4049.       break;
  4050.  
  4051.     case IDM_UNSEL_ALL:
  4052.       ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
  4053.       InvalidateRect (hWnd, NULL, FALSE);
  4054.       break;
  4055.  
  4056.     case IDM_SUBSCRIBE:
  4057.       InitGroupTable ();
  4058.       ForAllLines (&NetDoc, GroupAction, GROUP_ACTION_SUBSCRIBE, TRUE);
  4059.       MergeGroups (ADD_SUBSCRIBED_END_OF_SUB);
  4060.       CleanUpGroupTable ();
  4061.       ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
  4062.       ScreenToTop (&NetDoc);
  4063.       InvalidateRect (hWnd, NULL, FALSE);
  4064.       break;
  4065.  
  4066.     case IDM_UNSUBSCRIBE:
  4067.       InitGroupTable ();
  4068.       ForAllLines (&NetDoc, GroupAction, GROUP_ACTION_UNSUBSCRIBE, FALSE);
  4069.       ShellSort ((void far *) NewGroupTable,
  4070.              (size_t) nNewGroups,
  4071.              (size_t) sizeof (void far *),
  4072.              GroupCompare);
  4073.       MergeGroups (ADD_SUBSCRIBED_END_OF_SUB);
  4074.       CleanUpGroupTable ();
  4075.       ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
  4076.       ScreenToTop (&NetDoc);
  4077.       InvalidateRect (hWnd, NULL, FALSE);
  4078.       break;
  4079.  
  4080.     case IDM_GROUP_TOP:
  4081.       InitGroupTable ();
  4082.       ForAllLines (&NetDoc, GroupAction, GROUP_ACTION_SUBSCRIBE, TRUE);
  4083.       MergeGroups (ADD_SUBSCRIBED_TOP_OF_DOC);
  4084.       CleanUpGroupTable ();
  4085.       ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
  4086.       ScreenToTop (&NetDoc);
  4087.       InvalidateRect (hWnd, NULL, FALSE);
  4088.       break;
  4089.  
  4090.     case IDM_NEW_WIN_GROUP:
  4091.       ViewNew = !ViewNew;
  4092.       CheckView (hWnd);
  4093.       break;
  4094.  
  4095.     case IDM_NEW_WIN_ARTICLE:
  4096.       NewArticleWindow = !NewArticleWindow;
  4097.       CheckView (hWnd);
  4098.       break;
  4099.  
  4100.     case IDM_COMMOPTIONS:
  4101.  
  4102.       if (DialogBox (hInst, "WinVnComm", hWnd, lpfnWinVnCommDlg))
  4103.         {
  4104.           InvalidateRect (hWnd, NULL, TRUE);
  4105.         }
  4106.  
  4107.       break;
  4108.  
  4109.     case IDM_CONFIG_PERSONAL:
  4110.  
  4111.       DialogBox (hInst, "WinVnPersonal", hWnd, lpfnWinVnPersonalInfoDlg);
  4112.       break;
  4113.  
  4114.     case IDM_CONFIG_MISC:
  4115.  
  4116.       DialogBox (hInst, "WinVnMisc", hWnd, lpfnWinVnMiscDlg);
  4117.  
  4118.       break;
  4119.  
  4120.      case IDM_CONFIG_LOG:
  4121.  
  4122.       DialogBox (hInst, "WinVnLogOpts", hWnd, lpfnWinVnLogOptDlg);
  4123.  
  4124.       break;
  4125.  
  4126.  
  4127.     case IDM_RESET:
  4128.       CommBusy = FALSE;
  4129.       CommState = ST_NONE;
  4130.       break;
  4131.  
  4132.     case IDM_SAVE_WINDOW:
  4133.       {
  4134.       RECT rect;
  4135.  
  4136.       /* Save position and size of Usenet window. */
  4137.       GetWindowRect(hWndConf,&rect);
  4138.       sprintf(mybuf,"%d,%d,%d,%d",rect.left,rect.top,
  4139.         rect.right-rect.left,rect.bottom-rect.top);
  4140.       WritePrivateProfileString
  4141.         (szAppName, "UsenetWindowPos", mybuf, szAppProFile);
  4142.  
  4143.  
  4144.       /* Save position and size of first Group window */
  4145.  
  4146.       for(found=FALSE,idoc=0; !found && idoc<MAXGROUPWNDS; idoc++) {
  4147.          if(GroupDocs[idoc].InUse) {
  4148.             GetWindowRect(GroupDocs[idoc].hDocWnd,&rect);
  4149.             found = TRUE;
  4150.             sprintf(mybuf,"%d,%d,%d,%d",rect.left,rect.top,
  4151.                 rect.right-rect.left,rect.bottom-rect.top);
  4152.             WritePrivateProfileString
  4153.               (szAppName, "GroupWindowPos", mybuf, szAppProFile);
  4154.          }
  4155.       }
  4156.  
  4157.       /* Save position and size of first Article window */
  4158.  
  4159.       for(found=FALSE,idoc=0; !found && idoc<MAXARTICLEWNDS; idoc++) {
  4160.          if(ArticleDocs[idoc].InUse) {
  4161.             GetWindowRect(ArticleDocs[idoc].hDocWnd,&rect);
  4162.             found = TRUE;
  4163.             sprintf(mybuf,"%d,%d,%d,%d",rect.left,rect.top,
  4164.                 rect.right-rect.left,rect.bottom-rect.top);
  4165.             WritePrivateProfileString
  4166.               (szAppName, "ArticleWindowPos", mybuf, szAppProFile);
  4167.          }
  4168.       }
  4169.  
  4170.       break;
  4171.       }
  4172.  
  4173.     case IDM_FIND:
  4174.       FindDoc = &NetDoc;
  4175.  
  4176.       if (DialogBox (hInst, "WinVnFind", hWnd, lpfnWinVnFindDlg))
  4177.         {
  4178.           found = DoFind (TRUE);
  4179.           if (!found)
  4180.         {
  4181.           strcpy (mybuf, "\"");
  4182.           strcat (mybuf, NetDoc.SearchStr);
  4183.           strcat (mybuf, "\" not found.");
  4184.           MessageBox (hWnd, mybuf, "Not found", MB_OK);
  4185.         }
  4186.         }
  4187.       break;
  4188.  
  4189.     case IDM_FIND_NEXT_SAME:
  4190.       FindDoc = &NetDoc;
  4191.       if (strcmp (FindDoc->SearchStr, ""))
  4192.         {
  4193.           found = DoFind (FALSE);
  4194.           if (!found)
  4195.         {
  4196.           strcpy (mybuf, "\"");
  4197.           strcat (mybuf, NetDoc.SearchStr);
  4198.           strcat (mybuf, "\" not found.");
  4199.           MessageBox (hWnd, mybuf, "No more occurrences", MB_OK);
  4200.         }
  4201.         }
  4202.       break;
  4203.  
  4204.     case ID_ABOUT:
  4205.       lpProcAbout = MakeProcInstance (About, hInst);
  4206.       DialogBox (hInst, "AboutBox", hWnd, lpProcAbout);
  4207.       FreeProcInstance (lpProcAbout);
  4208.       break;
  4209.  
  4210.     case IDM_HELP:
  4211.       MakeHelpPathName (mybuf, MAXINTERNALLINE);
  4212.       WinHelp (hWndConf, mybuf, HELP_INDEX, 0L);
  4213.       break;
  4214.  
  4215.     case IDM_MAIL:
  4216.       (MailCtrl.fnMlWinCreate)(hWnd, (TypDoc *) NULL, DOCTYPE_MAIL);
  4217.       break;
  4218.       
  4219.     case IDM_LOGOUT:
  4220.       (MailCtrl.fnMlLogout)(hWnd);
  4221.       break;
  4222.  
  4223.     case IDM_SHOW_VERSION:
  4224.       show_version_strings();
  4225.       break;
  4226.  
  4227.     case IDM_POST:
  4228.       DialogBoxParam (hInst, "WinVnGeneric", hWnd,
  4229.               lpfnWinVnGenericDlg, (LPARAM) (char far *) "Newsgroup(s):");
  4230.       NewsgroupsPtr = DialogString;
  4231.       CreatePostingWnd (hWnd, (TypDoc *) NULL, DOCTYPE_POSTING);
  4232.       break;
  4233. d678 62
  4234. a739 1
  4235.     }
  4236. d744 18
  4237. a761 18
  4238.     HANDLE hBlock;
  4239.     SIZE sz;
  4240.     unsigned int Offset, MyLen, width, indicatorwidth;
  4241.     int VertLines, HorzChars;
  4242.     int EndofDoc = FALSE;
  4243.     int RangeHigh, CurPos;
  4244.     int RestX, Xtext;
  4245.     char far *textptr;
  4246.     char *cptr, *cptr2;
  4247.     char indicator;
  4248.     char indcptr[128];
  4249.     char group_name[MAXINTERNALLINE];
  4250.     char init_msg[60];
  4251.     TypGroup far *MyGroup;
  4252.     DWORD MyColors[4], MyBack[4];
  4253.     DWORD Rop;
  4254.     RECT myRect;
  4255.     int MyColorMask = 1, PrevColorMask = MyColorMask;
  4256. d765 57
  4257. a821 57
  4258.     hDC = BeginPaint (hWnd, &ps);
  4259.     GetClientRect (hWnd, &myRect);
  4260.     SelectObject (hDC, hFont);
  4261.  
  4262.     /* If still initializing comm link, put out a message    */
  4263.     /* to that effect.                                       */
  4264.  
  4265.     switch (Initializing)
  4266.       {
  4267.       case INIT_ESTAB_CONN:
  4268.         cptr = "Establishing link";
  4269.         cptr2 = "to news server...";
  4270.  
  4271.         goto display_msg;
  4272.  
  4273.       case INIT_READING_NEWSRC:
  4274.         cptr = "Reading your log";
  4275.         cptr2 = "(\"newsrc\")...";
  4276.         goto display_msg;
  4277.  
  4278.       case INIT_SCANNING_NETDOC:
  4279.         cptr = "Creating hash table";
  4280.         cptr2 = "from current groups...";
  4281.         goto display_msg;
  4282.  
  4283.       case INIT_GETTING_LIST:
  4284.         sprintf (mybuf, "Receiving %uth newsgroup", RcvLineCount);
  4285.         cptr = mybuf;
  4286.         cptr2 = "name from server...";
  4287.  
  4288.       display_msg:;
  4289.         X = SideSpace + CharWidth;
  4290.         Y = StartPen + 2 * LineHeight;
  4291.         strcpy (init_msg, cptr);
  4292.         strcat (init_msg, "    ");
  4293.         j = strlen (init_msg);
  4294.         TextOut (hDC, X, Y, init_msg, j);
  4295.         strcpy (init_msg, cptr2);
  4296.         strcat (init_msg, "    ");
  4297.         j = strlen (init_msg);
  4298.         TextOut (hDC, X, Y + LineHeight, init_msg, j);
  4299.         break;
  4300.  
  4301.  
  4302.       case INIT_DONE:
  4303.  
  4304.         VertLines = NetDoc.ScYLines;
  4305.         HorzChars = NetDoc.ScXChars;
  4306.         MyColors[0] = NetUnSubscribedColor;
  4307.         MyColors[1] = GetTextColor (hDC);
  4308.         MyColors[2] = MyColors[0];
  4309.         MyColors[3] = GetBkColor (hDC);
  4310.  
  4311.         MyBack[0] = MyColors[3];
  4312.         MyBack[1] = MyBack[0];
  4313.         MyBack[2] = MyColors[1];
  4314.         MyBack[3] = MyBack[2];
  4315. d826 4
  4316. a829 2
  4317.         LockLine (NetDoc.hCurTopScBlock, NetDoc.TopScOffset, NetDoc.TopScLineID,
  4318.               &BlockPtr, &LinePtr);
  4319. d831 95
  4320. a925 1
  4321.         /* Update the scroll bar thumb position.                 */
  4322. d927 8
  4323. a934 99
  4324.         CurPos = NetDoc.TopLineOrd;
  4325.         if (CurPos < 0)
  4326.           CurPos = 0;
  4327.         RangeHigh = NetDoc.TotalLines - VertLines;
  4328.         if (RangeHigh < 0)
  4329.           RangeHigh = 0;
  4330.         SetScrollRange (hWnd, SB_VERT, 0, RangeHigh, FALSE);
  4331.         SetScrollPos (hWnd, SB_VERT, CurPos, TRUE);
  4332.  
  4333.         /* Loop through the lines, painting them on the screen. */
  4334.  
  4335.         X = SideSpace;
  4336.         Xtext = X + indicatorwidth;
  4337.         Y = StartPen;
  4338.         if (LinePtr->length != END_OF_BLOCK)
  4339.           do
  4340.         {
  4341.           MyGroup = ((TypGroup far *)
  4342.                  ((char far *) LinePtr + sizeof (TypLine)));
  4343.           MyLen = MyGroup->NameLen;
  4344.           textptr = (char far *) LinePtr + sizeof (TypLine) +
  4345.             sizeof (TypGroup);
  4346.  
  4347.           /* Figure out the color of this line.                 */
  4348.  
  4349.           if (MyGroup->Subscribed)
  4350.             {
  4351.               MyColorMask |= SUBSCR_MASK;
  4352.             }
  4353.           else
  4354.             {
  4355.               MyColorMask &= (0xff - SUBSCR_MASK);
  4356.             }
  4357.           if (MyGroup->Selected)
  4358.             {
  4359.               MyColorMask |= SELECT_MASK;
  4360.               Rop = BLACKNESS;
  4361.             }
  4362.           else
  4363.             {
  4364.               MyColorMask &= 0xff - SELECT_MASK;
  4365.               Rop = WHITENESS;
  4366.             }
  4367.           if (MyColorMask != PrevColorMask)
  4368.             {
  4369.               SetTextColor (hDC, MyColors[MyColorMask]);
  4370.               SetBkColor (hDC, MyBack[MyColorMask]);
  4371.               PrevColorMask = MyColorMask;
  4372.             }
  4373.  
  4374.           /* Figure out what indicator character to use. */
  4375.  
  4376.           indicator = ' ';
  4377.           if (NetDoc.FindLineID == LinePtr->LineID)
  4378.             {
  4379.               indicator = '>';
  4380.             }
  4381.           else if (MyGroup->HighestPrevSeen)
  4382.             {
  4383.               if (MyGroup->ServerLast > MyGroup->HighestPrevSeen)
  4384.             {
  4385.               indicator = '*';
  4386.             }
  4387.             }
  4388.  
  4389.           mylstrncpy (group_name, textptr, MyGroup->NameLen + 1);
  4390.  
  4391.           sprintf (indcptr, "%c %5lu %s ",
  4392.                        indicator,
  4393.                        MyGroup->ServerEstNum,
  4394.                        group_name);
  4395.  
  4396.           /* Now write out the line.                            */
  4397.  
  4398.           MyLen = strlen (indcptr);
  4399.       GetTextExtentPoint (hDC, indcptr, MyLen, &sz);    
  4400.       width = sz.cx;                                    
  4401.           TextOut (hDC, X, Y, indcptr, MyLen);
  4402.  
  4403.         // This section was strange.  Maybe guilty.
  4404.  
  4405.               RestX = X + width;
  4406.               PatBlt (hDC, RestX, Y, myRect.right - RestX, LineHeight, Rop);
  4407.  
  4408.           Y += LineHeight;
  4409.         }
  4410.           while (--VertLines > 0 && NextLine (&BlockPtr, &LinePtr));
  4411.  
  4412.         SetTextColor (hDC, MyColors[1]);
  4413.         SetBkColor (hDC, MyBack[1]);
  4414.  
  4415.         /* Blank out bottom and top of screen */
  4416.         PatBlt (hDC, 0, Y, myRect.right, myRect.bottom - Y, PATCOPY);
  4417.         PatBlt (hDC, 0, 0, myRect.right, TopSpace, PATCOPY);
  4418.  
  4419.         UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
  4420.       }
  4421.     EndPaint (hWnd, &ps);
  4422.     break;
  4423. d946 6
  4424. a951 6
  4425.     {
  4426.       if (GroupDocs[idoc].InUse)
  4427.         {
  4428.           UpdateSeenArts (&(GroupDocs[idoc]));
  4429.         }
  4430.     }
  4431. d953 3
  4432. a955 3
  4433.     {
  4434.       WriteNewsrc ();
  4435.     }
  4436. d998 4
  4437. a1001 4
  4438.     {
  4439.       EndDialog (hDlg, TRUE);
  4440.       return (TRUE);
  4441.     }
  4442. d1101 3
  4443. a1103 3
  4444.     {
  4445.       group->Subscribed = TRUE;
  4446.     }
  4447. d1124 1
  4448. a1124 1
  4449.                RangeOffset (group->NameLen));
  4450. d1135 1
  4451. a1135 1
  4452.     buf++;
  4453. d1137 30
  4454. a1166 30
  4455.     {
  4456.       /* We have the first number in a range.                     */
  4457.       (group->nRanges)++;
  4458.       RangePtr->Last = RangePtr->First;
  4459.       if (*buf == '-')
  4460.         {
  4461.           buf++;
  4462.           if (GetNum (&buf, &(RangePtr->Last)))
  4463.         {
  4464.           RangePtr++;
  4465.           /* at this point, we are positioned just after a range */
  4466.         }
  4467.           else
  4468.         {
  4469.           RangePtr->Last = RangePtr->First;
  4470.           MoreNums = FALSE;
  4471.         }
  4472.         }
  4473.       else if (*buf == ',')
  4474.         {
  4475.           /* We have a single number "n"; interpret as the range "n-n".
  4476.            */
  4477.           RangePtr++;
  4478.         }
  4479.       else
  4480.         {
  4481.           /* That must have been the last number.                  */
  4482.           MoreNums = FALSE;
  4483.         }
  4484.     }
  4485. d1168 3
  4486. a1170 3
  4487.     {
  4488.       MoreNums = FALSE;
  4489.     }
  4490. d1222 2
  4491. a1223 1
  4492.         BlockPtr, LinePtr);
  4493. d1225 10
  4494. a1234 8
  4495.       for (found = TRUE, il = 0; il < SelLine; il++)
  4496.     {
  4497.       if (!NextLine (BlockPtr, LinePtr))
  4498.         {
  4499.           found = FALSE;    /* ran off end of document */
  4500.           break;
  4501.         }
  4502.     }
  4503. d1301 8
  4504. a1308 8
  4505.     {
  4506.       mybuf[returned] = '\0';
  4507.       if (CrackGroupLine (mybuf, LocalLinePtr))
  4508.         {
  4509.           NetDoc.ActiveLines++;
  4510.         }
  4511.       AddLine (LocalLinePtr, &BlockPtr, &GroupPtr);
  4512.     }
  4513. d1321 3
  4514. a1323 1
  4515.  
  4516. d1376 72
  4517. a1447 72
  4518.     {
  4519.       toptr = NewsLine;
  4520.       Group = (TypGroup far *) ((char far *) LinePtr + sizeof (TypLine));
  4521.  
  4522.       /* Remove groups only if we performed a LIST command and */
  4523.       /* the server did not have them.  Otherwise if !did_list, the */
  4524.       /* newsrc will be practically empty! */
  4525.  
  4526.       /* Jeeeeez!!  I'm fixing this AGAIN! */
  4527.       /* DoList is not a boolean. SMR 930610 */
  4528.  
  4529.       if ((Group->ServerFirst || Group->ServerEstNum) || !did_list ) {
  4530.       /* Copy group name                                          */
  4531.       fromptr = (char far *) LinePtr + sizeof (TypLine) + sizeof (TypGroup);
  4532.       while (*(toptr++) = *(fromptr++));
  4533.       toptr--;
  4534.  
  4535.       /* Affix : or ! depending upon whether subscribed.          */
  4536.       *(toptr++) = (char) (Group->Subscribed ? ':' : '!');
  4537.       *(toptr++) = ' ';
  4538.  
  4539.       /* If we know the highest article number on the server,
  4540.        * output it preceded by an "s".
  4541.        */
  4542.       if (Group->ServerLast)
  4543.         {
  4544.           *(toptr++) = 's';
  4545.           ltoa ((unsigned long) Group->ServerLast, toptr, 10);
  4546.           while (*toptr)
  4547.         toptr++;
  4548.           *(toptr++) = ' ';
  4549.         }
  4550.  
  4551.       /* Affix ranges of articles read.                          */
  4552.       firstrange = TRUE;
  4553.       nranges = Group->nRanges;
  4554.       RangePtr = (TypRange far *) ((char far *) Group + RangeOffset (Group->NameLen));
  4555.  
  4556.       while ((nranges--) > 0)
  4557.         {
  4558.           /* Write out ',' if not first range of articles.         */
  4559.  
  4560.           if (!firstrange)
  4561.         {
  4562.           *(toptr++) = ',';
  4563.         }
  4564.           else
  4565.         {
  4566.           firstrange = FALSE;
  4567.         }
  4568.           /* Write out first article in a range.                   */
  4569.  
  4570.           ltoa ((unsigned long) RangePtr->First, toptr, 10);
  4571.           while (*toptr)
  4572.         toptr++;
  4573.  
  4574.           /* If the range is of form "n-n", just put out "n"       */
  4575.  
  4576.           if (RangePtr->First != RangePtr->Last)
  4577.         {
  4578.           /* Put out the hyphen in middle of range.                */
  4579.           *(toptr++) = '-';
  4580.           /* Put out the last article in a range.                  */
  4581.           ltoa ((unsigned long) RangePtr->Last, toptr, 10);
  4582.           while (*toptr)
  4583.             toptr++;
  4584.         }
  4585.           RangePtr++;
  4586.         }
  4587.       MRRWriteLine (MRRFile, NewsLine, toptr - NewsLine);
  4588.       }
  4589.     }
  4590. d1463 1
  4591. a1463 1
  4592.        NetDoc.ActiveLines);
  4593. d1510 7
  4594. a1516 7
  4595.       ->Selected)
  4596.     {
  4597.       ((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
  4598.       ->Subscribed = wValue;
  4599.       AddGroupToTable ((char far *) *LinePtr);
  4600.       DeleteLine (BlockPtr, LinePtr);
  4601.     }
  4602. d1518 11
  4603. d1538 3
  4604. a1540 3
  4605.            directory as the HelpEx executable.This function derives
  4606.            the full path name of the help file from the path of the
  4607.            executable.
  4608. d1560 4
  4609. a1563 4
  4610.     {
  4611.       *(++pcFileName) = '\0';
  4612.       break;
  4613.     }
  4614. d1601 1
  4615. a1601 1
  4616.     return (-1);
  4617. d1608 1
  4618. a1608 1
  4619.         BlockPtr, LinePtr);
  4620. d1611 7
  4621. a1617 7
  4622.     {
  4623.       if (!NextLine (BlockPtr, LinePtr))
  4624.         {
  4625.           return (-1);
  4626.           break;
  4627.         }
  4628.     }
  4629. d1622 1
  4630. a1622 1
  4631.                   sizeof (TypLine)))->NameLen;
  4632. d1640 20
  4633. d1669 3
  4634. a1671 3
  4635.           version_string,
  4636.           "WinVN Version Information",
  4637.           MB_OK);
  4638. @
  4639.  
  4640.  
  4641.  
  4642. 1.21
  4643. log
  4644. @testing new ID.
  4645. @
  4646. text
  4647. @d10 2
  4648. a11 2
  4649. static char wvusenet_c[] =
  4650. "$Id: wvusenet.c 1.20 1993/10/12 17:47:26 rushing Exp rushing $\n"
  4651. d13 1
  4652. d15 3
  4653. d107 1
  4654. d491 1
  4655. a491 1
  4656.           /* lstrcat(mybuf,"\r"); */
  4657. d721 1
  4658. a721 9
  4659.       MessageBox (hWnd,
  4660. "$Id: winvn.c 1.15 1993/08/25 18:55:19 mbretherton Exp $\n"
  4661. "$Id: wvutil.c 1.31 1993/12/01 23:24:06 rushing Exp $\n"
  4662.               "Testing\n"
  4663.               "Multi\n"
  4664.               "Line\n"
  4665.               "Output\n",
  4666.               "Testing",
  4667.               MB_OK);
  4668. d1611 13
  4669. @
  4670.  
  4671.  
  4672.  
  4673. 1.20
  4674. log
  4675. @make winvn grok servers that start article numbers at 0
  4676. @
  4677. text
  4678. @d10 2
  4679. d13 3
  4680. a16 2
  4681.  * $Id: wvusenet.c 1.19 1993/09/12 20:26:52 rushing Exp rushing $
  4682.  * $Log: wvusenet.c $
  4683. d713 12
  4684. @
  4685.  
  4686.  
  4687.  
  4688. 1.19
  4689. log
  4690. @handle can't connect condition
  4691. @
  4692. text
  4693. @d12 1
  4694. a12 1
  4695.  * $Id: wvusenet.c 1.18 1993/08/25 18:54:36 mbretherton Exp rushing $
  4696. d14 3
  4697. d1357 1
  4698. a1357 1
  4699.       if ((Group->ServerFirst != 0) || !did_list ) {
  4700. @
  4701.  
  4702.  
  4703.  
  4704. 1.18
  4705. log
  4706. @MRB merge, mail & post logging
  4707. @
  4708. text
  4709. @d12 1
  4710. a12 1
  4711.  * $Id: wvusenet.c 1.17 1993/08/18 21:49:21 rushing Exp $
  4712. d14 2
  4713. d17 1
  4714. d495 2
  4715. a496 1
  4716.       DoCommInput ();
  4717. @
  4718.  
  4719.  
  4720.  
  4721. 1.17
  4722. log
  4723. @more 16-bit article number fixes.
  4724. @
  4725. text
  4726. @d12 1
  4727. a12 1
  4728.  * $Id: wvusenet.c 1.16 1993/08/17 21:46:49 DUMOULIN Exp rushing $
  4729. d14 7
  4730. d123 1
  4731. a123 1
  4732.   RECT myRect;                       /* selection rectangle        */
  4733. d417 1
  4734. a417 1
  4735.                         width,         /* Initial X Width */
  4736. d602 7
  4737. d705 1
  4738. a705 1
  4739.     case IDV_CREATE:
  4740. d879 2
  4741. a880 2
  4742.           GetTextExtentPoint (hDC, indcptr, MyLen, &sz);    
  4743.           width = sz.cx;                                    
  4744. d1254 1
  4745. a1254 1
  4746.   hRetCode = MRROpenFile (szNewsSrc, 0, OF_READ, &MRRFile);
  4747. d1330 1
  4748. a1330 1
  4749.   hRetCode = MRROpenFile (szNewsSrc, 0, OF_CREATE, &MRRFile);
  4750. @
  4751.  
  4752.  
  4753.  
  4754. 1.16
  4755. log
  4756. @Added support for Dragging mouse for selecting/deselecting Usenet groups
  4757. @
  4758. text
  4759. @d12 1
  4760. a12 1
  4761.  * $Id: wvusenet.c 1.15 1993/07/06 21:09:50 cnolan Exp DUMOULIN $
  4762. d14 3
  4763. d857 1
  4764. a857 1
  4765.           sprintf (indcptr, "%c %5ld %s ",
  4766. d859 1
  4767. a859 1
  4768.                        (long) MyGroup->ServerEstNum,
  4769. @
  4770.  
  4771.  
  4772.  
  4773. 1.15
  4774. log
  4775. @win32 support
  4776. @
  4777. text
  4778. @d1 9
  4779. d12 1
  4780. a12 1
  4781.  * $Id: wvusenet.c 1.14 1993/06/28 17:51:39 rushing Exp $
  4782. d14 3
  4783. a28 1
  4784.  *
  4785. a34 1
  4786.  *
  4787. d53 1
  4788. a53 1
  4789.  * Revision 1.3  1993/03/30  20:46:07  DUMOULIN
  4790. a64 5
  4791. /* wvusenet.c */
  4792. /*  This file consists of the window procedure and support routines
  4793.  *  for the main window to the application WinVn.
  4794.  */
  4795.  
  4796. d243 2
  4797. d247 1
  4798. d253 1
  4799. a253 1
  4800.           ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
  4801. d255 1
  4802. d261 38
  4803. @
  4804.  
  4805.  
  4806.  
  4807. 1.14
  4808. log
  4809. @fixed compiler warnings
  4810. @
  4811. text
  4812. @d3 1
  4813. a3 1
  4814.  * $Id: wvusenet.c 1.13 1993/06/24 17:13:14 riordan Exp rushing $
  4815. d5 3
  4816. d456 1
  4817. a456 1
  4818.       switch (wParam)
  4819. d654 1
  4820. d732 2
  4821. a733 1
  4822.         indicatorwidth = LOWORD (GetTextExtent (hDC, "*", 2)) * 7 / 7;
  4823. d815 2
  4824. a816 1
  4825.           width = LOWORD (GetTextExtent (hDC, indcptr, MyLen));
  4826. d844 1
  4827. a844 1
  4828.       CloseComm (CommDevice);
  4829. d1480 1
  4830. a1480 1
  4831.   int extent;
  4832. d1519 2
  4833. a1520 2
  4834.     extent = LOWORD (GetTextExtent (display_context, (LPSTR) textptr, charnum));
  4835.     if (extent > (X - SideSpace)) break;
  4836. @
  4837.  
  4838.  
  4839.  
  4840. 1.13
  4841. log
  4842. @Save window positions between sessions.
  4843. @
  4844. text
  4845. @d3 1
  4846. a3 1
  4847.  * $Id: wvusenet.c 1.12 1993/06/14 18:52:00 rushing Exp $
  4848. d5 3
  4849. d349 1
  4850. a349 1
  4851.           if(mybuf != '!') {
  4852. d640 1
  4853. a640 1
  4854.               lpfnWinVnGenericDlg, (char far *) "Newsgroup(s):");
  4855. d1108 1
  4856. a1108 1
  4857.   if (Y < TopSpace || Y > TopSpace + DocPtr->ScYLines * LineHeight ||
  4858. a1156 1
  4859.   char * env_var;
  4860. d1480 1
  4861. a1480 1
  4862.   if (Y < TopSpace || Y > TopSpace + DocPtr->ScYLines * LineHeight ||
  4863. @
  4864.  
  4865.  
  4866.  
  4867. 1.12
  4868. log
  4869. @'New Posting' menu option added
  4870. @
  4871. text
  4872. @d3 1
  4873. a3 1
  4874.  * $Id: wvusenet.c 1.11 1993/06/11 00:10:35 rushing Exp rushing $
  4875. d5 3
  4876. d102 1
  4877. a102 1
  4878.   RECT myRect;                  /* selection rectangle      */
  4879. d334 15
  4880. d352 4
  4881. a355 4
  4882.                        (int) docnum * CharWidth + 1,/* Initial X pos */
  4883.                        (int) docnum * LineHeight,
  4884.                        (int) xScreen,       /* Initial X Width */
  4885.                        (int) (yScreen * 1 / 2),     /* CW_USEDEFAULT, */
  4886. d543 41
  4887. @
  4888.  
  4889.  
  4890.  
  4891. 1.11
  4892. log
  4893. @second merge from Matt Bretherton sources
  4894. @
  4895. text
  4896. @d3 1
  4897. a3 1
  4898.  * $Id: wvusenet.c 1.10 1993/06/10 18:24:41 rushing Exp $
  4899. d5 2
  4900. d8 1
  4901. d575 8
  4902. @
  4903.  
  4904.  
  4905.  
  4906. 1.10
  4907. log
  4908. @hopefully newsrc&dolist thing is fixed FOR GOOD.
  4909. @
  4910. text
  4911. @d3 1
  4912. a3 1
  4913.  * $Id: wvusenet.c 1.9 1993/05/24 23:55:25 rushing Exp rushing $
  4914. d5 4
  4915. a135 1
  4916.       EnableMenuItem(GetMenu(hWnd),IDM_MAIL,MailCtrl.enableMail) ;
  4917. d160 5
  4918. d568 4
  4919. d783 1
  4920. a783 1
  4921.       MailLogout(hWnd) ;
  4922. @
  4923.  
  4924.  
  4925.  
  4926. 1.9
  4927. log
  4928. @Delete Fonts (cleanup before exiting) (MRB)
  4929. @
  4930. text
  4931. @d3 1
  4932. a3 1
  4933.  * $Id: wvusenet.c 1.8 1993/05/20 18:12:31 rushing Exp $
  4934. d5 2
  4935. d8 1
  4936. d1189 6
  4937. a1194 4
  4938.     // Remove groups only if we performed a LIST command and
  4939.     // the server did not have them.  Otherwise if !DoList, the
  4940.     // newsrc will be practically empty!
  4941.     // SMR 930224
  4942. d1196 1
  4943. a1196 1
  4944.       if ((Group->ServerFirst != 0) || !DoList || started_with_no_dolist) {
  4945. @
  4946.  
  4947.  
  4948.  
  4949. 1.8
  4950. log
  4951. @don't write out newsrc if Intializing is true
  4952. @
  4953. text
  4954. @d3 1
  4955. a3 1
  4956.  * $Id: wvusenet.c 1.7 1993/04/29 20:23:06 rushing Exp rushing $
  4957. d5 4
  4958. d769 9
  4959. @
  4960.  
  4961.  
  4962.  
  4963. 1.7
  4964. log
  4965. @attempted support for WSAAsyncSelect
  4966. @
  4967. text
  4968. @d3 1
  4969. a3 1
  4970.  * $Id: wvusenet.c 1.6 1993/04/27 20:11:38 rushing Exp rushing $
  4971. d5 3
  4972. d758 1
  4973. a758 1
  4974.       if (SaveNewsrc)
  4975. @
  4976.  
  4977.  
  4978.  
  4979. 1.6
  4980. log
  4981. @Fixed out-of-date code that killed the timer if
  4982. CommState was ST_NONE.
  4983. @
  4984. text
  4985. @d3 1
  4986. a3 1
  4987.  * $Id: wvusenet.c 1.5 1993/04/27 18:53:17 rushing Exp rushing $
  4988. d5 4
  4989. d77 1
  4990. a77 1
  4991.   PAINTSTRUCT ps;        /* paint structure          */
  4992. d80 1
  4993. a80 1
  4994.   HDC hDC;            /* handle to display context */
  4995. d82 1
  4996. a82 1
  4997.   RECT myRect;            /* selection rectangle      */
  4998. d181 5
  4999. a185 5
  5000.                * of the key just pressed, look up in the array
  5001.                * key2scroll to see if we should process this keystroke
  5002.                * as if it were a mouse event.  If so, simulate the
  5003.                * mouse event by sending the appropriate message.
  5004.                */
  5005. d258 5
  5006. a262 5
  5007.                * this newsgroup are not in memory, and that it's OK
  5008.                * to fetch them from the server.  (Comm line not busy.)
  5009.                * Figure out whether a new window/document should be
  5010.                * created for this group & set "newdoc" accordingly.
  5011.                */
  5012. d313 1
  5013. a313 1
  5014.                                    (int) docnum * CharWidth + 1,/* Initial X pos */
  5015. d315 2
  5016. a316 2
  5017.                        (int) xScreen,    /* Initial X Width */
  5018.                        (int) (yScreen * 1 / 2),    /* CW_USEDEFAULT, */
  5019. d323 1
  5020. a323 1
  5021.             return (0);    /* ??? */
  5022. d337 4
  5023. a340 4
  5024.                * initialize empty document to hold subject lines,
  5025.                * set focus to this document, set pointers linking
  5026.                * this document and the subject line.
  5027.                */
  5028. d359 2
  5029. a360 2
  5030.                * send the GROUP command to NNTP.
  5031.                */
  5032. d386 1
  5033. a386 1
  5034.           KillTimer(hWnd,ID_TIMER) ;
  5035. d390 1
  5036. a390 1
  5037.           DoCommInput ();
  5038. d450 2
  5039. a451 2
  5040.                      (size_t) nNewGroups,
  5041.                      (size_t) sizeof (void far *),
  5042. d565 1
  5043. a565 1
  5044.           char group_name[MAXINTERNALLINE];
  5045. d708 3
  5046. a710 3
  5047.                                indicator,
  5048.                                    (long) MyGroup->ServerEstNum,
  5049.                                group_name);
  5050. d720 1
  5051. a720 1
  5052.                       RestX = X + width;
  5053. d952 1
  5054. a952 1
  5055.                */
  5056. d1022 1
  5057. a1022 1
  5058.           found = FALSE;    /* ran off end of document */
  5059. d1063 1
  5060. a1063 1
  5061.   env_var = getenv ("WINVN");        /* get path to winvn.ini */
  5062. d1175 1
  5063. a1175 1
  5064.           if ((Group->ServerFirst != 0) || !DoList || started_with_no_dolist) {
  5065. d1186 2
  5066. a1187 2
  5067.            * output it preceded by an "s".
  5068.            */
  5069. d1234 1
  5070. a1234 1
  5071.           }
  5072. d1315 3
  5073. a1317 3
  5074.                directory as the HelpEx executable.This function derives
  5075.                the full path name of the help file from the path of the
  5076.                executable.
  5077. d1399 1
  5078. a1399 1
  5079.                               sizeof (TypLine)))->NameLen;
  5080. d1408 2
  5081. a1409 2
  5082.         extent = LOWORD (GetTextExtent (display_context, (LPSTR) textptr, charnum));
  5083.         if (extent > (X - SideSpace)) break;
  5084. @
  5085.  
  5086.  
  5087.  
  5088. 1.5
  5089. log
  5090. @attempt to fix newsrc problems.  allow newsrc line with
  5091. no range data.
  5092. @
  5093. text
  5094. @d3 1
  5095. a3 1
  5096.  * $Id: wvusenet.c 1.4 1993/03/30 21:07:15 DUMOULIN Exp rushing $
  5097. d5 4
  5098. d122 4
  5099. d377 2
  5100. a378 3
  5101. // changed to ST_NONE from ST_CLOSED_COMM during
  5102. // MAPI merge because of conflicting edits in wvsck???.c
  5103.  
  5104. d380 1
  5105. a380 1
  5106.      if (CommState == ST_NONE)
  5107. @
  5108.  
  5109.  
  5110.  
  5111. 1.4
  5112. log
  5113. @handle conflicting MAPI merge problem (with wvsck???.c)
  5114. use ST_NONE instead of ST_CLOSED_COMM
  5115. @
  5116. text
  5117. @d3 1
  5118. a3 1
  5119.  * $Id: wvusenet.c 1.3 1993/03/30 20:46:07 DUMOULIN Exp DUMOULIN $
  5120. d5 4
  5121. d894 1
  5122. a894 1
  5123.   while (*buf && *buf == ' ')
  5124. d911 4
  5125. a914 1
  5126.   MoreNums = TRUE;
  5127. @
  5128.  
  5129.  
  5130.  
  5131. 1.3
  5132. log
  5133. @MAPI
  5134. @
  5135. text
  5136. @d3 5
  5137. a7 2
  5138.  * $Id: wvusenet.c,v 1.2 1993/02/25 03:08:52 rushing Exp $
  5139.  * $Log: wvusenet.c,v $
  5140. d365 3
  5141. d369 1
  5142. a369 1
  5143.      if (CommState == ST_CLOSED_COMM)
  5144. @
  5145.  
  5146.  
  5147.  
  5148. 1.2
  5149. log
  5150. @fixed newsrc truncation when DoList = 0.
  5151. @
  5152. text
  5153. @d3 5
  5154. a7 2
  5155.  * $Id: wvusenet.c%v 1.1 1993/02/16 20:54:22 rushing Exp rushing $
  5156.  * $Log: wvusenet.c%v $
  5157. d106 2
  5158. d109 1
  5159. a109 1
  5160.       idTimer = SetTimer (hWnd, NULL, 1000, (FARPROC) NULL);
  5161. d363 8
  5162. a370 1
  5163.       DoCommInput ();
  5164. d527 1
  5165. a527 1
  5166.       CreatePostingWnd ((TypDoc *) NULL, DOCTYPE_MAIL);
  5167. d739 2
  5168. @
  5169.  
  5170.  
  5171.  
  5172. 1.1
  5173. log
  5174. @Initial revision
  5175. @
  5176. text
  5177. @d3 4
  5178. a6 2
  5179.  * $Id$
  5180.  * $Log$
  5181. d8 1
  5182. d29 7
  5183. d1076 3
  5184. d1132 6
  5185. a1137 1
  5186.           if (Group->ServerFirst != 0) {
  5187. @
  5188.  
  5189.