head	 1.53;
branch   ;
access   ;
symbols  test:1.51 V80:1.11 V76d:1.2;
locks    ; strict;
comment  @ * @;


1.53
date	 94.09.18.22.46.50;  author jcooper;  state Exp;
branches ;
next	 1.52;

1.52
date	 94.09.16.00.41.22;  author jcooper;  state Exp;
branches ;
next	 1.51;

1.51
date	 94.09.02.23.50.26;  author rushing;  state Exp;
branches ;
next	 1.50;

1.50
date	 94.08.23.23.17.34;  author martin;  state Exp;
branches ;
next	 1.49;

1.49
date	 94.08.12.01.39.21;  author dumoulin;  state Exp;
branches ;
next	 1.48;

1.48
date	 94.08.11.21.41.41;  author rushing;  state Exp;
branches ;
next	 1.47;

1.47
date	 94.08.11.20.28.11;  author rushing;  state Exp;
branches ;
next	 1.46;

1.46
date	 94.08.11.00.14.26;  author jcooper;  state Exp;
branches ;
next	 1.45;

1.45
date	 94.08.04.05.51.13;  author dumoulin;  state Exp;
branches ;
next	 1.44;

1.44
date	 94.08.03.00.55.24;  author dumoulin;  state Exp;
branches ;
next	 1.43;

1.43
date	 94.07.27.21.09.33;  author gardnerd;  state Exp;
branches ;
next	 1.42;

1.42
date	 94.07.25.18.51.03;  author jcooper;  state Exp;
branches ;
next	 1.41;

1.41
date	 94.07.12.19.50.52;  author cnolan;  state Exp;
branches ;
next	 1.40;

1.40
date	 94.07.12.19.15.49;  author rushing;  state Exp;
branches ;
next	 1.39;

1.39
date	 94.06.30.21.30.41;  author gardnerd;  state Exp;
branches ;
next	 1.38;

1.38
date	 94.06.30.16.36.23;  author dumoulin;  state Exp;
branches ;
next	 1.37;

1.37
date	 94.06.08.21.01.45;  author gardnerd;  state Exp;
branches ;
next	 1.36;

1.36
date	 94.06.06.22.06.13;  author gardnerd;  state Exp;
branches ;
next	 1.35;

1.35
date	 94.06.06.21.23.37;  author mrr;  state Exp;
branches ;
next	 1.34;

1.34
date	 94.06.01.20.48.43;  author rushing;  state Exp;
branches ;
next	 1.33;

1.33
date	 94.05.27.01.29.29;  author rushing;  state Exp;
branches ;
next	 1.32;

1.32
date	 94.05.25.22.53.26;  author dumoulin;  state Exp;
branches ;
next	 1.31;

1.31
date	 94.05.23.18.36.00;  author jcooper;  state Exp;
branches ;
next	 1.30;

1.30
date	 94.05.19.02.04.54;  author rushing;  state Exp;
branches ;
next	 1.29;

1.29
date	 94.05.02.20.38.53;  author rushing;  state Exp;
branches ;
next	 1.28;

1.28
date	 94.04.19.18.35.23;  author rushing;  state Exp;
branches ;
next	 1.27;

1.27
date	 94.02.24.21.35.08;  author jcoop;  state Exp;
branches ;
next	 1.26;

1.26
date	 94.02.09.18.01.08;  author cnolan;  state Exp;
branches ;
next	 1.25;

1.25
date	 94.01.24.17.41.01;  author jcoop;  state Exp;
branches ;
next	 1.24;

1.24
date	 94.01.16.12.04.33;  author jcoop;  state Exp;
branches ;
next	 1.23;

1.23
date	 94.01.12.19.27.32;  author mrr;  state Exp;
branches ;
next	 1.22;

1.22
date	 93.12.08.01.28.01;  author rushing;  state Exp;
branches ;
next	 1.21;

1.21
date	 93.12.07.20.24.43;  author rushing;  state Exp;
branches ;
next	 1.20;

1.20
date	 93.10.12.17.47.26;  author rushing;  state Exp;
branches ;
next	 1.19;

1.19
date	 93.09.12.20.26.52;  author rushing;  state Exp;
branches ;
next	 1.18;

1.18
date	 93.08.25.18.54.36;  author mbretherton;  state Exp;
branches ;
next	 1.17;

1.17
date	 93.08.18.21.49.21;  author rushing;  state Exp;
branches ;
next	 1.16;

1.16
date	 93.08.17.21.46.49;  author DUMOULIN;  state Exp;
branches ;
next	 1.15;

1.15
date	 93.07.06.21.09.50;  author cnolan;  state Exp;
branches ;
next	 1.14;

1.14
date	 93.06.28.17.51.39;  author rushing;  state Exp;
branches ;
next	 1.13;

1.13
date	 93.06.24.17.13.14;  author riordan;  state Exp;
branches ;
next	 1.12;

1.12
date	 93.06.14.18.52.00;  author rushing;  state Exp;
branches ;
next	 1.11;

1.11
date	 93.06.11.00.10.35;  author rushing;  state Exp;
branches ;
next	 1.10;

1.10
date	 93.06.10.18.24.41;  author rushing;  state Exp;
branches ;
next	 1.9;

1.9
date	 93.05.24.23.55.25;  author rushing;  state Exp;
branches ;
next	 1.8;

1.8
date	 93.05.20.18.12.31;  author rushing;  state Exp;
branches ;
next	 1.7;

1.7
date	 93.04.29.20.23.06;  author rushing;  state Exp;
branches ;
next	 1.6;

1.6
date	 93.04.27.20.11.38;  author rushing;  state Exp;
branches ;
next	 1.5;

1.5
date	 93.04.27.18.53.17;  author rushing;  state Exp;
branches ;
next	 1.4;

1.4
date	 93.03.30.21.07.15;  author DUMOULIN;  state Exp;
branches ;
next	 1.3;

1.3
date	 93.03.30.20.46.07;  author DUMOULIN;  state Exp;
branches ;
next	 1.2;

1.2
date	 93.02.25.03.08.52;  author rushing;  state Exp;
branches ;
next	 1.1;

1.1
date	 93.02.16.20.54.22;  author rushing;  state Exp;
branches ;
next	 ;


desc
@winvn version 0.76 placed into RCS
@


1.53
log
@New Window menu item, etc
@
text
@/********************************************************************
 *                                                                  *
 *  MODULE    :  WVUSENET.C                                         *
 *                                                                  *
 *  PURPOSE   : This file contains the window procedure and support *
 *              routines for WinVn's main window                    *
 *                                                                  *
 ********************************************************************/

/*
 * $Id: wvusenet.c 1.52 1994/09/16 00:41:22 jcooper Exp $
 *
 */
#include <windows.h>
#include <windowsx.h>
#include "wvglob.h"
#include "winvn.h"
#pragma hdrstop
#include <stdlib.h>

// This is for the special case where the user invoked the
// program with dolist=0, then turned it on.  Without checking
// this condition, the newsrc will be truncated to only those
// groups read.  SMR 930224

int started_with_no_dolist;

void show_version_strings(HWND);
void SetGroupActiveLines(void);
void AbortAllComm();

/*--- FUNCTION: WinVnConfWndProc ---------------------------------------
 *
 *    Window procedure for the "Net" window.
 *    This window displays the names of the newsgroups, one per line.
 *
 *    Entry    The usual parameters for any window function.
 *
 *    Note:    We don't do anything until "Initialized" is TRUE.
 *             This way, the user won't try to perform functions
 *             while the communications are still being set up.
 */

