home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 15 / CD_ASCQ_15_070894.iso / vrac / wsftp2.zip / WS_MAIN.C < prev    next >
C/C++ Source or Header  |  1994-06-03  |  47KB  |  1,431 lines

  1. /***************************************************************************
  2.   Windows Sockets FTP Client Application
  3.  
  4.   Written by:
  5.       John A. Junod             Internet: <junodj@gordon-emh2.army.mil>
  6.       267 Hillwood Street                 <zj8549@trotter.usma.edu>
  7.       Martinez, GA 30907      Compuserve: 72321,366 
  8.  
  9.   This program executable and all source code is released into the public
  10.   domain.  It would be nice (but is not required) to give me a little 
  11.   credit for any use of this code.
  12.  
  13.   The user interface for this FTP client is designed with the novice FTP user
  14.   in mind.  Usage should (??) be obvious with the possible exception of the
  15.   the transfer mode; ascii, binary or l8.  All controls are standard Windows
  16.   controls.
  17.  
  18.   My development and testing was all completed at home on two 386 PC's using
  19.   the Trumpet Windows Sockets DLL Alpha 15 with NCSA Telnet and WinQVT/Net 2.6
  20.   and 3.9 as the remote host.  Source code may be compiled with Borland C++
  21.   in large mode.
  22.  
  23.   Some code concepts and names are based on code that is copyright by the
  24.   Regents of the University of California or code published in UNIX Network
  25.   Programming by W. Richard Stevens or code in WATTCP or other public sources.
  26.   The rest is based on my knowledge of Windows programming and my 
  27.   interpretation of RFC 969 and the Windows Sockets API version 1.1.
  28.  
  29.   THE INFORMATION AND CODE PROVIDED IS PROVIDED AS IS WITHOUT WARRANTY 
  30.   OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
  31.   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
  32.   PURPOSE. IN NO EVENT SHALL JOHN A. JUNOD BE LIABLE FOR ANY DAMAGES 
  33.   WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS 
  34.   OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF JOHN A. JUNOD HAS BEEN 
  35.   ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  36.  
  37. *****************************************************************************/
  38. // modified extensively by l kahn for windows nt and multi threading
  39.  
  40. //----------------------
  41. #include "ws_glob.h"
  42. #include "WS_ftp.H"
  43. #include "version.h"
  44. //----------------------
  45. #include <stdarg.h>
  46. #include <ctype.h>
  47. #include <shellapi.h>
  48. #include <stdlib.h>
  49.  
  50.  // lgk new debugging variable
  51. BOOLEAN DEBUGGING_ON = FALSE;
  52.  
  53. int selects[256];
  54. extern char szInitDir[];
  55. HBRUSH hbrGray1,hbrGray2,hbrWhite;
  56. extern HWND hWndDbg;
  57. BOOLEAN connectpending = FALSE;
  58.  
  59. // lgk new stuff for multiple threads
  60. extern int check_command_line();
  61. CRITICAL_SECTION busy_variable;
  62. BOOLEAN busy = FALSE;
  63. HWND globalhWnd;
  64. WPARAM globalwParam;
  65. DWORD threadid;
  66. HANDLE threadhandle;
  67.  
  68. #ifndef USEASYNC
  69. SubProcessAsync(HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam)
  70. {
  71.   return(FALSE);
  72. }
  73. #endif
  74.  
  75. // lgk new routine to get the local search string
  76.  
  77. extern char *localsearchstring();
  78.  
  79. int VerifyDelete(LPSTR fname)
  80. {
  81.   wsprintf(szDlgPrompt,"Are you sure you want to delete \"%s\"?",fname);
  82.   return(MessageBox(hWndMain,szDlgPrompt,"Verify Deletion",MB_YESNO)==IDYES);
  83. }
  84.  
  85. void MakeLower(LPSTR str) {
  86.   while(*str) {
  87.     *str=tolower(*str);
  88.     str++;
  89.   }
  90. }
  91. // lgk function to set busy variable so that we don't get collisions
  92. void set_busy(invalue)
  93.  BOOLEAN invalue;
  94.    {
  95.      EnterCriticalSection(&busy_variable);
  96.      busy = invalue;
  97.      LeaveCriticalSection(&busy_variable);
  98.    }
  99.    
  100. BOOLEAN check_busy()
  101.    {
  102.      BOOLEAN rvalue;
  103.       
  104.      EnterCriticalSection(&busy_variable);
  105.      rvalue = busy;
  106.      LeaveCriticalSection(&busy_variable);
  107.      return rvalue;
  108.    }
  109.  
  110.   /* ------------------------------------------------------------------------------------------- */
  111.  
  112. // lgk new functions that will run in a thread
  113.  
  114. DWORD local_to_remote_fx()
  115. {
  116.     
  117.   int nIndex,nRC;
  118.  
  119.             u_char tmp[80];
  120.             char localname[220];
  121.             char remotename[80];
  122.             int count;
  123.  
  124.             count=SendMessage(hLbxLFiles,
  125.                       LB_GETSELITEMS,256,(LPARAM)(int far *)selects);
  126.             if(count>0 && count!=LB_ERR)
  127.               {
  128.                EnableWindow(hBtnAbort,TRUE);
  129.              for(nIndex=0;nIndex<count;nIndex++)
  130.                  {
  131.                 SendMessage(hLbxLFiles,LB_GETTEXT,selects[nIndex],
  132.                                  (LONG)localname);
  133.                 lstrcpy(remotename,localname);
  134.                 if(bInteractive) 
  135.                   StdInput(remotename,"Enter remote file name for %s:",localname);
  136.                 wsprintf(tmp,"sending %s as %s (%u of %u)",localname,remotename,nIndex+1,count);
  137.                 SendMessage(hTxtStatus,WM_SETTEXT,0,(LPARAM)tmp);
  138.                 wsprintf(tmp,"STOR %s",remotename);
  139.                 nRC=SendFile(ctrl_socket,tmp,localname,fType);
  140.                 if(nRC!=2) break;
  141.                  }  
  142.               GetRemoteDirForWnd(globalhWnd);
  143.           }
  144. set_busy(FALSE);
  145. EnableWindow(hBtnAbort,FALSE);
  146. return 0;
  147. }
  148.  
  149. /* -------------------------------------------------------------- */
  150. DWORD remote_mkdir_fx()
  151. {
  152.     
  153.   int nRC;
  154.  
  155.   if(StdInput(NULL,"Enter new remote directory name:"))
  156.   if((nRC=DoMKD(ctrl_socket,szDlgEdit))==FTP_COMPLETE)
  157.     {
  158.       GetRemoteDirForWnd(globalhWnd);
  159.     }
  160. set_busy(FALSE);
  161. EnableWindow(hBtnAbort,FALSE);
  162. return 0;
  163. }
  164.  
  165. /* ---------------------------------------- */
  166. DWORD remote_rmdir_fx()
  167. {
  168.     
  169.   int nIndex,nRC;
  170.  
  171.   if((nIndex=SendMessage(hLbxRDir,LB_GETCURSEL,0,0L))!=LB_ERR)
  172.     {
  173.        SendMessage(hLbxRDir,LB_GETTEXT,nIndex,(LONG)szMsgBuf2);
  174.        if(VerifyDelete(szMsgBuf2))
  175.          if((nRC=DoRMD(ctrl_socket,szMsgBuf2))==FTP_COMPLETE)
  176.                   GetRemoteDirForWnd(globalhWnd);
  177.     }
  178. set_busy(FALSE);
  179. EnableWindow(hBtnAbort,FALSE);
  180. return 0;
  181.  
  182. /* ------------------------------------------------- */
  183.  
  184. DWORD remote_list_fx()
  185.   {
  186.     
  187.    GetRemoteDirForWnd(globalhWnd);
  188. EnableWindow(hBtnAbort,TRUE);
  189. set_busy(FALSE);
  190. EnableWindow(hBtnAbort,FALSE);
  191. return 0;
  192. }
  193.  
  194. /* ----------------------------- */
  195. DWORD remote_delete_fx()
  196. {
  197.     
  198.   int nIndex,nRC;
  199.  
  200.   int count;
  201.   count=SendMessage(hLbxRFiles,LB_GETSELITEMS,
  202.                                  256,(LPARAM)(int far *)selects);
  203.   if(count>0 && count!=LB_ERR)
  204.       {
  205.        for(nIndex=0;nIndex<count;nIndex++)
  206.          {
  207.            SendMessage(hLbxRFiles,LB_GETTEXT,selects[nIndex],
  208.                                  (LONG)szDlgEdit);
  209.            if(VerifyDelete(szDlgEdit))
  210.              nRC=DoDELE(ctrl_socket,szDlgEdit);
  211.          } 
  212.               GetRemoteDirForWnd(globalhWnd);
  213.       }
  214. set_busy(FALSE);
  215. EnableWindow(hBtnAbort,FALSE);
  216. return 0;
  217. }
  218.  
  219. /* ----------------------------------------------------------- */
  220. DWORD remote_rename_fx()
  221. {
  222.     
  223.   int nIndex,nRC;
  224.  
  225.           if((nIndex=SendMessage(hLbxRFiles,LB_GETCURSEL,
  226.                 0,0L))!=LB_ERR)
  227.           {
  228.             SendMessage(hLbxRFiles,LB_GETTEXT,nIndex,
  229.                                (LONG)szMsgBuf2);
  230.                 if(StdInput(NULL,"Enter new name for \"%s\":",szMsgBuf2))
  231.                 if((nRC=command(ctrl_socket,"RNFR %s",szMsgBuf2))==FTP_CONTINUE)
  232.                 if((nRC=command(ctrl_socket,"RNTO %s",szDlgEdit))==FTP_COMPLETE)
  233.                     GetRemoteDirForWnd(globalhWnd);
  234.           }
  235. set_busy(FALSE);
  236. EnableWindow(hBtnAbort,FALSE);
  237. return 0;
  238. }
  239.  
  240. /* ----------------------------------------------------------- */
  241. DWORD remote_cwd_fx()
  242. {
  243.     
  244.   int nIndex,nRC;
  245.  
  246.    if((nIndex=SendMessage(hLbxRDir,LB_GETCURSEL,0,0L))!=LB_ERR)
  247.      {
  248.        EnableWindow(hBtnAbort,TRUE);
  249.        SendMessage(hLbxRDir,LB_GETTEXT,nIndex,
  250.                                  (LONG)szMsgBuf2);
  251.         nRC=DoCWD(ctrl_socket,szMsgBuf2);
  252.         if(nRC==FTP_COMPLETE)
  253.                    GetRemoteDirForWnd(globalhWnd);
  254.      }
  255.    else
  256.      {
  257.       if(StdInput(NULL,"Enter remote directory name:")) 
  258.       if((nRC=DoCWD((SOCKET)ctrl_socket,szDlgEdit))==FTP_COMPLETE)
  259.         GetRemoteDirForWnd(globalhWnd);
  260.      }
  261. set_busy(FALSE);
  262. EnableWindow(hBtnAbort,FALSE);
  263. return 0;
  264. }
  265.  
  266. /* ----------------------------------------------------------- */
  267. DWORD remote_to_local_fx()
  268. {
  269.   char tmp[80];
  270.   char remotename[256];
  271.   char localname[256];
  272.   char shortname[80];
  273.   int count;
  274.  
  275.   int nIndex,nRC;
  276.  
  277.             count=SendMessage(hLbxRFiles,LB_GETSELITEMS,
  278.                                  256,(LPARAM)(int far *)selects);
  279.             if(count>0 && count!=LB_ERR)
  280.               {
  281.                   EnableWindow(hBtnAbort,TRUE);
  282.                   for(nIndex=0;nIndex<count;nIndex++)
  283.                    {
  284.                      SendMessage(hLbxRFiles,LB_GETTEXT,selects[nIndex],
  285.                                  (LONG)remotename);
  286.                      MakeLocalName(localname,shortname,remotename);
  287.                      if(bInteractive)
  288.                       StdInput(localname,"Enter local file name for %s:",remotename);
  289.                       DoPrintf("receiving %s as %s (%u of %u)",
  290.                          remotename,localname,nIndex+1,count);
  291.                       wsprintf(tmp,"RETR %s",remotename);
  292.                       nRC=RetrieveFile((SOCKET)ctrl_socket,(LPSTR)tmp,
  293.                         (LPSTR)localname,(LPSTR)shortname,fType);
  294.                 if(nRC==2)
  295.                   SendMessage(hLbxLFiles,LB_ADDSTRING,0,(LONG)remotename);
  296.                 else
  297.                   break;
  298.                    } // end of loop
  299.                  GetLocalDirForWnd(globalhWnd);
  300.               } // end of count ok
  301.  
  302. set_busy(FALSE);
  303. EnableWindow(hBtnAbort,FALSE);
  304. return 0;
  305. }
  306.  
  307. /* --------------------------------------------------------- */
  308. DWORD remote_display_fx()
  309.  
  310. {
  311.     
  312.   int nIndex,nRC;
  313.  
  314.             char tmp[80];
  315.             char remotename[80];
  316.  
  317.             if((nIndex=SendMessage(hLbxRFiles,LB_GETCURSEL,
  318.                 0,0L))!=LB_ERR)
  319.             {
  320.                  SendMessage(hLbxRFiles,LB_GETTEXT,nIndex,
  321.                                  (LONG)remotename);
  322.                  wsprintf(tmp,"RETR %s",remotename);
  323.                  EnableWindow(hBtnAbort,TRUE);
  324.                  nRC=RetrieveFile((SOCKET)ctrl_socket,(LPSTR)tmp,
  325.                            (LPSTR)szTmp1File,(LPSTR)szTmp1File,TYPE_A);
  326.                  if(nRC==2)
  327.                    {
  328.                     wsprintf(szString,"%s %s",szViewer,szTmp1File);
  329.                     if(strchr(szTmp1File,'.')==NULL)
  330.                        strcat(szString,".");
  331.                     WinExec(szString,SW_SHOW);
  332.                    }
  333.                  GetLocalDirForWnd(globalhWnd);
  334.          }
  335. set_busy(FALSE);
  336. EnableWindow(hBtnAbort,FALSE);
  337. return 0;
  338. }
  339.  
  340.  
  341.  
  342. /* ----------------------------------------------------------- */
  343. DWORD connect_fx()
  344. {
  345.     
  346.   int nRC;
  347.   
  348.   connectpending = TRUE;
  349.  
  350.           if(ctrl_socket==INVALID_SOCKET)
  351.           {
  352.              EnableWindow(hBtnConnect,FALSE);
  353.              use_gateway=0;
  354.              nRC=DialogBox(hInst,(LPSTR)"DLG_HOST",globalhWnd,WS_HostMsgProc);
  355.              if(nRC)
  356.              {
  357.               EnableWindow(hBtnAbort,TRUE);
  358.               ctrl_socket=(SOCKET)DoConnect(szRemoteHost);
  359.               if(ctrl_socket!=INVALID_SOCKET)
  360.                 {
  361.                 if(szInitDir[0]!=0)
  362.                   DoCWD(ctrl_socket,szInitDir);
  363.                 }
  364.                else // didn't connect so renable button
  365.                  EnableWindow(hBtnConnect,TRUE);
  366.  
  367.                 if(LOWORD(globalwParam)==BTN_CONNECT)
  368.                   GetRemoteDirForWnd(globalhWnd);
  369.              } // ok nrc
  370.           }
  371.             else
  372.             SendMessage(hTxtStatus,WM_SETTEXT,0,(LPARAM)"Already connected");
  373. set_busy(FALSE);
  374. connectpending = FALSE;
  375. EnableWindow(hBtnAbort,FALSE);
  376. return 0;
  377. }
  378.           
  379. /* ---------------------------------------------------------- */
  380. DWORD drop_files_fx()
  381.  
  382. {
  383.     
  384.   int nRC;
  385.  
  386.          POINT pt;
  387.          WORD cFiles, a;
  388.          char szFile[256];
  389.          char szRemoteName[256];
  390.          u_char tmp[256];
  391.          LPSTR lpszBaseName;
  392.  
  393.          DragQueryPoint((HANDLE) globalwParam, &pt);
  394.  
  395.          cFiles = DragQueryFile((HANDLE) globalwParam, 0xFFFF, (LPSTR) NULL, 0);
  396.          if(!bConnected)
  397.            DoPrintf("NOT CONNECTED!! File(s) ignored.");
  398.          else if(bCmdInProgress)
  399.            DoPrintf("We are already busy!! File(s) ignored.");
  400.          else
  401.            {
  402.            for(a = 0; a < cFiles; pt.y += 20, a++)
  403.             {
  404.              DragQueryFile((HANDLE) globalwParam, a, szFile, sizeof(szFile));
  405.              MakeLower(szFile);
  406.              if((lpszBaseName=strrchr(szFile,'\\'))!=NULL)
  407.               {
  408.                lstrcpy(szRemoteName,++lpszBaseName);
  409.                if(bInteractive) 
  410.                   StdInput(szRemoteName,"Enter remote file name for %s:",lpszBaseName);
  411.                EnableWindow(hBtnAbort,TRUE);
  412.                wsprintf(tmp,"sending %s as %s (%u of %u)",szFile,szRemoteName,a,cFiles);
  413.                SendMessage(hTxtStatus,WM_SETTEXT,0,(LPARAM)tmp);
  414.                wsprintf(tmp,"STOR %s",szRemoteName);
  415.                nRC=SendFile(ctrl_socket,tmp,szFile,fType);
  416.                if(nRC!=2) break;
  417.               }
  418.             } // end of loop
  419.            GetRemoteDirForWnd(globalhWnd);
  420.            } // end ok case
  421.          DragFinish((HANDLE) globalwParam);
  422.  
  423. set_busy(FALSE);
  424. EnableWindow(hBtnAbort,FALSE);
  425. return 0;
  426. }
  427.  
  428. /* -------------------------------------------- */
  429.       
  430. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  431.                    LPSTR lpszCmdLine, int nCmdShow)
  432. {
  433.   MSG        msg;
  434.   int        nRc;
  435.   long       nWndunits;
  436.   int        nX;
  437.   int        nY;
  438.   int        nWidth;
  439.   int        nHeight;
  440.   int        err;
  441. //  HINSTANCE hWinSock;
  442.  
  443.   InitializeCriticalSection(&busy_variable);
  444.  
  445.   if (strstr(lpszCmdLine,"-d") != NULL)
  446.     {
  447.       // we want debugging
  448.       DEBUGGING_ON = TRUE;
  449.     }
  450.    
  451.   if ((err = WSAStartup((WORD)0x0101, &WSAData))!=0)  // register task with
  452.   {                                         // winsock tcp/ip API
  453.     MessageBox(NULL,ReturnWSError(err,NULL),"WS_FTP - WSAStartup",
  454.           MB_OK|MB_ICONEXCLAMATION);
  455.   } else {
  456.     strcpy(szAppName, "WS_FTP");
  457.     hInst = hInstance;
  458.  
  459.     if(!hPrevInstance)
  460.     {
  461.       // register window classes if first instance of application
  462.       if ((nRc = nCwRegisterClasses()) == -1)
  463.       {
  464.         // registering one of the windows failed
  465.         MessageBox((HWND)NULL, "Window creation failed",
  466.               NULL, MB_ICONEXCLAMATION);
  467.         return nRc;    
  468.       }
  469.     }
  470.  
  471.     // Create a device independant size and location
  472.     nWndunits = GetDialogBaseUnits();
  473.     nWndx = LOWORD(nWndunits);
  474.     nWndy = HIWORD(nWndunits);
  475.     nX = ((18 * nWndx) / 4);
  476.     nY = ((18 * nWndy) / 8);
  477.     nWidth = ((247 * nWndx) / 4);
  478.     nHeight = ((211 * nWndy) / 8);
  479.  
  480.     // create application's Main window
  481.     hWndMain = CreateWindow(
  482.       szAppName, "WinSock_FTP",
  483.       WS_CAPTION     | WS_SYSMENU    | WS_MINIMIZEBOX  |
  484.       WS_CLIPCHILDREN | WS_OVERLAPPED,
  485.       nX,nY, nWidth, nHeight,
  486.       (HWND)NULL, (HMENU)NULL, hInst,  NULL);
  487.  
  488.     if(hWndMain == (HWND)NULL)
  489.     {
  490.       MessageBox((HWND)NULL, "Error registering class",
  491.             NULL, MB_ICONEXCLAMATION);
  492.       return 2;
  493.     }
  494.  
  495.     ShowWindow(hWndMain, nCmdShow);         // display main window
  496.     GetLocalInfo();
  497.     if(bAutoStart)
  498.       PostMessage(hWndMain,WM_COMMAND,BTN_CONNECT,0L);
  499.  
  500.       // lgk now check if command line stuff
  501.       if (check_command_line() == 1)
  502.        { 
  503.        // use to exit here when not multi-threaded but now returns immediately
  504.        }
  505.         
  506.     while(GetMessage(&msg, (HWND)NULL, 0, 0))     // Until WM_QUIT message
  507.     {
  508.       TranslateMessage(&msg);
  509.       DispatchMessage(&msg);
  510.     }
  511.     WSACleanup();
  512.     ReleaseDisplayMem();
  513.  
  514.     // Do clean up before exiting from the application
  515.     CwUnRegisterClasses();
  516.   }
  517.   return msg.wParam;
  518. } //  End of WinMain
  519.  
  520.  
  521. int StdInput(LPSTR dest,LPSTR fmt,...)
  522. {
  523.   va_list args;
  524. //  FARPROC lpfnMsgProc;
  525.   int  iRetCode;
  526.  
  527.   va_start(args,fmt);
  528.   vsprintf(szDlgPrompt,fmt,args);
  529.   va_end(args);
  530.   if (dest != NULL) // lgk fix for nt caused access violation
  531.    lstrcpy(szDlgEdit,dest);
  532.   
  533.   else szDlgEdit[0] = 0;
  534.  
  535. //  lpfnMsgProc=MakeProcInstance((FARPROC)WS_InputMsgProc,hInst);
  536.     iRetCode=DialogBox(hInst,(LPSTR)"DLG_INPUT",hWndMain,WS_InputMsgProc);
  537. //  FreeProcInstance(lpfnMsgProc);
  538.   if(iRetCode && dest) 
  539.   
  540.   // lgk fix here since if dest was null we cannot copy to it
  541.    if (dest != NULL)
  542.     lstrcpy(dest,szDlgEdit);
  543.   
  544.   return(iRetCode);
  545. }
  546.  
  547. int StdInputPassword(LPSTR dest,LPSTR fmt,...)
  548. {
  549.   va_list args;
  550.   //FARPROC lpfnMsgProc;
  551.   int  iRetCode;
  552.  
  553.   va_start(args,fmt);
  554.   vsprintf(szDlgPrompt,fmt,args);
  555.   va_end(args);
  556.   lstrcpy(szDlgEdit,dest);
  557. //  lpfnMsgProc=MakeProcInstance((FARPROC)WS_InputMsgProc,hInst);
  558.   iRetCode=DialogBox(hInst,(LPSTR)"DLG_INPUT_PASSWORD",hWndMain,WS_InputMsgProc);
  559. //  FreeProcInstance(lpfnMsgProc);
  560.   if(iRetCode && dest) lstrcpy(dest,szDlgEdit);
  561.   return(iRetCode);
  562. }
  563.  
  564. /************************************************************************/
  565. /* Main Window Procedure                                                */
  566. /************************************************************************/
  567. LRESULT CALLBACK WndProc(HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam)
  568. {
  569.   int nIndex; //,nRC;
  570.   char tempdirectoryname[256];
  571.  
  572.  
  573.   switch (Message)
  574.   {
  575.  
  576.    /* case WM_KEYDOWN:
  577.  
  578.      // carriage return hit see which window is active
  579.      if (wParam == VK_RETURN)
  580.       {
  581.        HWND activewind = GetActiveWindow();
  582.        if (activewind == hLdirBox)
  583.          {
  584.            GetLocalDirForWnd(hWnd);
  585.          }
  586.        else
  587.         if (activewind == hRdirBox)
  588.            {
  589.            if (check_busy())
  590.                DoPrintf("Currently Busy with another remote operation ...\n");
  591.             else
  592.               {
  593.                 globalhWnd = hWnd;
  594.                 globalwParam = wParam;
  595.                 set_busy(TRUE);
  596.                // create thread and start remote list fx
  597.                 threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_list_fx,NULL,0,&threadid);
  598.               }               
  599.           }
  600.    
  601.       }
  602.      break;
  603.     */
  604.     case WM_COMMAND:
  605.       if(LOWORD(wParam)==BTN_CLOSE || LOWORD(wParam)==BTN_EXIT ||
  606.          LOWORD(wParam)==CMD_CLOSE || LOWORD(wParam)==IDM_EXIT)
  607.         {
  608.         bAborted=TRUE;
  609.  
  610.             // kill remote thread first 
  611.             if (check_busy())
  612.             {
  613.              DoAddLine("Aborting thread before closing/exiting\n");
  614.              TerminateThread(threadhandle,1);
  615.              set_busy(FALSE);
  616.             }
  617.        
  618.        if(data_socket!=INVALID_SOCKET)
  619.           data_socket=DoClose(data_socket);
  620.         if(listen_socket!=INVALID_SOCKET)
  621.           listen_socket=DoClose(listen_socket);
  622.         if(ctrl_socket!=INVALID_SOCKET)
  623.          {
  624.           command(ctrl_socket,"QUIT");
  625.           ctrl_socket=DoClose(ctrl_socket);
  626.           bConnected=FALSE;
  627.         }
  628.         SetWindowText(hWnd,"WS_FTP32");
  629.         if(LOWORD(wParam)==IDM_EXIT || LOWORD(wParam)==BTN_EXIT)
  630.           SendMessage(hWnd,WM_CLOSE,0,0L);
  631.         else
  632.           { // close not exit so enable windows correctly
  633.             EnableWindow(hBtnConnect,TRUE);
  634.             EnableWindow(hBtnAbort,FALSE);
  635.             EnableWindow(hBtnClose,FALSE);
  636.             GetRemoteDirForWnd(hWnd);
  637.           }
  638.         break;
  639.       } //else if ((bCmdInProgress)  return(FALSE);
  640.  
  641.       switch (LOWORD(wParam))
  642.       {
  643.  
  644. // child windows messages ************************************
  645. // local buttons and boxes
  646.  
  647. // lgk new case for abort
  648.            case BTN_ABORT:
  649.  
  650.           // kill remote thread first 
  651.           // problem here if we abort during a connect we also need to close the control socket
  652.           // check this via the connect flag
  653.   
  654.            // since we cant get this to work correctly disable it for now
  655.            DoPrintf("Abort is Not Yet Implemented Due to problems.\n");
  656.          /*
  657.           if (check_busy())
  658.             {
  659.              DoPrintf("Aborting Remote thread\n");
  660.              TerminateThread(threadhandle,1);
  661.              set_busy(FALSE);
  662.        
  663.              if(data_socket!=INVALID_SOCKET)
  664.                 {
  665.                 //  shutdown(data_socket,2);
  666.                   data_socket=DoClose(data_socket);
  667.                     }
  668.                  bAborted=TRUE;
  669.                  bCmdInProgress = 0;
  670.  
  671.              if(listen_socket!=INVALID_SOCKET)
  672.                listen_socket=DoClose(listen_socket);
  673.              
  674.              bCmdInProgress = 0;
  675.               
  676.               if (connectpending)
  677.               {
  678.                 int err = 0;
  679.                 if (ctrl_socket!=INVALID_SOCKET)
  680.                   {
  681.                     
  682.                     command(ctrl_socket,"QUIT");
  683.                     ctrl_socket = DoClose(ctrl_socket);
  684.                   }
  685.                     bConnected = FALSE;
  686.                     DoPrintf("Remote Connect Aborted\n");
  687.                     connectpending = FALSE;
  688.                     bCmdInProgress = 0;
  689.                     EnableWindow(hBtnConnect,TRUE);
  690.                     EnableWindow(hBtnAbort,FALSE);
  691.                     EnableWindow(hBtnClose,FALSE);
  692.                     SetWindowText(hWnd,"WS_FTP32");
  693.                     // bug in winsock after closing does not work correctly
  694.                 
  695.               } 
  696.               else DoPrintf("Remote Operation Aborted\n");
  697.             }    */
  698.         break;
  699.  
  700.  
  701.        // lgk new case for changing txt in directory search routine
  702.            case TXT_LDIRSEL:
  703.          {
  704.           // check if carriage return
  705.           char *temp = localsearchstring();
  706.           // if (HIWORD(wParam) == EN_CHANGE)
  707.            //  DoPrintf("temp is %s \n",temp);
  708.  
  709.            if ((HIWORD(wParam) == EN_KILLFOCUS) && SendMessage(hLdirBox,EM_GETMODIFY,0,0))
  710.            {
  711.              GetLocalDirForWnd(hWnd);
  712.            }
  713.            // bug in redraw so force it
  714.           if (HIWORD(wParam) == EN_UPDATE)
  715.              {
  716.               SendMessage(hLdirBox,WM_SETFONT,0,MAKELPARAM(TRUE,0));
  717.               }
  718.  
  719.           }    
  720.         break;
  721.  
  722.         case LST_LDIRS:
  723.           if (HIWORD(wParam) !=LBN_DBLCLK) return(FALSE);
  724.         case BTN_LCHANGE:
  725.             if((nIndex=SendMessage(hLbxLDir,LB_GETCURSEL,
  726.                 0,0L))!=LB_ERR)
  727.             {
  728.               SendMessage(hLbxLDir,LB_GETTEXT,nIndex,
  729.                                  (LONG)szMsgBuf2);
  730.               if(strncmp(szMsgBuf2,"[-",2)==0) {
  731. #ifdef _MSC_
  732.                 _chdrive(tolower(szMsgBuf2[2])-0x60);
  733. #else
  734.                 setdisk(szMsgBuf2[2]-'a');
  735. #endif
  736.                 GetLocalDirForWnd(hWnd);
  737.               } else if(chdir(szMsgBuf2)==0)
  738.                 GetLocalDirForWnd(hWnd);
  739.             } else
  740.  
  741.              {
  742.               if(StdInput(NULL,"Enter local directory name:")) {
  743.                 if(szDlgEdit[1]==':')
  744. #ifdef _MSC_
  745.                   _chdrive(tolower(szDlgEdit[0])-0x60);
  746. #else
  747.                   setdisk(tolower(szDlgEdit[0])-'a');
  748. #endif
  749.                 chdir(szDlgEdit);
  750.                 GetLocalDirForWnd(hWnd);
  751.               }
  752.             }
  753.           break;
  754.         case LST_LFILES:
  755.           if(HIWORD(wParam) !=LBN_DBLCLK) return(FALSE);
  756.         case BTN_LOCAL_TO_REMOTE:
  757.           {
  758.             globalhWnd = hWnd;
  759.             globalwParam = wParam;
  760.             // lgk new code first check if busy and if so print out a message
  761.             if (check_busy())
  762.                DoPrintf("Currently Busy with another remote operation ...\n");
  763.             else
  764.               {
  765.                globalhWnd = hWnd;
  766.                globalwParam = wParam;
  767.                 set_busy(TRUE);
  768.                // create and call button to remote thread here
  769.                threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)local_to_remote_fx,NULL,0,&threadid);
  770.               } // end of not busy
  771.           } // end of btn local to remote
  772.           break;
  773.  
  774.           // lgk allow local commands while remote are running
  775.           
  776.         case BTN_LMKDIR:
  777.           if(StdInput(NULL,"Enter new local directory name:")) {
  778.             mkdir(szDlgEdit);
  779.             GetLocalDirForWnd(hWnd);
  780.           }
  781.           break;
  782.         case BTN_LRMDIR:
  783.             if((nIndex=SendMessage(hLbxLDir,LB_GETCURSEL,
  784.                 0,0L))!=LB_ERR)
  785.             {
  786.               SendMessage(hLbxLDir,LB_GETTEXT,nIndex,
  787.                                  (LONG)szMsgBuf2);
  788.               if(VerifyDelete(szMsgBuf2))
  789.                 if(rmdir(szMsgBuf2)==0)
  790.                   GetLocalDirForWnd(hWnd);
  791.             }
  792.           break;
  793.         case BTN_LDELETE:
  794.           {
  795.             int count;
  796.             count=SendMessage(hLbxLFiles,
  797.                       LB_GETSELITEMS,256,(LPARAM)(int far *)selects);
  798.             if(count>0 && count!=LB_ERR) {
  799.               for(nIndex=0;nIndex<count;nIndex++) {
  800.                 SendMessage(hLbxLFiles,LB_GETTEXT,selects[nIndex],
  801.                                  (LONG)szDlgEdit);
  802.                 if(VerifyDelete(szDlgEdit))
  803.                   unlink(szDlgEdit);
  804.               }  
  805.               GetLocalDirForWnd(hWnd);
  806.             }
  807.           }
  808.           break;
  809.         case BTN_LRENAME:
  810.           if((nIndex=SendMessage(hLbxLFiles,LB_GETCURSEL,
  811.                 0,0L))!=LB_ERR)
  812.           {
  813.             SendMessage(hLbxLFiles,LB_GETTEXT,nIndex,
  814.                                (LONG)szMsgBuf2);
  815.             if(StdInput(NULL,"Enter new name for \"%s\":",szMsgBuf2))
  816.               if(rename(szMsgBuf2,szDlgEdit)==0)
  817.                 GetLocalDirForWnd(hWnd);
  818.           }
  819.           break;
  820.         case BTN_LDISPLAY:
  821.           {
  822.             char remotename[80];
  823.             if((nIndex=SendMessage(hLbxLFiles,LB_GETCURSEL,
  824.                 0,0L))!=LB_ERR)
  825.             {
  826.               SendMessage(hLbxLFiles,LB_GETTEXT,nIndex,
  827.                                  (LONG)remotename);
  828.               wsprintf(szMsgBuf2,"%s %s",szViewer,remotename);
  829.               if(strchr(remotename,'.')==NULL)
  830.                 strcat(szMsgBuf2,".");
  831.               WinExec(szMsgBuf2,SW_SHOW);
  832.             }
  833.           }
  834.           break;
  835.  
  836.          // remote buttons and boxes
  837.         case BTN_RMKDIR:
  838.            // lgk new code first check if busy and if so print out a message
  839.             if (check_busy())
  840.                DoPrintf("Currently Busy with another remote operation ...\n");
  841.             else
  842.               {
  843.                globalhWnd = hWnd;
  844.                globalwParam = wParam;
  845.                set_busy(TRUE);
  846.                threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_mkdir_fx,NULL,0,&threadid);
  847.                // create thread and start remote makedir fx
  848.           }               
  849.           break;
  850.           
  851.         case BTN_RRMDIR:
  852.             // lgk new code first check if busy and if so print out a message
  853.             if (check_busy())
  854.                DoPrintf("Currently Busy with another remote operation ...\n");
  855.             else
  856.               {
  857.                 globalhWnd = hWnd;
  858.                 globalwParam = wParam;
  859.                 set_busy(TRUE);
  860.                // create thread and start remote remove dir fx
  861.                 threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_rmdir_fx,NULL,0,&threadid);
  862.           }               
  863.           break;
  864.  
  865.         case BTN_RDELETE:
  866.             // lgk new code first check if busy and if so print out a message
  867.             if (check_busy())
  868.                DoPrintf("Currently Busy with another remote operation ...\n");
  869.             else
  870.               {
  871.                globalhWnd = hWnd;
  872.                globalwParam = wParam;
  873.                set_busy(TRUE);
  874.                // create thread and start remote delete fx
  875.                threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_delete_fx,NULL,0,&threadid);
  876.           }               
  877.           break;
  878.  
  879.           
  880.         case BTN_RRENAME:
  881.           // lgk new code first check if busy and if so print out a message
  882.            if (check_busy())
  883.                DoPrintf("Currently Busy with another remote operation ...\n");
  884.             else
  885.               {
  886.                 globalhWnd = hWnd;
  887.                 globalwParam = wParam;
  888.                  set_busy(TRUE);
  889.                // create thread and start remote rename fx
  890.                threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_rename_fx,NULL,0,&threadid);
  891.           }               
  892.           break;
  893.  
  894.         // lgk new case for changing txt in directory search routine
  895.            case TXT_RDIRSEL:
  896.            // bug in redraw so force it
  897.           if (HIWORD(wParam) == EN_UPDATE)
  898.              {
  899.               SendMessage(hRdirBox,WM_SETFONT,0,MAKELPARAM(TRUE,0));
  900.               }
  901.           if ((HIWORD(wParam) == EN_KILLFOCUS) && SendMessage(hRdirBox,EM_GETMODIFY,0,0))
  902.             // lgk new code first check if busy and if so print out a message
  903.             if (check_busy())
  904.                DoPrintf("Currently Busy with another remote operation ...\n");
  905.             else
  906.               {
  907.                 globalhWnd = hWnd;
  908.                 globalwParam = wParam;
  909.                 set_busy(TRUE);
  910.                // create thread and start remote list fx
  911.                 threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_list_fx,NULL,0,&threadid);
  912.           }               
  913.           break;
  914.        
  915.    
  916.         case LST_RDIRS:
  917.           if(HIWORD(wParam)!=LBN_DBLCLK) return(FALSE);
  918.         case BTN_RCHANGE:
  919.             // lgk new code first check if busy and if so print out a message
  920.             if (check_busy())
  921.                DoPrintf("Currently Busy with another remote operation ...\n");
  922.             else
  923.               {
  924.                 globalhWnd = hWnd;
  925.                 globalwParam = wParam;
  926.                 set_busy(TRUE);
  927.                // create thread and start remote cwd fx
  928.                 threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_cwd_fx,NULL,0,&threadid);
  929.           }               
  930.           break;
  931.           
  932.         case LST_RFILES:
  933.           if(HIWORD(wParam)!=LBN_DBLCLK) return(FALSE);
  934.         case BTN_REMOTE_TO_LOCAL:
  935.             // lgk new code first check if busy and if so print out a message
  936.             if (check_busy())
  937.                DoPrintf("Currently Busy with another remote operation ...\n");
  938.             else
  939.               {
  940.                 globalhWnd = hWnd;
  941.                 globalwParam = wParam;
  942.                set_busy(TRUE);
  943.                // create thread and start remote to local fx
  944.                threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_to_local_fx,NULL,0,&threadid);
  945.           }               
  946.           break;
  947.           
  948.         case BTN_RDISPLAY:
  949.             // lgk new code first check if busy and if so print out a message
  950.             if (check_busy())
  951.                DoPrintf("Currently Busy with another remote operation ...\n");
  952.             else
  953.               {
  954.                globalhWnd = hWnd;
  955.                globalwParam = wParam;
  956.                 set_busy(TRUE);
  957.                // create thread and start remote display fx
  958.                   threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_display_fx,NULL,0,&threadid);
  959.           }               
  960.           break;
  961.  
  962.         case RB_ASCII:
  963.           fType=TYPE_A;
  964. ShowType:
  965.         case RB_SHOWCHECKS:
  966.           SendMessage(hRBascii, BM_SETCHECK,fType==TYPE_A,0L);
  967.           SendMessage(hRBbinary,BM_SETCHECK,fType==TYPE_I,0L);
  968.           SendMessage(hRBl8,    BM_SETCHECK,fType==TYPE_L,0L);
  969.           break;
  970.         case RB_BINARY:
  971.           fType=TYPE_I;
  972.           goto ShowType;
  973.         case RB_L8:
  974.           fType=TYPE_L;
  975.           goto ShowType;
  976.  
  977. // end of child window message processing *******************
  978.  
  979.         case BTN_CONNECT:
  980.         case CMD_CONNECT:
  981.             // lgk new code first check if busy and if so print out a message
  982.             if (check_busy())
  983.                DoPrintf("Currently Busy with another remote operation ...\n");
  984.             else
  985.               {
  986.                globalhWnd = hWnd;
  987.                globalwParam = wParam;
  988.                set_busy(TRUE);
  989.                // create thread and start connect fx
  990.                threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)connect_fx,NULL,0,&threadid);
  991.           }               
  992.           break;
  993.  
  994.         case BTN_LONG:
  995.           if(bConnected) {
  996.             wsprintf(szMsgBuf2,"%s %s",szViewer,szTmpFile);
  997.             WinExec(szMsgBuf2,SW_SHOW);
  998.           }
  999.           break;
  1000.  
  1001.         case BTN_OPTION:
  1002.           {
  1003.            //FARPROC lpfnMsgProc;
  1004.     //        lpfnMsgProc = MakeProcInstance((FARPROC)WS_StatMsgProc, hInst);
  1005.             DialogBox(hInst, (LPSTR)"DLG_STATUS", hWnd, WS_StatMsgProc);
  1006.        //     FreeProcInstance(lpfnMsgProc);
  1007.           }
  1008.           SendMessage(hWnd,WM_COMMAND,RB_SHOWCHECKS,0l);
  1009.           break;
  1010.  
  1011.         case BTN_ABOUT:
  1012.         case IDM_ABOUT:
  1013.           { 
  1014.             DialogBox(hInst, (LPSTR)"DLG_ABOUT", hWnd, WS_AboutMsgProc);
  1015.           }
  1016.           break;
  1017.  
  1018.         default:
  1019.           if(!SubProcessAsync(hWnd,Message,wParam,lParam))
  1020.             return DefWindowProc(hWnd, Message, wParam, lParam);
  1021.       }
  1022.       break;
  1023.  
  1024.     case WM_VSCROLL:
  1025.       switch(LOWORD(wParam)) {
  1026.         case SB_LINEUP:
  1027.           ScrollStatus(-1);
  1028.           break;
  1029.         case SB_LINEDOWN:
  1030.           ScrollStatus(1);
  1031.           break;
  1032.       }
  1033.       break;
  1034.  
  1035.     case WM_CREATE:
  1036.       hStdCursor=LoadCursor((HINSTANCE)NULL,IDC_ARROW);
  1037.       hWaitCursor=LoadCursor((HINSTANCE)NULL,IDC_WAIT);
  1038.       LoadUserInfo();
  1039.       hbrGray1= CreateSolidBrush(RGB(192,192,192));
  1040.       hbrGray2=CreateSolidBrush(RGB(128,128,128)); 
  1041.       hbrWhite=CreateSolidBrush(RGB(255,255,255));
  1042.     
  1043.       if (DEBUGGING_ON)
  1044.         CreateDebugWindow(hWnd,hInst);
  1045.       
  1046.       CreateSubWindows(hWnd,hInst);
  1047.       SendMessage(hLdirBox,EM_LIMITTEXT,(WPARAM)50,0);
  1048.       SendMessage(hRdirBox,EM_LIMITTEXT,(WPARAM)50,0);
  1049.       SendMessage(hLdirBox,WM_SETTEXT,0,(LPARAM)"");
  1050.       SendMessage(hRdirBox,WM_SETTEXT,0,(LPARAM)"");
  1051.       SendMessage(hLdirBox,EM_GETMODIFY,0,0);
  1052.       SendMessage(hRdirBox,EM_GETMODIFY,0,0);     
  1053.       GetLocalDirForWnd(hWnd);
  1054.       GetRemoteDirForWnd(hWnd);
  1055.       SendMessage(hWnd,WM_COMMAND,RB_SHOWCHECKS,0L);
  1056.       GetCurrentDirectory(140,tempdirectoryname);
  1057.       GetTempFileName(tempdirectoryname,"DIR",0,szTmpFile);
  1058.       GetTempFileName(tempdirectoryname,"DSP",0,szTmp1File);
  1059.       DragAcceptFiles(hWnd,TRUE);
  1060.       // lgk limit the text for both dir boxes and initialize them to blank
  1061.  
  1062.         break;
  1063.   // lgk timer messages do not work between threads so use a timer proc now
  1064.  
  1065.     case WM_TIMER:
  1066.       if(wParam==10)
  1067.         {
  1068.         KillTimer(hWndMain,10);
  1069.         if(WSAIsBlocking())
  1070.          {
  1071.             // lgk if we are blocking in another thread here we need to kill
  1072.             // it also
  1073.            if (check_busy())
  1074.             {
  1075.              DoAddLine("Timer cancelled blocking call");    
  1076.              bAborted=TRUE;
  1077.              WSACancelBlockingCall();
  1078.              TerminateThread(threadhandle,1);
  1079.              set_busy(FALSE);
  1080.             }
  1081.          else
  1082.          {
  1083.           DoAddLine("Timer cancelled blocking call");    
  1084.           bAborted=TRUE;
  1085.           WSACancelBlockingCall();
  1086.      }
  1087.      }         
  1088.         }
  1089.       break;
  1090.  
  1091.  
  1092.      case WM_CTLCOLORBTN:
  1093.            if(LOWORD(lParam)<10) return((LRESULT)NULL);
  1094.  // lgk add suport for background color change for our edit box
  1095.      case WM_CTLCOLORSTATIC:
  1096.                SelectObject((HDC)wParam, GetStockObject(ANSI_VAR_FONT));
  1097.                 SetBkColor((HDC) wParam, RGB(192,192,192));
  1098.                 return(LRESULT)hbrGray1;
  1099.                 break;
  1100.  
  1101.      case WM_CTLCOLOREDIT:
  1102.                SelectObject((HDC)wParam, GetStockObject(ANSI_VAR_FONT));
  1103.                 SetBkColor((HDC) wParam, RGB(255, 255, 255));
  1104.                 return(LRESULT)hbrWhite;
  1105.                 break;
  1106.         
  1107.  
  1108.     case WM_SETCURSOR:
  1109.       if(bCmdInProgress) {
  1110.         SetCursor(hWaitCursor);
  1111.         return(TRUE);
  1112.       } else
  1113.         return DefWindowProc(hWnd, Message, wParam, lParam);
  1114.  
  1115.     case WM_DROPFILES:
  1116.             // lgk new code first check if busy and if so print out a message
  1117.             if (check_busy())
  1118.                DoPrintf("Currently Busy with another remote operation ...\n");
  1119.             else
  1120.               {
  1121.                globalhWnd = hWnd;
  1122.                globalwParam = wParam;
  1123.                 set_busy(TRUE);
  1124.                // create thread and start dropfiles fx
  1125.                threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)drop_files_fx,NULL,0,&threadid);
  1126.           }               
  1127.           break;
  1128.  
  1129.     case WM_PAINT:  // code for the window's client area
  1130.       DoMainPaint(hWnd);
  1131.       break;
  1132.  
  1133.     case WM_CLOSE:  // close the window 
  1134.       // Destroy child windows, modeless dialogs, then, this window
  1135.       if (hWnd == hWndMain) {
  1136.         if(data_socket!=INVALID_SOCKET)
  1137.           data_socket=DoClose(data_socket);
  1138.         if(listen_socket!=INVALID_SOCKET)
  1139.           listen_socket=DoClose(data_socket);
  1140.         if(ctrl_socket!=INVALID_SOCKET)
  1141.           ctrl_socket=DoClose(ctrl_socket);
  1142.         DestroyWindow(hWnd);
  1143.         SaveUserInfo();
  1144.         DeleteObject(hbrGray1);
  1145.         DeleteObject(hbrGray2);
  1146.         DeleteObject(hbrWhite);
  1147.         _unlink(szTmpFile);
  1148.         _unlink(szTmp1File);
  1149.         DragAcceptFiles(hWnd,FALSE);
  1150.    // lgk if we are busy here we must kill any active task
  1151.    if (check_busy())
  1152.      {
  1153.        DoPrintf("Killing active thread ... \n");
  1154.        TerminateThread(threadhandle,1);
  1155.        set_busy(FALSE);
  1156.      }
  1157.         PostQuitMessage(0);  // Quit the application
  1158.       } else
  1159.         DestroyWindow(hWnd);
  1160.         DeleteCriticalSection(&busy_variable);
  1161.       break;
  1162.  
  1163.     default:
  1164.       if(!SubProcessAsync(hWnd,Message,wParam,lParam))
  1165.         return DefWindowProc(hWnd, Message, wParam, lParam);
  1166.   }
  1167.   return 0L;
  1168. } // End of WndProc
  1169.  
  1170. /************************************************************************/
  1171. /* Misc Dialog Window Procedures                                        */
  1172. /************************************************************************/
  1173. BOOL CALLBACK WS_AboutMsgProc(HWND hWndDlg, UINT Message, 
  1174.                                 WPARAM wParam, LPARAM lParam)
  1175. {
  1176.  char buf[40];
  1177.   
  1178.  switch(Message)
  1179.  {
  1180.    case WM_INITDIALOG:
  1181.      cwCenter(hWndDlg, 0);
  1182.      wsprintf(buf,"Version %s",VERSION);
  1183.      SetDlgItemText(hWndDlg,DLG_EDIT,buf);
  1184.      break;
  1185.                     
  1186.       case WM_CTLCOLORBTN:
  1187.           if(LOWORD(lParam)<10) return((BOOL)NULL);
  1188.  
  1189.      case WM_CTLCOLORDLG:
  1190.      case WM_CTLCOLORSTATIC:
  1191.           SetBkColor((HDC) wParam, RGB(192,192,192));
  1192.         return (BOOL)hbrGray1;
  1193.         break;
  1194.  
  1195.  
  1196.    case WM_CLOSE:
  1197.      PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
  1198.      break;
  1199.  
  1200.    case WM_COMMAND:
  1201.      switch(LOWORD(wParam))
  1202.      {
  1203.        case IDOK:
  1204.          EndDialog(hWndDlg, TRUE);
  1205.          break;
  1206.        case IDCANCEL:
  1207.          EndDialog(hWndDlg, FALSE);
  1208.          break;
  1209.      }
  1210.      break;
  1211.     default:
  1212.         return FALSE;
  1213.   }
  1214.   return TRUE;
  1215. }
  1216.  
  1217. BOOL CALLBACK WS_InputMsgProc(HWND hWndDlg, UINT Message,
  1218.                                 WPARAM wParam, LPARAM lParam)
  1219.   switch(Message)
  1220.   {
  1221.     case WM_INITDIALOG:
  1222.       SetDlgItemText(hWndDlg,DLG_PROMPT,szDlgPrompt);
  1223.       SetDlgItemText(hWndDlg,DLG_EDIT,szDlgEdit);
  1224.       cwCenter(hWndDlg, 0);                                            
  1225.       break;
  1226.  
  1227.  
  1228.         case WM_CTLCOLORBTN:
  1229.              if(LOWORD(lParam)<10) return((LRESULT)NULL);
  1230.  
  1231.         case WM_CTLCOLORDLG:
  1232.         case WM_CTLCOLORSTATIC:
  1233.         SetBkColor((HDC) wParam, RGB(192,192,192));
  1234.          return(LRESULT)hbrGray1;
  1235.           break;
  1236.   case WM_CLOSE:
  1237.       PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
  1238.       break;
  1239.  
  1240.     case WM_COMMAND:
  1241.       switch(LOWORD(wParam))
  1242.       {
  1243.         case IDOK:
  1244.           GetDlgItemText(hWndDlg,DLG_EDIT,szDlgEdit,70);
  1245.           EndDialog(hWndDlg, TRUE);
  1246.           break;
  1247.         case IDCANCEL:
  1248.           EndDialog(hWndDlg, FALSE);
  1249.           break;
  1250.       }
  1251.       break;
  1252.     default:
  1253.       return FALSE;
  1254.   }
  1255.   return TRUE;
  1256. }
  1257.  
  1258. BOOL CALLBACK WS_StatMsgProc(HWND hWndDlg, UINT Message,
  1259.                                WPARAM wParam, LPARAM lParam)
  1260.   switch(Message)
  1261.   {
  1262.     case WM_INITDIALOG:
  1263.       SetDlgItemText(hWndDlg,DLG_EDIT,szViewer);
  1264.       SetDlgItemText(hWndDlg,DLG_MAILADDR,szMailAddress);
  1265.       if(fType==TYPE_A)
  1266.         CheckRadioButton(hWndDlg,RB_ASCII,RB_L8,RB_ASCII);
  1267.       else if(fType==TYPE_I)
  1268.         CheckRadioButton(hWndDlg,RB_ASCII,RB_L8,RB_BINARY);
  1269.       else
  1270.         CheckRadioButton(hWndDlg,RB_ASCII,RB_L8,RB_L8);
  1271.       CheckDlgButton(hWndDlg,CKB_VERBOSE,bVerbose);
  1272.       CheckDlgButton(hWndDlg,CKB_BELL,bBell);
  1273.       CheckDlgButton(hWndDlg,CKB_GLOBBING,bDoGlob);
  1274.       CheckDlgButton(hWndDlg,CKB_HASH,bHash);
  1275.       CheckDlgButton(hWndDlg,CKB_PROMPT,bInteractive);
  1276.       CheckDlgButton(hWndDlg,CKB_MCASE,bMCase);
  1277.       CheckDlgButton(hWndDlg,CKB_PORT_CMDS,bSendPort);
  1278.       CheckDlgButton(hWndDlg,CKB_RECV_UNIQUE,bRecvUniq);
  1279.       CheckDlgButton(hWndDlg,CKB_STOR_UNIQUE,bStorUniq);
  1280.       CheckDlgButton(hWndDlg,CKB_CRSTRIP,bCRstrip);
  1281.       CheckDlgButton(hWndDlg,CKB_AUTOSTART,bAutoStart);
  1282.       break;
  1283.  
  1284.     case WM_CLOSE:
  1285.       PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
  1286.       break;
  1287.  
  1288.     case WM_SETCURSOR:
  1289.       if(bCmdInProgress)
  1290.         SetCursor(hWaitCursor);
  1291.       else
  1292.         return FALSE;
  1293.       break;
  1294.  
  1295.         case WM_CTLCOLORBTN:
  1296.              if(LOWORD(lParam)<10) return((LRESULT)NULL);
  1297.        case WM_CTLCOLORDLG:
  1298.         case WM_CTLCOLORSTATIC:
  1299.          SetBkColor((HDC) wParam, RGB(192,192,192));
  1300.           return(LRESULT)hbrGray1;
  1301.           break;
  1302.  
  1303.     case WM_COMMAND:
  1304.       switch(LOWORD(wParam))
  1305.       {
  1306.         case IDOK:
  1307.           if(IsDlgButtonChecked(hWndDlg,RB_ASCII)) fType=TYPE_A;
  1308.           else if(IsDlgButtonChecked(hWndDlg,RB_BINARY)) fType=TYPE_I;
  1309.           else fType=TYPE_L;
  1310.  
  1311.           bVerbose=IsDlgButtonChecked(hWndDlg,CKB_VERBOSE);
  1312.           bBell=IsDlgButtonChecked(hWndDlg,CKB_BELL);
  1313.           bDoGlob=IsDlgButtonChecked(hWndDlg,CKB_GLOBBING);
  1314.           bHash=IsDlgButtonChecked(hWndDlg,CKB_HASH);
  1315.           bInteractive=IsDlgButtonChecked(hWndDlg,CKB_PROMPT);
  1316.           bMCase=IsDlgButtonChecked(hWndDlg,CKB_MCASE);
  1317.           bSendPort=IsDlgButtonChecked(hWndDlg,CKB_PORT_CMDS);
  1318.           bRecvUniq=IsDlgButtonChecked(hWndDlg,CKB_RECV_UNIQUE);
  1319.           bStorUniq=IsDlgButtonChecked(hWndDlg,CKB_STOR_UNIQUE);
  1320.           bCRstrip=IsDlgButtonChecked(hWndDlg,CKB_CRSTRIP);
  1321.           bAutoStart=IsDlgButtonChecked(hWndDlg,CKB_AUTOSTART);
  1322.  
  1323.           GetDlgItemText(hWndDlg,DLG_EDIT,szViewer,70);
  1324.           GetDlgItemText(hWndDlg,DLG_MAILADDR,szMailAddress,127);
  1325.           EndDialog(hWndDlg, TRUE);
  1326.           break;
  1327.         case IDCANCEL:
  1328.           EndDialog(hWndDlg, FALSE);
  1329.           break;
  1330.       }
  1331.       break;    // End of WM_COMMAND
  1332.     default:
  1333.       return FALSE;
  1334.   }
  1335.   return TRUE;
  1336. }
  1337.  
  1338. /************************************************************************/
  1339. /* nCwRegisterClasses Function                                          */
  1340. /* The following function registers all the classes of all the windows  */
  1341. /* associated with this application. The function returns an error code */
  1342. /* if unsuccessful, otherwise it returns 0.                             */
  1343. /************************************************************************/
  1344. int nCwRegisterClasses(void)
  1345. {
  1346.   WNDCLASS   wndclass;    // struct to define a window class
  1347.   memset(&wndclass, 0x00, sizeof(WNDCLASS));
  1348.  
  1349.   // load WNDCLASS with window's characteristics
  1350.   wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;
  1351.   wndclass.lpfnWndProc = WndProc;
  1352.   // Extra storage for Class and Window objects
  1353.   wndclass.cbClsExtra = 0;
  1354.   wndclass.cbWndExtra = 0;
  1355.   wndclass.hInstance = hInst;
  1356.   wndclass.hIcon = LoadIcon(hInst, szAppName);
  1357.   wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  1358.   // Create brush for erasing background
  1359.   wndclass.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(192,192,192));
  1360.   wndclass.lpszMenuName = NULL; // szAppName;   /* Menu Name is App Name */
  1361.   wndclass.lpszClassName = szAppName; /* Class Name is App Name */
  1362.   if(!RegisterClass(&wndclass))
  1363.     return -1;
  1364.   return(0);
  1365. } // End of nCwRegisterClasses
  1366.  
  1367. /************************************************************************/
  1368. /*  cwCenter Function                                                   */
  1369. /*  centers a window based on the client area of its parent             */
  1370. /************************************************************************/
  1371. void cwCenter(hWnd, top)
  1372. HWND hWnd;
  1373. int top;
  1374. {
  1375.   POINT      pt;
  1376.   RECT       swp;
  1377.   RECT       rParent;
  1378.   int        iwidth;
  1379.   int        iheight;
  1380.  
  1381.   // get the rectangles for the parent and the child
  1382.   GetWindowRect(hWnd, &swp);
  1383.  
  1384.   // calculate the height and width for MoveWindow
  1385.   iwidth = swp.right - swp.left;
  1386.   iheight = swp.bottom - swp.top;
  1387.  
  1388.   if(IsIconic(hWndMain))
  1389.     MoveWindow(hWnd, 0, 0, iwidth, iheight, FALSE);
  1390.   else {
  1391.     GetClientRect(hWndMain, &rParent);
  1392.  
  1393.     // find the center point and convert to screen coordinates
  1394.     pt.x = (rParent.right - rParent.left) / 2;
  1395.     pt.y = (rParent.bottom - rParent.top) / 2;
  1396.     ClientToScreen(hWndMain, &pt);
  1397.  
  1398.     // calculate the new x, y starting point
  1399.     pt.x = pt.x - (iwidth / 2);
  1400.     pt.y = pt.y - (iheight / 2);
  1401.  
  1402.     // top will adjust the window position, up or down
  1403.     if(top)
  1404.       pt.y = pt.y + top;
  1405.  
  1406.     // move the window
  1407.     MoveWindow(hWnd,max(0,pt.x),max(0,pt.y), iwidth, iheight, FALSE);
  1408.   }
  1409. } // end of cwCenter
  1410.  
  1411. /************************************************************************/
  1412. /*  CwUnRegisterClasses Function                                        */
  1413. /*  Deletes any refrences to windows resources created for this         */
  1414. /*  application, frees memory, deletes instance, handles and does       */
  1415. /*  clean up prior to exiting the window                                */
  1416. /************************************************************************/
  1417. void CwUnRegisterClasses(void)
  1418. {
  1419.   WNDCLASS   wndclass;    // struct to define a window class
  1420.   memset(&wndclass, 0x00, sizeof(WNDCLASS));
  1421.  
  1422.   GetClassInfo(hInst, szAppName, &wndclass);
  1423.   DeleteObject(wndclass.hbrBackground);
  1424.   UnregisterClass(szAppName, hInst);
  1425.   UnregisterClass(DBUGWNDCLASS,hInst);
  1426. } // End of CwUnRegisterClasses
  1427.  
  1428.