home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / winsock / wstim101 / src / ntime.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  55.2 KB  |  2,270 lines

  1. // Contents ---------------------------------------------------------------
  2. //
  3. //   ntime.c -- NTIME a Freeware Time Protocol Client
  4. //
  5. //   Version 1.0.1, a Windows Socket Time Client
  6. //
  7. //   Copyright (C) Frederick W. Bent 1994
  8. //   All rights reserved.
  9. //
  10. //
  11. // Redistribution and use in source and binary forms are permitted provided
  12. // that the above copyright notice and this paragraph are duplicated in all
  13. // such forms and that any documentation, advertising materials, and other
  14. // materials related to such distribution and use acknowledge that the
  15. // software was developed by Frederick W. Bent.  In addition, if you wish
  16. // to distribute this program in source and/or binary forms with other
  17. // samples of WinSock programs, you must first contact the author so that
  18. // I can keep accurate records of its usage.  The name of the author may
  19. // not be used to endorse or promote products derived from this software
  20. // without specific prior written permission. Specifically, do not modify
  21. // this source in any way and re-distribute it without the author's prior
  22. // consent.  THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OF
  23. // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
  24. // OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  25. //
  26. //
  27. // Description
  28. //
  29. //    See RFC 868.
  30. //
  31. // Ends -------------------------------------------------------------------
  32.  
  33. // History ----------------------------------------------------------------
  34. //
  35. // 6/28/94  1.0.0  Fred Bent    Wrote this thing
  36. // 8/18/94  1.0.1  Fred Bent    Fixed some UDP issues
  37. //
  38. // Ends -------------------------------------------------------------------
  39.  
  40. // Legal Stuff ------------------------------------------------------------
  41. //
  42. // Finger Version 3.1, a Windows Sockets Time Client
  43. //
  44. // Copyright 1992, 1993 Network Research Corporation
  45. //
  46. // Permission to use, modify, and distribute this software and its
  47. // documentation for any purpose and without fee is hereby granted, provided
  48. // that the above copyright notice appears in all copies and that both
  49. // that copyright notice and this permission notice appear in supporting
  50. // documentation.  NRC makes no claims as to the suitability of this software
  51. // for any purpose.
  52. //
  53. // Ends ---------------------------------------------------------------------
  54.  
  55. #pragma    warn -par
  56.  
  57. // Interface Dependencies -------------------------------------------------
  58.  
  59. #define USE_CTL3D
  60. #define STRICT
  61.  
  62. #include <windows.h>
  63. #include <windowsx.h>
  64. #include <stdlib.h>
  65. #include <stdio.h>    // sscanf
  66. #include <string.h>
  67. #include <winsock.h>
  68. #ifdef    USE_CTL3D
  69.    #include <ctl3d.h>
  70. #endif
  71. #include <stdarg.h>
  72. #include <time.h>
  73. #include "dsplist.h"
  74. #include "ntime.h"
  75.  
  76. #define MAXTEXT   132
  77. #define THUMBPOS  LOWORD(lParam)    // Win 16
  78. #define WM_RUN    (WM_USER + 100)
  79.  
  80. #define INI_FILE    "WSNTIME.INI"
  81. #define HELP_FILE    "WSNTIME.HLP"
  82.  
  83. #define DEFAULT_UDPTIME        192
  84. #define DEFAULT_UDPRETRY    3
  85. #define DEFAULT_TCPTIME        30
  86.  
  87. #define SECTION_MAIN      "NetTime"
  88. #define ENTRY_ONLYTCP     "UseTCP"
  89. #define ENTRY_DOUPDATE      "UpdateSysTime"
  90. #define ENTRY_DEFAULTHOST "TimeServer"
  91. #define ENTRY_TIMECORR      "AddSeconds"
  92. #define ENTRY_TCPTIMEOUT  "TCPTimeout"
  93. #define ENTRY_UDPTIMEOUT  "UDPTimeout"
  94. #define ENTRY_UDPRETRY      "UDPRetry"
  95.  
  96. #define MAXHOSTTABLE    5
  97. #define ENTRY_HOST1      "Host1"
  98. #define ENTRY_HOST2      "Host2"
  99. #define ENTRY_HOST3      "Host3"
  100. #define ENTRY_HOST4      "Host4"
  101. #define ENTRY_HOST5      "Host5"
  102.  
  103.  
  104. // Function prototypes ----------------------------------------------------
  105.  
  106. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
  107. LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  108.  
  109. BOOL CALLBACK HostDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam);
  110. BOOL CALLBACK AboutDlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  111.  
  112. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);
  113. BOOL InitApp(HINSTANCE hInstance);
  114.  
  115. LRESULT DoPaint(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  116. LRESULT DoRun(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  117. LRESULT DoSize(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  118. LRESULT DoCreate(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  119. LRESULT DoCommand(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  120. LRESULT DoDestroy(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  121. LRESULT DoMouseMove(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  122. LRESULT DoMenuHost(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  123. LRESULT DoOpenHost(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  124. LRESULT DoMenuOpen(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  125. LRESULT DoVScroll(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  126. LRESULT DoActivate(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  127. LRESULT DoClose(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  128. LRESULT DoMenuExit(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  129. LRESULT DoMenuAbout(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  130. LRESULT DoMenuHelp(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  131. LRESULT DoInitMenuPopup(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
  132.  
  133. void AddHostToPopup(PSTR szHostName);
  134.  
  135. VOID Repaint(VOID);
  136. VOID PosView(int nlines);
  137. VOID ReportWSError(int Err);
  138. VOID RelScroll(HWND hWnd, int nlines);
  139. VOID SetWinCaption(PSTR str);
  140. VOID SetScroll(VOID);
  141. VOID WinPrintf( HDC   hdc, int row, UINT   col, LPSTR pszFormat, ... );
  142. VOID MakeHelpPathName(HINSTANCE hInst, LPSTR szFileName);
  143. PSTR WSErrorString(UINT ResourceID);
  144.  
  145. // Global variables -------------------------------------------------------
  146.  
  147. char     szHostName[MAXHOST+1] = ""; // name of host to connect to
  148. char     szUser[MAXUSER+1] = "";     // query for this user id (can be null)
  149. char     szAppName[] = APP_NAME;     // application's title
  150. char     szAppClass[] = "WSNTime.Class";
  151.  
  152. char     szHostTable[MAXHOSTTABLE][MAXHOST+1];
  153. char     szEntryHost[MAXHOSTTABLE][6] = { ENTRY_HOST1, ENTRY_HOST2, ENTRY_HOST3, ENTRY_HOST4, ENTRY_HOST5 };
  154.  
  155. HLOCAL    pLineItems = NULL;           // ptr to display list LINEITEMS
  156. int      nLineItems = 0;            // number of items in display list
  157. HLOCAL    pTopLine;                 // pts to topmost displayable LINEITEM
  158. int      nTopLine = 0;              // line number of topmost displayed line
  159. int      nClientLines;              // # of text lines in view
  160. int      CharY;                     // pixel character height
  161. int     CharX;
  162. HWND     hFrame;                    // ntime main window handle
  163. HMENU    hMenu;                     // main window menu handle
  164. HINSTANCE    hInst;                     // this instance of ntime
  165. HCURSOR  hCursor;                   // current cursor (either wait or normal)
  166. WSADATA  WSAData;                     // windows sockets info return
  167.  
  168. BOOL    bCommandLineArgs = FALSE;
  169. BOOL    bShouldUseTCP = TRUE;
  170. BOOL    bUpdateSystemTime = FALSE;
  171. BOOL    bRunning = FALSE;
  172.  
  173. char    szHelpFileName[MAX_PATH];
  174.  
  175.  
  176. DECODEWORD frameMsgs[] =            // windows messages & handlers
  177. {
  178.      {WM_ACTIVATE,   DoActivate}
  179.    , {WM_CLOSE,      DoClose}
  180.    , {WM_COMMAND,    DoCommand}
  181.    , {WM_CREATE,     DoCreate}
  182.    , {WM_DESTROY,    DoDestroy}
  183.    , {WM_MOUSEMOVE,  DoMouseMove}
  184.    , {WM_PAINT,      DoPaint}
  185.    , {WM_RUN,         DoRun}
  186.    , {WM_INITMENUPOPUP, DoInitMenuPopup}
  187.    , {WM_SIZE,       DoSize}
  188.    , {WM_VSCROLL,    DoVScroll}
  189.    , {WM_KEYDOWN,    DoVScroll}
  190. };
  191.  
  192. DECODEWORD menuItems[] =            // menu items & associated handlers
  193. {
  194.      {IDM_OPEN,         DoMenuOpen}
  195.    , {IDM_SETUP,     DoMenuHost}
  196.    , {IDM_EXIT,      DoMenuExit}
  197.    , {IDM_ABOUT,     DoMenuAbout}
  198.    , {IDM_HELP_INDEX, DoMenuHelp}
  199.    , {IDM_HOST1,     DoOpenHost}
  200.    , {IDM_HOST2,     DoOpenHost}
  201.    , {IDM_HOST3,     DoOpenHost}
  202.    , {IDM_HOST4,     DoOpenHost}
  203.    , {IDM_HOST5,     DoOpenHost}
  204. };
  205.  
  206.  
  207. // Function
  208.  
  209.     BOOL    HandleCommandLine( LPSTR lpszCmdLine )
  210.  
  211. // Summary ----------------------------------------------------------------
  212. //
  213. //    This function attempts to read any command-line arguments that
  214. //    this program has been passed.  The arguments are copied into
  215. //    the szHostname and szUser global variables.
  216. //
  217. // Parameters
  218. //
  219. //    lpszCmdLine
  220. //
  221. // Returns
  222. //
  223. //    BOOL
  224. //
  225. //    Returns TRUE if there was an argument, FALSE otherwise
  226. //
  227. // Ends -------------------------------------------------------------------
  228. {
  229.     int    status;
  230.         char    szBuffer[128];
  231.  
  232.     if (lstrlen(lpszCmdLine) == 0 ) return(FALSE);
  233.  
  234.     lstrcpyn((LPSTR)szBuffer, lpszCmdLine, sizeof(szBuffer));
  235.     status = sscanf(szBuffer, "%s %s", szHostName, szUser);
  236.  
  237.     if ( status < 1 ) szHostName[0] = '\0';
  238.     if ( status < 2 ) szUser[0] = '\0';
  239.  
  240.     if ( status > 0 ) return(TRUE);
  241.     else return FALSE;
  242. }
  243.  
  244.  
  245. //
  246. // WinMain -- windows calls this to start the application.
  247. //
  248. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  249.     LPSTR lpCmdLine, int nCmdShow)
  250.  
  251. // Summary ----------------------------------------------------------------
  252. //
  253. //
  254. // Parameters
  255. //
  256. //    hInstance    The instance handle of this application
  257. //
  258. //    hPrevInstance    The handle of the previous instance of this
  259. //            application
  260. //
  261. //    lpCmdLine    A far pointer to a null-terminated command-line
  262. //
  263. //    nCmdShow    An integer that specifies the application's window
  264. //            display.
  265. //
  266. // Ends -------------------------------------------------------------------
  267.  
  268.  
  269.     {
  270.         MSG msg;                                  // holds current message
  271.         int err;
  272. #ifdef    USE_CTL3D
  273.         WORD    ctl3d_ver;
  274. #endif
  275.  
  276.  
  277.            hInst = hInstance;                        // save our instance handle
  278.  
  279. #ifdef USE_CTL3D
  280.         ctl3d_ver = Ctl3dGetVer();
  281.  
  282.         if ( ( HIBYTE(ctl3d_ver) < CTL3DVERSION_MAJOR ) ||
  283.              ( HIBYTE(ctl3d_ver) == CTL3DVERSION_MAJOR &&
  284.                LOBYTE(ctl3d_ver) < CTL3DVERSION_MINOR) )
  285.         {
  286.             MessageBox(NULL, WSErrorString(IDS_CTL3D_VER), szAppName, MB_ICONEXCLAMATION | MB_OK);
  287.             return(FALSE);
  288.         }
  289.         Ctl3dRegister(hInstance);
  290.            Ctl3dAutoSubclass(hInstance);
  291. #endif
  292.  
  293.         if (!hPrevInstance)                       // if first instance,
  294.                   if (!InitApp(hInstance))               // register window classes
  295.                   {
  296.                 MessageBox(hFrame, WSErrorString(FE_INIT), szAppName, MB_ICONSTOP | MB_OK);
  297. #ifdef USE_CTL3D
  298.                 Ctl3dUnregister(hInstance);
  299. #endif
  300.                  return(FALSE);
  301.                   }
  302.  
  303.         if ( HandleCommandLine(lpCmdLine) )
  304.         {
  305.             nCmdShow = SW_SHOWMINNOACTIVE;
  306.             bCommandLineArgs = TRUE;
  307.         } else {
  308.             bCommandLineArgs = FALSE;
  309.         }
  310.  
  311.         if (!InitInstance(hInstance, nCmdShow))   // per instance initialization &
  312.         {                                         // window creation
  313.             MessageBox(hFrame, WSErrorString(FE_INIT), szAppName, MB_ICONSTOP | MB_OK);
  314. #ifdef USE_CTL3D
  315.             Ctl3dUnregister(hInstance);
  316. #endif
  317.             return(FALSE);
  318.         }
  319.  
  320.         if ((err = WSAStartup(WSVERSION_REQ, &WSAData)) != 0 ) // register task with
  321.         {                                         // winsock tcp/ip API
  322.             ReportWSError(err);
  323. #ifdef USE_CTL3D
  324.             Ctl3dUnregister(hInstance);
  325. #endif
  326.             DestroyWindow(hFrame);            // kill application window & signal app exit
  327.             return(FALSE);
  328.         }
  329.  
  330.         if ( ( LOBYTE(WSAData.wVersion) < WSVERSION_MAJOR ) ||
  331.              ( LOBYTE(WSAData.wVersion) == WSVERSION_MAJOR &&
  332.                HIBYTE(WSAData.wVersion) < WSVERSION_MINOR) )
  333.         {
  334.             MessageBeep(MB_ICONSTOP);
  335.             MessageBox(hFrame, WSErrorString(IDS_BAD_VERSION), szAppName, MB_ICONSTOP | MB_OK);
  336.             DestroyWindow(hFrame);
  337. #ifdef USE_CTL3D
  338.             Ctl3dUnregister(hInstance);
  339. #endif
  340.             WSACleanup();
  341.             return(FALSE);
  342.         }
  343.  
  344.         /* If auto-run mode then start it now... */
  345.         if (bCommandLineArgs) SendMessage(hFrame, WM_RUN, 0, 0L);
  346.  
  347.         while (GetMessage(&msg, NULL, 0, 0))      // loop til WM_QUIT
  348.         {
  349.               TranslateMessage(&msg);
  350.               DispatchMessage(&msg);
  351.         }
  352.  
  353.         WSACleanup();                             // disconnect from winsock
  354. #ifdef USE_CTL3D
  355.         Ctl3dUnregister(hInstance);
  356. #endif
  357.         return msg.wParam;                        // return to windows
  358.     }
  359.  
  360.  
  361. // Function
  362.  
  363.     BOOL InitApp(HINSTANCE hInstance)
  364.  
  365. // Summary ----------------------------------------------------------------
  366. //
  367. // InitApp -- initialization for all instances of application.
  368. // Registers main window class.
  369. //
  370. // Paramters
  371. //
  372. //    hInstance    This instance of the NTime app
  373. //
  374. //    nCmdShow    Now to start the application
  375. //
  376. // Returns
  377. //
  378. //    BOOL
  379. //
  380. //    Returns TRUE is successful, FALSE otherwise
  381. //
  382. // Ends -------------------------------------------------------------------
  383.  
  384.     {
  385.         WNDCLASS    wndclass;
  386.  
  387.         InitNetApp();  // initializes (per application) network module
  388.  
  389.         wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  390.            wndclass.lpfnWndProc   = FrameWndProc;
  391.            wndclass.cbClsExtra    = 0;
  392.            wndclass.cbWndExtra    = 0;
  393.            wndclass.hInstance     = hInstance;
  394.            wndclass.hIcon         = LoadIcon(hInst, "NTimeIcon");
  395.         wndclass.hCursor       = NULL;
  396. #ifdef USE_CTL3D
  397.         wndclass.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
  398. #else
  399.         wndclass.hbrBackground = CreateSolidBrush(GetSysColoe(COLOR_WINDOW));
  400. #endif
  401.         wndclass.lpszMenuName  = "NTimeMenu";
  402.            wndclass.lpszClassName = szAppClass;
  403.  
  404.         return(RegisterClass(&wndclass));
  405.     }
  406.  
  407.  
  408. // Function
  409.  
  410.     BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  411.  
  412. // Summary ----------------------------------------------------------------
  413. //
  414. //    This function is used to initialize this instance of a WSNTime app
  415. //    and create its main window.  It reads the .INI file to setup
  416. //    some of the global variables.
  417. //
  418. //    It also initializes the various global variables, and calls to
  419. //    start the network window.
  420. //
  421. // Paramters
  422. //
  423. //    hInstance    This instance of the NTime app
  424. //
  425. //    nCmdShow    Now to start the application
  426. //
  427. // Returns
  428. //
  429. //    BOOL
  430. //
  431. //    Returns TRUE is successful, FALSE otherwise
  432. //
  433. // Ends -------------------------------------------------------------------
  434.  
  435.     {
  436.        HDC hdc;
  437.        TEXTMETRIC tm;                      // contains font dimensions
  438.        RECT rect;                          // outer dimensions of window
  439.        int  nTCPTimeOutValue;
  440.        int i;
  441.  
  442.        hFrame = CreateWindow( szAppClass, szAppName
  443.             , WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_VSCROLL | WS_MINIMIZEBOX
  444.             , CW_USEDEFAULT, CW_USEDEFAULT
  445.             , CW_USEDEFAULT, CW_USEDEFAULT
  446.             , NULL, NULL, hInstance, NULL);
  447.  
  448.        if (hFrame == NULL)
  449.           return(FALSE);
  450.  
  451.        hCursor = LoadCursor(NULL, IDC_ARROW);
  452.        hMenu = GetMenu(hFrame);
  453.        bRunning = FALSE;
  454.  
  455.        /* Read the settings in the .INI file */
  456.        nTCPTimeOutValue = GetPrivateProfileInt( SECTION_MAIN
  457.                         , ENTRY_TCPTIMEOUT
  458.                         , DEFAULT_TCPTIME
  459.                         , (LPCSTR) INI_FILE );
  460.  
  461.        nUDPTimeOutValue = GetPrivateProfileInt( SECTION_MAIN
  462.                         , ENTRY_UDPTIMEOUT
  463.                         , DEFAULT_UDPTIME
  464.                         , (LPCSTR) INI_FILE );
  465.  
  466.        nUDPNumberRetry = GetPrivateProfileInt( SECTION_MAIN
  467.                         , ENTRY_UDPRETRY
  468.                         , DEFAULT_UDPRETRY
  469.                         , (LPCSTR) INI_FILE );
  470.  
  471.        bShouldUseTCP = GetPrivateProfileInt( SECTION_MAIN
  472.                 , ENTRY_ONLYTCP
  473.                 , TRUE
  474.                 , (LPCSTR) INI_FILE);
  475.  
  476.  
  477.        MakeHelpPathName(hInstance, (LPSTR)szHelpFileName);
  478.  
  479.        if (!InitNetInst(hFrame, nTCPTimeOutValue, nUDPTimeOutValue, nUDPNumberRetry))
  480.         return(FALSE);  // initialize (per instance) the network module
  481.  
  482.        /* Setup for the output */
  483.        hdc = GetDC(hFrame);
  484.        SelectObject(hdc, GetStockObject(ANSI_VAR_FONT));
  485.        GetTextMetrics(hdc, &tm);
  486.        CharY = tm.tmHeight + tm.tmExternalLeading;
  487.        CharX = tm.tmAveCharWidth;
  488. #ifdef USE_CTL3D
  489.        SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
  490.        SetBkColor(hdc, GetSysColor(COLOR_BTNSHADOW));
  491. #else
  492.        SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
  493.        SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
  494. #endif
  495.        ReleaseDC(hFrame, hdc);
  496.  
  497.        // set initial window width & height to 80x10 chars
  498.        GetWindowRect(hFrame, &rect);
  499.  
  500.        MoveWindow( hFrame, rect.left, rect.top,
  501.                80 * CharX + GetSystemMetrics(SM_CXVSCROLL),
  502.                    10 * CharY + GetSystemMetrics(SM_CYCAPTION) +
  503.                    GetSystemMetrics(SM_CYMENU), FALSE);
  504.  
  505.        /* Show the window */
  506.        ShowWindow(hFrame, nCmdShow);
  507.        UpdateWindow(hFrame);
  508.  
  509.        if (!bCommandLineArgs)
  510.        {
  511.            bUpdateSystemTime = GetPrivateProfileInt( SECTION_MAIN
  512.                     , ENTRY_DOUPDATE
  513.                     , FALSE
  514.                     , (LPCSTR) INI_FILE );
  515.  
  516.             GetPrivateProfileString( SECTION_MAIN
  517.                        , ENTRY_DEFAULTHOST
  518.                        , "\0"
  519.                        , (LPSTR) szHostName
  520.                        , sizeof(szHostName)
  521.                        , (LPCSTR) INI_FILE);
  522.  
  523.             GetPrivateProfileString( SECTION_MAIN
  524.                        , ENTRY_TIMECORR
  525.                        , "\0"
  526.                        , (LPSTR) szUser
  527.                        , sizeof(szUser)
  528.                        , (LPCSTR) INI_FILE);
  529.  
  530.                     /* Setup the host tables */
  531.             for( i = 0; i < MAXHOSTTABLE; i++ )
  532.                     {
  533.                 GetPrivateProfileString( SECTION_MAIN
  534.                            , (LPSTR) szEntryHost[i]
  535.                            , "\0"
  536.                            , (LPSTR) szHostTable[i]
  537.                            , MAXHOST
  538.                            , (LPCSTR) INI_FILE);
  539.             }
  540.  
  541.             /* Add the hosts, if any, to the menu */
  542.             AddHostToPopup(NULL);
  543.  
  544.        } else {
  545.         for ( i = 0; i < MAXHOSTTABLE; i++ )
  546.         {
  547.             szEntryHost[i][0] = '\0';
  548.         }
  549.         bUpdateSystemTime = TRUE;
  550.        }
  551.  
  552.  
  553.        return(TRUE);
  554.     }
  555.  
  556.  
  557. // Function
  558.  
  559.     void SaveHosts(void)
  560.  
  561. // Summary ----------------------------------------------------------------
  562. //
  563. //    This function saves the time servers that are currently
  564. //    present in the Host Menu to the .INI file.
  565. //
  566. // Paramters
  567. //
  568. //    none
  569. //
  570. // Returns
  571. //
  572. //    Nothing
  573. //
  574. // Ends -------------------------------------------------------------------
  575.  
  576. {
  577.     int i;
  578.  
  579.     for( i = 0; i < MAXHOSTTABLE; i++ )
  580.     {
  581.         WritePrivateProfileString( SECTION_MAIN
  582.                    , (LPSTR) szEntryHost[i]
  583.                    , (LPSTR) szHostTable[i]
  584.                    , (LPCSTR) INI_FILE);
  585.     }
  586. }
  587.  
  588.  
  589. // Function
  590.  
  591.     BOOL    IsHostInTable(PSTR szHostName)
  592.  
  593. // Summary ----------------------------------------------------------------
  594. //
  595. //    This function searches for the specifies time host in the
  596. //    Host menu.
  597. //
  598. // Paramters
  599. //
  600. //    szHostName    The ASCIIZ string giving the host to search for.
  601. //
  602. // Returns
  603. //
  604. //    BOOL
  605. //
  606. //    Returns TRUE is the string is in the menu, FALSE otherwise
  607. //
  608. // Ends -------------------------------------------------------------------
  609.  
  610. {
  611.     int    i;
  612.  
  613.  
  614.     if (szHostName == NULL) return FALSE;
  615.  
  616.         i = 0;
  617.     while (strcmp(szHostTable[i], szHostName))
  618.     {
  619.         i++;
  620.                 if ( i == MAXHOSTTABLE ) break;
  621.     }
  622.  
  623.     return (i != MAXHOSTTABLE);
  624. }
  625.  
  626.  
  627. // Function
  628.  
  629.     void AddHostToPopup(PSTR szHostName)
  630.  
  631. // Summary ----------------------------------------------------------------
  632. //
  633. //    This function adds the given host to the Host Menu popup.
  634. //    If the host is already in the menu, nothing is done.  If
  635. //    the menu is full (i.e. 5 hosts) then the last one is
  636. //    removed from the menu.
  637. //
  638. // Paramters
  639. //
  640. //    szHostName    The ASCIIZ string that is to be added to the
  641. //            menu.
  642. //
  643. // Returns
  644. //
  645. //    Nothing.
  646. //
  647. // Ends -------------------------------------------------------------------
  648.  
  649. {
  650.     HMENU     hMenu;
  651.     HMENU     hMenuPopup;
  652.     int    nCount;
  653.     int    i;
  654.     char    szTempBuffer[MAXHOST + 4];
  655.  
  656.  
  657.         if (IsHostInTable(szHostName)) return;
  658.  
  659.     hMenu = GetMenu(hFrame);
  660.     hMenuPopup = GetSubMenu(hMenu, 0);    // Host menu...
  661.     nCount = GetMenuItemCount(hMenuPopup);
  662.  
  663.     if ( nCount < 5 )    // Have added separator already?
  664.     {
  665.         if ((szHostName != NULL) || (szHostTable[0][0] != '\0'))
  666.             AppendMenu(hMenuPopup, MF_SEPARATOR, 0, NULL);
  667.         nCount = GetMenuItemCount(hMenuPopup);
  668.     }
  669.  
  670.     if (szHostName != NULL )
  671.     {
  672.         for ( i = 0; ((i < MAXHOSTTABLE) && (nCount >= 5)); i++ )
  673.         {
  674.             RemoveMenu( hMenuPopup, (IDM_HOST1 + i), MF_BYCOMMAND );
  675.             nCount = GetMenuItemCount(hMenuPopup);
  676.         }
  677.  
  678.         for ( i = (MAXHOSTTABLE-1); i > 0; i-- )
  679.         {
  680.             strcpy(szHostTable[i], szHostTable[i-1]);
  681.         }
  682.         strcpy(szHostTable[0], szHostName);
  683.     }
  684.  
  685.     for ( i = 0; i < MAXHOSTTABLE; i++ )
  686.     {
  687.         if ( szHostTable[i][0] != '\0' )
  688.         {
  689.             sprintf(szTempBuffer, "&%1d ", (i+1));
  690.                         strcat(szTempBuffer, szHostTable[i]);
  691.             AppendMenu(hMenuPopup, MF_STRING, (IDM_HOST1 + i), szTempBuffer);
  692.                 }
  693.     }
  694.     DrawMenuBar(hFrame);
  695. }
  696.  
  697.  
  698. // Callback function
  699.  
  700.     LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  701.  
  702. // Summary ----------------------------------------------------------------
  703. //
  704. // FrameWndProc -- callback function for application frame (main) window.
  705. // Decodes message and routes to appropriate message handler. If no handler
  706. // found, calls DefWindowProc.
  707. // 
  708. //
  709. // Parameters
  710. //
  711. //    hWnd    Handle of the window.
  712. //
  713. //    Msg    Message.
  714. //
  715. //    wParam    First message paramter.
  716. //
  717. //    lParam    Second message parameter.
  718. //
  719. //
  720. // Returns
  721. //
  722. //    LRESULT
  723. //
  724. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  725. //
  726. // Ends -------------------------------------------------------------------
  727.  
  728.     {
  729.        int i;
  730.     
  731.        for (i = 0; i < dim(frameMsgs); i++)
  732.        {
  733.           if (Msg == frameMsgs[i].Code)
  734.          return(*frameMsgs[i].Fxn)(hWnd, Msg, wParam, lParam);
  735.        }
  736.  
  737.        return(DefWindowProc(hWnd, Msg, wParam, lParam));
  738.     }
  739.  
  740.  
  741. // Window function
  742.  
  743.     LRESULT DoCommand(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  744.  
  745. // Summary ----------------------------------------------------------------
  746. //
  747. // DoCommand -- demultiplexes WM_COMMAND messages resulting from menu
  748. // selections, and routes to corresponding menu item handler.  Sends back
  749. // any unrecognized messages to windows.
  750. //
  751. // Parameters
  752. //
  753. //    hWnd    Handle of the window.
  754. //
  755. //    Msg    Message.
  756. //
  757. //    wParam    First message paramter.
  758. //
  759. //    lParam    Second message parameter.
  760. //
  761. //
  762. // Returns
  763. //
  764. //    LRESULT
  765. //
  766. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  767. //
  768. // Ends -------------------------------------------------------------------
  769.  
  770.     {
  771.        int i;
  772.  
  773.        for (i = 0; i < dim(menuItems); i++)
  774.        {
  775.           if (wParam == menuItems[i].Code)
  776.          return(*menuItems[i].Fxn)(hWnd, Msg, wParam, lParam);
  777.        }
  778.  
  779.        return(DefWindowProc(hWnd, Msg, wParam, lParam));
  780.     }
  781.  
  782.  
  783. // Window function
  784.  
  785.     LONG DoMenuHost(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  786.  
  787. // Summary ----------------------------------------------------------------
  788. //
  789. // DoMenuHost -- handles the "Setup..." menu item.  We prompt for a
  790. // Domain Name System (DNS) host name, or a "dotted IP address" (e.g.,
  791. // 129.216.202.5). 
  792. //
  793. // Parameters
  794. //
  795. //    hWnd    Handle of the window.
  796. //
  797. //    Msg    Message.
  798. //
  799. //    wParam    First message paramter.
  800. //
  801. //    lParam    Second message parameter.
  802. //
  803. //
  804. // Returns
  805. //
  806. //    LRESULT
  807. //
  808. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  809. //
  810. // Ends -------------------------------------------------------------------
  811.  
  812.     {
  813.         DLGPROC lpfnProc;
  814.                 int ret;
  815.  
  816.            // prompt for the host's domain name or ip address
  817.  
  818.            lpfnProc = (DLGPROC) MakeProcInstance((FARPROC)HostDlgProc, hInst);
  819.         ret = DialogBox(hInst, "HostBox", hWnd, lpfnProc);
  820.         FreeProcInstance((FARPROC)lpfnProc);
  821.  
  822.         if (ret == IDB_CONNECT)
  823.         {
  824.             PostMessage(hWnd, WM_COMMAND, IDM_OPEN, 0L);
  825.         }
  826.  
  827.         return(FALSE);
  828.     }
  829.  
  830.  
  831. // Menu Function
  832.  
  833.     LONG DoMenuOpen(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  834.  
  835. // Summary ----------------------------------------------------------------
  836. //
  837. //    This function is called when the user has selected the Host Open
  838. //    menu command.  This causes the client to attempt to connect to
  839. //    the server and retrieve the data from the remote server.
  840. //
  841. //    The Open and Setup menu options are disabled while the request
  842. //    is being serviced.  Only ONE request at a time is allowed.
  843. //
  844. //    The function invokes NETWRK_ module FingerStart()
  845. //     routine to initiate a conversation with the time server on the
  846. //     remote host.  NETWRK_, in turn, calls TimeFinish() to signal
  847. //     completion.
  848. //
  849. // Parameters
  850. //
  851. //    hWnd    Handle of the window.
  852. //
  853. //    Msg    Message.
  854. //
  855. //    wParam    First message paramter.
  856. //
  857. //    lParam    Second message parameter.
  858. //
  859. //
  860. // Returns
  861. //
  862. //    LRESULT
  863. //
  864. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  865. //
  866. // Ends -------------------------------------------------------------------
  867.  
  868.     {
  869.         SetWinCaption(NULL);
  870.         AddHostToPopup(szHostName);
  871.         bRunning = TRUE;
  872.         SetCursor(hCursor = LoadCursor(NULL, IDC_WAIT));
  873.         FreeLineList(pLineItems);    // dispose old display
  874.         pLineItems = NULL;
  875.         nLineItems = 0;
  876.         PosView(0);                               // position view to top
  877.         FingerStart(szHostName);
  878.                 Repaint();
  879.         return(FALSE);
  880.     }
  881.  
  882.  
  883.  
  884. // Menu Function
  885.  
  886.     LONG DoOpenHost(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  887.  
  888. // Summary ----------------------------------------------------------------
  889. //
  890. //    This function is called when the user has selected the Host Open
  891. //    menu command.  This causes the client to attempt to connect to
  892. //    the server and retrieve the data from the remote server.
  893. //
  894. //    The Open and Setup menu options are disabled while the request
  895. //    is being serviced.  Only ONE request at a time is allowed.
  896. //
  897. //    The function invokes NETWRK_ module FingerStart()
  898. //     routine to initiate a conversation with the time server on the
  899. //     remote host.  NETWRK_, in turn, calls TimeFinish() to signal
  900. //     completion.
  901. //
  902. // Parameters
  903. //
  904. //    hWnd    Handle of the window.
  905. //
  906. //    Msg    Message.
  907. //
  908. //    wParam    First message paramter.
  909. //
  910. //    lParam    Second message parameter.
  911. //
  912. //
  913. // Returns
  914. //
  915. //    LRESULT
  916. //
  917. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  918. //
  919. // Ends -------------------------------------------------------------------
  920.  
  921.     {
  922.         HMENU    hMenu;
  923.         HMENU    hMenuPopup;
  924.                 char    szString[MAXHOST + 4];
  925.  
  926.         hMenu = GetMenu(hWnd);
  927.         hMenuPopup = GetSubMenu(hMenu, 0);
  928.  
  929.         GetMenuString(hMenuPopup, wParam, (LPSTR) szString, sizeof(szString), MF_BYCOMMAND);
  930.         CheckMenuItem(hMenuPopup, wParam, MF_CHECKED | MF_BYCOMMAND );
  931.  
  932.         strncpy(szHostName, &szString[3], MAXHOST);
  933.  
  934.         PostMessage(hWnd, WM_COMMAND, IDM_OPEN, 0L);
  935.  
  936.         return(FALSE);
  937.     }
  938.  
  939.  
  940. // Windows function
  941.  
  942.     LONG DoRun(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  943.  
  944. // Summary ----------------------------------------------------------------
  945. //
  946. //    This function is called when command line arguments have been
  947. //    supplied by the user, indicating that the program should be
  948. //    run in automatic mode using the command-line arguments.
  949. //
  950. // Parameters
  951. //
  952. //    hWnd    Handle of the window.
  953. //
  954. //    Msg    Message.
  955. //
  956. //    wParam    First message paramter.
  957. //
  958. //    lParam    Second message parameter.
  959. //
  960. //
  961. // Returns
  962. //
  963. //    LRESULT
  964. //
  965. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  966. //
  967. // Ends -------------------------------------------------------------------
  968.  
  969.     {
  970.         PostMessage(hWnd, WM_COMMAND, IDM_OPEN, 0L);
  971.         return(FALSE);
  972.     }
  973.  
  974.  
  975. // Function
  976.  
  977.     VOID TimeFinish(UINT Err)
  978.  
  979. // Summary ----------------------------------------------------------------
  980. //
  981. // TimeFinish -- invoked when the time operation is complete,
  982. // this function updates the display list & repaints the frame window
  983. // client area.  The menu is re-enabled.
  984. //
  985. // Paramters
  986. //
  987. //    Err    The error if any
  988. //
  989. // Returns
  990. //
  991. //    Nothing
  992. //
  993. // Ends -------------------------------------------------------------------
  994.  
  995.     {
  996.         HMENU    hMenuPopup;
  997.         int    i;
  998.  
  999.         FingerStop();                // tidy up network stuff
  1000.  
  1001.         GetDisplayList(&pLineItems, &nLineItems);
  1002.  
  1003.               SetWinCaption(szHostName);                // set win title to host name
  1004.               PosView(0);                               // position view to top
  1005.               SetScroll();                              // rescale (or delete)
  1006.               Repaint();                                // scrollbar & force a repaint
  1007.  
  1008.         bRunning = FALSE;            // No request pending
  1009.         SetCursor(hCursor = LoadCursor(NULL, IDC_ARROW));
  1010.  
  1011.         if (bCommandLineArgs)
  1012.             SendMessage(hFrame, WM_CLOSE, 0, 0);
  1013.  
  1014.         for ( i = 0; i < MAXHOSTTABLE; i++ )
  1015.         {
  1016.             if ( szHostTable[i][0] != '\0' )
  1017.             {
  1018.                 hMenu = GetMenu(hFrame);
  1019.                 hMenuPopup = GetSubMenu(hMenu, 0);
  1020.  
  1021.                 CheckMenuItem(hMenuPopup, (IDM_HOST1 + i), MF_UNCHECKED | MF_BYCOMMAND);
  1022.                 EnableMenuItem(hMenu, (IDM_HOST1 + i), MF_ENABLED | MF_BYCOMMAND);
  1023.                     }
  1024.         }
  1025.     }
  1026.  
  1027.  
  1028. // Windows function
  1029.  
  1030.     LONG DoMenuExit(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  1031.  
  1032. // Summary ----------------------------------------------------------------
  1033. //
  1034. // DoMenuExit -- allows close via menu item.  Same as sys menu close.
  1035. //
  1036. //
  1037. // Parameters
  1038. //
  1039. //    hWnd    Handle of the window.
  1040. //
  1041. //    Msg    Message.
  1042. //
  1043. //    wParam    First message paramter.
  1044. //
  1045. //    lParam    Second message parameter.
  1046. //
  1047. //
  1048. // Returns
  1049. //
  1050. //    LRESULT
  1051. //
  1052. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  1053. //
  1054. // Ends -------------------------------------------------------------------
  1055.  
  1056.     {
  1057.         SendMessage(hWnd, WM_CLOSE, 0, 0);
  1058.         return(FALSE);
  1059.     }
  1060.  
  1061.  
  1062. // Windows function
  1063.  
  1064.     LRESULT DoMenuAbout(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  1065.  
  1066. // Summary ----------------------------------------------------------------
  1067. //
  1068. // DoMenuAbout -- respond to "About..." menu selection by invoking the
  1069. // "About" dialog box.
  1070. //
  1071. //
  1072. // Parameters
  1073. //
  1074. //    hWnd    Handle of the window.
  1075. //
  1076. //    Msg    Message.
  1077. //
  1078. //    wParam    First message paramter.
  1079. //
  1080. //    lParam    Second message parameter.
  1081. //
  1082. //
  1083. // Returns
  1084. //
  1085. //    LRESULT
  1086. //
  1087. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  1088. //
  1089. // Ends -------------------------------------------------------------------
  1090.  
  1091.     {
  1092.         DLGPROC lpProcAbout;
  1093.  
  1094.         lpProcAbout = (DLGPROC) MakeProcInstance((FARPROC)AboutDlgProc, hInst);
  1095.            DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
  1096.            FreeProcInstance((FARPROC)lpProcAbout);
  1097.  
  1098.         return(FALSE);
  1099.     }
  1100.  
  1101.  
  1102. // Windows Function
  1103.  
  1104.     LRESULT DoMenuHelp(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
  1105.  
  1106. // Summary ----------------------------------------------------------------
  1107. //
  1108. //     Respond to "Help" menu selection by invoking the WinHelp system.
  1109. //
  1110. // Parameters
  1111. //
  1112. //    hWnd    Handle of the window.
  1113. //
  1114. //    Msg    Message.
  1115. //
  1116. //    wParam    First message paramter.
  1117. //
  1118. //    lParam    Second message parameter.
  1119. //
  1120. // Ends -------------------------------------------------------------------
  1121.  
  1122.     {
  1123.  
  1124.         WinHelp(hWnd,szHelpFileName,HELP_INDEX,0L);
  1125.         return(FALSE);
  1126.     }
  1127.  
  1128.  
  1129. // Windows function
  1130.  
  1131.     LONG DoDestroy(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  1132.  
  1133. // Summary ----------------------------------------------------------------
  1134. //
  1135. // DoDestroy -- posts a WM_QUIT message to the task's win queue, which
  1136. // causes the main translate & dispatch loop to exit, and the app to
  1137. // terminate.
  1138. //
  1139. //
  1140. // Parameters
  1141. //
  1142. //    hWnd    Handle of the window.
  1143. //
  1144. //    Msg    Message.
  1145. //
  1146. //    wParam    First message paramter.
  1147. //
  1148. //    lParam    Second message parameter.
  1149. //
  1150. //
  1151. // Returns
  1152. //
  1153. //    LRESULT
  1154. //
  1155. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  1156. //
  1157. // Ends -------------------------------------------------------------------
  1158.  
  1159.     {
  1160.        PostQuitMessage(0);
  1161.        return(FALSE);
  1162.     }
  1163.  
  1164.  
  1165. // Window Function
  1166.  
  1167.     LRESULT DoClose(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  1168.  
  1169. // Summary ----------------------------------------------------------------
  1170. //
  1171. // DoClose -- cleans up display list & tells windows to deallocate
  1172. // our window.  If there is a request pending, then the user is told
  1173. // about this fact.
  1174. //
  1175. //
  1176. // Parameters
  1177. //
  1178. //    hWnd    Handle of the window.
  1179. //
  1180. //    Msg    Message.
  1181. //
  1182. //    wParam    First message paramter.
  1183. //
  1184. //    lParam    Second message parameter.
  1185. //
  1186. //
  1187. // Returns
  1188. //
  1189. //    LRESULT
  1190. //
  1191. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  1192. //
  1193. // Ends -------------------------------------------------------------------
  1194.  
  1195. {
  1196.     char    szBuffer[128];
  1197.     int    result;
  1198.  
  1199.  
  1200.     if (!bCommandLineArgs)
  1201.         {
  1202.         if (( sSocket != INVALID_SOCKET ) || bRunning )
  1203.         {
  1204.             LoadString(hInst, IDS_EXIT_ACTIVE, (LPSTR)szBuffer, sizeof(szBuffer));
  1205.     
  1206.             MessageBeep(MB_ICONEXCLAMATION);
  1207.             result = MessageBox(hWnd, (LPSTR) szBuffer, szAppName,
  1208.                     MB_ICONEXCLAMATION | MB_OKCANCEL | MB_DEFBUTTON2 );
  1209.         }
  1210.         else result = IDYES;
  1211. //        {
  1212. //            LoadString(hInst, IDS_EXITING, (LPSTR)szBuffer, sizeof(szBuffer));
  1213. //             result = MessageBox(hWnd, szBuffer, szAppName,
  1214. //                    MB_ICONQUESTION | MB_YESNO);
  1215. //        }
  1216.  
  1217.         }
  1218.  
  1219.     if ((result == IDYES) || (result == IDOK) || bCommandLineArgs)
  1220.     {
  1221.        SaveHosts();
  1222.        NetClose();
  1223.        FreeLineList(pLineItems);
  1224.        pLineItems = NULL;
  1225.            nLineItems = 0;
  1226.        DestroyWindow(hWnd);        // WM_DESTROY
  1227.     }
  1228.  
  1229.     return(FALSE);
  1230. }
  1231.  
  1232.  
  1233. // Windows Function
  1234.  
  1235.     LRESULT DoCreate(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  1236.  
  1237. // Summary ----------------------------------------------------------------
  1238. //
  1239. //
  1240. // Parameters
  1241. //
  1242. //    hWnd    Handle of the window.
  1243. //
  1244. //    Msg    Message.
  1245. //
  1246. //    wParam    First message paramter.
  1247. //
  1248. //    lParam    Second message parameter.
  1249. //
  1250. //
  1251. // Returns
  1252. //
  1253. //    LRESULT
  1254. //
  1255. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  1256. //
  1257. // Ends -------------------------------------------------------------------
  1258.  
  1259.     {
  1260.         return(FALSE);
  1261.     }
  1262.  
  1263.  
  1264.  
  1265. // Window Function
  1266.  
  1267.     LRESULT DoInitMenuPopup(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  1268.  
  1269. // Summary ----------------------------------------------------------------
  1270. //
  1271. // Called prior to the displaying of the menu popup.  LOWORD(lParam) is the
  1272. // index of the popup in the menu.  This let's us disable the Open menu
  1273. // item of the Host popup menu if there is no valid host name present,
  1274. // or if there is a request pending.
  1275. //
  1276. // Note that the "Setup..." menu item is disabled while the
  1277. // time operation is in progress.  This prevents the user from
  1278. // altering the settings before the first request is finished.  The "Open"
  1279. // menu item is also disabled; NTime is not designed to process simultaneous
  1280. // requests.
  1281. //
  1282. //
  1283. // Parameters
  1284. //
  1285. //    hWnd    Handle of the window.
  1286. //
  1287. //    Msg    Message.
  1288. //
  1289. //    wParam    First message paramter.
  1290. //
  1291. //    lParam    Second message parameter.
  1292. //
  1293. //
  1294. // Returns
  1295. //
  1296. //    LRESULT
  1297. //
  1298. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  1299. //
  1300. // Ends -------------------------------------------------------------------
  1301.  
  1302.     {
  1303.        UINT    wEnable;
  1304.        int    i;
  1305.  
  1306.  
  1307.        if(HIWORD(lParam))
  1308.        {
  1309.          HMENU hSystemMenu;
  1310.  
  1311.          hSystemMenu = GetSystemMenu(hWnd, FALSE);
  1312.          EnableMenuItem(hSystemMenu, SC_SIZE, MF_GRAYED);
  1313.          EnableMenuItem(hSystemMenu, SC_MAXIMIZE, MF_GRAYED);
  1314.        }
  1315.  
  1316.        if (LOWORD(lParam) == 0)
  1317.        {
  1318.         if (( szHostName[0] == '\0' ) || bRunning )
  1319.             wEnable = MF_GRAYED;
  1320.         else
  1321.             wEnable = MF_ENABLED;
  1322.             EnableMenuItem(hMenu, IDM_OPEN, wEnable | MF_BYCOMMAND);
  1323.  
  1324.         wEnable = bRunning ? MF_GRAYED : MF_ENABLED;
  1325.         EnableMenuItem(hMenu, IDM_SETUP, wEnable | MF_BYCOMMAND);
  1326.  
  1327.         /*
  1328.          * Disable the various host entries
  1329.          */
  1330.         for ( i = 0; i < MAXHOSTTABLE; i++ )
  1331.         {
  1332.             if ( szHostTable[i][0] != '\0' )
  1333.             {
  1334.                 EnableMenuItem(hMenu, (IDM_HOST1 + i), wEnable | MF_BYCOMMAND);
  1335.                     }
  1336.         }
  1337.        }
  1338.  
  1339.        return(FALSE);
  1340.     }
  1341.  
  1342.  
  1343. // Window Function
  1344.  
  1345.     LONG DoActivate(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  1346.  
  1347. // Summary ----------------------------------------------------------------
  1348. //
  1349. // DoActivate -- grabs the keyboard focus whenever our deminimized window
  1350. // is activated.  This is so we can respond to VK_HOME, VK_END, etc.
  1351. // virtual keys for scrolling. HIWORD(lParam) is TRUE for minimized, while
  1352. // LOWORD(wParam) is FALSE for activation message.
  1353. // 
  1354. //
  1355. // Parameters
  1356. //
  1357. //    hWnd    Handle of the window.
  1358. //
  1359. //    Msg    Message.
  1360. //
  1361. //    wParam    First message paramter.
  1362. //
  1363. //    lParam    Second message parameter.
  1364. //
  1365. //
  1366. // Returns
  1367. //
  1368. //    LRESULT
  1369. //
  1370. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  1371. //
  1372. // Ends -------------------------------------------------------------------
  1373.  
  1374.     {
  1375.         if (!HIWORD(lParam) && LOWORD(wParam))
  1376.                   SetFocus(hFrame);
  1377.  
  1378.         return FALSE;
  1379.     }
  1380.  
  1381.  
  1382. // Function
  1383.  
  1384.     LONG DoMouseMove(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  1385.  
  1386. // Summary ----------------------------------------------------------------
  1387. //
  1388. // DoMouseMove -- resets the cursor back to the current cursor (either
  1389. // a wait, or normal cursor) because Windows will otherwise redraw it
  1390. // using the window's class.
  1391. //
  1392. // Parameters
  1393. //
  1394. //    hWnd    Handle of the window.
  1395. //
  1396. //    Msg    Message.
  1397. //
  1398. //    wParam    First message paramter.
  1399. //
  1400. //    lParam    Second message parameter.
  1401. //
  1402. //
  1403. // Returns
  1404. //
  1405. //    LRESULT
  1406. //
  1407. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  1408. //
  1409. // Ends -------------------------------------------------------------------
  1410.  
  1411.     {
  1412.         SetCursor(hCursor);
  1413.         return(FALSE);
  1414.     }
  1415.  
  1416.  
  1417. // Function
  1418.  
  1419.     VOID PosView(int nlines)
  1420.  
  1421. // Summary ----------------------------------------------------------------
  1422. //
  1423. // PosView -- repositions the view relative to the top of the display list.
  1424. // The view is a logical "window" onto the display list.  The frame window's
  1425. // client area is painted with the view's contents.
  1426. //
  1427. //
  1428. // Paramters
  1429. //
  1430. //    nlines    The position in the display
  1431. //
  1432. // Returns
  1433. //
  1434. //    Nothing.
  1435. //
  1436. // Ends -------------------------------------------------------------------
  1437.  
  1438.     {
  1439.        HLOCAL    pline;
  1440.        HLOCAL    ptemp;
  1441.        LINEITEM    *p;
  1442.        int i;
  1443.  
  1444.        pline = pLineItems;              // root of LINEITEM list
  1445.  
  1446.        for (i = 0; i < nlines; i++)
  1447.        {
  1448.           if (pline == NULL)
  1449.          break;
  1450.           else
  1451.           {
  1452.          p = LocalLock(pline);
  1453.          if ( p != NULL )
  1454.              {
  1455.              ptemp = p->next;
  1456.              LocalUnlock(pline);
  1457.              pline = ptemp;
  1458.          } else pline = NULL;
  1459.           }
  1460.        }
  1461.  
  1462.        pTopLine = pline;                // ptr to LINEITEM in topmost view line
  1463.        nTopLine =+ nlines;              // offset of topmost view line
  1464.     }
  1465.  
  1466.  
  1467. // Window Function
  1468.  
  1469.     LRESULT DoPaint(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  1470.  
  1471. // Summary ----------------------------------------------------------------
  1472. //
  1473. // DoPaint -- Paint the client area with the contents of the view.
  1474. //
  1475. // Parameters
  1476. //
  1477. //    hWnd    Handle of the window.
  1478. //
  1479. //    Msg    Message.
  1480. //
  1481. //    wParam    First message paramter.
  1482. //
  1483. //    lParam    Second message parameter.
  1484. //
  1485. //
  1486. // Returns
  1487. //
  1488. //    LRESULT
  1489. //
  1490. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  1491. //
  1492. // Ends -------------------------------------------------------------------
  1493.  
  1494.     {
  1495.        HDC hdc;                   // scratch device context
  1496.        TEXTMETRIC    tm;
  1497.        PAINTSTRUCT ps;            // scratch paint structure
  1498.        HLOCAL    pline;        // pts to topmost displayable LINEITEM
  1499.        HLOCAL    hLocal;
  1500.        int i;
  1501.        int CharY;
  1502.  
  1503.        pline = pTopLine;
  1504.  
  1505.        hdc = BeginPaint(hWnd, &ps);
  1506.        SelectObject(hdc, GetStockObject(ANSI_VAR_FONT));
  1507.        GetTextMetrics(hdc, &tm);
  1508.        CharY = tm.tmHeight + tm.tmExternalLeading;
  1509.     //   CharX = tm.tmAveCharWidth;
  1510. #ifdef USE_CTL3D
  1511.        SetTextColor(hdc, GetSysColor(COLOR_BTNHIGHLIGHT));
  1512.        SetBkColor(hdc, GetSysColor(COLOR_BTNSHADOW));
  1513. #else
  1514.        SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
  1515.        SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
  1516. #endif
  1517.  
  1518.        for (i = 0; i <= nClientLines; i++)
  1519.        {
  1520.           if (pline != NULL)
  1521.           {
  1522.          LINEITEM    *p;
  1523.          char    *sztext;
  1524.  
  1525.          p = LocalLock(pline);
  1526.          if ( p != NULL )
  1527.          {
  1528.             hLocal = p->next;
  1529.             if (p->hText != NULL)
  1530.                     {
  1531.                 sztext = LocalLock(p->hText);
  1532.                 if (sztext != NULL)
  1533.                     {
  1534.                      TextOut(hdc, 0, i * CharY, (LPSTR)sztext, p->len);
  1535.                      LocalUnlock(p->hText);
  1536.                 }
  1537.                     }
  1538.             LocalUnlock(pline);
  1539.             pline = hLocal;
  1540.          }
  1541.           } else // end of display list...
  1542.        break;
  1543.        } // for
  1544.  
  1545.        EndPaint(hWnd, &ps);
  1546.        return(FALSE);
  1547.     }
  1548.  
  1549.  
  1550. // Function
  1551.  
  1552.     VOID Repaint(VOID)
  1553.  
  1554. // Summary ----------------------------------------------------------------
  1555. //
  1556. // Repaint -- force refresh of client window.
  1557. // 
  1558. // Returns
  1559. //
  1560. //    Nothing.
  1561. //
  1562. // Ends -------------------------------------------------------------------
  1563.  
  1564.     {
  1565.         InvalidateRect(hFrame, NULL, TRUE);
  1566.     }
  1567.  
  1568.  
  1569. // Function
  1570.  
  1571.     VOID SetScroll(VOID)
  1572.  
  1573. // Summary ----------------------------------------------------------------
  1574. //
  1575. // SetScroll -- sets the vertical scroll range to the length of the display
  1576. // list.  The Scrollbar disappears when the list fits within the view.
  1577. //
  1578. // Returns
  1579. //
  1580. //    Nothing.
  1581. //
  1582. // Ends -------------------------------------------------------------------
  1583.  
  1584. {
  1585.    if (hFrame != NULL)
  1586.    {
  1587.        if (nLineItems > nClientLines)
  1588.           SetScrollRange(hFrame, SB_VERT, 0, nLineItems - nClientLines, FALSE);
  1589.        else
  1590.           SetScrollRange(hFrame, SB_VERT, 0, 0, FALSE);
  1591.  
  1592.        SetScrollPos(hFrame, SB_VERT, nTopLine, TRUE);
  1593.    }
  1594. }
  1595.  
  1596.  
  1597. // number of lines below the bottom of the view.
  1598. #define NLINESBELOW (nLineItems - nTopLine - nClientLines)
  1599.  
  1600. // Windows Function
  1601.  
  1602.     LRESULT DoVScroll(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  1603.  
  1604. // Summary ----------------------------------------------------------------
  1605. //
  1606. // DoVScroll -- process WM_VSCROLL & WM_KEYDOWN for main window.
  1607. //
  1608. // Parameters
  1609. //
  1610. //    hWnd    Handle of the window.
  1611. //
  1612. //    Msg    Message.
  1613. //
  1614. //    wParam    First message paramter.
  1615. //
  1616. //    lParam    Second message parameter.
  1617. //
  1618. //
  1619. // Returns
  1620. //
  1621. //    LRESULT
  1622. //
  1623. //    Returns FALSE of the dialog message was handled, otherwise TRUE.
  1624. //
  1625. // Ends -------------------------------------------------------------------
  1626.  
  1627. {
  1628.    switch (LOWORD(wParam))
  1629.    {
  1630.       case VK_HOME:
  1631.       case SB_TOP:
  1632.          if (nTopLine > 0)
  1633.             RelScroll(hWnd, -nTopLine);
  1634.          break;
  1635.  
  1636.       case VK_END:
  1637.       case SB_BOTTOM:
  1638.          if (NLINESBELOW)
  1639.             RelScroll(hWnd, NLINESBELOW);
  1640.      break;
  1641.  
  1642.       case VK_PRIOR:
  1643.       case SB_PAGEUP:
  1644.          if (nTopLine > 0)
  1645.             RelScroll(hWnd, max(-nClientLines, -nTopLine));
  1646.          break;
  1647.  
  1648.       case VK_NEXT:
  1649.       case SB_PAGEDOWN:
  1650.          if (NLINESBELOW)
  1651.             RelScroll(hWnd, min(nClientLines, NLINESBELOW));
  1652.          break;
  1653.  
  1654.       case VK_UP:
  1655.       case SB_LINEUP:
  1656.          if (nTopLine > 0)
  1657.             RelScroll(hWnd, -1);
  1658.          break;
  1659.  
  1660.       case VK_DOWN:
  1661.       case SB_LINEDOWN:
  1662.          if (NLINESBELOW)
  1663.             RelScroll(hWnd, 1);
  1664.          break;
  1665.  
  1666.       case SB_THUMBTRACK:
  1667.          RelScroll(hWnd, THUMBPOS - nTopLine);
  1668.      break;
  1669.    }
  1670.  
  1671.    SetScrollPos(hFrame, SB_VERT, nTopLine, TRUE);
  1672.    return(FALSE);
  1673. }
  1674.  
  1675.  
  1676. // Function
  1677.  
  1678.     VOID RelScroll(HWND hWnd, int nlines)
  1679.  
  1680. // Summary ----------------------------------------------------------------
  1681. //
  1682. // RelScroll -- scroll up/down nlines from present position
  1683. //
  1684. //
  1685. // Parameters
  1686. //
  1687. //    hWnd    Handle of the window
  1688. //
  1689. //    nlines    The number of lines to scroll
  1690. //
  1691. // Returns
  1692. //
  1693. //    Nothing.
  1694. //
  1695. // Ends -------------------------------------------------------------------
  1696.  
  1697. {
  1698.     PosView(nTopLine + nlines);
  1699.     ScrollWindow(hWnd, 0, -nlines * CharY, NULL, NULL);
  1700.     UpdateWindow(hWnd);
  1701. }
  1702.  
  1703.  
  1704. // Window Function
  1705.  
  1706.     LRESULT DoSize(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  1707.  
  1708. // Summary ----------------------------------------------------------------
  1709. //
  1710. // DoSize -- respond to WM_SIZE by recalculating the number of text lines
  1711. // in the main window's client area.
  1712. //
  1713. //
  1714. // Parameters
  1715. //
  1716. //    hWnd    Handle of the window.
  1717. //
  1718. //    Msg    Message.
  1719. //
  1720. //    wParam    First message paramter.
  1721. //
  1722. //    lParam    Second message parameter.
  1723. //
  1724. //
  1725. // Returns
  1726. //
  1727. //    LRESULT
  1728. //
  1729. //    Returns FALSE of the dialog message was handled, otherwise TURE.
  1730. //
  1731. // Ends -------------------------------------------------------------------
  1732.  
  1733. {
  1734.     HDC    hdc;
  1735.     TEXTMETRIC    tm;
  1736.  
  1737.  
  1738.     hdc = GetDC(hFrame);
  1739.     SelectObject(hdc, GetStockObject(ANSI_VAR_FONT));
  1740.     GetTextMetrics(hdc, &tm);
  1741.     CharY = tm.tmHeight + tm.tmExternalLeading;
  1742.     CharX = tm.tmAveCharWidth;
  1743.     ReleaseDC(hFrame, hdc);
  1744.  
  1745.     nClientLines = HIWORD(lParam) / CharY;
  1746.     PosView(0);
  1747.     SetScroll();
  1748.  
  1749.     return(FALSE);
  1750. }
  1751.  
  1752.  
  1753. // Function
  1754.  
  1755.     VOID SetWinCaption(PSTR szString)
  1756.  
  1757. // Summary ----------------------------------------------------------------
  1758. //
  1759. // SetWinCaption -- set the frame window caption according to last
  1760. // host fingered.
  1761. //
  1762. // Parameters
  1763. //
  1764. //    szString    The caption string
  1765. //
  1766. // Returns
  1767. //
  1768. //    Nothing.
  1769. //
  1770. // Ends -------------------------------------------------------------------
  1771.  
  1772. {
  1773.    char szcaption[128];
  1774.  
  1775.    strcpy(szcaption, szAppName);
  1776.    if ( szString != NULL )
  1777.    {
  1778.        strcat(szcaption, " - ");
  1779.            if ( strlen(szString) + strlen(szcaption) < sizeof(szcaption))
  1780.            strcat(szcaption, szString);
  1781.    }
  1782.  
  1783.    SetWindowText(hFrame, (LPSTR)szcaption);
  1784. }
  1785.  
  1786.  
  1787. #define MAXLINE    128
  1788. // Function
  1789.  
  1790.     PSTR WSErrorString(UINT ResourceID)
  1791.  
  1792. // Summary ----------------------------------------------------------------
  1793. //
  1794. //    Translates WinSock error number into an appropriate string.
  1795. //
  1796. //
  1797. // Parameters
  1798. //
  1799. //      ResourceID
  1800. //
  1801. //    The resource number/WS error number of the string to be printed.
  1802. //
  1803. // Return
  1804. //
  1805. //    PSTR    A pointer to the string that is to be printed.
  1806. //
  1807. // Ends -------------------------------------------------------------------
  1808.  
  1809.     {
  1810.         int i;
  1811.         static char szBuffer[MAXLINE];
  1812.  
  1813.         if ( !LoadString(hInst, ResourceID, (LPSTR)szBuffer, MAXLINE) )
  1814.             wsprintf( (LPSTR) szBuffer, "Windows Sockets error %d", ResourceID );
  1815.  
  1816.         return(szBuffer);
  1817.     }
  1818.  
  1819.  
  1820. // Function
  1821.  
  1822.     VOID ReportWSError(int Err)
  1823.  
  1824. // Summary ----------------------------------------------------------------
  1825. //
  1826. // ReportWSError -- prompt user with a windows sockets error message.
  1827. //
  1828. //
  1829. // Parameters
  1830. //
  1831. //    Err    The WinSock error.
  1832. //
  1833. // Returns
  1834. //
  1835. //    Nothing.
  1836. //
  1837. // Ends -------------------------------------------------------------------
  1838.  
  1839.     {
  1840.        int i;
  1841.        char szerr[128];
  1842.  
  1843.  
  1844.        strcpy(szerr, WSErrorString(Err));
  1845.        MessageBeep( MB_ICONSTOP );
  1846.        MessageBox(hFrame, (LPSTR)szerr, (LPSTR)szAppName, MB_ICONSTOP | MB_OK);
  1847.     }
  1848.  
  1849.  
  1850. // Function
  1851.  
  1852.     VOID ReportFingerErr(UINT Err, int nWSErr)
  1853.  
  1854. // Summary ----------------------------------------------------------------
  1855. //
  1856. // ReportFingerErr -- prompt user with a ntime specific error
  1857. //
  1858. //
  1859. // Parameters
  1860. //
  1861. //    Err    The ntime error message
  1862. //
  1863. //    nWSErr    The WinSock error message
  1864. //
  1865. // Returns
  1866. //
  1867. //    Nothing.
  1868. //
  1869. // Ends -------------------------------------------------------------------
  1870.  
  1871.     {
  1872.        int i;
  1873.        char szerr[128];
  1874.        HDC    hdc;
  1875.  
  1876.  
  1877.        hdc = GetDC(hFrame);
  1878.        strcpy(szerr, WSErrorString(Err));
  1879.        WinPrintf(hdc, -1, 0, "%s", (LPSTR) szerr);
  1880.  
  1881.        if (nWSErr > 0)
  1882.        {
  1883.         strcat(szerr, "\n");
  1884.         strcat(szerr, WSErrorString(nWSErr));
  1885.        }
  1886.        WinPrintf(hdc, -1, 0, "%s", (LPSTR) WSErrorString(nWSErr));
  1887.        ReleaseDC(hFrame, hdc);
  1888.  
  1889.        MessageBeep( MB_ICONSTOP );
  1890.        MessageBox(hFrame, (LPSTR)szerr, (LPSTR)szAppName, MB_ICONSTOP | MB_OK);
  1891.  
  1892.     }
  1893.  
  1894.  
  1895. // Dialog callback function
  1896.  
  1897.     BOOL CALLBACK HostDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
  1898.  
  1899. // Summary ----------------------------------------------------------------
  1900. //
  1901. //     HostDlgProc -- dialog box proc for "setup dialog".
  1902. //     This box queries user for a host name in response to the user's
  1903. //     selection of the "Setup..." main menu item.
  1904. //
  1905. //
  1906. // Parameters
  1907. //
  1908. //    hWnd    Handle of the window.
  1909. //
  1910. //    Msg    Message.
  1911. //
  1912. //    wParam    First message paramter.
  1913. //
  1914. //    lParam    Second message parameter.
  1915. //
  1916. //
  1917. // Returns
  1918. //
  1919. //    BOOL
  1920. //
  1921. //    Returns TRUE of the dialog message was handled, otherwise FALSE.
  1922. //
  1923. // Ends -------------------------------------------------------------------
  1924.  
  1925. {
  1926.    BOOL    fTranslated;
  1927.    char    string[25];
  1928.  
  1929.  
  1930.    switch(Msg)
  1931.    {
  1932.       case WM_INITDIALOG:
  1933.          SetDlgItemText(hDlg, IDC_HOSTNAME, szHostName);
  1934.      SetDlgItemText(hDlg, IDC_USER, szUser);
  1935.  
  1936.      SetDlgItemInt(hDlg, IDC_UDPRETRY, nUDPNumberRetry, FALSE);
  1937.      SetDlgItemInt(hDlg, IDC_UDPTIME, nUDPTimeOutValue, FALSE);
  1938.  
  1939.      bShouldUseTCP = GetPrivateProfileInt( SECTION_MAIN
  1940.                     , ENTRY_ONLYTCP
  1941.                     , TRUE
  1942.                     , (LPCSTR) INI_FILE);
  1943.      CheckDlgButton(hDlg, IDC_USETCP, bShouldUseTCP);
  1944.  
  1945.      bUpdateSystemTime = GetPrivateProfileInt( SECTION_MAIN
  1946.                     , ENTRY_DOUPDATE
  1947.                     , FALSE
  1948.                     , (LPCSTR) INI_FILE);
  1949.      CheckDlgButton(hDlg, IDC_UPDATE, bUpdateSystemTime);
  1950.  
  1951.      EnableWindow(GetDlgItem(hDlg, IDB_CONNECT), strlen(szHostName));
  1952.      EnableWindow(GetDlgItem(hDlg, IDC_UDPRETRY), !bShouldUseTCP);
  1953.      EnableWindow(GetDlgItem(hDlg, IDC_UDPTIME), !bShouldUseTCP);
  1954.      EnableWindow(GetDlgItem(hDlg, IDT_UDP1), !bShouldUseTCP);
  1955.      EnableWindow(GetDlgItem(hDlg, IDT_UDP2), !bShouldUseTCP);
  1956.  
  1957.      GetPrivateProfileString( SECTION_MAIN
  1958.                 , ENTRY_DEFAULTHOST
  1959.                 , (LPSTR) szHostName
  1960.                                 , (LPSTR) szHostName
  1961.                 , sizeof(szHostName)
  1962.                 , INI_FILE );
  1963.      return TRUE;
  1964.  
  1965.       case WM_SYSCOLORCHANGE:
  1966. #ifdef USE_CTL3D
  1967.      Ctl3dColorChange();
  1968. #endif
  1969.      return TRUE;
  1970.  
  1971.  
  1972.       case WM_COMMAND:
  1973.          switch(wParam)
  1974.      {
  1975.             case IDB_CONNECT:
  1976.             case IDOK:
  1977.                 GetDlgItemText(hDlg, IDC_HOSTNAME, szHostName, MAXHOST);
  1978.         GetDlgItemText(hDlg, IDC_USER, szUser, MAXUSER);
  1979.         nUDPTimeOutValue = GetDlgItemInt(hDlg, IDC_UDPTIME, (BOOL FAR *) &fTranslated, FALSE);
  1980.         if ( !fTranslated )
  1981.         {
  1982.             nUDPTimeOutValue = DEFAULT_UDPTIME;
  1983.              SetDlgItemInt(hDlg, IDC_UDPTIME, nUDPTimeOutValue, FALSE);
  1984.                 }
  1985.  
  1986.         nUDPNumberRetry = GetDlgItemInt(hDlg, IDC_UDPRETRY, (BOOL FAR *) &fTranslated, FALSE);
  1987.         if ( !fTranslated )
  1988.         {    nUDPNumberRetry = DEFAULT_UDPRETRY;
  1989.             SetDlgItemInt(hDlg, IDC_UDPRETRY, nUDPNumberRetry, FALSE);
  1990.         }
  1991.  
  1992.         bShouldUseTCP = IsDlgButtonChecked(hDlg, IDC_USETCP);
  1993.         if ( bShouldUseTCP )
  1994.         {
  1995.             WritePrivateProfileString(SECTION_MAIN
  1996.                 , ENTRY_ONLYTCP
  1997.                 , (LPSTR) "1"
  1998.                 , (LPSTR) INI_FILE);
  1999.         } else {
  2000.             WritePrivateProfileString(SECTION_MAIN
  2001.                 , ENTRY_ONLYTCP
  2002.                 , (LPSTR) "0"
  2003.                 , (LPSTR) INI_FILE);
  2004.         }
  2005.  
  2006.         bUpdateSystemTime = IsDlgButtonChecked(hDlg, IDC_UPDATE);
  2007.         if ( bUpdateSystemTime )
  2008.         {
  2009.             WritePrivateProfileString(SECTION_MAIN
  2010.                 , ENTRY_DOUPDATE
  2011.                 , (LPSTR) "1"
  2012.                 , (LPSTR) INI_FILE);
  2013.         } else {
  2014.             WritePrivateProfileString(SECTION_MAIN
  2015.                 , ENTRY_DOUPDATE
  2016.                 , (LPSTR) "0"
  2017.                 , (LPSTR) INI_FILE);
  2018.         }
  2019.         WritePrivateProfileString(SECTION_MAIN
  2020.                 , ENTRY_DEFAULTHOST
  2021.                 , (LPSTR) szHostName
  2022.                 , (LPSTR) INI_FILE);
  2023.  
  2024.         WritePrivateProfileString(SECTION_MAIN
  2025.                 , ENTRY_TIMECORR
  2026.                 , (LPSTR) szUser
  2027.                 , (LPSTR) INI_FILE);
  2028.  
  2029.         GetDlgItemText(hDlg, IDC_UDPRETRY, (LPSTR)string, sizeof(string));
  2030.         WritePrivateProfileString(SECTION_MAIN
  2031.                 , ENTRY_UDPRETRY
  2032.                 , (LPSTR) string
  2033.                 , (LPSTR) INI_FILE);  
  2034.  
  2035.         GetDlgItemText(hDlg, IDC_UDPTIME, (LPSTR)string, sizeof(string));
  2036.         WritePrivateProfileString(SECTION_MAIN
  2037.                 , ENTRY_UDPTIMEOUT
  2038.                 , (LPSTR) string
  2039.                 , (LPSTR) INI_FILE);  
  2040.  
  2041.            EndDialog(hDlg, wParam);
  2042.            return TRUE;
  2043.  
  2044.             case IDCANCEL:
  2045.            EndDialog(hDlg, IDCANCEL);
  2046.            return TRUE;
  2047.  
  2048.         case IDC_USETCP:
  2049.         if (SendMessage(GetDlgItem(hDlg,IDC_USETCP), BM_GETCHECK, 0, 0L))
  2050.         {
  2051.              EnableWindow(GetDlgItem(hDlg, IDC_UDPRETRY), FALSE);
  2052.              EnableWindow(GetDlgItem(hDlg, IDC_UDPTIME), FALSE);
  2053.              EnableWindow(GetDlgItem(hDlg, IDT_UDP1), FALSE);
  2054.              EnableWindow(GetDlgItem(hDlg, IDT_UDP2), FALSE);
  2055.         } else {
  2056.              EnableWindow(GetDlgItem(hDlg, IDC_UDPRETRY), TRUE);
  2057.              EnableWindow(GetDlgItem(hDlg, IDC_UDPTIME), TRUE);
  2058.              EnableWindow(GetDlgItem(hDlg, IDT_UDP1), TRUE);
  2059.              EnableWindow(GetDlgItem(hDlg, IDT_UDP2), TRUE);
  2060.         }
  2061.                 return TRUE;
  2062.  
  2063.         case IDC_HOSTNAME:
  2064.            if (HIWORD(lParam) == EN_CHANGE)
  2065.             EnableWindow(GetDlgItem(hDlg, IDB_CONNECT),
  2066.                 (BOOL) SendMessage((HWND) LOWORD(lParam), WM_GETTEXTLENGTH, 0, 0L));
  2067.                return TRUE;
  2068.          }
  2069.          break;
  2070.    }
  2071.  
  2072.    return FALSE;
  2073. }
  2074.  
  2075.  
  2076. //
  2077. // AboutDlgProc -- callback for the "About" dialog box
  2078. //
  2079. BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
  2080.  
  2081. // Summary ----------------------------------------------------------------
  2082. //
  2083. //
  2084. // Parameters
  2085. //
  2086. //    hWnd    Handle of the window.
  2087. //
  2088. //    Msg    Message.
  2089. //
  2090. //    wParam    First message paramter.
  2091. //
  2092. //    lParam    Second message parameter.
  2093. //
  2094. //
  2095. // Returns
  2096. //
  2097. //    BOOL
  2098. //
  2099. //    Returns TRUE of the dialog message was handled, otherwise FALSE.
  2100. //
  2101. // Ends -------------------------------------------------------------------
  2102.  
  2103.     {
  2104.  
  2105.         switch(Msg)
  2106.         {
  2107.             default: return FALSE;
  2108.  
  2109.             case WM_INITDIALOG:
  2110.                             return TRUE;
  2111.  
  2112.             case WM_SYSCOLORCHANGE:
  2113. #ifdef USE_CTL3D
  2114.                 Ctl3dColorChange();
  2115. #endif
  2116.                 break;
  2117.  
  2118.             case WM_COMMAND:
  2119.             {
  2120.                 switch(wParam)
  2121.                 {
  2122.                 case IDOK:
  2123.                 case IDCANCEL:
  2124.                     EndDialog(hDlg, TRUE);
  2125.                     break;
  2126.  
  2127.                 default : return FALSE;
  2128.                 }
  2129.             } // WM_COMMAND
  2130.         }
  2131.         return TRUE;
  2132.     }
  2133.  
  2134.  
  2135. #define MAX_PRINTF_OUTPUT    128
  2136. /*******************************************************************
  2137.  
  2138.     NAME:       WinPrintf
  2139.  
  2140.     SYNOPSIS:   A printf-like interface to TextOut
  2141.  
  2142.     ENTRY:      hdc - Display context for the text.
  2143.  
  2144.                 row - Starting row (* tmHeight).
  2145.  
  2146.                 col - Starting column (* tmAveCharWidth).
  2147.  
  2148.                 pszFormat - A printf-like format string.
  2149.  
  2150.                 ... - Other printf-like arguments as needed.
  2151.  
  2152. ********************************************************************/
  2153. VOID WinPrintf( HDC   hdc, int row, UINT   col, LPSTR pszFormat, ... )
  2154. {
  2155.     TEXTMETRIC    tm;
  2156.     int    CharX, CharY;
  2157.     char szOutput[MAX_PRINTF_OUTPUT];
  2158.     int  cbOutput;
  2159.     va_list ArgList;
  2160.     static int prevrow;
  2161.  
  2162.     va_start( ArgList, pszFormat );
  2163.     cbOutput = wvsprintf( szOutput, pszFormat, ArgList );
  2164.     va_end( ArgList );
  2165.  
  2166.     SelectObject(hdc, GetStockObject(ANSI_VAR_FONT));
  2167.     GetTextMetrics(hdc, &tm);
  2168.     CharY = tm.tmHeight + tm.tmExternalLeading;
  2169.     CharX = tm.tmAveCharWidth;
  2170. #ifdef USE_CTL3D
  2171.     SetTextColor(hdc, GetSysColor(COLOR_BTNHIGHLIGHT));
  2172.     SetBkColor(hdc, GetSysColor(COLOR_BTNSHADOW));
  2173. #else
  2174.     SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
  2175.     SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
  2176. #endif
  2177.  
  2178.     if ( row < 0 )
  2179.     {
  2180.         prevrow++;
  2181.     row = prevrow;
  2182.     } else { prevrow = row; }
  2183.  
  2184.     TextOut( hdc,
  2185.          col * CharX,
  2186.          row * CharY,
  2187.              szOutput,
  2188.          cbOutput );
  2189.  
  2190.  
  2191.     if (bCommandLineArgs)
  2192.         SetWinCaption(szOutput);
  2193.  
  2194.     strcat(szOutput, "\r\n");
  2195.     PushChars(szOutput, strlen(szOutput));
  2196.  
  2197.     GetDisplayList(&pLineItems, &nLineItems); // list and get new one
  2198.  
  2199.     PosView(0);                               // position view to top
  2200.     SetScroll();                              // rescale (or delete)
  2201. //    Repaint();                                // scrollbar & force a repaint
  2202.  
  2203.  
  2204. }   // WinPrintf
  2205.  
  2206.  
  2207.  
  2208.  
  2209.  
  2210. // Function
  2211.  
  2212.     void MakeHelpPathName(HINSTANCE hInst, LPSTR szFileName)
  2213.  
  2214. // Summary ----------------------------------------------------------------
  2215. //
  2216. //    This function will attempt to generate the full path name of
  2217. //    the help file from the path of the executable.  It assumes that
  2218. //    the .HLP file is in the same directory as the executable.
  2219. //
  2220. // Parameters
  2221. //
  2222. //
  2223. //    hInst
  2224. //
  2225. //    Identifies the module or the instance of the program.
  2226. //
  2227. //    szFileName
  2228. //
  2229. //    The buffer to accept the name of the help file.
  2230. //
  2231. //
  2232. // Return
  2233. //
  2234. //    nothing
  2235. //
  2236. // Ends -------------------------------------------------------------------
  2237.  
  2238.     {
  2239.         LPSTR   lpcFileName;
  2240.         int     nFileNameLen;
  2241.         const char    szHelpFile[] = HELP_FILE;
  2242.  
  2243.         nFileNameLen = GetModuleFileName(hInst, szFileName, MAX_PATH);
  2244.         lpcFileName = szFileName + nFileNameLen;
  2245.  
  2246.         /* Start looking in reverse for a backslash or full colon */
  2247.         while (lpcFileName > szFileName)
  2248.         {
  2249.             if ((*lpcFileName == '\\') || (*lpcFileName == ':'))
  2250.             {
  2251.                 *(++lpcFileName) = '\0';
  2252.         break;
  2253.             }
  2254.             nFileNameLen--;
  2255.             lpcFileName--;
  2256.         }
  2257.  
  2258.         /* Is there enough room to append the help file name? */
  2259.         if ( ( nFileNameLen + lstrlen((LPSTR)szHelpFile) ) < MAX_PATH)
  2260.         {
  2261.             lstrcat( szFileName, (LPSTR) szHelpFile );
  2262.         }
  2263.         else
  2264.         {
  2265.             lstrcat( szFileName, "?" );
  2266.         }
  2267.     
  2268.         return;
  2269.     }
  2270.