long WINAPI WinVnConfWndProc (hWnd, message, wParam, lParam)
     HWND hWnd;
     unsigned message;
     WPARAM wParam;
     LPARAM lParam;
{

  DLGPROC lpProcAbout;
  HMENU hMenu, hSubMenu;

  PAINTSTRUCT ps;               /* paint structure          */
  POINT ptCursor;

  HDC hDC;                      /* handle to display context */
  HWND hWndView;
  RECT myRect;                                    /* selection rectangle                */

  int j, idoc;
  int found;
  char far *lpsz;
  TypLine far *LinePtr, far * GroupLinePtr;
  TypBlock far *BlockPtr, far * GroupBlockPtr;
  HANDLE hBlock;
  TypDoc *MyDoc;
  unsigned int Offset;
  BOOL looping = TRUE;
  BOOL continueFind;
  TypGroup far *MyGroup;
  
  int X, Y;
  int docnum;
  int newdoc;
  char mybuf[MAXINTERNALLINE];
  int OldSel = FALSE;
  int CtrlState;
  TypLineID MyLineID;

  switch (message)
    {

    case WM_SYSCOMMAND:
      if (wParam == ID_ABOUT)
   {
     lpProcAbout = (DLGPROC)MakeProcInstance ((FARPROC)About, hInst);
     DialogBox (hInst, "AboutBox", hWnd, lpProcAbout);
     FreeProcInstance ((FARPROC)lpProcAbout);
     break;
   }
      else
   return (DefWindowProc (hWnd, message, wParam, lParam));

    case WM_CREATE:
      MailInit (hWnd) ;

      /* Get handle to the hourglass cursor */

      hHourGlass = LoadCursor (hInst, IDC_WAIT);

      /* Add the "About" option to the system menu.            */

      hMenu = GetSystemMenu (hWnd, FALSE);
      ChangeMenu (hMenu, NULL, NULL, NULL, MF_APPEND | MF_SEPARATOR);
      ChangeMenu (hMenu, NULL, "A&bout WinVn...", ID_ABOUT,
        MF_APPEND | MF_STRING);

      /* Fill in the Net document's window handle that we
       * were unable to fill in in the call to InitDoc.
       */
      NetDoc.hDocWnd = hWnd;
      InitBitmaps();
      break;

    case WM_INITMENU:
      hMenu = GetMenu (hWnd);
      hSubMenu = GetSubMenu (hMenu, 2);	/* Utilities menu */
      EnableMenuItem (GetSubMenu (hSubMenu, 3), IDM_SEND_ALL_POST, NumPostWnds ? MF_ENABLED : MF_DISABLED|MF_GRAYED);
      EnableMenuItem (GetSubMenu (hSubMenu, 3), IDM_SEND_ALL_MAIL, NumMailWnds ? MF_ENABLED : MF_DISABLED|MF_GRAYED);
		
      hSubMenu = GetSubMenu (hMenu, 4);	/* Window menu */
      EnableMenuItem (GetSubMenu (hSubMenu, 1), IDM_CLOSE_ALL_ARTICLE, NumArticleWnds ? MF_ENABLED : MF_DISABLED|MF_GRAYED);
      EnableMenuItem (GetSubMenu (hSubMenu, 1), IDM_CLOSE_ALL_GROUP, NumGroupWnds ? MF_ENABLED : MF_DISABLED|MF_GRAYED);
      EnableMenuItem (GetSubMenu (hSubMenu, 1), IDM_CLOSE_ALL_STATUS, NumStatusTexts ? MF_ENABLED : MF_DISABLED|MF_GRAYED);
      EnableMenuItem (GetSubMenu (hSubMenu, 1), IDM_CLOSE_ALL, (NumArticleWnds||NumGroupWnds||NumStatusTexts) ? MF_ENABLED : MF_DISABLED|MF_GRAYED);
      break;
    
    case WM_CHAR:
      /* Hitting CR on a group name is the same as double-clicking
       * on the name.
       */
      if (!Initializing)
   {
     if (wParam == '\r')
       {

         GetCursorPos (&ptCursor);
         ScreenToClient (hWnd, &ptCursor);
         X = ptCursor.x;
         Y = ptCursor.y;
         goto getgroup;
       }
   }
      break;

    case WM_KEYDOWN:
      /* See if this key should be mapped to a scrolling event
       * for which we have programmed the mouse.  If so,
       * construct the appropriate mouse call and call the mouse code.
       * Also, F6 means switch to next window.
       * (This latter should also be table-driven.)
       */
      if (!Initializing)
   {
     if (wParam == VK_F6)
       {
         NextWindow (&NetDoc);
       }
     else
       {
         /* Based on the state of the Control key and the value
          * of the key just pressed, look up in the array
          * key2scroll to see if we should process this keystroke
          * as if it were a mouse event.  If so, simulate the
          * mouse event by sending the appropriate message.
          */

         CtrlState = GetKeyState (VK_CONTROL) < 0;
         for (j = 0; j < NUMKEYS; j++)
      {
        if (wParam == key2scroll[j].wVirtKey &&
            CtrlState == key2scroll[j].CtlState)
          {
            SendMessage (hWnd, key2scroll[j].iMessage,
               key2scroll[j].wRequest, 0L);
            break;
          }
      }

       }
   }
      break;

    case WM_LBUTTONDOWN:
      /*  Clicking the left button on a group name toggles the
       *  selected/not selected status of that group.
       *  Currently selected groups are displayed in reverse video.
       */
   
      DragMouseAction = DRAG_NONE;
      if (!Initializing)
   {
          BOOL status;
     X = LOWORD (lParam);
     Y = HIWORD (lParam);

     // make this behave more like a multi-select listbox (jlg)
     // if click,       make the line the only one selected
     // if ctrl-click,  add the line to the selection
     // if shift-click, select from previously selected to current
     if (GroupMultiSelect) {                                 
        if ( !(wParam & MK_CONTROL) && !(wParam & MK_SHIFT) ) {
           ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
           }
        }
     if (CursorToTextLine (X, Y, &NetDoc, &BlockPtr, &LinePtr))
       {
         status = ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
                     ->Selected ^= TRUE;
         if (GroupMultiSelect) {                                 
            if ( wParam & MK_SHIFT ) {
               do {
                  looping = PrevLine (&BlockPtr, &LinePtr);
                  MyGroup = (TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine));
                  if (MyGroup->Selected)
                     looping = FALSE;
                  else
                     MyGroup->Selected = TRUE;   
                  } 
                  while (looping);
               }
            }
         DragMouseAction = status ? DRAG_SELECT : DRAG_DESELECT;
         GlobalUnlock (BlockPtr->hCurBlock);
         SetCapture(hWnd); // release capture on button up
       }

     InvalidateRect (hWnd, NULL, FALSE);
   }
      break;

    case WM_LBUTTONUP:
      /*  Letting up on the left button on a group name 
       *  gets us out of Dragging mode   */

      ReleaseCapture();
      DragMouseAction = DRAG_NONE;
      break;

    case WM_MOUSEMOVE:
      /*  Code to drag the mouse and change the select/not selected
       *  status of that group.
       */

      if ((!Initializing) && (DragMouseAction != DRAG_NONE))
      {
        X = LOWORD (lParam);
        Y = HIWORD (lParam);

        GetClientRect (hWnd, &myRect);
        if (CursorToTextLine (X, Y, &NetDoc, &BlockPtr, &LinePtr))
        {
              switch (DragMouseAction)
              {
               case DRAG_SELECT:
                 ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
                    ->Selected = TRUE;
                 break;
               case DRAG_DESELECT:
                 ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
                    ->Selected = FALSE;
               break;
              }
             GlobalUnlock (BlockPtr->hCurBlock);
          }
          InvalidateRect (hWnd, NULL, FALSE);
      }
      break;

    case WM_LBUTTONDBLCLK:
      /*  Double-clicking on a group name creates a "Group"
       *  window, whose purpose is to display the subjects
       *  of the articles in the group.
       */
      if (!Initializing)
   {
     X = LOWORD (lParam);
     Y = HIWORD (lParam);
   getgroup:;


     if (CursorToTextLine (X, Y, &NetDoc, &GroupBlockPtr, &GroupLinePtr))
       {
         if (MyDoc = (((TypGroup far *)
      (((char far *) GroupLinePtr) + sizeof (TypLine)))->SubjDoc))
      {

        /* We already have a document containing the subjects */
        /* of this group, so just activate it.                */

        SetActiveWindow (MyDoc->hDocWnd);
        SetFocus (MyDoc->hDocWnd);
        GlobalUnlock (GroupBlockPtr->hCurBlock);
        break;
      }
      if (TestCommBusy(hWnd, "Can't request info on group"))
   {
     GlobalUnlock (GroupBlockPtr->hCurBlock);
     break;
   }

         /* At this point, we've determined that the subjects for
          * this newsgroup are not in memory, and that it's OK
          * to fetch them from the server.  (Comm line not busy.)
          * Figure out whether a new window/document should be
          * created for this group & set "newdoc" accordingly.
          */
         newdoc = FALSE;
         if (ViewNew || !ActiveGroupDoc || !(ActiveGroupDoc->InUse))
      {
        found = FALSE;
        for (docnum = 0; docnum < MAXGROUPWNDS; docnum++)
          {
            if (!GroupDocs[docnum].InUse)
         {
           found = TRUE;
           newdoc = TRUE;
           CommDoc = &(GroupDocs[docnum]); 
           CommDoc->LongestLine = 0;
           CommDoc->ScXOffset = 0;
           break;
         }
          }
        if (!found)
          {
            MessageBox (hWnd, "You have too many group windows \
active;\nClose one or select 'Reuse Old Window'.", "Can't open new window", MB_OK | MB_ICONASTERISK);
            UnlockLine (GroupBlockPtr, GroupLinePtr, &hBlock, &Offset, &MyLineID);
            break;
          }
      }
         else
      {
        /* Must reuse old window for this group.           */  
        ActiveGroupDoc->LongestLine = 0;
        ActiveGroupDoc->ScXOffset = 0;
        CommDoc = ActiveGroupDoc;
	UpdateSeenArts (CommDoc);
        UnlinkArtsInGroup (CommDoc);
        LockLine (CommDoc->hParentBlock, CommDoc->ParentOffset, CommDoc->ParentLineID, &BlockPtr, &LinePtr);
        ((TypGroup far *)
         (((char far *) LinePtr) + sizeof (TypLine)))->SubjDoc = (TypDoc *) NULL;
        UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
        /* clear out contents of this document for reuse */
        FreeDoc (CommDoc);
      }

         /* Create window title indicating we are retrieving text. */

         CommDoc->InUse = TRUE;
         lpsz = (char far *) (((char far *) GroupLinePtr) +
               sizeof (TypLine) + sizeof (TypGroup));
         strcpy (mybuf, "Retrieving ");
         lstrcat (mybuf, lpsz);

         /* If necessary, create a new window.              */

         if (newdoc)
      {
        int x,y,width,height;
        char poschars[MAXINTERNALLINE];

        /* Compute default screen position. */
        x = 1;
        y = 0;
        width = (int) xScreen;
        height = (int) (yScreen * 1 / 2);

        /* If the screen position has been saved, use that instead. */
        GetPrivateProfileString (szAppName, "GroupWindowPos", "!",
          poschars,MAXINTERNALLINE,szAppProFile);
        if(poschars[0] != '!') {
          sscanf(poschars,"%d,%d,%d,%d",&x,&y,&width,&height);
        }
        hWndView = CreateWindow ("WinVnView",
                  mybuf,
                  WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
                  x + (int) docnum * CharWidth,/* Initial X pos */
                  y + (int) docnum * LineHeight,
                  width,           /* Initial X Width */
                  height,
                  NULL,
                  NULL,
                  hInst,
                  NULL);

        if (!hWndView)
          return (0); /* ??? */

    SetHandleBkBrush (hWndView, hListBackgroundBrush);
   ShowWindow (hWndView, SW_SHOWNORMAL);
      }
         else
      {
        hWndView = CommDoc->hDocWnd;
        SetWindowText (hWndView, mybuf);
      }
         RcvLineCount = 0;
         TimesWndUpdated = 0;

         /* Do some housekeeping:  Set group as selected,
          * initialize empty document to hold subject lines,
          * set focus to this document, set pointers linking
          * this document and the subject line.
          */
         ((TypGroup far *) (((char far *) GroupLinePtr) +
             sizeof (TypLine)))->Selected = TRUE;
         InitDoc (CommDoc, hWndView, &NetDoc, DOCTYPE_GROUP);
         PtrToOffset (GroupBlockPtr, GroupLinePtr, &(CommDoc->hParentBlock),
         &(CommDoc->ParentOffset), &(CommDoc->ParentLineID));
         SetActiveWindow (hWndView);
         SetFocus (hWndView);

         ((TypGroup far *) (((char far *) GroupLinePtr) + sizeof (TypLine)))
      ->SubjDoc = CommDoc;
         GlobalUnlock (GroupBlockPtr->hCurBlock);
         InvalidateRect (hWndView, NULL, FALSE);

         UpdateWindow (hWndView);

         InvalidateRect (NetDoc.hDocWnd, NULL, FALSE);

         /* Deal with Comm-related stuff:  set FSA variables,
          * send the GROUP command to NNTP.
          */

         CommLinePtr = CommLineIn;
         CommBusy = TRUE;
         CommState = ST_GROUP_RESP;
         hSaveCursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
         ShowCursor (TRUE);

/* capture the mouse to the usenet window, so that we keep the hourglass */

//       SetCapture (hWnd);
         strcpy (mybuf, "GROUP ");
         lpsz = (char far *) GroupLinePtr + sizeof (TypLine) + sizeof (TypGroup);
         lstrcat (mybuf, lpsz);
         mylstrncpy (CurrentGroup, lpsz, MAXFINDSTRING);
         PutCommLine (mybuf);
       }
   }
      break;

// If we've lost the connection for some reason, kill the timer
// that's banging on the socket.
    case WM_TIMER:
     if ((CommState == ST_CLOSED_COMM) && (!Initializing))
       {
     KillTimer(hWnd,ID_TIMER) ;
       }
     else 
       {
    if (CommState != ST_CLOSED_COMM)
      DoCommInput ();
       };
      break;

    case WM_SIZE:
      /* Store the new size of the window.                     */
      GetClientRect (hWnd, &myRect);
      NetDoc.ScXWidth = myRect.right;
      NetDoc.ScYHeight = myRect.bottom;
      NetDoc.ScYLines = (myRect.bottom - myRect.top - TopSpace) / LineHeight;
      NetDoc.ScXChars = (myRect.right - myRect.left - SideSpace) / CharWidth;
      break;

    case WM_VSCROLL:
      if (!Initializing)
   {
     ScrollIt (&NetDoc, wParam, lParam);
   }
      break;

    case WM_HSCROLL:
      if (!Initializing)
      {
        HScrollIt (&NetDoc, wParam, lParam);
      }
      break;

    case WM_COMMAND:
      switch (LOWORD(wParam))
   {
                                                           
   case IDM_QUIT:
     SaveNewsrc = SaveConfig = FALSE;
     DestroyWindow (hWnd);
     break;

   case IDM_EXIT: 
      SendMessage(hWnd, WM_CLOSE, 0, 0L);
      break;

   case IDM_VIEW_SEL_GROUP:
     break;

   case IDM_SHOW_SUBSCR:
   case IDM_SHOW_ALL_GROUP:
   case IDM_SEL_SUBSCR:
   case IDM_SELECTALL:
     MessageBox (hWnd, "Command not implemented",
            "Sorry", MB_OK);
     break;

   case IDM_UNSEL_ALL:
     ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
     InvalidateRect (hWnd, NULL, FALSE);
     break;

   case IDM_SUBSCRIBE:
     InitGroupTable ();
     ForAllLines (&NetDoc, GroupAction, GROUP_ACTION_SUBSCRIBE, TRUE);
     BuildPtrList ();
     MergeGroups (ADD_SUBSCRIBED_END_OF_SUB);
     CleanUpGroupTable ();
     ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
     NetDoc.LongestLine = 0;
     SetGroupActiveLines();
     ScreenToTop (&NetDoc);
     SetNetDocTitle ();
     InvalidateRect (hWnd, NULL, FALSE);
     break;

   case IDM_UNSUBSCRIBE:
     InitGroupTable ();
     ForAllLines (&NetDoc, GroupAction, GROUP_ACTION_UNSUBSCRIBE, FALSE);
     BuildPtrList ();
     ShellSort (NewGroupTable,
		(size_t) nNewGroups,
		(size_t) sizeof (void far *),
		GroupCompare);
     MergeGroups (ADD_SUBSCRIBED_END_OF_SUB);
     CleanUpGroupTable ();
     ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
     NetDoc.LongestLine = 0;
     SetGroupActiveLines();
     ScreenToTop (&NetDoc);
     SetNetDocTitle ();
     InvalidateRect (hWnd, NULL, FALSE);
     break;

   case IDM_GROUP_TOP:
     InitGroupTable ();
     ForAllLines (&NetDoc, GroupAction, GROUP_ACTION_SUBSCRIBE, TRUE);
     BuildPtrList ();
     MergeGroups (ADD_SUBSCRIBED_TOP_OF_DOC);
     CleanUpGroupTable ();
     ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
     ScreenToTop (&NetDoc);
     InvalidateRect (hWnd, NULL, FALSE);
     break;

#if 0 // This code not used anywhere (JSC 1/12/94)
   case IDM_NEW_WIN_GROUP:
     ViewNew = !ViewNew;
     CheckView (hWnd);
     break;

   case IDM_NEW_WIN_ARTICLE:
     NewArticleWindow = !NewArticleWindow;
     CheckView (hWnd);
     break;
#endif

   case IDM_COMMOPTIONS:

     if (DialogBox (hInst, "WinVnComm", hWnd, lpfnWinVnCommDlg))
       {
         InvalidateRect (hWnd, NULL, TRUE);
       }

     break;

   case IDM_CONFIG_PERSONAL:

     DialogBox (hInst, "WinVnPersonal", hWnd, lpfnWinVnPersonalInfoDlg);
     break;

   case IDM_CONFIG_MISC:

     DialogBox (hInst, "WinVnMisc", hWnd, lpfnWinVnMiscDlg);

     break;

   case IDM_CONFIG_LOG:

     DialogBox (hInst, "WinVnLogOpts", hWnd, lpfnWinVnLogOptDlg);

     break;

   case IDM_CONFIG_SIGFILE:
     if (DialogBox (hInst, "WinVnSigFile", hWndConf, lpfnWinVnSigFileDlg))
       {
         InvalidateRect (hWnd, NULL, TRUE);
       }

     break;

   case IDM_CONFIG_SMART_FILER:
     DialogBox(hInst, "WinvnSmartFiler", hWndConf, lpfnWinVnSmartFilerDlg);
     break;

   case IDM_FONT_GROUPLIST:
     if (AskForFont (hWndConf, ListFontFace, &ListFontSize, ListFontStyle)) 
       break;
     InitListFonts();
     SendMessage (hWndConf, WM_SIZE, 0, 0L);
     InvalidateRect (hWndConf, NULL, TRUE);
     RefreshGroupWnds();
     break;

   case IDM_FONT_ARTICLE_TEXT:
     if (AskForFont (hWndConf, ArticleFontFace, &ArticleFontSize, ArticleFontStyle)) 
       break;
     InitArticleFonts();
     RefreshArticleWnds();
     break;

   case IDM_FONT_STATUS_TEXT:
    askStatusFont:;
     if (AskForFont (hWndConf, StatusFontFace, &StatusFontSize, StatusFontStyle)) 
        break;
     InitStatusFonts();
     if (STATUSWIDTH > xScreen)
     {
       MessageBox (hWndConf,"The status window will not fit on your screen with this font.\nPlease select a smaller font",
                       "Font too big", MB_OK|MB_ICONSTOP);
       goto askStatusFont;
     }
     RefreshStatusWnds();
     break;

   case IDM_FONT_PRINT_TEXT:
     if (AskForFont (hWndConf, PrintFontFace, &PrintFontSize, "Printer")) 
       break;
     InitPrintFonts();
     InvalidateRect (hWndConf, NULL, TRUE);
     break;

   case IDM_COLOR_SUBSCRIBED:
     if (AskForColor (hWndConf, &NetSubscribedColor))
       break;
     InvalidateRect (hWndConf, NULL, TRUE);
     break;

   case IDM_COLOR_UNSUBSCRIBED:
     if (AskForColor (hWndConf, &NetUnSubscribedColor))
       break;
     InvalidateRect (hWndConf, NULL, TRUE);
     break;

   case IDM_COLOR_SEEN:
     if (AskForColor (hWndConf, &ArticleSeenColor))
       break;
     RefreshGroupWnds();
     break;

   case IDM_COLOR_UNSEEN:
     if (AskForColor (hWndConf, &ArticleUnSeenColor))
       break;
     RefreshGroupWnds();
     break;

   case IDM_COLOR_ARTICLE_TEXT:
     if (AskForColor (hWndConf, &ArticleTextColor))
       break;
     RefreshArticleWnds();
     break;

   case IDM_COLOR_STATUS_TEXT:
     if (AskForColor (hWndConf, &StatusTextColor))
       break;
     RefreshStatusWnds();
     break;

   case IDM_COLOR_LIST_BACKGROUND:
     if (AskForColor (hWndConf, &ListBackgroundColor))
       break;
     DeleteObject (hListBackgroundBrush);
     hListBackgroundBrush = CreateSolidBrush (ListBackgroundColor);
     SetHandleBkBrush (hWnd, hListBackgroundBrush);

     RefreshGroupWnds();
     InvalidateRect (hWndConf, NULL, TRUE);
     break;

   case IDM_COLOR_ARTICLE_BACKGROUND:
     if (AskForColor (hWndConf, &ArticleBackgroundColor))
        break;
      DeleteObject (hArticleBackgroundBrush);
      hArticleBackgroundBrush = CreateSolidBrush (ArticleBackgroundColor);
      RefreshArticleWnds();
      break;

   case IDM_COLOR_STATUS_BACKGROUND:
     if (AskForColor (hWndConf, &StatusBackgroundColor))
       break;
     DeleteObject (hStatusBackgroundBrush);
     hStatusBackgroundBrush = CreateSolidBrush (StatusBackgroundColor);
     RefreshStatusWnds();
     break;


   case IDM_WINDOW_CASCADE:
     CascadeWindows();
     break;
   
   case IDM_CLOSE_ALL:
     if (ConfirmBatchOps)
       if (MessageBox (hWndConf, "Are you sure you wish to close all open windows?", 
                       "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO)
         break;
     CloseArticleWnds();
     CloseGroupWnds();
     CloseStatusWnds();
     break;

   case IDM_CLOSE_ALL_ARTICLE:
     if (ConfirmBatchOps)
       if (MessageBox (hWndConf, "Are you sure you wish to close all open article windows?", 
                       "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO)
         break;
     CloseArticleWnds();
     break;

   case IDM_CLOSE_ALL_GROUP:
     if (ConfirmBatchOps)
       if (MessageBox (hWndConf,"Are you sure you wish to close all open group windows?", 
                       "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO)
         break;
     CloseGroupWnds();
     break;

   case IDM_CLOSE_ALL_STATUS:
     if (ConfirmBatchOps)
       if (MessageBox (hWndConf, "Are you sure you wish to close all open status windows?", 
                       "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO)
         break;
     CloseStatusWnds();
     break;

   case IDM_SEND_ALL_POST:
     if (ConfirmBatchOps)
       if (MessageBox (hWndConf, "Are you sure you wish to send all open post windows?", 
                       "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO)
         break;
     BatchSend(DOCTYPE_POSTING);
     break;

   case IDM_SEND_ALL_MAIL:
     if (ConfirmBatchOps)
       if (MessageBox (hWndConf, "Are you sure you wish to send all open mail windows?", 
                       "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO)
         break;
     BatchSend(DOCTYPE_MAIL);
     break;

   case IDM_DECODE_FILE:
     if (TestDecodeBusy(hWndConf, "Can't decode file"))
       break;

     if (!DialogBoxParam (hInst, "WinVnDecodeArts", hWndConf, lpfnWinVnDecodeArtsDlg, 0))
        InvalidateRect (hWndConf, NULL, TRUE);
     else
        DecodeFile(hWnd);
     break;

   case IDM_ENCODE_FILE:
      if (TestDecodeBusy(hWndConf, "Can't encode file"))
        break;
      if (!DialogBox (hInst, "WinVnEncode", hWndConf, lpfnWinVnEncodeDlg))
         InvalidateRect (hWndConf, NULL, TRUE);
      else
         EncodeToFile (hWndConf, AttachFileName);
      break;

   case IDM_RESET:
     AbortAllComm();
     break;

   case IDM_CONNECT:
     Connect (); // menus are enabled in WM_PAINT once connection is established
     break;

   case IDM_DISCONNECT:
     /* If the NNTP server disconnected, then Initializing == INIT_NOT_CONNECTED */
     if ((Initializing != INIT_NOT_CONNECTED)
   	 && (MessageBox (hWndConf, 
   		        "Are you sure you wish to disconnect from the server?\n"
   		        "All active windows will be closed.",
                        "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO))
        break;

   //  PutCommLine ("QUIT\r\n");      // breaks Pathworks stack 
       PutCommData ("QUIT\r\n",6);
     KillTimer(hWnd, ID_TIMER);

     Initializing = INIT_NOT_CONNECTED;
     SetUserMenus (hWnd, DISABLE);
     InvalidateRect (hWnd, NULL, TRUE);
     UpdateWindow (hWnd);

     MRRCloseComm(); 	// blammo

     if (Decoding)
     {
     	CompleteThisDecode();
     	DecodeDone();
     }
     else if (Attaching)
     	FinishAttachment (ABORT);

     CommDoc = NULL;
     CloseArticleWnds();
     CloseGroupWnds();
     CloseStatusWnds();
    
     break;

   case IDM_SAVE_CONFIG:
     WriteWinvnProfile();
     MessageBox (hWndConf, "WinVn Configuration Saved", "WinVn Configuration", MB_OK);
     break;

   case IDM_SAVE_WINDOW:
     {
     RECT rect;

     /* Save position and size of Usenet window. */
     GetWindowRect(hWndConf,&rect);
     sprintf(mybuf,"%d,%d,%d,%d",rect.left,rect.top,
       rect.right-rect.left,rect.bottom-rect.top);
     WritePrivateProfileString
      (szAppName, "UsenetWindowPos", mybuf, szAppProFile);


     /* Save position and size of first Group window */

     for(found=FALSE,idoc=0; !found && idoc<MAXGROUPWNDS; idoc++) {
       if(GroupDocs[idoc].InUse) {
         GetWindowRect(GroupDocs[idoc].hDocWnd,&rect);
         found = TRUE;
         sprintf(mybuf,"%d,%d,%d,%d",rect.left,rect.top,
            rect.right-rect.left,rect.bottom-rect.top);
         WritePrivateProfileString
           (szAppName, "GroupWindowPos", mybuf, szAppProFile);
       }
     }

     /* Save position and size of first Article window */

     for(found=FALSE,idoc=0; !found && idoc<MAXARTICLEWNDS; idoc++) {
       if(ArticleDocs[idoc].InUse) {
         GetWindowRect(ArticleDocs[idoc].hDocWnd,&rect);
         found = TRUE;
         sprintf(mybuf,"%d,%d,%d,%d",rect.left,rect.top,
            rect.right-rect.left,rect.bottom-rect.top);
         WritePrivateProfileString
           (szAppName, "ArticleWindowPos", mybuf, szAppProFile);
       }
     }

     break;
     }

   case IDM_FIND:
     FindDoc = &NetDoc;
     if (!(FindDoc->SearchStr[0]) && LastGroupNameFind[0]) 
        strcpy(FindDoc->SearchStr, LastGroupNameFind);

     if (DialogBox (hInst, "WinVnFind", hWnd, lpfnWinVnFindDlg))
       {
         found = DoFind (TRUE);
         if (!found)
      {
        strcpy (mybuf, "\"");
        strcat (mybuf, NetDoc.SearchStr);
        strcat (mybuf, "\" not found.");
        MessageBox (hWnd, mybuf, "Not found", MB_OK);
      }
      else
          strcpy(LastGroupNameFind, FindDoc->SearchStr);

       }
     break;

   case IDM_FIND_NEXT_SAME:
     FindDoc = &NetDoc;
   
     continueFind = TRUE;
     if (!FindDoc->SearchStr[0]) {
       if (!(FindDoc->SearchStr[0]) && LastGroupNameFind[0]) 
          strcpy(FindDoc->SearchStr, LastGroupNameFind);
       continueFind = DialogBox (hInst, "WinVnFind", hWnd, lpfnWinVnFindDlg);
     }

     if (continueFind && FindDoc->SearchStr[0])
       {
         found = DoFind (!FindDoc->hFindBlock && !FindDoc->FindLineID);
         if (!found)
      {
        strcpy (mybuf, "\"");
        strcat (mybuf, NetDoc.SearchStr);
        strcat (mybuf, "\" not found.");
        MessageBox (hWnd, mybuf, "No more occurrences", MB_OK);
      }
       }
     break;

   case ID_ABOUT:
     lpProcAbout = (DLGPROC)MakeProcInstance ((FARPROC)About, hInst);
     DialogBox (hInst, "AboutBox", hWnd, lpProcAbout);
     FreeProcInstance ((FARPROC)lpProcAbout);
     break;

   case IDM_HELP:
     MakeHelpPathName (mybuf, MAXINTERNALLINE);
     WinHelp (hWndConf, mybuf, HELP_INDEX, 0L);
     break;

   case IDM_MAIL:
     (MailCtrl.fnMlWinCreate)(hWnd, (TypDoc *) NULL, DOCTYPE_MAIL);
     break;

   case IDM_LOGOUT:
     (MailCtrl.fnMlLogout)(hWnd);
     break;

   case IDM_SHOW_VERSION:
     show_version_strings(hWnd);
     break;

   case IDM_POST:
     DialogBoxParam (hInst, "WinVnGeneric", hWnd,
           lpfnWinVnGenericDlg, (LPARAM) (char far *) "Newsgroup(s):");
     NewsgroupsPtr = DialogString;
     CreatePostingWnd (hWnd, (TypDoc *) NULL, DOCTYPE_POSTING);
     break;

   }
      break;

    case WM_PAINT:
      {
   HANDLE hBlock;
   SIZE sz;
   unsigned int Offset, MyLen, indicatorwidth;
   int VertLines, HorzChars;
   int EndofDoc = FALSE;
   int RangeHigh, CurPos;
   int Xtext;
   char far *textptr;
   char *cptr, *cptr2;
   char indicator;
   char indcptr[128];
   char group_name[MAXINTERNALLINE];
   char init_msg[60];
   TypGroup far *MyGroup;
   TypRange far *RangePtr;
   unsigned long int   HighestRead;
   COLORREF MyColors[4], MyBack[4];
// DWORD Rop;
   RECT myRect, aRect;
   int MyColorMask = 1, PrevColorMask = MyColorMask;
#define SUBSCR_MASK 1
#define SELECT_MASK 2

   hDC = BeginPaint (hWnd, &ps); 
   SetBkColor (hDC, ListBackgroundColor);
   if (ListBackgroundColor == RGB(0,0,0))
      SetTextColor(hDC, RGB(200,200,200)); 	// if background is black, make text white
   else
      SetTextColor(hDC, RGB(0,0,0));		// otherwise text is black

   GetClientRect (hWnd, &myRect);
   SelectObject (hDC, hListFont);

   /* If still initializing comm link, put out a message    */
   /* to that effect.                                       */

   switch (Initializing)
     {
     case INIT_NOT_CONNECTED:
       cptr = "Not connected";
       cptr2 = "to news server";

       goto display_msg;

     case INIT_ESTAB_CONN:
       cptr = "Establishing link";
       cptr2 = "to news server...";

       goto display_msg;

     case INIT_READING_NEWSRC:
       cptr = "Reading your log";
       cptr2 = "(\"newsrc\")...";
       goto display_msg;

     case INIT_SCANNING_NETDOC:
       cptr = "Creating hash table";
       cptr2 = "from current groups...";
       goto display_msg;

     case INIT_GETTING_LIST:
       sprintf (mybuf, "Receiving %uth newsgroup", RcvLineCount);
       cptr = mybuf;
       cptr2 = "name from server...";

     display_msg:;
       X = SideSpace + CharWidth;
       Y = StartPen + 2 * LineHeight;
       strcpy (init_msg, cptr);
       strcat (init_msg, "    ");
       j = strlen (init_msg);
       TextOut (hDC, X, Y, init_msg, j);
       strcpy (init_msg, cptr2);
       strcat (init_msg, "    ");
       j = strlen (init_msg);
       TextOut (hDC, X, Y + LineHeight, init_msg, j);
       break;

     case INIT_READY:
		/* this state happens when all connection prep is finished 
		 * and we are ready to begin normal WinVn user operation
		 */
     	SetUserMenus (hWnd, ENABLE);
		Initializing = INIT_DONE;
		// fall into INIT_DONE

     case INIT_DONE:

       VertLines = NetDoc.ScYLines;
       HorzChars = NetDoc.ScXChars;
       MyColors[0] = NetUnSubscribedColor;      // unseen/unselected    
       MyColors[1] = NetSubscribedColor;     // seen/unselected
       MyColors[2] = MyColors[0];         // unseen/selected
       MyColors[3] = ListBackgroundColor;    // seen/selected

       MyBack[0] = MyColors[3];
       MyBack[1] = MyBack[0];
       if (ListBackgroundColor == RGB(0,0,0))
         MyBack[2] = RGB(200,200,200);    // selected = white background
       else
         MyBack[2] = RGB(0,0,0);       // selected = black background
//       MyBack[2] = MyColors[1];
       MyBack[3] = MyBack[2];

       SetTextColor (hDC, MyColors[MyColorMask]);
       SetBkColor (hDC, MyBack[MyColorMask]);

       GetTextExtentPoint (hDC, "*", 2, &sz);             
       indicatorwidth = sz.cx*7*7;                        

       LockLine (NetDoc.hCurTopScBlock, NetDoc.TopScOffset, NetDoc.TopScLineID,
            &BlockPtr, &LinePtr);

       /* Update the scroll bar thumb position.                 */

       CurPos = NetDoc.TopLineOrd;
       if (CurPos < 0)
         CurPos = 0;   
       RangeHigh = NetDoc.ActiveLines - VertLines;;
       if (RangeHigh < 0)
         RangeHigh = 0;
       SetScrollRange (hWnd, SB_VERT, 0, RangeHigh, FALSE);
       SetScrollPos (hWnd, SB_VERT, CurPos, TRUE);

       RangeHigh = NetDoc.LongestLine - NetDoc.ScXChars; 
       if (RangeHigh < 0) 
       {
         RangeHigh = 0;
         NetDoc.ScXOffset = 0;
       }
       SetScrollRange (hWnd, SB_HORZ, 0, RangeHigh, FALSE);
	   SetScrollPos (hWnd, SB_HORZ, NetDoc.ScXOffset, TRUE); 

       /* Loop through the lines, painting them on the screen. */

       X = SideSpace - NetDoc.ScXOffset * (CharWidth+1);
       Xtext = X + indicatorwidth;
       Y = StartPen;
       if (LinePtr->length != END_OF_BLOCK)
         do
       {                               
        MyGroup = ((TypGroup far *)
              ((char far *) LinePtr + sizeof (TypLine)));
        MyLen = MyGroup->NameLen;
        textptr = (char far *) LinePtr + sizeof (TypLine) +
          sizeof (TypGroup); 
          
        /* Display this line only if it is active. */  
        if(LinePtr->active) {

        /* Figure out the color of this line.                 */

        if (MyGroup->Subscribed)
          {
            MyColorMask |= SUBSCR_MASK;
          }
        else
          {
            MyColorMask &= (0xff - SUBSCR_MASK);
          }
        if (MyGroup->Selected)
          {
            MyColorMask |= SELECT_MASK;
          }
        else
          {
            MyColorMask &= 0xff - SELECT_MASK;
          }
        if (MyColorMask != PrevColorMask)
          {
            SetTextColor (hDC, MyColors[MyColorMask]);
            SetBkColor (hDC, MyBack[MyColorMask]);
            PrevColorMask = MyColorMask;
          }

        /* Figure out what indicator character to use. */

        indicator = ' ';
        if (NetDoc.FindLineID == LinePtr->LineID)
          {
            indicator = '>';
          }
        else if (MyGroup->HighestPrevSeen)
          {
            if (MyGroup->ServerLast > MyGroup->HighestPrevSeen)
            {
              indicator = '*';
            }
            else {
              /* check if there are unread articles - jlg 4/9/94 */
              RangePtr = (TypRange far *) ((char far *) MyGroup + RangeOffset (MyGroup->NameLen));
              if (MyGroup->nRanges) {
                 HighestRead = RangePtr[MyGroup->nRanges-1].Last;
                 if (MyGroup->ServerLast > HighestRead && MyGroup->ServerEstNum > 0)
                   indicator = '*';
                 }
            }
          }

        mylstrncpy (group_name, textptr, MyGroup->NameLen + 1);

        if (MyGroup->Determined == FALSE)
           strcpy(str, "-");
        else
           sprintf(str, "%5lu", MyGroup->ServerEstNum); 
        
        sprintf (indcptr, "%c %5s %s ", indicator, str, group_name);

        /* Now write out the line.                            */

        MyLen = strlen (indcptr);

        SetRect (&aRect, 0, Y, myRect.right, Y+LineHeight);
	    
        ExtTextOut (hDC, X, Y, ETO_OPAQUE|ETO_CLIPPED, &aRect,
                    indcptr, MyLen, (LPINT)NULL);
	   
        Y += LineHeight;
        --VertLines;
        }  /* end if LinePtr->active */  
       }
       while (VertLines > 0 && NextLine (&BlockPtr, &LinePtr));

//       SetTextColor (hDC, MyColors[1]);
//       SetBkColor (hDC, MyBack[1]);
//       SelectObject (hDC, UnSelectedBrush);

       /* Blank out bottom and top of screen */
       SelectObject (hDC, hListBackgroundBrush);
       PatBlt (hDC, 0, Y, myRect.right-1, myRect.bottom - Y, PATCOPY);
       PatBlt (hDC, 0, 0, myRect.right-1, TopSpace, PATCOPY);

       UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
     }
     EndPaint (hWnd, &ps);
     break;
    }

    case WM_ENDSESSION:

      WinHelp (hWndConf, LFN_HELP, HELP_QUIT, 0L);
      //CloseComm (CommDevice);

      break;

    case WM_CLOSE:
      if (!ConfirmExit) {
        SaveNewsrc = SaveConfig = TRUE;
      } else {
        // WinVnExitDlg sets SaveNewsrc and SaveConfig
        if (!DialogBox (hInst, "WinVnExit", hWnd, lpfnWinVnExitDlg))
        {
          InvalidateRect (hWnd, NULL, TRUE);
          break;
        }
      } 
      DestroyWindow (hWnd);
      break;

    case WM_DESTROY:
#if 0	/* happens as each group window is destroyed by CloseGroupWnds (jsc) */
      for (idoc = 0; idoc < MAXGROUPWNDS; idoc++)
   {
     if (GroupDocs[idoc].InUse)
       {
         UpdateSeenArts (&(GroupDocs[idoc]));
       }
   }
#endif
      if (Initializing != INIT_NOT_CONNECTED) {
  //       PutCommLine ("QUIT\r\n");                // breaks pathworks 
           PutCommData ("QUIT\r\n",6);
         MRRCloseComm ();
      }

      MailClose(hWnd);

      AbortAllComm();

      /* force client wnds to close before doing WriteNewsrc */
      CloseArticleWnds();	
      CloseGroupWnds();	
      CloseStatusWnds();

	  if (SaveNewsrc)	/* do we need  && !Initializing? */
		WriteNewsrc();
	  
	  if (SaveConfig)
	  	WriteWinvnProfile();

      /* Remove resources before exiting program */
      FreeTextBlock (Signature);
      if (MailList)
        FreeTextBlock (MailList);
      
      DestroyFonts();
      DestroyBitmaps();
      // deselect the brush from the DC, or we can't free it
     SetHandleBkBrush (hWndConf, GetStockObject (WHITE_BRUSH));
      if (hListBackgroundBrush) DeleteObject(hListBackgroundBrush);
      if (hArticleBackgroundBrush) DeleteObject(hArticleBackgroundBrush);
      if (hStatusBackgroundBrush) DeleteObject(hStatusBackgroundBrush);

      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, message, wParam, lParam));
    }
  return (0);
}

void
SetConnectMenuItem (HWND hWnd, int enable)
{
	HMENU hMenu, hSubMenu;
	UINT mode;
	
	if (enable == ENABLE)	
		mode = MF_BYCOMMAND|MF_ENABLED;
	else
		mode = MF_BYCOMMAND|MF_DISABLED|MF_GRAYED;
	
	hMenu = GetMenu (hWnd);
	hSubMenu = GetSubMenu (hMenu, 0);	// config menu
	EnableMenuItem (hSubMenu, IDM_CONNECT, mode);
}

void
SetMainMailMenu (HWND hWnd)
{
	HMENU hMenu, hSubMenu;
	
	hMenu = GetMenu (hWnd);
	hSubMenu = GetSubMenu (hMenu, 0);	// network menu
  	EnableMenuItem (hSubMenu, IDM_LOGOUT, MailCtrl.enableLogout) ;	

	hSubMenu = GetSubMenu (hMenu, 2);	// utilities menu
    EnableMenuItem (hSubMenu, IDM_MAIL, MailCtrl.enableMail) ;	
}

void
SetUserMenus (HWND hWnd, int enable)
{
	HMENU hMenu, hSubMenu;
	UINT mode;
	
	if (enable == ENABLE)	
		mode = MF_BYCOMMAND|MF_ENABLED;
	else
		mode = MF_BYCOMMAND|MF_DISABLED|MF_GRAYED;
	
	hMenu = GetMenu (hWnd);
	hSubMenu = GetSubMenu (hMenu, 1);	// group menu
	EnableMenuItem (hSubMenu, IDM_FIND, mode);
	EnableMenuItem (hSubMenu, IDM_FIND_NEXT_SAME, mode);
	EnableMenuItem (hSubMenu, IDM_SUBSCRIBE, mode);
	EnableMenuItem (hSubMenu, IDM_UNSUBSCRIBE, mode);
	EnableMenuItem (hSubMenu, IDM_GROUP_TOP, mode);
	EnableMenuItem (hSubMenu, IDM_UNSEL_ALL, mode);

	hSubMenu = GetSubMenu (hMenu, 2);	// utilities menu
	EnableMenuItem (hSubMenu, IDM_POST, mode);
    EnableMenuItem (hSubMenu, 3, mode|MF_BYPOSITION ) ;	  // batch submenu
	
	hSubMenu = GetSubMenu (hMenu, 0);	// network menu
	EnableMenuItem (hSubMenu, IDM_RESET, mode);
	EnableMenuItem (hSubMenu, IDM_DISCONNECT, mode);

	SetConnectMenuItem (hWnd, !enable);		// connect item has reverse attributes
	SetMainMailMenu (hWnd);
}


/*---  FUNCTION: AbortAllComm -------------------------------------------
 *
 *  Kills all active comm stuff
 *  jsc 9/12/94
 */

void
AbortAllComm()
{
   if (Decoding) {
     CompleteThisDecode();
     DecodeDone();
   }
   else if (Attaching)
     FinishAttachment(ABORT);
	
   if (PostEdit)	/* !NULL if posting */
     CompletePost(PostEdit, ABORT);

   CommDoc = (TypDoc *)NULL;
   CommBusy = FALSE;
   CommState = ST_NONE;
}

 	
/*---  FUNCTION: About ---------------------------------------------------
 *
 *  Process messages for "About" dialog box
 */

BOOL WINAPI About (hDlg, message, wParam, lParam)
     HWND hDlg;
     unsigned message;
     WORD wParam;
     LONG lParam;
{
  switch (message)
    {
    case WM_INITDIALOG:
      return (TRUE);

    case WM_COMMAND:
      if (wParam == IDOK)
   {
     EndDialog (hDlg, TRUE);
     return (TRUE);
   }
      break;
    }
  return (FALSE);
}

#if 0 // This code not used anywhere (JSC 1/12/94)
/* Function CheckView -----------------------------
 *
 *  This function handles checking and unchecking menu items.
 *
 *    Entry    hWnd     is the window whose menu is to be altered.
 *                      Currently works only for the Net window.
 *
 *    Exit     The appropriate items on the menu have been checked or
 *             unchecked.
 */

VOID 
CheckView (hWnd)
     HWND hWnd;
{
  HMENU hMenu;
  int CheckIt;

  if (ViewNew)
    {
      CheckIt = MF_CHECKED | MF_BYCOMMAND;
    }
  else
    {
      CheckIt = MF_UNCHECKED | MF_BYCOMMAND;
    }
  hMenu = GetMenu (hWnd);

  CheckMenuItem (hMenu, IDM_NEW_WIN_GROUP, CheckIt);

  if (NewArticleWindow)
    {
      CheckIt = MF_CHECKED | MF_BYCOMMAND;
    }
  else
    {
      CheckIt = MF_UNCHECKED | MF_BYCOMMAND;
    }
  CheckMenuItem (hMenu, IDM_NEW_WIN_ARTICLE, CheckIt);
}
#endif
/* --- function CrackGroupLine --------------------------------------
 *
 *  Given a line from a .newsrc file, create a text line containing
 *  a structure of type TypGroup containing the same information.
 *  The line is zero-terminated upon input.
 *
 *    Entry    buf      points to a zero-terminated line from .newsrc.
 *             lineptr  points to a place to put the converted textline.
 *
 *    Exit     The line pointed to by "lineptr" now is a TypLine textline
 *             containing a structure of type TypGroup, containing the
 *             information in the input line from .newsrc.
 *
 *  Returns TRUE iff group was subscribed to.
 */
BOOL
CrackGroupLine (buf, lineptr)
     char *buf;
     TypLine *lineptr;
{
  char *grname = (char *) lineptr + sizeof (TypLine) + sizeof (TypGroup);
  TypGroup *group = (TypGroup *) ((char *) lineptr + sizeof (TypLine));
  TypRange *RangePtr;
  BOOL MoreNums;
  unsigned int MyLength;

  group->Subscribed = FALSE;
  group->Selected = FALSE;
  group->Determined = FALSE;
  group->NameLen = 0;
  group->SubjDoc = (TypDoc *) NULL;
  group->ServerEstNum = 0;
  group->ServerFirst = 0;
  group->ServerLast = 0;
  group->HighestPrevSeen = 0;
  group->nRanges = 0;
  group->header_handle = (HANDLE) NULL;

  /* Copy group name to output line.                               */

  while (*buf && *buf != ':' && *buf != '!')
    {
      *(grname++) = *(buf++);
      (group->NameLen)++;
    }
  *(grname++) = '\0';

  if (!(*buf))
    {
      /* Ran off end of line without seeing ':' or '!'.  Error.      */
    }
  else
    {
      if (*buf == ':')
   {
     group->Subscribed = TRUE;
   }
      buf++;
    }

  /* Look for the highest article number previously seen, in an
   * entry of form "s" followed by a number.
   */

  while (*buf && *buf == ' ' && *buf != '\n')
    buf++;
  if (*buf == 's')
    {
      buf++;
      GetNum (&buf, &(group->HighestPrevSeen));
    }

  /* Convert the article number ranges to the internal numeric
   * form we use in WinVN.
   */

  RangePtr = (TypRange *) ((char *) lineptr + sizeof (TypLine) +
            RangeOffset (group->NameLen));

  RangePtr->Last = RangePtr->First = 0;

  // allow lines like this, with no range data:
  // news.group: 
  //
  MoreNums = ( (*buf)=='\n' ? FALSE : TRUE);
  while (MoreNums)
    {
      while (*buf && (*buf == ' ' || *buf == ','))
   buf++;
      if (GetNum (&buf, &(RangePtr->First)))
   {
     /* We have the first number in a range.                     */
     (group->nRanges)++;
     RangePtr->Last = RangePtr->First;
     if (*buf == '-')
       {
         buf++;
         if (GetNum (&buf, &(RangePtr->Last)))
      {
        RangePtr++;
        /* at this point, we are positioned just after a range */
      }
         else
      {
        RangePtr->Last = RangePtr->First;
        MoreNums = FALSE;
      }
       }
     else if (*buf == ',')
       {
         /* We have a single number "n"; interpret as the range "n-n".
          */
         RangePtr++;
       }
     else
       {
         /* That must have been the last number.                  */
         MoreNums = FALSE;
       }
   }
      else
   {
     MoreNums = FALSE;
   }
    }
  if (group->nRanges == 0)
    (group->nRanges)++;

  MyLength = sizeof (TypLine) + RangeOffset (group->NameLen) +
    sizeof (TypRange) * (group->nRanges) + sizeof (int);

  lineptr->length = MyLength;
  lineptr->LineID = NextLineID++;
  *(int *) ((char *) lineptr + MyLength - sizeof (int)) = MyLength;

  return (group->Subscribed);
}

/*-- function CursorToTextLine ----------------------------------------
 *
 *   Routine to locate a text line in a document, based on the
 *   cursor position.  Used to figure out which line is being selected
 *   when a user clicks a mouse button.
 *
 *   Entry    X, Y    are the position of the cursor.
 *            DocPtr  points to the current document.
 *
 *   Exit     *LinePtr points to the current line, if one was found.
 *            *BlockPtr points to the current block, if found.
 *            Function returns TRUE iff a line was found that corresponds
 *              to the cursor position.
 */
BOOL
CursorToTextLine (X, Y, DocPtr, BlockPtr, LinePtr)
     int X;
     int Y;
     TypDoc *DocPtr;
     TypBlock far **BlockPtr;
     TypLine far **LinePtr;
{
  int found;
  int SelLine;

  if (Y < TopSpace || (unsigned) Y > TopSpace + DocPtr->ScYLines * LineHeight ||
      X < SideSpace)
    {
      /* Cursor is in no-man's-land at edge of window.               */
      found = FALSE;
    }
  else
    {
      found = TRUE;
      SelLine = (Y - TopSpace) / LineHeight;

      LockLine (DocPtr->hCurTopScBlock, DocPtr->TopScOffset, DocPtr->TopScLineID,
      BlockPtr, LinePtr);
      AdvanceToActive(BlockPtr,LinePtr);

      for (found = TRUE, il = 0; il < SelLine; )
   {
     if (!NextLine (BlockPtr, LinePtr))
       {
         found = FALSE;    /* ran off end of document */
         break;
       } else if((*LinePtr)->active){
         il++;
       }
   }
    }
  return (found);
}

/*-- function ReadNewsrc ----------------------------------------------
 *
 *    Reads NEWSRC into the Net document.
 *    This routine opens NEWSRC, reads & parses the lines into the NetDoc
 *    document, and closes the file.  One call does it all.
 *
 *    Entry    The NetDoc document is assumed to be initialized.
 *
 *    Exit     Returns TRUE if all went well, else zero.
 */
int
ReadNewsrc ()
{
  TypBlock far *BlockPtr;
  TypLine *LocalLinePtr, far * GroupPtr;
  HANDLE hLine;
  HANDLE hBlock;
  HFILE hRetCode;
  unsigned int Offset;
  TypLineID MyLineID;
  char mybuf[TEMPBUFSIZE];
  TypMRRFile *MRRFile;
  int returned;

  LockLine (NetDoc.hCurAddBlock, NetDoc.AddOffset, NetDoc.AddLineID, &BlockPtr, &GroupPtr);
  NetDoc.hDocWnd = hWndConf;

  hLine = LocalAlloc (LMEM_MOVEABLE, TEMPBUFSIZE);
  LocalLinePtr = (TypLine *) LocalLock (hLine);

#if 0
  env_var = getenv ("WINVN");           /* get path to winvn.ini */
  if (lstrlen (env_var))
   {
     lstrcpy (newsrc_filename, env_var);
     if (*(newsrc_filename + lstrlen (newsrc_filename) - 1) == '\\')
       lstrcat (newsrc_filename, "newsrc");
     else
       lstrcat (newsrc_filename, "\\newsrc");
   }
  else
   {
     MessageBox (hWndConf,"Environment variable WINVN not set.","Fatal Error", MB_OK | MB_ICONEXCLAMATION);
     return (0);
   }

#endif


  hRetCode = MRROpenFile (szNewsSrc, OF_READ, &MRRFile);
  if ((int) hRetCode <= 0)
    {
      return FALSE;
    }
  else
    {
      /* Loop to read lines, convert them to internal format, and
       * insert them into the NetDoc document.
       */
      
      LinesInRC = 0;
      while ((returned = MRRReadLine (MRRFile, mybuf, TEMPBUFSIZE)) > (-1))
   {
     mybuf[returned] = '\0';
     if (CrackGroupLine (mybuf, LocalLinePtr))
       {
         NetDoc.CountedLines++;
       }
     AddLine (LocalLinePtr, &BlockPtr, &GroupPtr);
     LinesInRC++;
   }
      MRRCloseFile (MRRFile);
    }

  /* Change the title of the Net document.  I suppose that,
   * strictly speaking, this oughtn't be done in this routine.
   */
  SetNetDocTitle ();
  UnlockLine (BlockPtr, GroupPtr, &hBlock, &Offset, &MyLineID);

  NetDoc.hCurTopScBlock = NetDoc.hFirstBlock;
  NetDoc.TopScOffset = sizeof (TypBlock);
  NetDoc.TopScLineID = 0L;
  NetDoc.LongestLine = 0;
  /* Mark lines active or inactive according to ShowUnsubscribed. */                                        
  SetGroupActiveLines();                                          
  // we'll check this during WriteNewsrc(). SMR 930224
  started_with_no_dolist = !DoList;
  LocalUnlock (hLine);
  LocalFree (hLine);

  return (TRUE);
}

char *ltoa ();

/*--- function WriteNewsrc ---------------------------------------------
 *
 *  Write out a NEWSRC file, based on the information in the
 *  NetDoc document.  Use the standard Unix "rn" format for .newsrc.
 *
 *    Entry    no parameters
 *             NetDoc   has the group information.
 *
 *    Exit     The NEWSRC file has been written.
 */
void
WriteNewsrc ()
{
  TypBlock far *BlockPtr;
  TypLine far *LinePtr;
  HANDLE hLine;
  HANDLE hBlock;
  unsigned int Offset;
  TypLineID MyLineID;
  char mes[60], mybuf[60];
  char far *fromptr;
  char *toptr;
  char *NewsLine;
  HFILE hRetCode;
  TypMRRFile *MRRFile;
  int nranges;
  TypGroup far *Group;
  TypRange far *RangePtr;
  BOOL firstrange;

  LockLine (NetDoc.hFirstBlock, sizeof (TypBlock), 0L, &BlockPtr, &LinePtr);

  hLine = LocalAlloc (LMEM_MOVEABLE, BLOCK_SIZE);
  NewsLine = (char *) LocalLock (hLine);

  hRetCode = MRROpenFile (szNewsSrc, OF_CREATE, &MRRFile);
  if ((int) hRetCode < 0)
    {
      sprintf (mes, "MRROpenFile returned %d", hRetCode);
      MessageBox (hWndConf, mes, mybuf, MB_OK);
    }
  else
    {
      do
   {
     toptr = NewsLine;
     Group = (TypGroup far *) ((char far *) LinePtr + sizeof (TypLine));

     /* Remove groups only if we performed a LIST command and */
     /* the server did not have them.  Otherwise if !did_list, the */
     /* newsrc will be practically empty! */

     /* Jeeeeez!!  I'm fixing this AGAIN! */
     /* DoList is not a boolean. SMR 930610 */

     if ((Group->ServerFirst || Group->ServerEstNum) || !did_list ) {
     /* Copy group name                                          */
     fromptr = (char far *) LinePtr + sizeof (TypLine) + sizeof (TypGroup);
     while (*(toptr++) = *(fromptr++));
     toptr--;

     /* Affix : or ! depending upon whether subscribed.          */
     *(toptr++) = (char) (Group->Subscribed ? ':' : '!');
     *(toptr++) = ' ';

     /* If we know the highest article number on the server,
      * output it preceded by an "s".
      */
     if (Group->ServerLast || Group->HighestPrevSeen)
       {
         *(toptr++) = 's';
         if (Group->ServerLast)
         	ltoa ((unsigned long) Group->ServerLast, toptr, 10);
         else
         	ltoa ((unsigned long) Group->HighestPrevSeen, toptr, 10);

         while (*toptr)
      toptr++;
         *(toptr++) = ' ';
       }

     /* Affix ranges of articles read.                          */
     firstrange = TRUE;
     nranges = Group->nRanges;
     RangePtr = (TypRange far *) ((char far *) Group + RangeOffset (Group->NameLen));

     while ((nranges--) > 0)
       {
         /* Write out ',' if not first range of articles.         */

         if (!firstrange)
      {
        *(toptr++) = ',';
      }
         else
      {
        firstrange = FALSE;
      }
         /* Write out first article in a range.                   */

         ltoa ((unsigned long) RangePtr->First, toptr, 10);
         while (*toptr)
      toptr++;

         /* If the range is of form "n-n", just put out "n"       */

         if (RangePtr->First != RangePtr->Last)
      {
        /* Put out the hyphen in middle of range.                */
        *(toptr++) = '-';
        /* Put out the last article in a range.                  */
        ltoa ((unsigned long) RangePtr->Last, toptr, 10);
        while (*toptr)
          toptr++;
      }
         RangePtr++;
       }
     MRRWriteLine (MRRFile, NewsLine, toptr - NewsLine);
     }
   }
      while (NextLine (&BlockPtr, &LinePtr));
      UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
      MRRCloseFile (MRRFile);
    }
    LocalUnlock (hLine);
    LocalFree (hLine);
    
}

/*--- function SetNetDocTitle -------------------------------------------
 *
 */
void
SetNetDocTitle ()
{
  char mybuf[120];

  sprintf (mybuf, "WinVN:  %u groups; %u subscribed", NetDoc.TotalLines,
      NetDoc.CountedLines);
  SetWindowText (hWndConf, mybuf);

}

/*--- function SetLineFlag --------------------------------------------
 *
 *  Set some flag in a line in a document.
 *
 *  Entry   Doc      points to the document.
 *          LinePtr  points to th line.
 *
 *  Exit    lFlag    says what to do.
 */
void
SetLineFlag (TypDoc * Doc, TypBlock far ** BlockPtr, TypLine far ** LinePtr, int wFlag, int wValue)
{
  switch (wFlag)
    {
      case LINE_FLAG_SET:
      ((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
      ->Selected = wValue;
      break;
    }
}


/*--- function GroupAction --------------------------------------------
 *
 *  Perform some action on a group that is specified by a pointer
 *  to a line in the Net document.
 *  Typically called for each line in the Net document by
 *  ForAllLines.
 *
 *  Entry   Doc      points to NetDoc
 *          LinePtr  points to a line in that document.
 *          lFlag    indicates what to do with that line.
 */
void
GroupAction (TypDoc * Doc, TypBlock far ** BlockPtr, TypLine far ** LinePtr, int wFlag, int wValue)
{

  switch (wFlag)
    {
      case GROUP_ACTION_SUBSCRIBE:
      case GROUP_ACTION_UNSUBSCRIBE:
      if (((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
     ->Selected)
   {
     ((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
     ->Subscribed = wValue;
     AddGroupToTable ((char far *) *LinePtr);
     DeleteLine (BlockPtr, LinePtr);
   }
      break;
      
      case GROUP_ACTION_CHECK_ACTIVE:
         if(((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
            ->Subscribed || ShowUnsubscribed ) {
            (*LinePtr)->active = TRUE;
            (*BlockPtr)->NumActiveLines++;
            NetDoc.ActiveLines++;
            NetDoc.LongestLine = max(NetDoc.LongestLine,(unsigned)
                                    ((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
                                    ->NameLen+GROUP_NAME_OFFSET);
            if(((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
            ->Subscribed) NetDoc.CountedLines++;
         } else {
            (*LinePtr)->active = FALSE;
         }
         break;

    }
}

/****************************************************************************

   FUNCTION:   MakeHelpPathName

   PURPOSE:    HelpEx assumes that the .HLP help file is in the same
          directory as the HelpEx executable.This function derives
          the full path name of the help file from the path of the
          executable.

   Taken from HELPEX.C, from the MS Windows SDK.

****************************************************************************/

void 
MakeHelpPathName (szFileName, maxchars)
     char *szFileName;
     int maxchars;
{
  char *pcFileName;
  int nFileNameLen;

  nFileNameLen = GetModuleFileName (hInst, szFileName, maxchars);
  pcFileName = szFileName + nFileNameLen;

  while (pcFileName > szFileName)
    {
      if (*pcFileName == '\\' || *pcFileName == ':')
   {
     *(++pcFileName) = '\0';
     break;
   }
      nFileNameLen--;
      pcFileName--;
    }

  if ((nFileNameLen + 13) < maxchars)
    {
      lstrcat (szFileName, LFN_HELP);
    }

  else
    {
      lstrcat (szFileName, "?");
    }

  return;
}


int
cursor_to_char_number (X, Y, DocPtr, BlockPtr, LinePtr)
     int X;
     int Y;
     TypDoc *DocPtr;
     TypBlock far **BlockPtr;
     TypLine far **LinePtr;
{
  int SelLine;
  int charnum = -1;
  SIZE extent;
                                                                                      
  char far * textptr;
  int textlen;
  HDC display_context;
  int iTopSpace, iSideSpace, iLineHeight, iCharWidth;
  
  if (DocPtr->DocType == DOCTYPE_ARTICLE)
  {
    iTopSpace = ArtTopSpace;
    iSideSpace = ArtSideSpace;
    iLineHeight = ArtLineHeight;                    
    iCharWidth = ArtCharWidth;
  }
  else
  {
    iTopSpace = TopSpace;
    iSideSpace = SideSpace;
    iLineHeight = LineHeight;
    iCharWidth = CharWidth;  
  }
    
  if (Y < iTopSpace || (unsigned) Y > iTopSpace + DocPtr->ScYLines * iLineHeight ||
      X < iSideSpace)
    {
   return (-1);
    }
  else
    {
      SelLine = (Y - iTopSpace) / iLineHeight;

      LockLine (DocPtr->hCurTopScBlock, DocPtr->TopScOffset, DocPtr->TopScLineID,
      BlockPtr, LinePtr);

      for (il = 0; il < SelLine; il++)
   {
     if (!NextLine (BlockPtr, LinePtr))
       {
         return (-1);  
         break;
       }
   }
    }

  /* find the right character on the text line */
  textlen = ((TypText far *) ((char far *) (*LinePtr) +
               sizeof (TypLine)))->NameLen;


  if (textlen) {
    textptr = (char far *) ((char far *) (*LinePtr) + sizeof (TypLine) + sizeof (TypText) );
    display_context = GetDC (DocPtr->hDocWnd);

    if (isLineQuotation(textptr))
      {  /* prepare to print a quotation Line */
        SelectObject (display_context, hFontArtQuote);
	  }
	else
	  {  /* prepare to print a normal line */
	    SelectObject (display_context, hFontArtNormal);
	  }

    for (charnum = 1; charnum < textlen; charnum++)
      {
    GetTextExtentPoint(display_context, (LPSTR) textptr, charnum, &extent); 
    if (extent.cx > (X + (int)DocPtr->ScXOffset * (iCharWidth + 1)- iSideSpace)) break;                                 
      }
    ReleaseDC (DocPtr->hDocWnd, display_context);
    return (charnum - 1);
  }

}

/*--- function SetGroupActiveLines --------------------------------------
 *
 *  Go through all the lines in the Net document, marking each
 *  as active or inactive according to whether the corresponding
 *  group is subscribed and whether we are displaying unsubscribed
 *  groups.
 *
 *  Entry:  NetDoc and ShowUnsubscribed are set properly.
 *
 *  Exit:   Each of the lines in NetDoc has had its "active" field
 *          set properly.
 */
void
SetGroupActiveLines() {
   NetDoc.ActiveLines = 0; 
   NetDoc.CountedLines = 0;
   ForAllBlocks (&NetDoc, SetForBlock, BLOCK_ACTION_SET_ACTIVE, 0);
   ForAllLines (&NetDoc, GroupAction, GROUP_ACTION_CHECK_ACTIVE, 0);
}                 


/* stuff for showing version numbers of the files */

#include "version.h"
#include "version.c"

/*-- function VerListDlgProc ---------------------------------------
 *
 *  Dialog function to handle selection of Version List
 *                                  JD 8/3/94
 */

LRESULT CALLBACK VerListDlgProc (HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)                  
                          
{
  int j;
  char far *cptr;
  char    szVersion[64];

  switch (iMessage)
    {
    case WM_INITDIALOG: 
         sprintf(szVersion,"Version %s",(LPSTR) WINVN_VERSION);    
         SetDlgItemText ((HWND) hDlg, IDD_VERSION_NUMBER, (LPSTR)szVersion);         
      	 hVerDlgList = GetDlgItem (hDlg, IDD_VERSION_LISTBOX);     	 
      	 SendMessage (hVerDlgList, WM_SETREDRAW, FALSE, 0L);
                   
         cptr = 0;
 	 for (j = 0; j < (sizeof(version_string) / sizeof version_string[0]); j++)
          {
    	    cptr = version_string[j];
            SendMessage (hVerDlgList, LB_ADDSTRING, 0, (LONG) cptr);
 	  }
      	SendMessage (hVerDlgList, WM_SETREDRAW, TRUE, 0L);
      	return TRUE;
      	break;

    case WM_COMMAND:
      switch (wParam)
       {
   	case IDOK:
     	     EndDialog (hDlg, TRUE);
    	     break;

        case IDCANCEL:
             EndDialog (hDlg, FALSE);
             break;

        default:
             return FALSE;
       }
      break;

    case WM_DESTROY:
      break;

    default:
      return FALSE;
      break;
    }
  return TRUE;
}
          
/*  Display Dialog Box to show version info   JD 8/4/94 */
void show_version_strings(HWND hWnd)
{
  lpfnWinVnVersionListDlg = (DLGPROC) MakeProcInstance((FARPROC) VerListDlgProc, (HINSTANCE) hInst);
  DialogBox (hInst, "WINVNVERSIONLIST", hWnd, lpfnWinVnVersionListDlg);  
  FreeProcInstance((FARPROC) lpfnWinVnVersionListDlg);

}

/* Last line of WVUSENET.C */
@


1.52
log
@massive cleanup for 92.6
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.51 1994/09/02 23:50:26 rushing Exp $
d52 1
a52 1
  HMENU hMenu;
d116 13
d705 15
d725 1
a725 1
     CloseArticleWnds();	// don't force the close
d733 1
a733 1
     CloseGroupWnds();		// don't force the close
d741 1
a741 1
     CloseStatusWnds(); 	// don't force the close
d764 1
a764 1
     if (!DialogBox (hInst, "WinVnDecodeArts", hWndConf, lpfnWinVnDecodeArtsDlg))
@


1.51
log
@call huge shellsort correctly
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.50 1994/08/23 23:17:34 martin Exp rushing $
d14 5
a18 2

#include "windows.h"
a19 2
#include "WVglob.h"
#include "WinVn.h"
a20 3
#include <stdlib.h>   /* for getenv */


d30 1
d39 1
a39 1
 *    Note:    We don't do anything until "Initialized" is true.
d51 1
a51 1
  FARPROC lpProcAbout;
d70 1
d87 1
a87 1
     lpProcAbout = MakeProcInstance (About, hInst);
d89 1
a89 1
     FreeProcInstance (lpProcAbout);
d113 1
a115 5
/*    case WM_INITMENUPOPUP :
      EnableMenuItem(GetMenu(hWnd),IDM_LOGOUT,MailCtrl.enableLogout) ;	// moved to SetUserMenus
      EnableMenuItem(GetMenu(hWnd),IDM_MAIL,MailCtrl.enableMail) ;
      break ;
*/
d475 1
d480 1
a480 19
      // from exit menu always query exit options
      // to quit without asking, uncheck "Always confirm save on exit" in MiscDlg
      // and double click upper-left corner

      if (ConfirmExit)
      { // if confirming, actual writes occur in lpfnWinVnExitDlg
        if (!DialogBox (hInst, "WinVnExit", hWnd, lpfnWinVnExitDlg))
        {
          InvalidateRect (hWnd, NULL, TRUE);
          break;
        }
      }
      else
      { // not confirming, so just write em
        WriteNewsrc ();
        WriteWinvnProfile();
      }

      DestroyWindow (hWnd);
d588 4
d697 1
a697 1
     CloseArticleWnds();
d705 1
a705 1
     CloseGroupWnds();
d713 1
a713 1
     CloseStatusWnds();
d752 1
a752 2
     CommBusy = FALSE;
     CommState = ST_NONE;
d842 2
d855 3
d863 9
a871 1
     if (strcmp (FindDoc->SearchStr, ""))
d873 1
a873 1
         found = DoFind (FALSE);
d885 1
a885 1
     lpProcAbout = MakeProcInstance (About, hInst);
d887 1
a887 1
     FreeProcInstance (lpProcAbout);
d944 5
d1120 6
a1125 4
        sprintf (indcptr, "%c %5lu %s ",
                  indicator,
                  MyGroup->ServerEstNum,
                  group_name);
d1165 4
a1168 2
      if (ConfirmExit)
      { // if confirming, actual writes occur in lpfnWinVnExitDlg
a1174 5
      else
      { // not confirming, so just write em
        WriteNewsrc ();
        WriteWinvnProfile();
      }
d1179 1
d1187 1
a1187 5
/*      if (SaveNewsrc && (!Initializing))
   {
     WriteNewsrc ();
   }
*/
d1194 1
a1194 1
      MailClose(hWnd) ;
d1196 13
a1208 12
      if (Decoding)
      {
        CompleteThisDecode();
        DecodeDone();
      }
      else if (Attaching)
        FinishAttachment (ABORT);
	
// make sure all coding status windows are closed and resources freed
     while (numStatusTexts)
        DestroyWindow (codingStatusText[0]->hTextWnd);
      
d1214 2
a1217 8
      if (hListFont) DeleteObject(hListFont);
      if (hFontArtNormal) DeleteObject(hFontArtNormal);
      if (hFontArtQuote) DeleteObject(hFontArtQuote);
      if (hStatusFont) DeleteObject(hStatusFont);
      if (hFontPrint) DeleteObject(hFontPrint);
      if (hFontPrintB) DeleteObject(hFontPrintB);
      if (hFontPrintS) DeleteObject(hFontPrintS);
      if (hFontPrintI) DeleteObject(hFontPrintI);   
d1248 13
d1281 2
a1282 1
		EnableMenuItem (hSubMenu, IDM_POST, mode);
a1283 8
	if (enable == ENABLE) {
//    	EnableMenuItem (hSubMenu, IDM_LOGOUT, MailCtrl.enableLogout) ;
	    EnableMenuItem (hSubMenu, IDM_MAIL, MailCtrl.enableMail) ;	
	} else {
//		EnableMenuItem (hSubMenu, IDM_MAIL, mode);		// should we leave this as is??  Yes!! (CN)
//		EnableMenuItem (hSubMenu, IDM_LOGOUT, mode);
	}
		
a1286 5
	
if (enable == ENABLE) 	
   	EnableMenuItem (hSubMenu, IDM_LOGOUT, MailCtrl.enableLogout) ;	
else
	EnableMenuItem (hSubMenu, IDM_LOGOUT, mode);
d1289 19
d1309 6
a1314 7
// Batch is now off of Utilities menu
//	hSubMenu = GetSubMenu (hMenu, 3);	// batch menu
//	EnableMenuItem (hSubMenu, IDM_CLOSE_ALL_ARTICLE, mode);
//	EnableMenuItem (hSubMenu, IDM_CLOSE_ALL_GROUP, mode);
//	EnableMenuItem (hSubMenu, IDM_CLOSE_ALL_STATUS, mode);
//	EnableMenuItem (hSubMenu, IDM_SEND_ALL_POST, mode);
//	EnableMenuItem (hSubMenu, IDM_SEND_ALL_MAIL, mode);
d1317 1
a1317 1
	
d1415 1
d1596 1
a1596 1
  HANDLE hRetCode;
d1698 1
a1698 1
  HANDLE hRetCode;
d1743 1
a1743 1
     if (Group->ServerLast)
d1746 5
a1750 1
         ltoa ((unsigned long) Group->ServerLast, toptr, 10);
@


1.50
log
@new hash table mechanism
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.49 1994/08/12 01:39:21 dumoulin Exp $
d538 4
a541 4
     ShellSort ((void far *) NewGroupTable,
           (size_t) nNewGroups,
           (size_t) sizeof (void far *),
           GroupCompare);
@



1.49
log
@Fix Quit option to not bomb pathworks upon exit
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.48 1994/08/11 21:41:41 rushing Exp dumoulin $
d523 1
d530 1
d537 1
d548 1
d555 1
d1628 1
d1637 1
@



1.48
log
@ensure quit command sent to server on exit/disconnect
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.47 1994/08/11 20:28:11 rushing Exp rushing $
d781 2
a782 1
     PutCommLine ("QUIT\r\n");
d1188 2
a1189 1
         PutCommLine ("QUIT\r\n");
@



1.47
log
@handle server-side disconnect quietly
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.46 1994/08/11 00:14:26 jcooper Exp $
d494 1
a494 1
      } 
d500 1
d781 1
a781 1
     MRRCloseComm(); 	// blammo
d789 2
d1186 2
a1187 1
      if (Initializing != INIT_NOT_CONNECTED)
d1189 1
@



1.46
log
@bug fixes to properly finish decoding before exiting
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.45 1994/08/04 05:51:13 dumoulin Exp $
d772 6
a777 3
   
     if (MessageBox (hWndConf, "Are you sure you wish to disconnect from the server?\nAll active windows will be closed.", 
                       "Please confirm", MB_YESNO|MB_ICONQUESTION) == IDNO)
@



1.45
log
@Added support for scrollable version box
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.44 1994/08/03 00:55:24 dumoulin Exp dumoulin $
d791 1
a791 1
     	FinishAttachment ();
d1185 11
a1195 3
      // make sure all coding status windows are closed and resources freed
      while (numStatusTexts)
     DestroyWindow (codingStatusText[0]->hTextWnd);
@



1.44
log
@Fixed bug cleaning up printer fonts even if someone doesn't
have a printer attached.
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.43 1994/07/27 21:09:33 gardnerd Exp dumoulin $
d28 1
a28 1
int started_with_no_dolist;            
d30 1
a30 1
void show_version_strings(void);
d897 1
a897 1
     show_version_strings();
d2006 59
a2064 1
void show_version_strings(void)
d2066 4
a2069 5
  
  MessageBox (hWndConf,
         version_string,
         "WinVN Version Information",
         MB_OK);
@



1.43
log
@copy to clipboard
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.42 1994/07/25 18:51:03 jcooper Exp $
d904 1
a904 1
     CreatePosti.gWnd (hWnd, (TypDoc *) NULL, DOCTYPE_POSTING);
d1196 11
a1206 11
      DeleteObject(hListFont);
      DeleteObject(hFontArtNormal);
      DeleteObject(hFontArtQuote);
      DeleteObject(hStatusFont);
      DeleteObject(hFontPrint);
      DeleteObject(hFontPrintB);
      DeleteObject(hFontPrintS);
      DeleteObject(hFontPrintI);   
      DeleteObject(hListBackgroundBrush);
      DeleteObject(hArticleBackgroundBrush);
      DeleteObject(hStatusBackgroundBrush);
@



1.42
log
@execution of decoded files
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.41 1994/07/12 19:50:52 cnolan Exp $
d1908 1
a1908 1

d1912 19
a1930 3

  if (Y < TopSpace || (unsigned) Y > TopSpace + DocPtr->ScYLines * LineHeight ||
      X < SideSpace)
d1936 1
a1936 1
      SelLine = (Y - TopSpace) / ArtLineHeight;
d1945 1
a1945 1
         return (-1);
d1960 9
d1972 1
a1972 1
    if (extent.cx > (X - SideSpace)) break;                                 
@



1.41
log
@menu fixes from cnolan
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.40 1994/07/12 19:15:49 rushing Exp $
a755 2
      if (AskForExistingFileName (hWndConf, AttachFileName, "Open file to be encoded") == FAIL)
         break; 
@



1.40
log
@UpdateSeenArts() when reusing a group window
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.39 1994/06/30 21:30:41 gardnerd Exp rushing $
d774 1
d799 1
d1231 1
a1231 1
	hSubMenu = GetSubMenu (hMenu, 2);	// config menu
d1247 1
a1247 1
	hSubMenu = GetSubMenu (hMenu, 0);	// group menu
d1255 1
a1255 1
	hSubMenu = GetSubMenu (hMenu, 1);	// utilities menu
d1259 1
a1259 1
    	EnableMenuItem (hSubMenu, IDM_LOGOUT, MailCtrl.enableLogout) ;
d1262 2
a1263 2
		EnableMenuItem (hSubMenu, IDM_MAIL, mode);		// should we leave this as is??
		EnableMenuItem (hSubMenu, IDM_LOGOUT, mode);
d1266 1
a1266 1
	hSubMenu = GetSubMenu (hMenu, 2);	// config menu
d1269 5
d1277 7
a1283 6
	hSubMenu = GetSubMenu (hMenu, 3);	// batch menu
	EnableMenuItem (hSubMenu, IDM_CLOSE_ALL_ARTICLE, mode);
	EnableMenuItem (hSubMenu, IDM_CLOSE_ALL_GROUP, mode);
	EnableMenuItem (hSubMenu, IDM_CLOSE_ALL_STATUS, mode);
	EnableMenuItem (hSubMenu, IDM_SEND_ALL_POST, mode);
	EnableMenuItem (hSubMenu, IDM_SEND_ALL_MAIL, mode);
@



1.39
log
@Allow scrolling by pixels instead of characters
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.38 1994/06/30 16:36:23 dumoulin Exp $
d330 1
@



1.38
log
@Fixed Exit to check the Confirm-upon-Exit flag
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.37 1994/06/08 21:01:45 gardnerd Exp dumoulin $
d476 1
a476 1

d1041 1
a1041 1
       X = SideSpace;
d1117 4
a1120 13
	    if((int)MyLen - (int)NetDoc.ScXOffset < 0)
	    {
          ExtTextOut (hDC, X, Y, ETO_OPAQUE|ETO_CLIPPED, &aRect,
                      " ", 1, (LPINT)NULL);
	    }
	    else
	    {
          ExtTextOut (hDC, X, Y, ETO_OPAQUE|ETO_CLIPPED, &aRect, 
	                  indcptr+NetDoc.ScXOffset, MyLen-NetDoc.ScXOffset,
	                  (LPINT)NULL);
	    }  
   

@



1.37
log
@more scrolling changes...
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.36 1994/06/06 22:06:13 gardnerd Exp $
d45 1
a45 2
long FAR PASCAL
WinVnConfWndProc (hWnd, message, wParam, lParam)
d485 13
a497 4
      if (!DialogBox (hInst, "WinVnExit", hWnd, lpfnWinVnExitDlg))
      {
         InvalidateRect (hWnd, NULL, TRUE);
         break;
d500 1
a500 1
     break;
d1160 1
a1160 1
      { // if confirming, acutal writes occur in lpfnWinVnExitDlg
d1292 1
a1292 2
BOOL FAR PASCAL 
About (hDlg, message, wParam, lParam)
@



1.36
log
@horizontal scrolling support
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.35 1994/06/06 21:23:37 mrr Exp $
d516 1
d532 1
d1621 1
a1621 1
  
d1830 3
@



1.35
log
@fix subscribed-count bug
@
text
@d11 1
a11 1
 * $Id: $
d311 3
a313 1
           CommDoc = &(GroupDocs[docnum]);
d327 3
a329 1
        /* Must reuse old window for this group.           */
d369 1
a369 1
                  WS_OVERLAPPEDWINDOW | WS_VSCROLL,
d467 7
d1020 9
d1106 13
a1118 3
   SetRect (&aRect, 0, Y, myRect.right, Y+LineHeight);
   ExtTextOut (hDC, X, Y, ETO_OPAQUE|ETO_CLIPPED, &aRect,
               indcptr, MyLen, (LPINT)NULL);
d1597 1
a1597 1

@



1.34
log
@rewrote GroupAction for debugging...
@
text
@d11 1
a11 2
 * Revision 1.30  1994/05/19  02:04:54  rushing
 * changes for gensock, version 0.91
a12 95
 * Revision 1.29  1994/05/02  20:38:53  rushing
 * changes from jody glasser
 *
 * Revision 1.28  1994/04/19  18:35:23  rushing
 * check for NULL MailList in FreeTextBlock
 *
 * Revision 1.27  1994/02/24  21:35:08  jcoop
 * jcoop changes
 *
 * Revision 1.26  1994/02/09  18:01:08  cnolan
 * cnolan 90.2 changes
 *
 * Revision 1.25  1994/01/24  17:41:01  jcoop
 * 90.2 changes
 *
 * Revision 1.24  1994/01/16  12:04:33  jcoop
 * Color/fonts, signatures, exit INI handling, general cleanup
 *
 * Revision 1.23  1994/01/12  19:27:32  mrr
 * mrr mods 4
 * 
 * Revision 1.22  1993/12/08  01:28:01  rushing
 * new version box and cr lf consistency
 *
 * Revision 1.21  1993/12/07  20:24:43  rushing
 * testing new ID.
 *
 * Revision 1.20  1993/10/12  17:47:26  rushing
 * make winvn grok servers that start article numbers at 0
 *
 * Revision 1.19  1993/09/12  20:26:52  rushing
 * handle can't connect condition
 *
 * Revision 1.18  1993/08/25  18:54:36  mbretherton
 * MRB merge, mail & post logging
 *
 *
 * MBretherton
 * remove vRef from MRROpenFile (Mac Stuff)
 *
 * Revision 1.17  1993/08/18  21:49:21  rushing
 * more 16-bit article number fixes.
 *
 * Revision 1.16  1993/08/17  21:46:49  DUMOULIN
 * Added support for Dragging mouse for selecting/deselecting Usenet groups
 *
 * Revision 1.15  1993/07/06  21:09:50  cnolan
 * win32 support
 *
 * Revision 1.14  1993/06/28  17:51:39  rushing
 * fixed compiler warnings
 *
 * Revision 1.13  1993/06/24  17:13:14  riordan
 * Save window positions between sessions.
 *
 * Revision 1.12  1993/06/14  18:52:00  rushing
 * 'New Posting' menu option added
 *
 * Revision 1.11  1993/06/11  00:10:35  rushing
 * second merge from Matt Bretherton sources
 *
 * Revision 1.10  1993/06/10  18:24:41  rushing
 * hopefully newsrc&dolist thing is fixed FOR GOOD.
 *
 * Revision 1.9  1993/05/24  23:55:25  rushing
 * Delete Fonts (cleanup before exiting) (MRB)
 *
 * Revision 1.8  1993/05/20  18:12:31  rushing
 * don't write out newsrc if Intializing is true
 *
 * Revision 1.7  1993/04/29  20:23:06  rushing
 * attempted support for WSAAsyncSelect
 *
 * Revision 1.6  1993/04/27  20:11:38  rushing
 * Fixed out-of-date code that killed the timer if
 * CommState was ST_NONE.
 *
 * Revision 1.5  1993/04/27  18:53:17  rushing
 * attempt to fix newsrc problems.  allow newsrc line with
 * no range data.
 *
 * Revision 1.4  1993/03/30  21:07:15  DUMOULIN
 * handle conflicting MAPI merge problem (with wvsck???.c)
 * use ST_NONE instead of ST_CLOSED_COMM
 *
 * Revision 1.3  1993/03/30  20:46:07  bretherton
 * MAPI
 *
 * Revision 1.2  1993/02/25  03:08:52  rushing
 * fixed newsrc truncation when DoList = 0.
 *
 * Revision 1.1  1993/02/16  20:54:22  rushing
 * Initial revision
 *
 *
d1573 1
a1573 1
         NetDoc.ActiveLines++;
d1735 2
a1736 5
  /* someone else is using activelines, reset it (SMR 940601) */
  SetGroupActiveLines();                                          

  sprintf (mybuf, "WinVN:  %d groups; %d subscribed", NetDoc.TotalLines,
      NetDoc.ActiveLines);
a1776 1
  TypGroup far * this_group = (TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine));
d1780 10
a1789 8
    case GROUP_ACTION_SUBSCRIBE:
    case GROUP_ACTION_UNSUBSCRIBE:
      if (this_group->Selected)
	{
	  this_group->Subscribed = wValue;
	  AddGroupToTable ((char far *) *LinePtr);
	  DeleteLine (BlockPtr, LinePtr);
	}
d1792 13
a1804 9
    case GROUP_ACTION_CHECK_ACTIVE:
      if (this_group->Subscribed  || ShowUnsubscribed ) {
	(*LinePtr)->active = TRUE;
	(*BlockPtr)->NumActiveLines++;
	if (this_group->Subscribed) NetDoc.ActiveLines++;
      } else {
	(*LinePtr)->active = FALSE;
      }
      break;
d1929 2
a1930 1
   NetDoc.ActiveLines = 0;
@



1.33
log
@unnecessary winundoc.h
@
text
@d1831 3
d1876 1
d1880 8
a1887 10
      case GROUP_ACTION_SUBSCRIBE:
      case GROUP_ACTION_UNSUBSCRIBE:
      if (((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
     ->Selected)
   {
     ((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
     ->Subscribed = wValue;
     AddGroupToTable ((char far *) *LinePtr);
     DeleteLine (BlockPtr, LinePtr);
   }
d1890 9
a1898 11
      case GROUP_ACTION_CHECK_ACTIVE:
         if(((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
            ->Subscribed || ShowUnsubscribed ) {
            (*LinePtr)->active = TRUE;
            (*BlockPtr)->NumActiveLines++;
            NetDoc.ActiveLines++;
         } else {
            (*LinePtr)->active = FALSE;
         }
         break;

@



1.32
log
@Added support for the Quit option on the Network Menu
@
text
@a111 3


#include "winundoc.h"
a112 2


@



1.31
log
@new attach code, session [dis]connect
@
text
@d568 4
a571 2
// case IDM_QUIT:
//   SaveNewsrc = FALSE;
d681 1
a681 1
     
d704 1
a704 1
     {   
d708 1
a708 1
     }                
d721 1
a721 1
       break;  
d724 1
a724 1
   
d736 1
a736 1
   
d754 1
a754 1
   
d761 1
a761 1
       
d773 1
a773 1
   
d789 1
a789 1
   
d856 1
a856 1
        
d864 1
a864 1
     
d872 1
a872 1
     
d970 1
a970 1
     
d1070 1
a1070 1
		// fall into INIT_DONE     	
@



1.30
log
@changes for gensock, version 0.91
@
text
@d11 3
a13 2
 * $Id: wvusenet.c 1.29 1994/05/02 20:38:53 rushing Exp rushing $
 * $Log: wvusenet.c $
a133 1

d217 2
a218 2
    case WM_INITMENUPOPUP :
      EnableMenuItem(GetMenu(hWnd),IDM_LOGOUT,MailCtrl.enableLogout) ;
d221 1
a221 1

d846 31
d1022 6
d1062 7
d1247 2
a1248 1
      MRRCloseComm ();
d1284 60
d1345 1
@



1.29
log
@changes from jody glasser
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.28 1994/04/19 18:35:23 rushing Exp $
d13 3
d303 1
a303 1
                     ->Selected = TRUE;
d529 1
a529 2
         lstrcat(mybuf,"\r");
         PutCommLine (mybuf, lstrlen (mybuf));
@



1.28
log
@check for NULL MailList in FreeTextBlock
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.27 1994/02/24 21:35:08 jcoop Exp rushing $
d13 3
d169 3
a171 1

d288 9
d300 14
a313 1
                     ->Selected ^= TRUE;
d316 1
a316 1
         SetCapture(hWnd);	// release capture on button up
d372 1
d388 4
a391 4
	{
	  GlobalUnlock (GroupBlockPtr->hCurBlock);
	  break;
	}
d477 1
a477 1
	ShowWindow (hWndView, SW_SHOWNORMAL);
d632 1
a632 1
#if 0	// This code not used anywhere (JSC 1/12/94)
d700 1
a700 1
     {	
d757 1
a757 1
	    
d970 2
d1028 4
a1031 4
       MyColors[0] = NetUnSubscribedColor;		// unseen/unselected    
       MyColors[1] = NetSubscribedColor;		// seen/unselected
       MyColors[2] = MyColors[0];			// unseen/selected
       MyColors[3] = ListBackgroundColor;		// seen/selected
d1036 1
a1036 1
         MyBack[2] = RGB(200,200,200);		// selected = white background
d1038 1
a1038 1
         MyBack[2] = RGB(0,0,0);			// selected = black background
d1117 9
d1139 3
a1141 3
	SetRect (&aRect, 0, Y, myRect.right, Y+LineHeight);
	ExtTextOut (hDC, X, Y, ETO_OPAQUE|ETO_CLIPPED, &aRect,
	            indcptr, MyLen, (LPINT)NULL);
d1207 1
a1207 1
	  DestroyWindow (codingStatusText[0]->hTextWnd);
d1215 1
a1215 1
	  SetHandleBkBrush (hWndConf, GetStockObject (WHITE_BRUSH));
d1266 1
a1266 1
#if 0	// This code not used anywhere (JSC 1/12/94)
@



1.27
log
@jcoop changes
@
text
@d11 1
a11 1
 * $Id: wvusenet.c 1.26 1994/02/09 18:01:08 cnolan Exp $
d13 3
d1172 2
a1173 1
      FreeTextBlock (MailList);
@



1.26
log
@cnolan 90.2 changes
@
text
@a9 2


d11 1
a11 1
 * $Id: wvusenet.c 1.25 1994/01/24 17:41:01 jcoop Exp $
d13 3
d283 2
a284 2
      ->Selected ^= TRUE;
              DragMouseAction = status ? DRAG_SELECT : DRAG_DESELECT;
d286 1
d297 1
d307 3
a309 3
   {
     X = LOWORD (lParam);
     Y = HIWORD (lParam);
d311 3
a313 2
     if (CursorToTextLine (X, Y, &NetDoc, &BlockPtr, &LinePtr))
       {
d315 14
a328 16
                {
       case DRAG_SELECT:
                       ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
               ->Selected = TRUE;
                      break;
       case DRAG_DESELECT:
                      ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
              ->Selected = FALSE;
                      break;
       }
         GlobalUnlock (BlockPtr->hCurBlock);
       }

     InvalidateRect (hWnd, NULL, FALSE);
        }

d538 9
a546 1
     goto closeWnd;
d664 1
d668 6
d927 1
a927 1
   unsigned int Offset, MyLen, width, indicatorwidth;
d931 1
a931 1
   int RestX, Xtext;
d941 1
a941 2
   HBRUSH hOldBr, SelectedBrush, UnSelectedBrush;
   RECT myRect;
d998 1
a998 1
       MyColors[3] = GetBkColor (hDC);		// seen/selected
a1008 2
       SelectedBrush = CreateSolidBrush (MyBack[2]);
       UnSelectedBrush = CreateSolidBrush (MyBack[0]);
a1010 1
       hOldBr = SelectObject (hDC, UnSelectedBrush);
a1058 1
//          Rop = BLACKNESS;
a1062 1
//          Rop = WHITENESS;
a1068 5

            if (MyColorMask >= SELECT_MASK)
              SelectObject (hDC, SelectedBrush);
            else
              SelectObject (hDC, UnSelectedBrush);
d1081 3
a1083 3
         {
           indicator = '*';
         }
a1095 5
     GetTextExtentPoint (hDC, indcptr, MyLen, &sz);    
     width = sz.cx;                                    
        TextOut (hDC, X, Y, indcptr, MyLen);

      // This section was strange.  Maybe guilty.
d1097 3
a1099 2
            RestX = X + width;
            PatBlt (hDC, RestX, Y, myRect.right - RestX, LineHeight, PATCOPY);
d1103 3
a1105 3
      }  /* end if LinePtr->active */  
      }
         while (VertLines > 0 && NextLine (&BlockPtr, &LinePtr));
d1107 3
a1109 3
       SetTextColor (hDC, MyColors[1]);
       SetBkColor (hDC, MyBack[1]);
       SelectObject (hDC, UnSelectedBrush);
d1112 1
a1116 3
       SelectObject (hDC, hOldBr);
       DeleteObject (SelectedBrush);
       DeleteObject (UnSelectedBrush);
d1118 3
a1120 3
   EndPaint (hWnd, &ps);
   break;
      }
d1130 8
a1137 3
     closeWnd:;
      if (!DialogBox (hInst, "WinVnExit", hWnd, lpfnWinVnExitDlg))
        InvalidateRect (hWnd, NULL, TRUE);
d1139 5
a1143 1
        DestroyWindow (hWnd);
d1169 2
d1670 3
@



1.25
log
@90.2 changes
@
text
@d13 1
a13 1
 * $Id: wvusenet.c 1.24 1994/01/16 12:04:33 jcoop Exp $
d15 3
d443 1
a443 1
	SetClassWord (hWndView, GCW_HBRBACKGROUND, hListBackgroundBrush);
d708 1
a708 1
     SetClassWord (hWnd, GCW_HBRBACKGROUND, hListBackgroundBrush);
d1161 1
a1161 1
      SetClassWord (hWndConf, GCW_HBRBACKGROUND, GetStockObject (WHITE_BRUSH));
@



1.24
log
@Color/fonts, signatures, exit INI handling, general cleanup
@
text
@d13 1
a13 1
 * $Id: wvusenet.c 1.24 1994/01/16 01:05:01 jcoop Exp $
d15 3
a182 5
      /* Set up the timer which will wake us up every so often
       * so we can check to see if new characters have arrived from
       * the server.
       */

a184 6
      idTimer = SetTimer (hWnd, ID_TIMER ,1000, (FARPROC) NULL);

      if (!idTimer) {
   MessageBox (hWnd, "Couldn't create timer!", "WinVN", MB_OK | MB_ICONASTERISK);
      }

d627 1
a627 1
     if (DialogBox (hInst, "WinVnSigFile", hWnd, lpfnWinVnSigFileDlg))
d727 40
d768 1
a768 1
     if (TestDecodeBusy(hWnd, "Can't decode file"))
d771 2
a772 2
     if (!DialogBox (hInst, "WinVnDecodeArts", hWnd, lpfnWinVnDecodeArtsDlg))
        InvalidateRect (hWnd, NULL, TRUE);
a774 1
     
d778 1
a778 1
      if (TestDecodeBusy(hWnd, "Can't encode file"))
d780 1
a780 1
      if (AskForExistingFileName (hWnd, AttachFileName, "Open file to be encoded") == FAIL)
d782 2
a783 2
      if (!DialogBox (hInst, "WinVnEncode", hWnd, lpfnWinVnEncodeDlg))
         InvalidateRect (hWnd, NULL, TRUE);
d785 1
a785 1
         EncodeToFile (hWnd, AttachFileName);
d795 1
a795 1
     MessageBox (hWnd, "WinVn Configuration Saved", "WinVn Configuration", MB_OK);
@



1.23
log
@mrr mods 4
@
text
@d13 1
a13 1
 * $Id: wvusenet.c 1.22 1993/12/08 01:28:01 rushing Exp $
d15 3
d359 5
a363 7
         if (CommBusy)
      {
        GlobalUnlock (GroupBlockPtr->hCurBlock);
        MessageBox (hWnd, "Sorry, I am already busy retrieving information from the server.\n\
Try again in a little while.", "Can't request info on group", MB_OK | MB_ICONASTERISK);
        break;
      }
d448 2
a449 2
        ShowWindow (hWndView, SW_SHOWNORMAL);

d493 1
a493 1
         SetCapture (hWnd);
d538 4
a541 4
   case IDM_QUIT:
     SaveNewsrc = FALSE;
   case IDM_EXIT:
     DestroyWindow (hWnd);
d596 1
d606 1
d634 5
d640 117
d762 5
d888 3
a890 2
   DWORD MyColors[4], MyBack[4];
   DWORD Rop;
d896 2
a897 1
   hDC = BeginPaint (hWnd, &ps);
d899 1
a899 1
   SelectObject (hDC, hFont);
d945 4
a948 4
       MyColors[0] = NetUnSubscribedColor;
       MyColors[1] = GetTextColor (hDC);
       MyColors[2] = MyColors[0];
       MyColors[3] = GetBkColor (hDC);
d952 5
a956 1
       MyBack[2] = MyColors[1];
d959 6
d1012 1
a1012 1
            Rop = BLACKNESS;
d1017 1
a1017 1
            Rop = WHITENESS;
d1024 5
d1063 1
a1063 1
            PatBlt (hDC, RestX, Y, myRect.right - RestX, LineHeight, Rop);
d1073 1
d1076 2
a1077 2
       PatBlt (hDC, 0, Y, myRect.right, myRect.bottom - Y, PATCOPY);
       PatBlt (hDC, 0, 0, myRect.right, TopSpace, PATCOPY);
d1080 3
d1095 8
d1111 1
a1111 1
      if (SaveNewsrc && (!Initializing))
d1115 1
d1120 4
d1125 4
a1128 1
      DeleteObject(hFont);
d1131 1
d1136 3
d1178 1
d1219 1
a1219 1

a1430 1
#define  TEMPBUFSIZE   1240
d1497 2
@



1.22
log
@new version box and cr lf consistency
@
text
@d13 1
a13 1
 * $Id: wvusenet.c 1.21 1993/12/07 20:24:43 rushing Exp rushing $
d15 3
d109 2
a110 1
int started_with_no_dolist;
d112 2
d167 6
a172 6
	{
	  lpProcAbout = MakeProcInstance (About, hInst);
	  DialogBox (hInst, "AboutBox", hWnd, lpProcAbout);
	  FreeProcInstance (lpProcAbout);
	  break;
	}
d174 1
a174 1
	return (DefWindowProc (hWnd, message, wParam, lParam));
d187 1
a187 1
	MessageBox (hWnd, "Couldn't create timer!", "WinVN", MB_OK | MB_ICONASTERISK);
d199 1
a199 1
		  MF_APPEND | MF_STRING);
d217 11
a227 11
	{
	  if (wParam == '\r')
	    {

	      GetCursorPos (&ptCursor);
	      ScreenToClient (hWnd, &ptCursor);
	      X = ptCursor.x;
	      Y = ptCursor.y;
	      goto getgroup;
	    }
	}
d238 25
a262 25
	{
	  if (wParam == VK_F6)
	    {
	      NextWindow (&NetDoc);
	    }
	  else
	    {
	      /* Based on the state of the Control key and the value
	       * of the key just pressed, look up in the array
	       * key2scroll to see if we should process this keystroke
	       * as if it were a mouse event.  If so, simulate the
	       * mouse event by sending the appropriate message.
	       */

	      CtrlState = GetKeyState (VK_CONTROL) < 0;
	      for (j = 0; j < NUMKEYS; j++)
		{
		  if (wParam == key2scroll[j].wVirtKey &&
		      CtrlState == key2scroll[j].CtlState)
		    {
		      SendMessage (hWnd, key2scroll[j].iMessage,
				   key2scroll[j].wRequest, 0L);
		      break;
		    }
		}
d264 2
a265 2
	    }
	}
d276 1
a276 1
	{
d278 2
a279 2
	  X = LOWORD (lParam);
	  Y = HIWORD (lParam);
d281 4
a284 4
	  if (CursorToTextLine (X, Y, &NetDoc, &BlockPtr, &LinePtr))
	    {
	      status = ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
		->Selected ^= TRUE;
d286 2
a287 2
	      GlobalUnlock (BlockPtr->hCurBlock);
	    }
d289 2
a290 2
	  InvalidateRect (hWnd, NULL, FALSE);
	}
d306 3
a308 3
	{
	  X = LOWORD (lParam);
	  Y = HIWORD (lParam);
d310 2
a311 2
	  if (CursorToTextLine (X, Y, &NetDoc, &BlockPtr, &LinePtr))
	    {
d314 3
a316 3
		 case DRAG_SELECT:
            	        ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
		         ->Selected = TRUE;
d318 1
a318 1
		 case DRAG_DESELECT:
d320 1
a320 1
		        ->Selected = FALSE;
d322 3
a324 3
		 }
	      GlobalUnlock (BlockPtr->hCurBlock);
	    }
d326 1
a326 1
	  InvalidateRect (hWnd, NULL, FALSE);
d337 23
a359 23
	{
	  X = LOWORD (lParam);
	  Y = HIWORD (lParam);
	getgroup:;

	  if (CursorToTextLine (X, Y, &NetDoc, &GroupBlockPtr, &GroupLinePtr))
	    {
	      if (MyDoc = (((TypGroup far *)
		(((char far *) GroupLinePtr) + sizeof (TypLine)))->SubjDoc))
		{

		  /* We already have a document containing the subjects */
		  /* of this group, so just activate it.                */

		  SetActiveWindow (MyDoc->hDocWnd);
		  SetFocus (MyDoc->hDocWnd);
		  GlobalUnlock (GroupBlockPtr->hCurBlock);
		  break;
		}
	      if (CommBusy)
		{
		  GlobalUnlock (GroupBlockPtr->hCurBlock);
		  MessageBox (hWnd, "Sorry, I am already busy retrieving information from the server.\n\
d361 2
a362 2
		  break;
		}
d364 23
a386 23
	      /* At this point, we've determined that the subjects for
	       * this newsgroup are not in memory, and that it's OK
	       * to fetch them from the server.  (Comm line not busy.)
	       * Figure out whether a new window/document should be
	       * created for this group & set "newdoc" accordingly.
	       */
	      newdoc = FALSE;
	      if (ViewNew || !ActiveGroupDoc || !(ActiveGroupDoc->InUse))
		{
		  found = FALSE;
		  for (docnum = 0; docnum < MAXGROUPWNDS; docnum++)
		    {
		      if (!GroupDocs[docnum].InUse)
			{
			  found = TRUE;
			  newdoc = TRUE;
			  CommDoc = &(GroupDocs[docnum]);
			  break;
			}
		    }
		  if (!found)
		    {
		      MessageBox (hWnd, "You have too many group windows \
d388 24
a411 101
		      UnlockLine (GroupBlockPtr, GroupLinePtr, &hBlock, &Offset, &MyLineID);
		      break;
		    }
		}
	      else
		{
		  /* Must reuse old window for this group.           */
		  CommDoc = ActiveGroupDoc;
		  UnlinkArtsInGroup (CommDoc);
		  LockLine (CommDoc->hParentBlock, CommDoc->ParentOffset, CommDoc->ParentLineID, &BlockPtr, &LinePtr);
		  ((TypGroup far *)
		   (((char far *) LinePtr) + sizeof (TypLine)))->SubjDoc = (TypDoc *) NULL;
		  UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
		  /* clear out contents of this document for reuse */
		  FreeDoc (CommDoc);
		}

	      /* Create window title indicating we are retrieving text. */

	      CommDoc->InUse = TRUE;
	      lpsz = (char far *) (((char far *) GroupLinePtr) +
				   sizeof (TypLine) + sizeof (TypGroup));
	      strcpy (mybuf, "Retrieving ");
	      lstrcat (mybuf, lpsz);

	      /* If necessary, create a new window.              */

	      if (newdoc)
		{
		  int x,y,width,height;
		  char poschars[MAXINTERNALLINE];

		  /* Compute default screen position. */
		  x = 1;
		  y = 0;
		  width = (int) xScreen;
		  height = (int) (yScreen * 1 / 2);

		  /* If the screen position has been saved, use that instead. */
		  GetPrivateProfileString (szAppName, "GroupWindowPos", "!",
			 poschars,MAXINTERNALLINE,szAppProFile);
		  if(poschars[0] != '!') {
			 sscanf(poschars,"%d,%d,%d,%d",&x,&y,&width,&height);
		  }
		  hWndView = CreateWindow ("WinVnView",
					   mybuf,
					   WS_OVERLAPPEDWINDOW | WS_VSCROLL,
						x + (int) docnum * CharWidth,/* Initial X pos */
						y + (int) docnum * LineHeight,
						width,           /* Initial X Width */
						height,
					   NULL,
					   NULL,
					   hInst,
					   NULL);

		  if (!hWndView)
		    return (0); /* ??? */

		  ShowWindow (hWndView, SW_SHOWNORMAL);

		}
	      else
		{
		  hWndView = CommDoc->hDocWnd;
		  SetWindowText (hWndView, mybuf);
		}
	      RcvLineCount = 0;
	      TimesWndUpdated = 0;

	      /* Do some housekeeping:  Set group as selected,
	       * initialize empty document to hold subject lines,
	       * set focus to this document, set pointers linking
	       * this document and the subject line.
	       */
	      ((TypGroup far *) (((char far *) GroupLinePtr) +
				 sizeof (TypLine)))->Selected = TRUE;
	      InitDoc (CommDoc, hWndView, &NetDoc, DOCTYPE_GROUP);
	      PtrToOffset (GroupBlockPtr, GroupLinePtr, &(CommDoc->hParentBlock),
			&(CommDoc->ParentOffset), &(CommDoc->ParentLineID));
	      SetActiveWindow (hWndView);
	      SetFocus (hWndView);

	      ((TypGroup far *) (((char far *) GroupLinePtr) + sizeof (TypLine)))
		->SubjDoc = CommDoc;
	      GlobalUnlock (GroupBlockPtr->hCurBlock);
	      InvalidateRect (hWndView, NULL, FALSE);

	      UpdateWindow (hWndView);

	      InvalidateRect (NetDoc.hDocWnd, NULL, FALSE);

	      /* Deal with Comm-related stuff:  set FSA variables,
	       * send the GROUP command to NNTP.
	       */

	      CommLinePtr = CommLineIn;
	      CommBusy = TRUE;
	      CommState = ST_GROUP_RESP;
	      hSaveCursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
	      ShowCursor (TRUE);
d413 77
d492 9
a500 9
	      SetCapture (hWnd);
	      strcpy (mybuf, "GROUP ");
	      lpsz = (char far *) GroupLinePtr + sizeof (TypLine) + sizeof (TypGroup);
	      lstrcat (mybuf, lpsz);
	      mylstrncpy (CurrentGroup, lpsz, MAXFINDSTRING);
	      lstrcat(mybuf,"\r");
	      PutCommLine (mybuf, lstrlen (mybuf));
	    }
	}
d508 1
a508 1
	  KillTimer(hWnd,ID_TIMER) ;
d512 2
a513 2
	 if (CommState != ST_CLOSED_COMM)
	   DoCommInput ();
d528 3
a530 3
	{
	  ScrollIt (&NetDoc, wParam, lParam);
	}
d535 139
a673 1
	{
d675 2
a676 199
	case IDM_QUIT:
	  SaveNewsrc = FALSE;
	case IDM_EXIT:
	  DestroyWindow (hWnd);
	  break;

	case IDM_VIEW_SEL_GROUP:
	  break;

	case IDM_SHOW_SUBSCR:
	case IDM_SHOW_ALL_GROUP:
	case IDM_SEL_SUBSCR:
	case IDM_SELECTALL:
	  MessageBox (hWnd, "Command not implemented",
		      "Sorry", MB_OK);
	  break;

	case IDM_UNSEL_ALL:
	  ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
	  InvalidateRect (hWnd, NULL, FALSE);
	  break;

	case IDM_SUBSCRIBE:
	  InitGroupTable ();
	  ForAllLines (&NetDoc, GroupAction, GROUP_ACTION_SUBSCRIBE, TRUE);
	  MergeGroups (ADD_SUBSCRIBED_END_OF_SUB);
	  CleanUpGroupTable ();
	  ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
	  ScreenToTop (&NetDoc);
	  InvalidateRect (hWnd, NULL, FALSE);
	  break;

	case IDM_UNSUBSCRIBE:
	  InitGroupTable ();
	  ForAllLines (&NetDoc, GroupAction, GROUP_ACTION_UNSUBSCRIBE, FALSE);
	  ShellSort ((void far *) NewGroupTable,
		     (size_t) nNewGroups,
		     (size_t) sizeof (void far *),
		     GroupCompare);
	  MergeGroups (ADD_SUBSCRIBED_END_OF_SUB);
	  CleanUpGroupTable ();
	  ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
	  ScreenToTop (&NetDoc);
	  InvalidateRect (hWnd, NULL, FALSE);
	  break;

	case IDM_GROUP_TOP:
	  InitGroupTable ();
	  ForAllLines (&NetDoc, GroupAction, GROUP_ACTION_SUBSCRIBE, TRUE);
	  MergeGroups (ADD_SUBSCRIBED_TOP_OF_DOC);
	  CleanUpGroupTable ();
	  ForAllLines (&NetDoc, SetLineFlag, 0, FALSE);
	  ScreenToTop (&NetDoc);
	  InvalidateRect (hWnd, NULL, FALSE);
	  break;

	case IDM_NEW_WIN_GROUP:
	  ViewNew = !ViewNew;
	  CheckView (hWnd);
	  break;

	case IDM_NEW_WIN_ARTICLE:
	  NewArticleWindow = !NewArticleWindow;
	  CheckView (hWnd);
	  break;

	case IDM_COMMOPTIONS:

	  if (DialogBox (hInst, "WinVnComm", hWnd, lpfnWinVnCommDlg))
	    {
	      InvalidateRect (hWnd, NULL, TRUE);
	    }

	  break;

	case IDM_CONFIG_PERSONAL:

	  DialogBox (hInst, "WinVnPersonal", hWnd, lpfnWinVnPersonalInfoDlg);
	  break;

	case IDM_CONFIG_MISC:

	  DialogBox (hInst, "WinVnMisc", hWnd, lpfnWinVnMiscDlg);

	  break;

 	case IDM_CONFIG_LOG:

	  DialogBox (hInst, "WinVnLogOpts", hWnd, lpfnWinVnLogOptDlg);

	  break;


	case IDM_RESET:
	  CommBusy = FALSE;
	  CommState = ST_NONE;
	  break;

	case IDM_SAVE_WINDOW:
	  {
	  RECT rect;

	  /* Save position and size of Usenet window. */
	  GetWindowRect(hWndConf,&rect);
	  sprintf(mybuf,"%d,%d,%d,%d",rect.left,rect.top,
	    rect.right-rect.left,rect.bottom-rect.top);
	  WritePrivateProfileString
		(szAppName, "UsenetWindowPos", mybuf, szAppProFile);


	  /* Save position and size of first Group window */

	  for(found=FALSE,idoc=0; !found && idoc<MAXGROUPWNDS; idoc++) {
		 if(GroupDocs[idoc].InUse) {
			GetWindowRect(GroupDocs[idoc].hDocWnd,&rect);
			found = TRUE;
			sprintf(mybuf,"%d,%d,%d,%d",rect.left,rect.top,
				rect.right-rect.left,rect.bottom-rect.top);
			WritePrivateProfileString
			  (szAppName, "GroupWindowPos", mybuf, szAppProFile);
		 }
	  }

	  /* Save position and size of first Article window */

	  for(found=FALSE,idoc=0; !found && idoc<MAXARTICLEWNDS; idoc++) {
		 if(ArticleDocs[idoc].InUse) {
			GetWindowRect(ArticleDocs[idoc].hDocWnd,&rect);
			found = TRUE;
			sprintf(mybuf,"%d,%d,%d,%d",rect.left,rect.top,
				rect.right-rect.left,rect.bottom-rect.top);
			WritePrivateProfileString
			  (szAppName, "ArticleWindowPos", mybuf, szAppProFile);
		 }
	  }

	  break;
	  }

	case IDM_FIND:
	  FindDoc = &NetDoc;

	  if (DialogBox (hInst, "WinVnFind", hWnd, lpfnWinVnFindDlg))
	    {
	      found = DoFind (TRUE);
	      if (!found)
		{
		  strcpy (mybuf, "\"");
		  strcat (mybuf, NetDoc.SearchStr);
		  strcat (mybuf, "\" not found.");
		  MessageBox (hWnd, mybuf, "Not found", MB_OK);
		}
	    }
	  break;

	case IDM_FIND_NEXT_SAME:
	  FindDoc = &NetDoc;
	  if (strcmp (FindDoc->SearchStr, ""))
	    {
	      found = DoFind (FALSE);
	      if (!found)
		{
		  strcpy (mybuf, "\"");
		  strcat (mybuf, NetDoc.SearchStr);
		  strcat (mybuf, "\" not found.");
		  MessageBox (hWnd, mybuf, "No more occurrences", MB_OK);
		}
	    }
	  break;

	case ID_ABOUT:
	  lpProcAbout = MakeProcInstance (About, hInst);
	  DialogBox (hInst, "AboutBox", hWnd, lpProcAbout);
	  FreeProcInstance (lpProcAbout);
	  break;

	case IDM_HELP:
	  MakeHelpPathName (mybuf, MAXINTERNALLINE);
	  WinHelp (hWndConf, mybuf, HELP_INDEX, 0L);
	  break;

	case IDM_MAIL:
	  (MailCtrl.fnMlWinCreate)(hWnd, (TypDoc *) NULL, DOCTYPE_MAIL);
	  break;
	  
	case IDM_LOGOUT:
	  (MailCtrl.fnMlLogout)(hWnd);
	  break;

	case IDM_SHOW_VERSION:
	  show_version_strings();
	  break;

	case IDM_POST:
	  DialogBoxParam (hInst, "WinVnGeneric", hWnd,
			  lpfnWinVnGenericDlg, (LPARAM) (char far *) "Newsgroup(s):");
	  NewsgroupsPtr = DialogString;
	  CreatePostingWnd (hWnd, (TypDoc *) NULL, DOCTYPE_POSTING);
	  break;
d678 62
a739 1
	}
d744 18
a761 18
	HANDLE hBlock;
	SIZE sz;
	unsigned int Offset, MyLen, width, indicatorwidth;
	int VertLines, HorzChars;
	int EndofDoc = FALSE;
	int RangeHigh, CurPos;
	int RestX, Xtext;
	char far *textptr;
	char *cptr, *cptr2;
	char indicator;
	char indcptr[128];
	char group_name[MAXINTERNALLINE];
	char init_msg[60];
	TypGroup far *MyGroup;
	DWORD MyColors[4], MyBack[4];
	DWORD Rop;
	RECT myRect;
	int MyColorMask = 1, PrevColorMask = MyColorMask;
d765 57
a821 57
	hDC = BeginPaint (hWnd, &ps);
	GetClientRect (hWnd, &myRect);
	SelectObject (hDC, hFont);

	/* If still initializing comm link, put out a message    */
	/* to that effect.                                       */

	switch (Initializing)
	  {
	  case INIT_ESTAB_CONN:
	    cptr = "Establishing link";
	    cptr2 = "to news server...";

	    goto display_msg;

	  case INIT_READING_NEWSRC:
	    cptr = "Reading your log";
	    cptr2 = "(\"newsrc\")...";
	    goto display_msg;

	  case INIT_SCANNING_NETDOC:
	    cptr = "Creating hash table";
	    cptr2 = "from current groups...";
	    goto display_msg;

	  case INIT_GETTING_LIST:
	    sprintf (mybuf, "Receiving %uth newsgroup", RcvLineCount);
	    cptr = mybuf;
	    cptr2 = "name from server...";

	  display_msg:;
	    X = SideSpace + CharWidth;
	    Y = StartPen + 2 * LineHeight;
	    strcpy (init_msg, cptr);
	    strcat (init_msg, "    ");
	    j = strlen (init_msg);
	    TextOut (hDC, X, Y, init_msg, j);
	    strcpy (init_msg, cptr2);
	    strcat (init_msg, "    ");
	    j = strlen (init_msg);
	    TextOut (hDC, X, Y + LineHeight, init_msg, j);
	    break;


	  case INIT_DONE:

	    VertLines = NetDoc.ScYLines;
	    HorzChars = NetDoc.ScXChars;
	    MyColors[0] = NetUnSubscribedColor;
	    MyColors[1] = GetTextColor (hDC);
	    MyColors[2] = MyColors[0];
	    MyColors[3] = GetBkColor (hDC);

	    MyBack[0] = MyColors[3];
	    MyBack[1] = MyBack[0];
	    MyBack[2] = MyColors[1];
	    MyBack[3] = MyBack[2];
d826 4
a829 2
	    LockLine (NetDoc.hCurTopScBlock, NetDoc.TopScOffset, NetDoc.TopScLineID,
		      &BlockPtr, &LinePtr);
d831 95
a925 1
	    /* Update the scroll bar thumb position.                 */
d927 8
a934 99
	    CurPos = NetDoc.TopLineOrd;
	    if (CurPos < 0)
	      CurPos = 0;
	    RangeHigh = NetDoc.TotalLines - VertLines;
	    if (RangeHigh < 0)
	      RangeHigh = 0;
	    SetScrollRange (hWnd, SB_VERT, 0, RangeHigh, FALSE);
	    SetScrollPos (hWnd, SB_VERT, CurPos, TRUE);

	    /* Loop through the lines, painting them on the screen. */

	    X = SideSpace;
	    Xtext = X + indicatorwidth;
	    Y = StartPen;
	    if (LinePtr->length != END_OF_BLOCK)
	      do
		{
		  MyGroup = ((TypGroup far *)
			     ((char far *) LinePtr + sizeof (TypLine)));
		  MyLen = MyGroup->NameLen;
		  textptr = (char far *) LinePtr + sizeof (TypLine) +
		    sizeof (TypGroup);

		  /* Figure out the color of this line.                 */

		  if (MyGroup->Subscribed)
		    {
		      MyColorMask |= SUBSCR_MASK;
		    }
		  else
		    {
		      MyColorMask &= (0xff - SUBSCR_MASK);
		    }
		  if (MyGroup->Selected)
		    {
		      MyColorMask |= SELECT_MASK;
		      Rop = BLACKNESS;
		    }
		  else
		    {
		      MyColorMask &= 0xff - SELECT_MASK;
		      Rop = WHITENESS;
		    }
		  if (MyColorMask != PrevColorMask)
		    {
		      SetTextColor (hDC, MyColors[MyColorMask]);
		      SetBkColor (hDC, MyBack[MyColorMask]);
		      PrevColorMask = MyColorMask;
		    }

		  /* Figure out what indicator character to use. */

		  indicator = ' ';
		  if (NetDoc.FindLineID == LinePtr->LineID)
		    {
		      indicator = '>';
		    }
		  else if (MyGroup->HighestPrevSeen)
		    {
		      if (MyGroup->ServerLast > MyGroup->HighestPrevSeen)
			{
			  indicator = '*';
			}
		    }

		  mylstrncpy (group_name, textptr, MyGroup->NameLen + 1);

		  sprintf (indcptr, "%c %5lu %s ",
					   indicator,
					   MyGroup->ServerEstNum,
					   group_name);

		  /* Now write out the line.                            */

		  MyLen = strlen (indcptr);
	  GetTextExtentPoint (hDC, indcptr, MyLen, &sz);    
	  width = sz.cx;                                    
		  TextOut (hDC, X, Y, indcptr, MyLen);

		// This section was strange.  Maybe guilty.

		      RestX = X + width;
		      PatBlt (hDC, RestX, Y, myRect.right - RestX, LineHeight, Rop);

		  Y += LineHeight;
		}
	      while (--VertLines > 0 && NextLine (&BlockPtr, &LinePtr));

	    SetTextColor (hDC, MyColors[1]);
	    SetBkColor (hDC, MyBack[1]);

	    /* Blank out bottom and top of screen */
	    PatBlt (hDC, 0, Y, myRect.right, myRect.bottom - Y, PATCOPY);
	    PatBlt (hDC, 0, 0, myRect.right, TopSpace, PATCOPY);

	    UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
	  }
	EndPaint (hWnd, &ps);
	break;
d946 6
a951 6
	{
	  if (GroupDocs[idoc].InUse)
	    {
	      UpdateSeenArts (&(GroupDocs[idoc]));
	    }
	}
d953 3
a955 3
	{
	  WriteNewsrc ();
	}
d998 4
a1001 4
	{
	  EndDialog (hDlg, TRUE);
	  return (TRUE);
	}
d1101 3
a1103 3
	{
	  group->Subscribed = TRUE;
	}
d1124 1
a1124 1
			   RangeOffset (group->NameLen));
d1135 1
a1135 1
	buf++;
d1137 30
a1166 30
	{
	  /* We have the first number in a range.                     */
	  (group->nRanges)++;
	  RangePtr->Last = RangePtr->First;
	  if (*buf == '-')
	    {
	      buf++;
	      if (GetNum (&buf, &(RangePtr->Last)))
		{
		  RangePtr++;
		  /* at this point, we are positioned just after a range */
		}
	      else
		{
		  RangePtr->Last = RangePtr->First;
		  MoreNums = FALSE;
		}
	    }
	  else if (*buf == ',')
	    {
	      /* We have a single number "n"; interpret as the range "n-n".
	       */
	      RangePtr++;
	    }
	  else
	    {
	      /* That must have been the last number.                  */
	      MoreNums = FALSE;
	    }
	}
d1168 3
a1170 3
	{
	  MoreNums = FALSE;
	}
d1222 2
a1223 1
		BlockPtr, LinePtr);
d1225 10
a1234 8
      for (found = TRUE, il = 0; il < SelLine; il++)
	{
	  if (!NextLine (BlockPtr, LinePtr))
	    {
	      found = FALSE;    /* ran off end of document */
	      break;
	    }
	}
d1301 8
a1308 8
	{
	  mybuf[returned] = '\0';
	  if (CrackGroupLine (mybuf, LocalLinePtr))
	    {
	      NetDoc.ActiveLines++;
	    }
	  AddLine (LocalLinePtr, &BlockPtr, &GroupPtr);
	}
d1321 3
a1323 1

d1376 72
a1447 72
	{
	  toptr = NewsLine;
	  Group = (TypGroup far *) ((char far *) LinePtr + sizeof (TypLine));

	  /* Remove groups only if we performed a LIST command and */
	  /* the server did not have them.  Otherwise if !did_list, the */
	  /* newsrc will be practically empty! */

	  /* Jeeeeez!!  I'm fixing this AGAIN! */
	  /* DoList is not a boolean. SMR 930610 */

	  if ((Group->ServerFirst || Group->ServerEstNum) || !did_list ) {
	  /* Copy group name                                          */
	  fromptr = (char far *) LinePtr + sizeof (TypLine) + sizeof (TypGroup);
	  while (*(toptr++) = *(fromptr++));
	  toptr--;

	  /* Affix : or ! depending upon whether subscribed.          */
	  *(toptr++) = (char) (Group->Subscribed ? ':' : '!');
	  *(toptr++) = ' ';

	  /* If we know the highest article number on the server,
	   * output it preceded by an "s".
	   */
	  if (Group->ServerLast)
	    {
	      *(toptr++) = 's';
	      ltoa ((unsigned long) Group->ServerLast, toptr, 10);
	      while (*toptr)
		toptr++;
	      *(toptr++) = ' ';
	    }

	  /* Affix ranges of articles read.                          */
	  firstrange = TRUE;
	  nranges = Group->nRanges;
	  RangePtr = (TypRange far *) ((char far *) Group + RangeOffset (Group->NameLen));

	  while ((nranges--) > 0)
	    {
	      /* Write out ',' if not first range of articles.         */

	      if (!firstrange)
		{
		  *(toptr++) = ',';
		}
	      else
		{
		  firstrange = FALSE;
		}
	      /* Write out first article in a range.                   */

	      ltoa ((unsigned long) RangePtr->First, toptr, 10);
	      while (*toptr)
		toptr++;

	      /* If the range is of form "n-n", just put out "n"       */

	      if (RangePtr->First != RangePtr->Last)
		{
		  /* Put out the hyphen in middle of range.                */
		  *(toptr++) = '-';
		  /* Put out the last article in a range.                  */
		  ltoa ((unsigned long) RangePtr->Last, toptr, 10);
		  while (*toptr)
		    toptr++;
		}
	      RangePtr++;
	    }
	  MRRWriteLine (MRRFile, NewsLine, toptr - NewsLine);
	  }
	}
d1463 1
a1463 1
	   NetDoc.ActiveLines);
d1510 7
a1516 7
	  ->Selected)
	{
	  ((TypGroup far *) (((char far *) *LinePtr) + sizeof (TypLine)))
	  ->Subscribed = wValue;
	  AddGroupToTable ((char far *) *LinePtr);
	  DeleteLine (BlockPtr, LinePtr);
	}
d1518 11
d1538 3
a1540 3
	       directory as the HelpEx executable.This function derives
	       the full path name of the help file from the path of the
	       executable.
d1560 4
a1563 4
	{
	  *(++pcFileName) = '\0';
	  break;
	}
d1601 1
a1601 1
	return (-1);
d1608 1
a1608 1
		BlockPtr, LinePtr);
d1611 7
a1617 7
	{
	  if (!NextLine (BlockPtr, LinePtr))
	    {
	      return (-1);
	      break;
	    }
	}
d1622 1
a1622 1
			      sizeof (TypLine)))->NameLen;
d1640 20
d1669 3
a1671 3
	      version_string,
	      "WinVN Version Information",
	      MB_OK);
@



1.21
log
@testing new ID.
@
text
@d10 2
a11 2
static char wvusenet_c[] =
"$Id: wvusenet.c 1.20 1993/10/12 17:47:26 rushing Exp rushing $\n"
d13 1
d15 3
d107 1
d491 1
a491 1
	      /* lstrcat(mybuf,"\r"); */
d721 1
a721 9
	  MessageBox (hWnd,
"$Id: winvn.c 1.15 1993/08/25 18:55:19 mbretherton Exp $\n"
"$Id: wvutil.c 1.31 1993/12/01 23:24:06 rushing Exp $\n"
		      "Testing\n"
		      "Multi\n"
		      "Line\n"
		      "Output\n",
		      "Testing",
		      MB_OK);
d1611 13
@



1.20
log
@make winvn grok servers that start article numbers at 0
@
text
@d10 2
d13 3
a16 2
 * $Id: wvusenet.c 1.19 1993/09/12 20:26:52 rushing Exp rushing $
 * $Log: wvusenet.c $
d713 12
@



1.19
log
@handle can't connect condition
@
text
@d12 1
a12 1
 * $Id: wvusenet.c 1.18 1993/08/25 18:54:36 mbretherton Exp rushing $
d14 3
d1357 1
a1357 1
	  if ((Group->ServerFirst != 0) || !did_list ) {
@



1.18
log
@MRB merge, mail & post logging
@
text
@d12 1
a12 1
 * $Id: wvusenet.c 1.17 1993/08/18 21:49:21 rushing Exp $
d14 2
d17 1
d495 2
a496 1
	  DoCommInput ();
@



1.17
log
@more 16-bit article number fixes.
@
text
@d12 1
a12 1
 * $Id: wvusenet.c 1.16 1993/08/17 21:46:49 DUMOULIN Exp rushing $
d14 7
d123 1
a123 1
  RECT myRect; 					  /* selection rectangle		*/
d417 1
a417 1
						width,		 /* Initial X Width */
d602 7
d705 1
a705 1
	case IDV_CREATE:
d879 2
a880 2
          GetTextExtentPoint (hDC, indcptr, MyLen, &sz);    
          width = sz.cx;                                    
d1254 1
a1254 1
  hRetCode = MRROpenFile (szNewsSrc, 0, OF_READ, &MRRFile);
d1330 1
a1330 1
  hRetCode = MRROpenFile (szNewsSrc, 0, OF_CREATE, &MRRFile);
@



1.16
log
@Added support for Dragging mouse for selecting/deselecting Usenet groups
@
text
@d12 1
a12 1
 * $Id: wvusenet.c 1.15 1993/07/06 21:09:50 cnolan Exp DUMOULIN $
d14 3
d857 1
a857 1
		  sprintf (indcptr, "%c %5ld %s ",
d859 1
a859 1
					   (long) MyGroup->ServerEstNum,
@



1.15
log
@win32 support
@
text
@d1 9
d12 1
a12 1
 * $Id: wvusenet.c 1.14 1993/06/28 17:51:39 rushing Exp $
d14 3
a28 1
 *
a34 1
 *
d53 1
a53 1
 * Revision 1.3  1993/03/30  20:46:07  DUMOULIN
a64 5
/* wvusenet.c */
/*  This file consists of the window procedure and support routines
 *  for the main window to the application WinVn.
 */

d243 2
d247 1
d253 1
a253 1
	      ((TypGroup far *) (((char far *) LinePtr) + sizeof (TypLine)))
d255 1
d261 38
@



1.14
log
@fixed compiler warnings
@
text
@d3 1
a3 1
 * $Id: wvusenet.c 1.13 1993/06/24 17:13:14 riordan Exp rushing $
d5 3
d456 1
a456 1
      switch (wParam)
d654 1
d732 2
a733 1
	    indicatorwidth = LOWORD (GetTextExtent (hDC, "*", 2)) * 7 / 7;
d815 2
a816 1
		  width = LOWORD (GetTextExtent (hDC, indcptr, MyLen));
d844 1
a844 1
      CloseComm (CommDevice);
d1480 1
a1480 1
  int extent;
d1519 2
a1520 2
	extent = LOWORD (GetTextExtent (display_context, (LPSTR) textptr, charnum));
	if (extent > (X - SideSpace)) break;
@



1.13
log
@Save window positions between sessions.
@
text
@d3 1
a3 1
 * $Id: wvusenet.c 1.12 1993/06/14 18:52:00 rushing Exp $
d5 3
d349 1
a349 1
		  if(mybuf != '!') {
d640 1
a640 1
			  lpfnWinVnGenericDlg, (char far *) "Newsgroup(s):");
d1108 1
a1108 1
  if (Y < TopSpace || Y > TopSpace + DocPtr->ScYLines * LineHeight ||
a1156 1
  char * env_var;
d1480 1
a1480 1
  if (Y < TopSpace || Y > TopSpace + DocPtr->ScYLines * LineHeight ||
@



1.12
log
@'New Posting' menu option added
@
text
@d3 1
a3 1
 * $Id: wvusenet.c 1.11 1993/06/11 00:10:35 rushing Exp rushing $
d5 3
d102 1
a102 1
  RECT myRect;                  /* selection rectangle      */
d334 15
d352 4
a355 4
					   (int) docnum * CharWidth + 1,/* Initial X pos */
					   (int) docnum * LineHeight,
					   (int) xScreen,       /* Initial X Width */
					   (int) (yScreen * 1 / 2),     /* CW_USEDEFAULT, */
d543 41
@



1.11
log
@second merge from Matt Bretherton sources
@
text
@d3 1
a3 1
 * $Id: wvusenet.c 1.10 1993/06/10 18:24:41 rushing Exp $
d5 2
d8 1
d575 8
@



1.10
log
@hopefully newsrc&dolist thing is fixed FOR GOOD.
@
text
@d3 1
a3 1
 * $Id: wvusenet.c 1.9 1993/05/24 23:55:25 rushing Exp rushing $
d5 4
a135 1
      EnableMenuItem(GetMenu(hWnd),IDM_MAIL,MailCtrl.enableMail) ;
d160 5
d568 4
d783 1
a783 1
      MailLogout(hWnd) ;
@



1.9
log
@Delete Fonts (cleanup before exiting) (MRB)
@
text
@d3 1
a3 1
 * $Id: wvusenet.c 1.8 1993/05/20 18:12:31 rushing Exp $
d5 2
d8 1
d1189 6
a1194 4
	// Remove groups only if we performed a LIST command and
	// the server did not have them.  Otherwise if !DoList, the
	// newsrc will be practically empty!
	// SMR 930224
d1196 1
a1196 1
	  if ((Group->ServerFirst != 0) || !DoList || started_with_no_dolist) {
@



1.8
log
@don't write out newsrc if Intializing is true
@
text
@d3 1
a3 1
 * $Id: wvusenet.c 1.7 1993/04/29 20:23:06 rushing Exp rushing $
d5 4
d769 9
@



1.7
log
@attempted support for WSAAsyncSelect
@
text
@d3 1
a3 1
 * $Id: wvusenet.c 1.6 1993/04/27 20:11:38 rushing Exp rushing $
d5 3
d758 1
a758 1
      if (SaveNewsrc)
@



1.6
log
@Fixed out-of-date code that killed the timer if
CommState was ST_NONE.
@
text
@d3 1
a3 1
 * $Id: wvusenet.c 1.5 1993/04/27 18:53:17 rushing Exp rushing $
d5 4
d77 1
a77 1
  PAINTSTRUCT ps;		/* paint structure          */
d80 1
a80 1
  HDC hDC;			/* handle to display context */
d82 1
a82 1
  RECT myRect;			/* selection rectangle      */
d181 5
a185 5
               * of the key just pressed, look up in the array
               * key2scroll to see if we should process this keystroke
               * as if it were a mouse event.  If so, simulate the
               * mouse event by sending the appropriate message.
               */
d258 5
a262 5
               * this newsgroup are not in memory, and that it's OK
               * to fetch them from the server.  (Comm line not busy.)
               * Figure out whether a new window/document should be
               * created for this group & set "newdoc" accordingly.
               */
d313 1
a313 1
		                           (int) docnum * CharWidth + 1,/* Initial X pos */
d315 2
a316 2
					   (int) xScreen,	/* Initial X Width */
					   (int) (yScreen * 1 / 2),	/* CW_USEDEFAULT, */
d323 1
a323 1
		    return (0);	/* ??? */
d337 4
a340 4
               * initialize empty document to hold subject lines,
               * set focus to this document, set pointers linking
               * this document and the subject line.
               */
d359 2
a360 2
               * send the GROUP command to NNTP.
               */
d386 1
a386 1
          KillTimer(hWnd,ID_TIMER) ;
d390 1
a390 1
          DoCommInput ();
d450 2
a451 2
                     (size_t) nNewGroups,
                     (size_t) sizeof (void far *),
d565 1
a565 1
      	char group_name[MAXINTERNALLINE];
d708 3
a710 3
			                   indicator,
		                           (long) MyGroup->ServerEstNum,
			                   group_name);
d720 1
a720 1
            	      RestX = X + width;
d952 1
a952 1
               */
d1022 1
a1022 1
	      found = FALSE;	/* ran off end of document */
d1063 1
a1063 1
  env_var = getenv ("WINVN");		/* get path to winvn.ini */
d1175 1
a1175 1
          if ((Group->ServerFirst != 0) || !DoList || started_with_no_dolist) {
d1186 2
a1187 2
           * output it preceded by an "s".
           */
d1234 1
a1234 1
          }
d1315 3
a1317 3
               directory as the HelpEx executable.This function derives
               the full path name of the help file from the path of the
               executable.
d1399 1
a1399 1
                              sizeof (TypLine)))->NameLen;
d1408 2
a1409 2
        extent = LOWORD (GetTextExtent (display_context, (LPSTR) textptr, charnum));
        if (extent > (X - SideSpace)) break;
@



1.5
log
@attempt to fix newsrc problems.  allow newsrc line with
no range data.
@
text
@d3 1
a3 1
 * $Id: wvusenet.c 1.4 1993/03/30 21:07:15 DUMOULIN Exp rushing $
d5 4
d122 4
d377 2
a378 3
// changed to ST_NONE from ST_CLOSED_COMM during
// MAPI merge because of conflicting edits in wvsck???.c

d380 1
a380 1
     if (CommState == ST_NONE)
@



1.4
log
@handle conflicting MAPI merge problem (with wvsck???.c)
use ST_NONE instead of ST_CLOSED_COMM
@
text
@d3 1
a3 1
 * $Id: wvusenet.c 1.3 1993/03/30 20:46:07 DUMOULIN Exp DUMOULIN $
d5 4
d894 1
a894 1
  while (*buf && *buf == ' ')
d911 4
a914 1
  MoreNums = TRUE;
@



1.3
log
@MAPI
@
text
@d3 5
a7 2
 * $Id: wvusenet.c,v 1.2 1993/02/25 03:08:52 rushing Exp $
 * $Log: wvusenet.c,v $
d365 3
d369 1
a369 1
     if (CommState == ST_CLOSED_COMM)
@



1.2
log
@fixed newsrc truncation when DoList = 0.
@
text
@d3 5
a7 2
 * $Id: wvusenet.c%v 1.1 1993/02/16 20:54:22 rushing Exp rushing $
 * $Log: wvusenet.c%v $
d106 2
d109 1
a109 1
      idTimer = SetTimer (hWnd, NULL, 1000, (FARPROC) NULL);
d363 8
a370 1
      DoCommInput ();
d527 1
a527 1
	  CreatePostingWnd ((TypDoc *) NULL, DOCTYPE_MAIL);
d739 2
@



1.1
log
@Initial revision
@
text
@d3 4
a6 2
 * $Id$
 * $Log$
d8 1
d29 7
d1076 3
d1132 6
a1137 1
          if (Group->ServerFirst != 0) {
@

