home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / nsapp.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  58.4 KB  |  2,031 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. // netscape.cpp : Defines the class behaviors for the application.
  20. //
  21.  
  22. #include "stdafx.h"
  23.  
  24. #define XP_CPLUSPLUS  // temporary hack - jsw
  25.  
  26. // XP Includes
  27. #include "np.h"
  28. #include "cvffc.h"
  29.  
  30. #include "prefapi.h"
  31.  
  32. #ifdef XP_WIN32
  33. #include "shcut.h"
  34. #endif
  35.  
  36. #include "libevent.h"
  37. #include "wfemsg.h"
  38.  
  39. // Misc Includes
  40. #include "res\appicon.h"
  41. #include "custom.h"
  42. #include "dialog.h"
  43. #include "ngdwtrst.h"
  44. #include "oleregis.h"
  45. #include "sysinfo.h"
  46. #include "timer.h"
  47. #include "winproto.h"
  48. #include "cmdparse.h"
  49. #include "ddecmd.h"
  50. #include "apiapi.h"
  51. #include "apipage.h"
  52. #include "logindg.h"
  53.  
  54. #include "hiddenfr.h"
  55. #include "cxprint.h"
  56. #include "cxicon.h"
  57. #include "navfram.h"
  58.  
  59. #include "pw_public.h"
  60. extern "C"      {
  61. #include "mkaccess.h"
  62. };
  63. #ifdef MOZ_LOC_INDEP
  64. #include "li_public.h"
  65. #endif /* MOZ_LOC_INDEP */
  66.  
  67. #ifdef _DEBUG
  68. #undef THIS_FILE
  69. static char BASED_CODE THIS_FILE[] = __FILE__;
  70. #endif
  71.  
  72. #ifndef VER_PLATFORM_WIN32_WINDOWS
  73. #define VER_PLATFORM_WIN32_WINDOWS      1
  74. #endif
  75.  
  76. #ifdef __BORLANDC__
  77.     #define _mkdir mkdir
  78. #endif
  79.  
  80. // Registry key constants
  81. static const CString strMARKUP_KEY = "NetscapeMarkup";
  82. static const CString strOPEN_CMD_FMT = "%s\\shell\\open\\command";
  83. static const CString strDDE_EXEC_FMT = "%s\\shell\\open\\ddeexec";
  84. static const CString strDDE_APP_FMT = "%s\\shell\\open\\ddeexec\\Application";
  85. static const CString strDDE_APP_NAME = "NSShell";
  86. static const CString strDDE_OLDAPP_NAME = "Netscape";
  87. static const CString strDEF_ICON_FMT = "%s\\DefaultIcon";
  88. static const CString strDDE_EXEC_VALUE = "%1";
  89. static const CString strDDE_TOPIC_FMT = "%s\\shell\\open\\ddeexec\\Topic";
  90. static const CString strEDIT_CMD_FMT = "%s\\shell\\edit\\command";
  91.  
  92. // li_stuff
  93. static int LIActive = 0;
  94.  
  95.  
  96. #if defined( _DEBUG) && defined( XP_WIN32 )
  97. int
  98. CNetscapeApp::InitConsoleWindow(void)
  99. {
  100.  
  101.     STARTUPINFO si = {0};          // initialize all members to zero
  102.     si.cb          = sizeof(STARTUPINFO);
  103.     AllocConsole();                       // get that console window
  104.     freopen("CONOUT$", "a", stderr);      // redirect stderr to console
  105.  
  106.     // Warn user
  107.     fputs( "Netscape stderr output window\n"
  108.        "DO NOT CLOSE THIS WINDOW, it will terminate Netscape\n",
  109.        stderr);
  110.     // launch command interpreter to keep window open
  111.     return CreateProcess(NULL,            // module name
  112.        "cmd.exe",                     // gotta run something
  113.         NULL,                         // process security attributes
  114.         NULL,                         // thread  security attributes
  115.         TRUE,                         // process inherits handles
  116.         CREATE_SUSPENDED,             // creation flags
  117.         NULL,                         // new environment
  118.         NULL,                         // current directory
  119.         &si,                          //
  120.         &m_pi);                       //
  121. }
  122. #endif
  123.  
  124.  
  125.  
  126. /////////////////////////////////////////////////////////////////////////////
  127. // CNetscapeApp construction
  128.  
  129. CNetscapeApp::CNetscapeApp()
  130. {
  131.     //  Initially allow UNC file access.
  132.     m_bUNC = TRUE;
  133.     
  134.     // No slave context yet.
  135.     m_pSlaveCX = NULL;
  136.     m_pRDFCX = NULL;
  137.     
  138.     //  Explicitly clear the idle binding to timeout code.
  139.     m_bIdleProcessTimeouts = FALSE;
  140.  
  141.     //  Not in init instance.
  142.     m_bInInitInstance = FALSE;   //  Flag for frames created to use m_iFrameCmdShow
  143.     m_bInGetCriticalFiles = FALSE;  // Flag for frames created while getting early files 
  144.                                     // These are just HTML dialogs and need not have toolbars, etc
  145.     m_iFrameCmdShow = -1;
  146.  
  147.     // No windows / frames or Hotlist yet
  148.     m_bDontLoadHome          = FALSE;
  149.     m_pMainWnd              = NULL;
  150.     m_pUpdateWhatsNewWnd     = NULL;
  151.     m_pFrameList          = NULL;
  152.     m_pHiddenFrame          = NULL; 
  153.     m_pBookmarks          = NULL;
  154.     m_pNetcasterWindow          = NULL;
  155.     m_iTemplateLocationCount = 0;
  156.     pIconDC = pImageDC          = NULL;
  157.     m_ParentAppWindow          = NULL;
  158.     m_bChildWindow          = FALSE;
  159.     m_bParseTelnetURLs       = FALSE;
  160.     m_bNetworkProfile        = FALSE;
  161.  
  162.     // no dialup stuff yet
  163.     m_bKioskMode        = FALSE; 
  164.     m_bSuperKioskMode        = FALSE; 
  165. #ifdef MOZ_MAIL_NEWS
  166.     m_bCreateMail        = FALSE;
  167.     m_bCreateNews        = FALSE;
  168. #endif /* MOZ_MAIL_NEWS */
  169.     m_bCreateNetcaster    = FALSE;
  170. #ifdef MOZ_MAIL_NEWS
  171.     m_bCreateInbox        = FALSE;//causes the inbox to be started
  172.     m_bCreateFolders    = FALSE;//causes the folders frame window to be started
  173.     m_bCreateFolder        = FALSE;//causes a particular folder in the folders frame window to open
  174.     m_bCreateCompose    = FALSE;//causes the compose window to be opened, 3 different possibilities
  175. #endif /* MOZ_MAIL_NEWS */
  176. #ifdef EDITOR
  177.     m_bCreateEdit        = FALSE;//brings up the edit window
  178. #endif /* EDITOR */
  179. #ifdef MOZ_MAIL_NEWS
  180.     m_bCreateAddress    = FALSE;//openes the address book window
  181. #endif /* MOZ_MAIL_NEWS */
  182.     m_bCreateLDIF_IMPORT        = FALSE;//imports an LDIF file
  183.     m_bCreateLDIF_EXPORT        = FALSE;//imports an LDIF file
  184.     m_bCreateBrowser    = FALSE;//forces the browser to launch despite preferences settings.
  185.     m_bHasArguments        = FALSE;//signals that switch parameters need parsing 
  186.     m_bAccountSetupStartupJava = FALSE;
  187.  
  188.     m_bCreateNewProfile = FALSE;
  189.     m_bProfileManager    = FALSE;
  190.     m_bCreateJavaDebugAgent = FALSE;
  191.     m_bAccountSetup     = FALSE;
  192.     m_bAlwaysDockTaskBar = FALSE;
  193.     m_bShowNetscapeButton = FALSE;
  194.  
  195.     // No global java event queue yet...
  196.     mozilla_event_queue      = NULL;
  197.  
  198.     m_hPostalLib             = NULL;
  199.     m_fnOpenMailSession      = NULL;
  200.     m_fnComposeMailMessage   = NULL;
  201.     m_fnUnRegisterMailClient = NULL;
  202.     m_fnShowMailBox          = NULL; 
  203.     m_fnShowMessageCenter    = NULL; 
  204.     m_fnCloseMailSession     = NULL; 
  205.     m_fnGetMenuItemString    = NULL; 
  206.     m_bInitMapi          = TRUE;
  207.     m_bExitStatus          = FALSE;
  208.     InitTime();
  209.  
  210. #ifdef XP_WIN16
  211.     m_nMsgLast = WM_NULL;
  212.     ::GetCursorPos(&m_ptCursorLast);
  213. #endif
  214.  
  215.     /* This is the very first TRACE call in the client.
  216.      * If we want the output to work outside the debugger, 
  217.      * we must pass the output file handle to the C runtime debug 
  218.      * output routines.  Note: "CONOUT$" is the name of "/dev/tty"
  219.      */
  220. #if defined( _DEBUG) && defined( XP_WIN32 )
  221.     m_pi.hProcess = 0;
  222.     char * mozTraceFileName = getenv("MOZTRCFILE");
  223.     if (mozTraceFileName) {
  224.     HANDLE hTraceFile = INVALID_HANDLE_VALUE;
  225.     int success;
  226.  
  227.     if (!strcmp( "CONOUT$", mozTraceFileName)) {
  228.         success = InitConsoleWindow();
  229.     } else {
  230. //   This freopen doesn't work, so do it the hard way, use CreateFile.
  231. //          success = (NULL != freopen(mozTraceFileName, "a", stderr));
  232.         hTraceFile = CreateFile(
  233.             mozTraceFileName,
  234.             /* GENERIC_READ    | */ GENERIC_WRITE,
  235.             /* FILE_SHARE_READ | */ FILE_SHARE_WRITE,
  236.             NULL, OPEN_ALWAYS, 
  237.             FILE_ATTRIBUTE_NORMAL /* | FILE_FLAG_WRITE_THROUGH */,
  238.             NULL);
  239.         success = (hTraceFile != INVALID_HANDLE_VALUE);
  240.         if (success) {
  241.         SetStdHandle(STD_ERROR_HANDLE, hTraceFile);
  242.         }
  243.     }
  244.     if (success) {
  245.         _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  246.         _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
  247.     } else {
  248.         LPVOID lpMsgBuf;
  249.         DWORD lastErr = GetLastError();
  250.  
  251.         FormatMessage( 
  252.         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  253.         NULL,
  254.         lastErr,
  255.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  256.         (LPTSTR) &lpMsgBuf,
  257.         0,
  258.         NULL );
  259.  
  260.         // Display the string.
  261.         MessageBox( NULL, (char *)lpMsgBuf, "Create trace file", 
  262.             MB_OK|MB_ICONINFORMATION );
  263.  
  264.         // Free the buffer.
  265.         LocalFree( lpMsgBuf );
  266.     }
  267.     }
  268.  
  269. #endif
  270.     TRACE("Netscape App Constructor! \n");
  271. }
  272.  
  273. void CNetscapeApp::InitTime()
  274. {
  275.     m_ttStartTime = ::time(NULL);
  276.     m_dwLastMsgTick = m_dwStartTick = m_dwMsgTick = ::GetTickCount();
  277. }
  278.  
  279. BOOL
  280. CNetscapeApp::LoadPageSetupOptions()
  281. {
  282.     ApiPageSetup(api,0);
  283.     api->SetMargins ( 
  284.         (long) GetProfileInt ( "Page Setup", "Left", 720 ), 
  285.         (long) GetProfileInt ( "Page Setup", "Right", 720 ),
  286.         (long) GetProfileInt ( "Page Setup", "Top", 720 ),  
  287.         (long) GetProfileInt ( "Page Setup", "Bottom", 720 ) );
  288.     api->Header ( GetProfileInt ( 
  289.         "Page Setup", "Header", PRINT_TITLE | PRINT_URL ) );
  290.     api->Footer ( GetProfileInt ( 
  291.         "Page Setup","Footer", PRINT_PAGECOUNT | PRINT_PAGENO | PRINT_DATE ) );
  292.     api->SolidLines ( GetProfileInt ( "Page Setup", "SolidLines", 0 ) );
  293.     api->BlackLines ( GetProfileInt ( "Page Setup", "BlackLines", 0 ) );
  294.     api->BlackText ( GetProfileInt ( "Page Setup", "BlackText", 0 ) );
  295.     api->ReverseOrder ( GetProfileInt ( "Page Setup", "Reverse", 0 ) );
  296.     return TRUE;
  297. }
  298.  
  299. void
  300. CNetscapeApp::SavePageSetupOptions()
  301. {
  302.     ApiPageSetup(api,0);
  303.     long mleft, mright, mtop, mbottom;
  304.  
  305.     // save margins
  306.     api->GetMargins ( &mleft, &mright, &mtop, &mbottom );
  307.     theApp.WriteProfileInt ( "Page Setup", "left",  LOWORD(mleft) );
  308.     theApp.WriteProfileInt ( "Page Setup", "right", LOWORD(mright) );
  309.     theApp.WriteProfileInt ( "Page Setup", "top",   LOWORD(mtop) );
  310.     theApp.WriteProfileInt ( "Page Setup", "bottom",LOWORD(mbottom) );
  311.  
  312.     // save miscellaneous page setup flags
  313.     theApp.WriteProfileInt ( "Page Setup", "Header", api->Header ( ) );
  314.     theApp.WriteProfileInt ( "Page Setup", "Footer", api->Footer ( ) );
  315.     theApp.WriteProfileInt ( "Page Setup", "SolidLines", api->SolidLines ( ) );
  316.     theApp.WriteProfileInt ( "Page Setup", "BlackText", api->BlackText ( ) );
  317.     theApp.WriteProfileInt ( "Page Setup", "BlackLines", api->BlackLines ( ) );
  318.     theApp.WriteProfileInt ( "Page Setup", "Reverse", api->ReverseOrder ( ) );
  319. }
  320.  
  321. //
  322. // Parse the command line for INI file location and home page
  323. //
  324. void CNetscapeApp::parseCommandLine(char * commandLine)
  325. {
  326.     // assume no startup URL or profile
  327.     m_CmdLineLoadURL = NULL;
  328.     m_CmdLineProfile = NULL;
  329.  
  330.     if(IsRuntimeSwitch("-P",FALSE)) {
  331.         // extract the quoted profile name..the format is -P"jonm@netscape.com"
  332.         CString csCommandLine = commandLine;
  333.         int iFirstQuote = csCommandLine.Find("-P\"");
  334.         if( iFirstQuote != -1 ){
  335.             iFirstQuote += 2;
  336.             csCommandLine = csCommandLine.Mid(iFirstQuote+1);
  337.             int iLastQuote = csCommandLine.Find('\"');
  338.             if( iLastQuote == -1 ){
  339.                 // No last quote -- remove first quote from command line
  340.                 strcpy( (commandLine+iFirstQuote), (commandLine+iFirstQuote+1));
  341.             } else {
  342.                 m_CmdLineProfile = XP_STRDUP(csCommandLine.Left(iLastQuote));
  343.                 // Remove the extracted string from command line
  344.                 strcpy( (commandLine+iFirstQuote), (commandLine+iFirstQuote+iLastQuote+2));
  345.             }
  346.             IsRuntimeSwitch("-P",TRUE);  // now remove the -P from the command line
  347.         }
  348.     }
  349.     // Extract a filepath enclosed in quotes
  350.     // MUST have both quotes, or we ignore it and strip away the first quote
  351.     CString csCommandLine = commandLine;
  352.     int iFirstQuote = csCommandLine.Find('\"');
  353.     if( iFirstQuote != -1 ){
  354.         csCommandLine = csCommandLine.Mid(iFirstQuote+1);
  355.         int iLastQuote = csCommandLine.Find('\"');
  356.         if( iLastQuote == -1 ){
  357.             // No last quote -- remove first quote from command line
  358.             strcpy( (commandLine+iFirstQuote), (commandLine+iFirstQuote+1));
  359.         } else {
  360.             m_CmdLineLoadURL = XP_STRDUP(csCommandLine.Left(iLastQuote));
  361.             // Remove the extracted string from command line
  362.             strcpy( (commandLine+iFirstQuote), (commandLine+iFirstQuote+iLastQuote+2));
  363.         }
  364.     }
  365.  
  366.     //  Need way to track if used command line -i switch.
  367.     //
  368.     BOOL bIniOption = FALSE;
  369.  
  370.     //    Check for the INI file location.
  371.     CString csINI;
  372.     CString csParentHwnd;
  373.  
  374.     // kiosk mode
  375.     if(IsRuntimeSwitch("-k", TRUE))
  376.         m_bKioskMode = TRUE;
  377.         
  378.     // super kiosk mode
  379.     if(IsRuntimeSwitch("-sk", TRUE)) {
  380.         m_bKioskMode = TRUE;
  381.         m_bSuperKioskMode = TRUE;
  382.     }
  383.         
  384.     // load home page?
  385.     if(IsRuntimeSwitch("-H", TRUE))
  386.         m_bDontLoadHome = TRUE;
  387.  
  388. #ifdef MOZ_MAIL_NEWS
  389.     if(IsRuntimeSwitch("-mail",TRUE))
  390.         m_bCreateMail = TRUE;
  391. #endif /* MOZ_MAIL_NEWS */
  392.  
  393.     if(IsRuntimeSwitch("-netcaster",TRUE))
  394.         m_bCreateNetcaster = TRUE;
  395.  
  396. #ifdef MOZ_MAIL_NEWS
  397.     if(IsRuntimeSwitch("-news",TRUE))
  398.         m_bCreateNews = TRUE;
  399. #endif /* MOZ_MAIL_NEWS */
  400.  
  401.     if(IsRuntimeSwitch("-new_profile",TRUE))
  402.         m_bCreateNewProfile = TRUE;
  403.  
  404.     if(IsRuntimeSwitch("-profile_manager",TRUE))
  405.         m_bProfileManager = TRUE;
  406.  
  407.     if (IsRuntimeSwitch("-parse_telnet"))
  408.         m_bParseTelnetURLs = TRUE;
  409.  
  410. #ifdef JAVA
  411.     if(IsRuntimeSwitch("-javadebug",TRUE)) {
  412.         m_bCreateJavaDebugAgent = TRUE;
  413.     }
  414. #endif
  415.  
  416.     //This is a rather hideous hack to allow Navigator as a child window.
  417.     //It is turned off until such time as it is deemed safe and absolutely necessary.
  418.     /*if(IsRuntimeSwitch("-child",FALSE)) {
  419.     csParentHwnd = RuntimeStringSwitch("-child");
  420.     sscanf(csParentHwnd, "%x", &m_ParentAppWindow);
  421.     } */
  422.  
  423.     if(IsRuntimeSwitch("-new_account",TRUE)){
  424.         m_bAccountSetup = TRUE;
  425.         m_bAlwaysDockTaskBar = TRUE;
  426.         m_bAccountSetupStartupJava = TRUE;
  427.     }
  428.  
  429.  
  430.     if(IsRuntimeSwitch("-start_java",TRUE))
  431.         m_bAccountSetupStartupJava = TRUE;
  432.  
  433.  
  434.     // do *NOT* let /I be a run time switch because IsRuntimeSwitch
  435.     //   is currently not smart enough to deal with http://foo/index.html
  436.     //   correctly
  437.     if(IsRuntimeSwitch("-I", FALSE)) {
  438.         csINI = RuntimeStringSwitch("-I");
  439.     }
  440.  
  441. #ifdef XP_WIN16
  442.  
  443.     if(csINI.IsEmpty() == FALSE)    {
  444.         //    Make sure it's a good location.
  445.         if(FEU_SanityCheckFile(csINI) == FALSE)    {
  446.             MessageBox(NULL, szLoadString(IDS_INVALID_INIFILE), szLoadString(AFX_IDS_APP_TITLE), MB_OK);
  447.         }
  448.         else    {
  449.             //    This is our new INI file
  450.             theApp.m_pszProfileName = (const char *)XP_STRDUP(csINI);
  451.             bIniOption = TRUE;
  452.         }
  453.     }
  454. #endif
  455.  
  456. #ifdef EDITOR
  457.     // This is used to tst for edit startup and 
  458.     // is only TRUE if we are a Gold version
  459.     m_bCmdEdit = FALSE;
  460.     CString csEditFile;
  461. // Look for Start-Editor switch
  462.     if(IsRuntimeSwitch("-EDIT",FALSE))    {
  463.         csEditFile = RuntimeStringSwitch("-EDIT");
  464.         m_bCmdEdit = TRUE;
  465.     }
  466.     if ( m_bCmdEdit ) {
  467.         // Copy the returnd string back to the command line
  468.            XP_STRCPY( commandLine, LPCSTR(csEditFile) );
  469.     }
  470. #endif // EDITOR
  471.  
  472.      //  Pointer into command line as we parse it
  473.     //
  474.     char *curLoc = m_lpCmdLine;
  475.  
  476.     //    Skip the white space.
  477.     while(curLoc && *curLoc != '\0' && isspace(*curLoc))
  478.         curLoc++;
  479.  
  480.     if( m_CmdLineLoadURL == NULL ){
  481.         // still stuff left --- assume its a file to load.
  482.         // if someone dragged a file onto us this will be a DOS path
  483.         //   when we get around to calling OnNormalLoad() to actually
  484.         //   load the page it will get interpreted correctly.
  485.         if(curLoc && *curLoc) {
  486.  
  487.             // if first char is a double quote don't copy it over
  488.             if(curLoc[0] == '\"')
  489.                 m_CmdLineLoadURL = XP_STRDUP(&(curLoc[1]));
  490.             else
  491.                 m_CmdLineLoadURL = XP_STRDUP(curLoc);
  492.  
  493.             // Win9x conveniently brackets the filename in double quotes
  494.             //   convert them to spaces and let the netlib strip them out
  495.             for(char * c = m_CmdLineLoadURL; c && *c; c++)
  496.                 if(*c == '\"')
  497.                     *c = ' ';
  498.         }
  499.     }
  500.  
  501. #ifdef XP_WIN16
  502.     
  503.     //    If they didn't use the command line -i to specify
  504.     //        the location of the INI file, attempt to use
  505.     //        the location specified in the win.ini file.
  506.     //    Scope the function call correctly or you will get
  507.     //        the wrong information.
  508.     //    The return buffer will never be empty.
  509.     //
  510.     //    Revised:
  511.     //        Order of INI preference is as follows:
  512.     //            command line
  513.     //            win.ini
  514.     //            current directory
  515.     //            windows directory
  516.     //        After resolution from win.ini down, then make
  517.     //            sure the the win.ini file actually contains
  518.     //            the correct reference; otherwise replace it.
  519.     //
  520.     if(!bIniOption)    {
  521.         const char *cp_NotInIni = "Garrett 'Archibald Cox' Blythe";
  522.         const char *cp_WinIniSection = XP_STRDUP(szLoadString(IDS_WIN_INI_SECTION));
  523.         const char *cp_IniFile = XP_STRDUP(szLoadString(IDS_INI_FILE_NAME));
  524.         const char *cp_WinIniEntry = "ini";
  525.     
  526.         //  Figure out the app's path for the default value.
  527.         //  Tack on netscape.ini on the end.
  528.         //
  529.         auto char ca_default[_MAX_PATH];
  530.         ::GetModuleFileName(m_hInstance, ca_default, _MAX_PATH);
  531.         auto char *cp_lastslash = ::strrchr(ca_default, '\\') + 1;
  532.         ::strcpy(cp_lastslash, cp_IniFile);
  533.     
  534.  
  535.         //  Check the win.ini file for an entry pointing to the ini file.
  536.         //
  537.         auto char ca_iniBuff[_MAX_PATH];
  538.         ::GetProfileString(cp_WinIniSection, cp_WinIniEntry, cp_NotInIni, ca_iniBuff, _MAX_PATH);
  539.     
  540.         //  If it isn't located in the ini file, set a flag,
  541.         //    and copy over a default file name.
  542.         //
  543.         auto int i_UpdateWinIni = FALSE;
  544.         if(::strcmp(cp_NotInIni, ca_iniBuff) == 0)  {
  545.             i_UpdateWinIni = TRUE;
  546.             ::strcpy(ca_iniBuff, ca_default);
  547.         }
  548.     
  549.         m_pszProfileName = (const char *)XP_STRDUP(ca_iniBuff);
  550.     
  551.         //  Does it exist?
  552.         //
  553.         if(FEU_SanityCheckFile(m_pszProfileName) == FALSE)  {
  554.             //  Well, shoot.
  555.             //  Attempt to use the windows directory for the INI file.
  556.             //
  557.             char ca_windir[_MAX_PATH];
  558.             ::GetWindowsDirectory(ca_windir, _MAX_PATH);
  559.             if(ca_windir[::strlen(ca_windir) - 1] != '\\')  {
  560.                 ::strcat(ca_windir, "\\");
  561.             }
  562.             ::strcat(ca_windir, cp_IniFile);
  563.       
  564.             if(FEU_SanityCheckFile(ca_windir) == FALSE) {
  565.                 //  Unable to locate any INI file.
  566.                 //  We are going to use the original default, because
  567.                 //    we know the directory exists.
  568.                 //  Update the win.ini file regardless; there is no good location anyhow.
  569.                 //
  570.                 XP_FREE((void *)m_pszProfileName);
  571.                 m_pszProfileName = (const char *)XP_STRDUP(ca_default);
  572.                 i_UpdateWinIni = TRUE;
  573.             } else  {
  574.                 //  Use INI in windows directory.
  575.                 //
  576.                 XP_FREE((void *)m_pszProfileName);
  577.                 m_pszProfileName = (const char *)XP_STRDUP(ca_windir);
  578.  
  579.                 //  Add this to the win.ini file to avoid confusion
  580.                 //    in the future.
  581.                 //
  582.                 i_UpdateWinIni = TRUE;        
  583.             }
  584.         }
  585.     
  586.         //  Update the win.ini file if need be.
  587.         //
  588.         if(i_UpdateWinIni == TRUE)
  589.             ::WriteProfileString(cp_WinIniSection, cp_WinIniEntry, m_pszProfileName);
  590.     }
  591.  
  592. #endif // XP_WIN16
  593.  
  594. } // CNetscapeApp::parseCommandLine
  595.  
  596. /****************************************************************************
  597. *
  598. *    CNetscapeApp::CheckDefaultBrowser
  599. *
  600. *    PARAMETERS:
  601. *        none
  602. *
  603. *    RETURNS:
  604. *        void
  605. *
  606. *    DESCRIPTION:
  607. *        This function checks the registry to see if we are still registered
  608. *        as the "default browser" (listed under http key and other extensions),
  609. *        since the MS Explorer has a nasty habit of kicking us out! If not,
  610. *        we prompt the user to restore our registry settings and make us
  611. *        the default again.
  612. *
  613. ****************************************************************************/
  614.  
  615. void CNetscapeApp::CheckDefaultBrowser()
  616. {
  617. // We're only worrying about this for Win32
  618. #ifdef XP_WIN32
  619.     
  620.     // Construct the App's owned and lost list.  Used to determine exactly which
  621.     // file types were lost.  This construction should perform the comparison and
  622.     // update the lost list.  The result will be written out to the registry.
  623.     m_OwnedAndLostList.ConstructLists();
  624.     
  625.     MakeDefaultBrowser();
  626.     
  627.     m_OwnedAndLostList.WriteLists();
  628.  
  629. #endif // XP_WIN32
  630. } // END OF    FUNCTION CNetscapeApp::CheckDefaultBrowser()
  631.  
  632.  
  633. void CNetscapeApp::MakeDefaultBrowser()
  634. {
  635. #ifdef XP_WIN32
  636.  
  637.     // Pop up a list containing the lost file types.
  638.     CDefaultBrowserDlg dlg;
  639.     CPtrArray* lostList = m_OwnedAndLostList.GetLostList();
  640.     if (theApp.m_OwnedAndLostList.NonemptyLostIgnoredIntersection())
  641.         dlg.DoModal();
  642.  
  643. #endif // XP_WIN32
  644. }
  645.  
  646. int CNetscapeApp::RuntimeIntSwitch(const char *pSwitch)    {
  647.     int iRetval = -1;
  648.  
  649.     //    Search for the switch in the command line.
  650.     char *pFound = strcasestr(m_lpCmdLine, pSwitch);
  651.     if(pFound == NULL)    {
  652.         return(iRetval);
  653.     }
  654.  
  655.     //    Okay, found it.  Now, go beyond it, and return the value following as an int.
  656.     char *pStart = pFound;
  657.     pFound += strlen(pSwitch);
  658.     while(isspace(*pFound))    {
  659.         pFound++;
  660.     }
  661.     sscanf(pFound, "%d", &iRetval);
  662.  
  663.     //    Take the entire thing out of the command line.
  664.     while(FALSE == isspace(*pFound) && *pFound != '\0')    {
  665.         pFound++;
  666.     }
  667.     char *pTravEnd = pFound;
  668.     char *pTraverse = pStart;
  669.  
  670.     *pTraverse = *pTravEnd;
  671.     while(*pTraverse != '\0')    {
  672.         pTraverse++;
  673.         pTravEnd++;
  674.         *pTraverse = *pTravEnd;
  675.     }
  676.  
  677.     return(iRetval);
  678. }
  679.  
  680. static BOOL IsCommand( const char *pszCmdLine, const char *pszOffset, const char *pszSwitch )
  681. {
  682.     //
  683.     // Let's be somewhat smart and make sure this is really a command and not e.g., /netscape/<command>stuff.html
  684.     // For now we just ensure the command is sandwiched between spaces e.g., "netscape.exe /<command> /somewhere/doc.html"
  685.     //
  686.     
  687.     if( *pszOffset != '/' )
  688.     {
  689.         return TRUE;
  690.     }
  691.     
  692.     if( pszOffset != pszCmdLine )
  693.     {
  694.         if( !isspace( *(pszOffset-1) ) )
  695.         {
  696.             // Must have a preceding space if not the beginning of the cmd line
  697.             
  698.             return FALSE;
  699.         }
  700.     }    
  701.     
  702.     if( !isspace( *(pszOffset + _tcslen( pszSwitch )) ) )
  703.     {
  704.         // Must have a traling space
  705.         
  706.         return FALSE;
  707.     }
  708.     
  709.     return TRUE;
  710. }
  711.  
  712. CString CNetscapeApp::RuntimeStringSwitch(const char *pSwitch, BOOL bCheckCommand)    
  713. {
  714.     CString csRetval;
  715.  
  716.     //    Search for the switch in the command line.
  717.     char *pFound = strcasestr(m_lpCmdLine, pSwitch);
  718.     
  719.     //  Don't attempt to be smart about the command if asked not to be, as the
  720.     //      command detector is not smart about complex switches like /printto
  721.     //      being detected by /print.
  722.     if( !pFound || (bCheckCommand && !IsCommand( m_lpCmdLine, pFound, pSwitch )) )    
  723.     {
  724.         return csRetval;
  725.     }
  726.  
  727.     //    Okay, found it.  Now, go beyond it, and return the value following as a string.
  728.     char *pStart = pFound;
  729.     pFound += strlen(pSwitch);
  730.     while(isspace(*pFound))    {
  731.         pFound++;
  732.     }
  733.  
  734.     //    Take the entire thing out of the command line.
  735.     //  Respect quotes (spaces allowed inside of quotes).
  736.     BOOL bQuote = FALSE;
  737.     while((!isspace(*pFound) || bQuote) && *pFound != '\0')    {
  738.         if(*pFound == '\"') {
  739.             if(bQuote)  {
  740.                 bQuote = FALSE;
  741.             }
  742.             else    {
  743.                 bQuote = TRUE;
  744.             }
  745.         }
  746.         csRetval += *pFound;
  747.         pFound++;
  748.     }
  749.     char *pTravEnd = pFound;
  750.     char *pTraverse = pStart;
  751.  
  752.     // OK, so pTraverse points to the first character of the command line switch
  753.     //   and pTravEnd points to the first character after the string part of the
  754.     //   command.  While there are bits of command line left copy them over
  755.     while(*pTravEnd != '\0')    {
  756.         *pTraverse++ = *pTravEnd++;
  757.     }
  758.  
  759.     // Make sure we are NULL terminated
  760.     *pTraverse = '\0';
  761.  
  762.     return(csRetval);
  763. }
  764.  
  765. BOOL CNetscapeApp::IsRuntimeSwitch(const char *pSwitch, BOOL bRemove)    
  766. {
  767.     //  Search for the switch in the command line.
  768.     //  Don't take it out by default
  769.     char *pFound = strcasestr(m_lpCmdLine, pSwitch);
  770.     if(pFound == NULL ||
  771.         // Switch must be at beginning of command line
  772.         //   or have a space in front of it to avoid
  773.         //   mangling filenames
  774.         ( (pFound != m_lpCmdLine) &&
  775.           *(pFound-1) != ' ' ) ) {
  776.         return(FALSE);
  777.     }
  778.  
  779.     if (bRemove) {
  780.         // remove the flag from the command line
  781.         char *pTravEnd = pFound + strlen(pSwitch);
  782.         char *pTraverse = pFound;
  783.  
  784.         *pTraverse = *pTravEnd;
  785.         while(*pTraverse != '\0')   {
  786.             pTraverse++;
  787.             pTravEnd++;
  788.             *pTraverse = *pTravEnd;
  789.         }
  790.     }
  791.  
  792.     return(TRUE);
  793. }
  794.  
  795.  
  796. BOOL CNetscapeApp::IsRuntimeSwitch(const char *pSwitch, char *pszCommandLine, BOOL bRemove)    
  797. {
  798.     //  Search for the switch in the command line.
  799.     //  Don't take it out by default
  800.     char *pFound = strcasestr(pszCommandLine, pSwitch);
  801.     if(pFound == NULL ||
  802.         // Switch must be at beginning of command line
  803.         //   or have a space in front of it to avoid
  804.         //   mangling filenames
  805.         ( (pFound != pszCommandLine) &&
  806.           *(pFound-1) != ' ' ) ) {
  807.         return(FALSE);
  808.     }
  809.  
  810.     if (bRemove) {
  811.         // remove the flag from the command line
  812.         char *pTravEnd = pFound + strlen(pSwitch);
  813.         char *pTraverse = pFound;
  814.  
  815.         *pTraverse = *pTravEnd;
  816.         while(*pTraverse != '\0')   {
  817.             pTraverse++;
  818.             pTravEnd++;
  819.             *pTraverse = *pTravEnd;
  820.         }
  821.     }
  822.  
  823.     return(TRUE);
  824. }
  825.  
  826. void CNetscapeApp::StoreVersionInReg() {
  827.     //  Figure out the versioning information about the binary.
  828.     CString csVersion;
  829.     char *tmpBuf;
  830.     char *ptr = NULL;
  831.  
  832.     csVersion = ResolveShortAppVersion();
  833.  
  834.     // we need to replace square brackets with parens to store into ini file
  835.     tmpBuf = (char *)XP_ALLOC(csVersion.GetLength() + 1);
  836.     strcpy(tmpBuf,csVersion);
  837.     
  838.     // point to start
  839.     ptr = tmpBuf;
  840.     while (ptr && *ptr) {
  841.         if (*ptr == '[') *ptr = '(';
  842.         if (*ptr == ']') *ptr = ')';
  843.         ptr++;
  844.     }
  845.  
  846.     long result;
  847. #ifdef XP_WIN32
  848.     HKEY hKeyRet = NULL;
  849.     CString csSub = "SOFTWARE\\Netscape\\Netscape Navigator\\";
  850.  
  851.     result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  852.                         csSub,
  853.                         NULL,
  854.                         KEY_SET_VALUE,
  855.                         &hKeyRet);
  856.  
  857.     if (result == ERROR_SUCCESS) {
  858.         RegSetValueEx(hKeyRet,"CurrentVersion",NULL,REG_SZ,(const BYTE *)tmpBuf,strlen(tmpBuf)+1);
  859.         RegCloseKey(hKeyRet);
  860.     }
  861. #else
  862.     CString csNSCPini;
  863.     login_GetIniFilePath(csNSCPini);
  864.  
  865.     result = ::WritePrivateProfileString("Netscape Navigator", "CurrentVersion", tmpBuf ,csNSCPini);   
  866. #endif
  867.     if (tmpBuf) XP_FREE(tmpBuf);
  868.     return;
  869.  
  870. }
  871.  
  872. CString CNetscapeApp::ResolveShortAppVersion()   {
  873.     //  Figure out the versioning information about the binary.
  874.     CString csVersion;
  875.     char *tmpversionBuf;
  876.  
  877.     tmpversionBuf = (char *)XP_ALLOC(15);
  878.     //Loading from netscape.exe instead of resdll.dll since the string has been moved #109455
  879.     LoadString(::AfxGetInstanceHandle(), IDS_APP_VERSION, tmpversionBuf, 15);
  880.     csVersion = tmpversionBuf;
  881.     csVersion += " [";
  882.     csVersion += XP_AppLanguage;
  883.     csVersion += "]";
  884.     if (tmpversionBuf) XP_FREE(tmpversionBuf);
  885.     return csVersion;
  886. }
  887.  
  888. CString CNetscapeApp::ResolveAppVersion()   {
  889.     //  Figure out the versioning information about the binary.
  890.     CString csVersion;
  891.     
  892.     csVersion = ResolveShortAppVersion();
  893.  
  894.     //  Start building the return value.
  895.     //  Version and Platform.
  896.     BOOL bShowBuildBits = FALSE;
  897.     CString csReturn;
  898.     csReturn += csVersion;
  899.  
  900.     char *pCustAgent = NULL;
  901.     PREF_CopyConfigString("user_agent",&pCustAgent);
  902.     if (pCustAgent) {
  903.         if (*pCustAgent) {
  904.             csReturn += "C-";
  905.             csReturn += pCustAgent;
  906.             csReturn += ' ';
  907.         }
  908.         XP_FREE(pCustAgent);
  909.     }
  910.  
  911.     csReturn += " (Win";
  912.  
  913.     if(sysInfo.m_bWin16 == TRUE)    {
  914.         if(sysInfo.m_bWin32s == TRUE)    {
  915.             csReturn += "32s";
  916.             bShowBuildBits = TRUE;
  917.         }
  918.         else if(sysInfo.m_bWinNT == TRUE)    {
  919.             csReturn += "NT";
  920.             bShowBuildBits = TRUE;
  921.         }
  922.         else if(sysInfo.m_bWin4 == TRUE)    {
  923.             csReturn += "95";
  924.             bShowBuildBits = TRUE;
  925.         }
  926.         else    {
  927.             csReturn += "16";
  928.         }
  929.     }
  930.     else if(sysInfo.m_bWin32 == TRUE)    {
  931.         if(sysInfo.m_bWin32s == TRUE)    {
  932.             csReturn += "32s";
  933.             bShowBuildBits = TRUE;
  934.         }
  935.         else if(sysInfo.m_bWinNT == TRUE)    {
  936.             csReturn += "NT";
  937.             if(sysInfo.m_dwMajor > 4) {
  938.                 csReturn += (char)('0' + sysInfo.m_dwMajor);
  939.             }
  940.         }
  941.         else if(sysInfo.m_bWin4 == TRUE)    {
  942.             if(sysInfo.m_dwMinor >= 10) {
  943.                 csReturn += "98";
  944.             }
  945.             else {
  946.                 csReturn += "95";
  947.             }
  948.         }
  949.         else    {
  950.             TRACE("What OS are you on anyhow?\n");
  951.             csReturn += "dows";
  952.             bShowBuildBits = TRUE;
  953.             ASSERT(0);
  954.         }
  955.     }
  956.     else    {
  957.         TRACE("What OS are you on anyhow?\n");
  958.         csReturn += "dows";
  959.         bShowBuildBits = TRUE;
  960.         ASSERT(0);
  961.     }
  962.  
  963.     csReturn += "; ";
  964.  
  965.     //  Security.
  966.     csReturn += XP_SecurityVersion(0);
  967.  
  968.     //    Only show the build bits if the OS is ambiguous.
  969.     if(bShowBuildBits == TRUE)    {
  970.         csReturn += "; ";
  971.  
  972.         //  Build type.
  973. #if defined(WIN32) || defined(__WIN32__)
  974.         csReturn += "32bit";
  975. #else
  976.         csReturn += "16bit";
  977. #endif
  978.     }
  979.    
  980. #ifndef MOZ_COMMUNICATOR_NAME
  981.     csReturn += " ;Nav";
  982. #endif /* MOZ_COMMUNICATOR_NAME */    
  983.  
  984.     csReturn += ")";
  985.     return(csReturn);
  986. }
  987.  
  988. //
  989. // Overload GetProfileString to get out of the registry if we are a Win32
  990. //   application
  991. //
  992. CString CNetscapeApp::GetProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszDefault)
  993. {
  994.  
  995. #ifdef XP_WIN16
  996.  
  997.     return(CWinApp::GetProfileString(lpszSection, lpszEntry, lpszDefault)); 
  998.  
  999. #else
  1000.  
  1001.     HKEY  hKey;
  1002.     long result;
  1003.     DWORD type, size;
  1004.     char buffer[255];
  1005.     char * pString;
  1006.     static CString csStr;
  1007.  
  1008.     sprintf(buffer, "Software\\%s\\%s\\%s", "Netscape", "Netscape Navigator", lpszSection);
  1009.  
  1010.     csStr = lpszDefault;
  1011.  
  1012.     // get a pointer to this entry
  1013.     result = RegOpenKeyEx(HKEY_CURRENT_USER,
  1014.                             buffer,
  1015.                             NULL,
  1016.                             KEY_QUERY_VALUE,
  1017.                             &hKey);
  1018.  
  1019.     if(result != ERROR_SUCCESS)
  1020.         return(csStr);
  1021.  
  1022.     // see how much space we need
  1023.     size = 0;
  1024.     result = RegQueryValueEx(hKey,
  1025.                               (char *) lpszEntry,
  1026.                               NULL,
  1027.                               &type,
  1028.                               NULL,
  1029.                               &size);
  1030.  
  1031.     // if we didn't find it just use the default
  1032.     if((result != ERROR_SUCCESS) || (size == 0)) {
  1033.         RegCloseKey(hKey);
  1034.         return(csStr);
  1035.     }
  1036.  
  1037.     // allocate space to hold the string
  1038.     pString = (char *) XP_ALLOC(size * sizeof(char));
  1039.  
  1040.     // actually load the string now that we have the space
  1041.     result = RegQueryValueEx(hKey,
  1042.                               (char *) lpszEntry,
  1043.                               NULL,
  1044.                               &type,
  1045.                               (LPBYTE) pString,
  1046.                               &size);
  1047.  
  1048.     // use default id something went wrong this time
  1049.     if(result == ERROR_SUCCESS)
  1050.         csStr = pString;
  1051.  
  1052.     XP_FREE(pString);
  1053.  
  1054.     RegCloseKey(hKey);
  1055.     return(csStr);
  1056.  
  1057. #endif
  1058.  
  1059. }
  1060.  
  1061. //
  1062. // Overload GetProfileInt to get out of the registry if we are a Win32
  1063. //   application
  1064. //
  1065. UINT CNetscapeApp::GetProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nDefault)
  1066. {
  1067.  
  1068. #ifdef XP_WIN16
  1069.  
  1070.     return(CWinApp::GetProfileInt(lpszSection, lpszEntry, nDefault)); 
  1071.  
  1072. #else
  1073.  
  1074.     HKEY  hKey;
  1075.     long result;
  1076.     DWORD type, size;
  1077.     char buffer[255];
  1078.  
  1079.     sprintf(buffer, "Software\\%s\\%s\\%s", "Netscape", "Netscape Navigator", lpszSection);
  1080.  
  1081.     result = RegOpenKeyEx(HKEY_CURRENT_USER,
  1082.                             buffer,
  1083.                             NULL,
  1084.                             KEY_QUERY_VALUE,
  1085.                             &hKey);
  1086.  
  1087.     // use default if something went wrong this time
  1088.     if(result != ERROR_SUCCESS)
  1089.         return(nDefault);
  1090.  
  1091.     int value;
  1092.     size = sizeof(int);
  1093.     result = RegQueryValueEx(hKey,
  1094.                               (char *) lpszEntry,
  1095.                               NULL,
  1096.                               &type,
  1097.                               (LPBYTE) &value,
  1098.                               &size);
  1099.     RegCloseKey(hKey);
  1100.  
  1101.     // use default if something went wrong this time
  1102.     if(result != ERROR_SUCCESS)
  1103.         return(nDefault);
  1104.  
  1105.     return(value);
  1106.  
  1107. #endif
  1108.  
  1109. }
  1110.  
  1111.  
  1112. //
  1113. // Overload WriteProfileString to write to the registry if we are a Win32
  1114. //   application
  1115. //
  1116. BOOL CNetscapeApp::WriteProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszValue)
  1117. {
  1118.  
  1119. #ifdef XP_WIN16
  1120.  
  1121.     return(CWinApp::WriteProfileString(lpszSection, lpszEntry, lpszValue)); 
  1122.  
  1123. #else
  1124.   
  1125.     HKEY  hKey;
  1126.     DWORD dwDisposition; 
  1127.     long result;
  1128.     char buffer[255];
  1129.  
  1130.     if (lpszValue == NULL) {
  1131.         sprintf(buffer, "Software\\%s\\%s\\%s", "Netscape", "Netscape Navigator", lpszSection);
  1132.     
  1133.         // Open the key to the section
  1134.         result = RegOpenKeyEx(HKEY_CURRENT_USER, buffer, NULL, KEY_WRITE, &hKey);
  1135.         
  1136.         if (result == ERROR_SUCCESS) {
  1137.             // Delete the value
  1138.             ::RegDeleteValue(hKey, lpszEntry);
  1139.     
  1140.             // Close the key
  1141.             ::RegCloseKey(hKey);
  1142.         }
  1143.         return TRUE;
  1144.     }
  1145.  
  1146.     // The MSDN CD sez RegSetValueEx() should create the key if it
  1147.     //   doesn't exist but it doesn't seem to be respecting hierarchies
  1148.     sprintf(buffer, "Software\\%s\\%s\\%s", "Netscape", "Netscape Navigator", lpszSection);
  1149.     result = RegCreateKeyEx(HKEY_CURRENT_USER,
  1150.                             buffer,
  1151.                             NULL,
  1152.                             NULL,
  1153.                             NULL,
  1154.                             KEY_ALL_ACCESS,
  1155.                             NULL,
  1156.                             &hKey,
  1157.                             &dwDisposition);
  1158.  
  1159.     if(result != ERROR_SUCCESS)
  1160.         return(0);
  1161.  
  1162.     result = RegSetValueEx(hKey,
  1163.                               lpszEntry,
  1164.                               NULL,
  1165.                               REG_SZ,
  1166.                               (LPBYTE) lpszValue,
  1167.                               XP_STRLEN(lpszValue) + 1);
  1168.     RegCloseKey(hKey);
  1169.  
  1170.     return(result == ERROR_SUCCESS);
  1171.  
  1172. #endif
  1173.  
  1174. }
  1175.  
  1176. //
  1177. // Overload WriteProfileInt to write to the registry if we are a Win32
  1178. //   application
  1179. //
  1180. BOOL CNetscapeApp::WriteProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nValue)
  1181. {
  1182.  
  1183. #ifdef XP_WIN16
  1184.  
  1185.     return(CWinApp::WriteProfileInt(lpszSection, lpszEntry, nValue)); 
  1186.  
  1187. #else
  1188.   
  1189.     HKEY  hKey;
  1190.     DWORD dwDisposition; 
  1191.     long result;
  1192.     char buffer[255];
  1193.  
  1194.     // The MSDN CD sez RegSetValueEx() should create the key if it
  1195.     //   doesn't exist but it doesn't seem to be respecting hierarchies
  1196.     sprintf(buffer, "Software\\%s\\%s\\%s", "Netscape", "Netscape Navigator", lpszSection);
  1197.     result = RegCreateKeyEx(HKEY_CURRENT_USER,
  1198.                             buffer,
  1199.                             NULL,
  1200.                             NULL,
  1201.                             NULL,
  1202.                             KEY_ALL_ACCESS,
  1203.                             NULL,
  1204.                             &hKey,
  1205.                             &dwDisposition);
  1206.  
  1207.     if(result != ERROR_SUCCESS)
  1208.         return(0);
  1209.  
  1210.     result = RegSetValueEx(hKey,
  1211.                               lpszEntry,
  1212.                               NULL,
  1213.                               REG_DWORD,
  1214.                               (LPBYTE) &nValue,
  1215.                               sizeof(int));
  1216.     RegCloseKey(hKey);
  1217.  
  1218.     return(result == ERROR_SUCCESS);
  1219.  
  1220. #endif
  1221.  
  1222. }
  1223.  
  1224.  
  1225. DWORD CNetscapeApp::GetPrivateProfileString(LPCSTR lpSectionName, LPCSTR lpKeyName,
  1226.     LPCSTR lpDefault, LPSTR lpReturnedString, DWORD nSize, LPCSTR lpFileName)    {
  1227. #ifdef XP_WIN16
  1228.     return((DWORD) ::GetPrivateProfileString(lpSectionName, lpKeyName,  lpDefault, lpReturnedString,
  1229.         CASTINT(nSize), lpFileName));
  1230. #else
  1231.     //    For safty, automatically copy two nulls into the return value.
  1232.     //    This will ensure any code looking into this string will fail.
  1233.     *lpReturnedString = *(lpReturnedString + 1) = '\0';
  1234.  
  1235.     //    We don't handle empty sections!
  1236.     //    However, we could with a little code.
  1237.     if(lpSectionName == NULL)    {
  1238.         ASSERT(0);
  1239.         return(0);
  1240.     }
  1241.  
  1242.     //    See if we're getting a full section, or just one specific key.
  1243.     if(lpKeyName != NULL)    {
  1244.         //    Name value pair requested.
  1245.         CString csValue = GetProfileString(lpSectionName, lpKeyName, lpDefault);
  1246.         if(csValue.IsEmpty() == TRUE)    {
  1247.             return(0);
  1248.         }
  1249.  
  1250.         //    Copy over the string.
  1251.         strncpy(lpReturnedString, csValue, nSize);
  1252.  
  1253.         //    End the string manually (might not have appended NULL).
  1254.         *(lpReturnedString + nSize - 1) = '\0';
  1255.  
  1256.         //    Return the length.
  1257.         return(strlen(lpReturnedString));
  1258.     }
  1259.     
  1260.     //    Create the appropriate key.
  1261.     //    We'll need to enumerate over everything.
  1262.     HKEY hKey;
  1263.     DWORD dwDisposition;
  1264.     char aBuffer[256];
  1265.     sprintf(aBuffer, "Software\\%s\\%s\\%s", "Netscape", "Netscape Navigator",
  1266.         lpSectionName);
  1267.     long lResult = RegCreateKeyEx(HKEY_CURRENT_USER, aBuffer, NULL, NULL, NULL,
  1268.         KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition);
  1269.     if(lResult != ERROR_SUCCESS)    {
  1270.         return(0);
  1271.     }
  1272.  
  1273.     //    Enumerate everything.
  1274.     //    We stick all values into the same string.
  1275.     //    Each is followed by a '\0'.
  1276.     //    The final one is followed by '\0''\0'.
  1277.     //    Be careful not to overrun the buffer size.
  1278.     char *pTraverse = lpReturnedString;
  1279.     char *pValue = new char[2048];
  1280.     char *pTraverseValue;
  1281.     DWORD dwValueSize;
  1282.     for(int iIndex = 0; 1; iIndex++)    {
  1283.         dwValueSize = 2048;
  1284.         if(RegEnumValue(hKey, iIndex, pValue, &dwValueSize, NULL, NULL, NULL, NULL) !=
  1285.             ERROR_SUCCESS)    {
  1286.             //    No more indexes/values left.
  1287.             break;
  1288.         }
  1289.  
  1290.         //    Copy this into the return value.
  1291.         pTraverseValue = pValue;
  1292.         while((DWORD)(pTraverse    - lpReturnedString) != nSize)    {
  1293.             *pTraverse = *pTraverseValue;
  1294.             pTraverse++;
  1295.             if(*pTraverseValue == '\0')    {
  1296.                 break;
  1297.             }
  1298.             pTraverseValue++;
  1299.         }
  1300.  
  1301.         //    Check to see if we're at the end of the rope.
  1302.         if((DWORD)(pTraverse - lpReturnedString) == nSize)    {
  1303.             //    Need to set the final two chars to NULL.
  1304.             pTraverse -= 2;
  1305.             *pTraverse = '\0';
  1306.             pTraverse++;
  1307.             *pTraverse = '\0';
  1308.             pTraverse++;
  1309.             break;
  1310.         }
  1311.     }
  1312.  
  1313.     //    Done with the buffer and Key.
  1314.     delete[] pValue;
  1315.     RegCloseKey(hKey);
  1316.  
  1317.     //    Now, we make sure we have two NULLs at the end of the string.
  1318.     if(pTraverse == lpReturnedString)    {
  1319.         //    We didn't do squat.
  1320.         //    Increment this so that the return value is correct.
  1321.         pTraverse += 2;
  1322.     }
  1323.     else if((DWORD)(pTraverse - lpReturnedString) != nSize)    {
  1324.         *pTraverse = '\0';
  1325.         pTraverse++;
  1326.     }
  1327.  
  1328.     //    Return the number of chars copied over.
  1329.     return((DWORD)(pTraverse - lpReturnedString) - 2);
  1330. #endif
  1331. }
  1332.  
  1333. //
  1334. // This method re-implements the CWnd::SendMessageToDescendants() BUT
  1335. // only notifies permanent MFC windows...
  1336. //
  1337. void PASCAL CNetscapeApp::SendMessageToDescendants(HWND hWnd, UINT message,
  1338.                                                    WPARAM wParam, LPARAM lParam) 
  1339. {
  1340.     // walk through HWNDs to avoid creating temporary CWnd objects
  1341.     // unless we need to call this function recursively
  1342.     for (HWND hWndChild = ::GetTopWindow(hWnd); hWndChild != NULL;
  1343.         hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT))
  1344.     {
  1345.         // Don't send to non-permanent windows
  1346.         CWnd* pWnd = CWnd::FromHandlePermanent(hWndChild);
  1347.         if (pWnd != NULL)
  1348.         {
  1349.             // call window proc directly since it is a C++ window
  1350.             #ifdef XP_WIN32
  1351.             AfxCallWndProc(pWnd, pWnd->m_hWnd, message, wParam, lParam);
  1352.             #else
  1353.             _AfxCallWndProc(pWnd, pWnd->m_hWnd, message, wParam, lParam);
  1354.             #endif
  1355.             if ( ::GetTopWindow(hWndChild) != NULL)
  1356.             {
  1357.                 // Only recurse if current window is MFC
  1358.                 CNetscapeApp::SendMessageToDescendants(hWndChild, message, 
  1359.                                                        wParam, lParam);
  1360.             }
  1361.         }
  1362.     }
  1363. }
  1364.  
  1365. int CNetscapeApp::MessageBox(HWND hWnd,
  1366.                              LPCSTR lpszText,
  1367.                              LPCSTR lpszCaption /* = NULL */,
  1368.                              UINT nType /* = MB_OK */)
  1369. {
  1370.     if (lpszCaption == NULL)
  1371.         lpszCaption = AfxGetAppName();
  1372.  
  1373.     m_splash.ShowWindow(SW_HIDE);
  1374.     int result = ::MessageBox(hWnd, lpszText, lpszCaption, nType);
  1375.     m_splash.ShowWindow(SW_SHOW);
  1376.     m_splash.UpdateWindow();
  1377.  
  1378.     return result;
  1379. }
  1380.  
  1381. //  Register misc shell extensions supported.
  1382. void CNetscapeApp::EnableShellStuff()
  1383. {
  1384.     char aPath[_MAX_PATH];
  1385.     if(::GetModuleFileName(m_hInstance, aPath, _MAX_PATH))  {
  1386. #ifdef XP_WIN32
  1387.         //    should use short file name.
  1388.         char aShortPath[_MAX_PATH + 1];
  1389.         if(::GetShortPathName(aPath, aShortPath, sizeof(aShortPath)))    {
  1390.             strcpy(aPath, aShortPath);
  1391.         }
  1392. #endif
  1393.  
  1394.         CString csMunge;
  1395.  
  1396.         //  The Print Command.
  1397.         csMunge = aPath;
  1398.         csMunge += " /print(\"%1\")";
  1399.         FEU_RegistryWizard(HKEY_CLASSES_ROOT, "NetscapeMarkup\\shell\\print\\command", csMunge);
  1400.         FEU_RegistryWizard(HKEY_CLASSES_ROOT, "NetscapeMarkup\\shell\\print\\ddeexec", "[print(\"%1\")]");
  1401.         FEU_RegistryWizard(HKEY_CLASSES_ROOT, "NetscapeMarkup\\shell\\print\\ddeexec\\Application", strDDE_APP_NAME);
  1402.  
  1403.         //  The PrintTo Command.
  1404.         csMunge = aPath;
  1405.         csMunge += " /printto(\"%1\",\"%2\",\"%3\",\"%4\")";
  1406.         FEU_RegistryWizard(HKEY_CLASSES_ROOT, "NetscapeMarkup\\shell\\PrintTo\\command", csMunge);
  1407.         FEU_RegistryWizard(HKEY_CLASSES_ROOT, "NetscapeMarkup\\shell\\PrintTo\\ddeexec", "[printto(\"%1\",\"%2\",\"%3\",\"%4\")]");
  1408.         FEU_RegistryWizard(HKEY_CLASSES_ROOT, "NetscapeMarkup\\shell\\PrintTo\\ddeexec\\Application", strDDE_APP_NAME);
  1409.     }
  1410. }
  1411.  
  1412.  
  1413.  
  1414. /////////////////////////////////////////////////////////////////////////////
  1415. // Exit the whole application
  1416. void CNetscapeApp::OnAppSuperExit()
  1417. {
  1418.     //    Dont ask user.
  1419.     CommonAppExit();
  1420. }
  1421.  
  1422. void CNetscapeApp::OnAppExit()
  1423. {
  1424.  
  1425.     // if more than one top level window prompt to make sure they
  1426.     //     want to exit
  1427.     if(m_pFrameList && m_pFrameList->m_pNext) {
  1428.     int iExit = ::MessageBox(NULL,
  1429.                  szLoadString(IDS_CLOSEWINDOWS_EXIT),
  1430.                  szLoadString(IDS_EXIT_CONFIRMATION),
  1431.                  MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2);
  1432.  
  1433.         // false alarm, user didn't really want to exit
  1434.     if(IDNO == iExit)
  1435.         return;
  1436.  
  1437.     }
  1438.  
  1439.     CommonAppExit();
  1440. }
  1441.  
  1442.  
  1443. void CNetscapeApp::CommonAppExit()
  1444. {
  1445.     // Make sure each frame window really does want to close
  1446.     for (CGenericFrame *pFrame = m_pFrameList; NULL != pFrame; pFrame = pFrame->m_pNext) {
  1447.         CDocument*    pDocument = pFrame->GetActiveDocument();
  1448.  
  1449.     if (pDocument && !pDocument->CanCloseFrame(pFrame)) {
  1450.                         // Document doesn't want to close so don't close any of the frames
  1451.  
  1452.         // Clear the flags previously set
  1453.         //    so we prompt to save edit changes next time we try to close
  1454.         CGenericFrame *pCurrentFrame = pFrame;
  1455.         for (pFrame = m_pFrameList; pCurrentFrame != pFrame; pFrame = pFrame->m_pNext) {
  1456.          pFrame->m_bSkipSaveEditChanges = FALSE;
  1457.         }
  1458.  
  1459.             // We aren't going to close -- get out!
  1460.         return;
  1461.         }
  1462.     // Set flag to prevent prompting for saving edit changes
  1463.     //  in CEditFrame::OnClose() since this was done in CanCloseFrame()
  1464.     pFrame->m_bSkipSaveEditChanges = TRUE;
  1465.     }
  1466.  
  1467.     //  Set wether or not the app is exiting.
  1468.     m_bExit = TRUE;
  1469.  
  1470. #ifdef MOZ_MAIL_NEWS
  1471.     WFE_MSGSearchClose();
  1472.     WFE_MSGLDAPSearchClose();
  1473. #endif /* MOZ_MAIL_NEWS */
  1474.  
  1475.     //    Go through each frame, closing it....
  1476.     CGenericFrame *pNext = NULL;
  1477.     for(pFrame = m_pFrameList; NULL != pFrame; pFrame = pNext) {
  1478.  
  1479.     //  Extract the frame from the list.
  1480.     pNext = pFrame->m_pNext;
  1481.  
  1482.     pFrame->PostMessage(WM_CLOSE);
  1483.     }
  1484.   
  1485. }
  1486.  
  1487. #ifdef MOZ_LOC_INDEP
  1488. // LI_STUFF start
  1489. // REMIND: This is all experimental stuff which will get cleaned up and moved when 
  1490. // we are done
  1491. void putFileClosure(void * closure, LIStatus result)
  1492. {
  1493.     LIActive = 0;
  1494. }
  1495.  
  1496. void putCookieFileClosure(void * closure, LIStatus result)
  1497. {
  1498.     // a cheesy place to put this. until I do clients
  1499.     LIActive --;
  1500.     
  1501. }
  1502.  
  1503. void getCookieFileClosure(void * closure, LIStatus result, XP_Bool fileExists)
  1504. {
  1505.     if (fileExists) {
  1506.         /* remove and reset the cookies. */
  1507.         NET_RemoveAllCookies();
  1508.         NET_ReadCookies("");
  1509.     }
  1510. }
  1511.  
  1512. BOOL CNetscapeApp::LIStuffEnd() {
  1513.     static BOOL beenHere = FALSE;
  1514.  
  1515.     /* if li is active then go through this to upload stuff, 
  1516.         when the uploads are done, isliactive gets set to false.
  1517.     */
  1518.     if (LIActive > 0) {
  1519.         if (beenHere)
  1520.             return FALSE;
  1521.  
  1522.         //To save the prefs before the upload all: 
  1523.         char * prefName = WH_FileName(NULL, xpLIPrefs);
  1524.         PREF_SaveLIPrefFile(prefName);
  1525.         XP_FREEIF (prefName);
  1526.  
  1527.         LIMediator::uploadAll(putFileClosure, NULL);
  1528.         beenHere = TRUE;
  1529.  
  1530.  
  1531.         /* don't close the browser yet */ 
  1532.         return FALSE;
  1533.     }
  1534.     /* ok to close browser */
  1535.     return TRUE;
  1536. }
  1537.  
  1538. void LIStuff() {
  1539.     char *    lifilename ;
  1540.     BOOL prefBool;
  1541.  
  1542.     PREF_GetBoolPref("li.enabled", &LIActive);
  1543.  
  1544.     if (LIActive > 0) {
  1545.         PREF_GetDefaultBoolPref("li.client.bookmarks", &prefBool);
  1546.         if (prefBool) {
  1547.             //BM_SetModified(theApp.m_pBmContext, FALSE); // REMIND - still needed?
  1548.             //LIFile * file = new LIFile (theApp.m_pBookmarkFile,"bookmarks", "Bookmarks File");
  1549.             //file->startGettingIfNecessary(getBookmarkFileClosure, file);
  1550.         }
  1551.         //else
  1552.         //    BM_ReadBookmarksFromDisk(theApp.m_pBmContext, theApp.m_pBookmarkFile, NULL );
  1553.         // RDF is going to have to be hooked up here.  (Dave H.)
  1554.         // WORK STILL NEEDS TO BE DONE
  1555.  
  1556.         PREF_GetDefaultBoolPref("li.client.cookies",  &prefBool);
  1557.         if (prefBool) {
  1558.             lifilename = WH_FileName("", xpHTTPCookie);
  1559.             if (lifilename) {
  1560.                 LIFile * file2 = new LIFile (lifilename, "cookies", "Cookies File");
  1561.                 file2->startGettingIfNecessary(getCookieFileClosure, file2);
  1562.                 XP_FREE(lifilename);
  1563.             }
  1564.         }
  1565.     }
  1566.     //else
  1567.     //    BM_ReadBookmarksFromDisk(theApp.m_pBmContext, theApp.m_pBookmarkFile, NULL );
  1568. }
  1569. #endif // MOZ_LOC_INDEP
  1570.  
  1571. /////////////////////////////////////////////////////////////////////////////
  1572. // CNetscapeApp commands
  1573.  
  1574. #if _MSC_VER > 1100
  1575. //  Warn others of possible logic missing from newer versions of MFC and NS code.
  1576. #pragma message(__FILE__ ": Check CNetscapeApp::[Run|NSPumpMessage|IsIdleMessage] for compatibility with new MFC source")
  1577. #endif
  1578.  
  1579. //  Mainly as CWinThread::Run except for the NSPumpMessage call (PumpMessage non virtual on win16).
  1580. int CNetscapeApp::Run()
  1581. {
  1582.     BOOL bIdle = TRUE;
  1583.     LONG lIdleCount = 0;
  1584.  
  1585. #ifdef MOZ_LOC_INDEP
  1586.     LIStuff();
  1587. #endif // MOZ_LOC_INDEP
  1588.  
  1589.     for(;;) {
  1590.     while(bIdle && !::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))    {
  1591.         if (!OnIdle(lIdleCount++))
  1592.         bIdle = FALSE;
  1593.     }
  1594.  
  1595. #ifdef XP_WIN16
  1596. #if defined(JAVA) || defined(MOCHA)
  1597.     /*
  1598.     ** On Win16 the only way for another thread to run is to explicitly
  1599.     ** yield...
  1600.     */
  1601.     extern void fe_yield(void);
  1602.     fe_yield();
  1603. #endif    /* JAVA */
  1604. #endif    /* XP_WIN16 */
  1605.  
  1606.     do  {
  1607.         if(!NSPumpMessage())    {
  1608.         return(ExitInstance());
  1609.         }
  1610.  
  1611.         if(IsIdleMessage(&m_msgCur)) {
  1612.         bIdle = TRUE;
  1613.         lIdleCount = 0;
  1614.         }
  1615.     } while(::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
  1616.     }
  1617. }
  1618.  
  1619. //  Mainly as CWinThread::PumpMessage except for giving priority to certain events.
  1620. //  NSPumpMessage instead of PumpMessage as non-virtual on Win16
  1621. BOOL CNetscapeApp::NSPumpMessage()
  1622. {
  1623.     BOOL bRetval = FALSE;
  1624.     BOOL bPeeked = FALSE;
  1625.  
  1626.     //    Net dike (see hiddenfr.h).
  1627.     gNetFloodStage++;
  1628.  
  1629.     if((gNetFloodStage % NET_FLOWCONTROL) != 0) {
  1630.     bPeeked = bRetval = ::PeekMessage(&m_msgCur, NULL, 0, NET_MESSAGERANGE, PM_REMOVE);
  1631.     if(bPeeked && m_msgCur.message == WM_QUIT) {
  1632.         bRetval = FALSE;
  1633.     }
  1634.     }
  1635.  
  1636.     //    As normal PumpMessage
  1637.     if(!bPeeked)    {
  1638.     //  Wait for message or getting a registered message.
  1639.     bRetval = ::GetMessage(&m_msgCur, NULL, NULL, NULL);
  1640.     }
  1641.  
  1642.     if(bRetval) {
  1643.     //  Update tick count used in GetMessageTime call.
  1644.     //  This can be used as an ID to tell wether or not a message
  1645.     //    was generated from this dispatch function.
  1646.     m_dwLastMsgTick = m_msgCur.time;
  1647.  
  1648.     //  Update time by MSG tickcount.
  1649.     //  Allow 30 second play period for messages before resetting clock or
  1650.     //    assuming roll over on the tick counter (49.7 days)
  1651.     if(m_msgCur.time > m_dwMsgTick) {
  1652.         m_dwMsgTick = m_msgCur.time;
  1653.     }
  1654.     else if((m_msgCur.time + 30000) < m_dwMsgTick) {
  1655.         InitTime();
  1656.     }
  1657.  
  1658.     if(m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))    {
  1659.         ::TranslateMessage(&m_msgCur);
  1660.         ::DispatchMessage(&m_msgCur);
  1661.     }
  1662.     }
  1663.  
  1664.     return(bRetval);
  1665. }
  1666.  
  1667. BOOL CNetscapeApp::IsIdleMessage(MSG *pMsg)
  1668. {
  1669.     ASSERT(pMsg);
  1670.  
  1671.     if (pMsg->message == msg_NetActivity ||
  1672.     pMsg->message == msg_FoundDNS ||
  1673.     pMsg->message == msg_ForceIOSelect ||
  1674.     pMsg->message == m_msgNSPREventNotify) {
  1675.         return FALSE;
  1676.     }
  1677.  
  1678.         // We have to be careful about how often we go idle. We don't want timer
  1679.     // messages (e.g. animation timer) or Winsock async notifications to cause
  1680.     // us to go idle. We need to filter WM_GETDLGCODE messages, because clicking
  1681.     // in the URL bar generates an endless stream of them
  1682.     switch (pMsg->message) {
  1683.     case WM_KEYDOWN:
  1684.         if (pMsg->wParam == VK_SHIFT || pMsg->wParam == VK_CONTROL) {
  1685.         // Avoid consuming all of the CPU when the Shift/Control
  1686.         // keys are held down
  1687.         if (LOWORD(pMsg->lParam) > 0) {
  1688.             return FALSE;
  1689.         }
  1690.         }
  1691.         break;
  1692.  
  1693.         case WM_TIMER:
  1694.         case WM_GETDLGCODE:
  1695.         case WM_MOUSEMOVE:
  1696.         case WM_NCMOUSEMOVE:
  1697.             return FALSE;
  1698.     }
  1699.  
  1700.     //    As CWinThread::IsIdleMessage
  1701.     if(pMsg->message == WM_MOUSEMOVE || pMsg->message == WM_NCMOUSEMOVE)    {
  1702.     if (m_ptCursorLast == pMsg->pt && pMsg->message == m_nMsgLast)    {
  1703.         return FALSE;
  1704.     }
  1705.  
  1706.     m_ptCursorLast = pMsg->pt;
  1707.     m_nMsgLast = pMsg->message;
  1708.     return TRUE;
  1709.     }
  1710.  
  1711.     return(pMsg->message != WM_PAINT && pMsg->message != 0x0118);
  1712. }
  1713.  
  1714. BOOL CNetscapeApp::OnIdle(LONG lCount)
  1715. {
  1716.     // call base class idle first
  1717.     BOOL bResult = CWinApp::OnIdle(lCount);
  1718.  
  1719.         // ZZZ: We don't need to do this in the 32-bit version, because CWinApp::InIdle
  1720.     // already sends a WM_IDLEUPDATECMDUI to each of the frames
  1721.  
  1722. #ifdef XP_WIN16
  1723. #if defined(JAVA) || defined(MOCHA)
  1724.     /*
  1725.     ** On Win16 the only way for another thread to run is to explicitly
  1726.     ** yield...
  1727.     */
  1728.     extern void fe_yield(void);
  1729.     fe_yield();
  1730. #endif    /* JAVA */
  1731.  
  1732.     //    Update the UI of the frames.
  1733.     if(lCount == 0)    {
  1734.     CGenericFrame * f;
  1735.  
  1736.     // update command buttons etc from the top down
  1737.     for(f = m_pFrameList; f; f = f->m_pNext) {
  1738.         if (f) {
  1739.         CNetscapeApp::SendMessageToDescendants(f->m_hWnd,
  1740.                 WM_IDLEUPDATECMDUI, (WPARAM)TRUE, (LPARAM)0);
  1741.         }
  1742.     }
  1743.     return(TRUE);
  1744.     }
  1745. #endif
  1746.  
  1747.     //    Do we really have to do manual binding to timeout code?
  1748.     //    This is set if the code was unable to allocate a timer.
  1749.     if(m_bIdleProcessTimeouts)    {
  1750.         TRACE("Yo!: processing timeouts in idle binding.\n");
  1751.     wfe_ProcessTimeouts();
  1752.     bResult = TRUE;
  1753.     }
  1754.  
  1755.     // Poll the socket list and call Netlib
  1756.     if(NET_PollSockets())
  1757.         bResult = TRUE;
  1758.  
  1759. #ifdef MOZ_MAIL_NEWS
  1760.     // currently just to give NeoAccess a chance to do some chores
  1761.         // If we become a real CNeoApp, this won't be neccesary.
  1762.     //    --- DREAM ON ---
  1763.     MSG_OnIdle();
  1764. #endif /* MOZ_MAIL_NEWS */
  1765.     
  1766.     //  Good time to free up heap and unused COM Dlls when really going idle.
  1767.     if(bResult == FALSE) {
  1768.     CoFreeUnusedLibraries();
  1769. #ifdef XP_WIN32
  1770.     _heapmin();
  1771. #endif
  1772.     }
  1773.  
  1774.     return(bResult);
  1775. }
  1776.  
  1777. BOOL CNetscapeApp::OnDDECommand(char *pszCommand)
  1778. {
  1779.     TRACE("DDE command:  %s\n", pszCommand);
  1780.  
  1781. ////////////  The block below belongs to Abe Jarrett /////////////
  1782. //    Intercept all commandline DDE commands before Intercepting Print commands
  1783.     if (strcasestr(pszCommand,"cmdline") != NULL)
  1784.     {
  1785.         if (ProcessCommandLineDDE(pszCommand))
  1786.             return TRUE;
  1787.         else
  1788.             return FALSE;
  1789.     }
  1790. ////////////  The above belongs to Abe Jarrett  /////////////////////////
  1791. //////////////////////////////////////////////////////////////////////////////
  1792. //    Intercept all print commands before we reach the below.
  1793.     BOOL bPrint = FALSE;
  1794.     BOOL bPrintTo = FALSE;
  1795.     char *pszCompare = pszCommand + 1;
  1796.  
  1797.     if(strnicmp(pszCompare, "print(", 6) == 0) {
  1798.     bPrint = TRUE;
  1799.         TRACE("Handling command to print\n");
  1800.     }
  1801.     else if(strnicmp(pszCompare, "printto(", 8) == 0) {
  1802.     bPrintTo = TRUE;
  1803.         TRACE("Handling command to printto\n");
  1804.     }
  1805.     if(bPrint || bPrintTo)  {
  1806.     //  There are four arguments that we figure out for each print job.
  1807.     //  1)    What to print.
  1808.     //  2)    The destination printer
  1809.     //  3)    The printer driver used for printing
  1810.     //  4)    The destination port for printing
  1811.     //
  1812.     //  They will all be represented as strings.
  1813.     //  All but 1 can be NULL, which means to use the default setting.
  1814.     //  There should be no UI interaction except for authentication and other such
  1815.     //    backend stuff that we have no control over.
  1816.     //  Each argument is quoted.
  1817.     //  Each quoted argument is seperated by a comma.
  1818.     char *pArg1 = FEU_ExtractCommaDilimetedQuotedString(pszCommand, 1);
  1819.     char *pArg2 = FEU_ExtractCommaDilimetedQuotedString(pszCommand, 2);
  1820.     char *pArg3 = FEU_ExtractCommaDilimetedQuotedString(pszCommand, 3);
  1821.     char *pArg4 = FEU_ExtractCommaDilimetedQuotedString(pszCommand, 4);
  1822.  
  1823.     //  Do it.
  1824.     CPrintCX::AutomatedPrint(pArg1, pArg2, pArg3, pArg4);
  1825.  
  1826.     //  Get rid of any allocations that FEU did for us.
  1827.     if(pArg1)   {
  1828.         XP_FREE(pArg1);
  1829.     }
  1830.     if(pArg2)   {
  1831.         XP_FREE(pArg2);
  1832.     }
  1833.     if(pArg3)   {
  1834.         XP_FREE(pArg3);
  1835.     }
  1836.     if(pArg4)   {
  1837.         XP_FREE(pArg4);
  1838.     }
  1839.  
  1840.     //  Handled.
  1841.     return(TRUE);
  1842.     }
  1843.  
  1844.     BOOL bTranslate = TRUE;
  1845.     //    Copy the string to mess with.
  1846.     char *pDelete = XP_STRDUP(pszCommand);
  1847.     char *pOpen = pDelete;
  1848.  
  1849. #ifdef EDITOR
  1850.     // edit format is "[edit("%s")]" - no whitespace allowed, one per line
  1851.     if (strnicmp(pOpen, "[edit(\"", 7) == 0)   {
  1852.         pOpen += 7;
  1853.         char *pEnd = strchr(pOpen, '"');
  1854.         if (pOpen == NULL) {
  1855.             XP_FREE(pDelete);
  1856.             return FALSE;        // illegally terminated
  1857.         }
  1858.         // trim the string, and edit the file
  1859.         *pEnd = '\0';
  1860.         // This will do the WFE_ConvertFile2Url before loading URL
  1861.         FE_LoadUrl( pOpen, LOAD_URL_COMPOSER);
  1862.         XP_FREE(pDelete);
  1863.         return TRUE;
  1864.     }
  1865. #endif /* EDITOR */    
  1866.  
  1867.     // open format is "[open("%s")]" - no whitespace allowed, one per line
  1868.     if (strnicmp(pOpen, "[open(\"", 7) != 0)
  1869.     {
  1870.         if ( strnicmp(pOpen, "[openurl(\"", 10) != 0 ) 
  1871.         {
  1872.             XP_FREE(pDelete);   //Added by CLM - memory leak       
  1873.             return FALSE;
  1874.         }
  1875.         else
  1876.         {
  1877.             bTranslate = FALSE;
  1878.             pOpen += 10;
  1879.         }
  1880.     }
  1881.     else
  1882.     {
  1883.         pOpen += 7;
  1884.     }
  1885.  
  1886.     char *pEnd = strchr(pOpen, '"');
  1887.     if (pEnd == NULL)   
  1888.     {
  1889.         XP_FREE(pDelete);
  1890.         return FALSE;        // illegally terminated
  1891.     }
  1892.     // trim the string, and open the file
  1893.     *pEnd = '\0';
  1894.  
  1895.     //    Convert the name to a URL.
  1896.     CString csUrl;
  1897.     WFE_ConvertFile2Url(csUrl, pOpen);
  1898.  
  1899.     //    Open it in a new window.
  1900.     //    Use the first window as the provider of the context.
  1901.     URL_Struct *pUrl = NET_CreateURLStruct(csUrl, NET_DONT_RELOAD);
  1902.     if(m_pFrameList && m_pFrameList->GetMainContext())
  1903.     {
  1904.         if (bTranslate)
  1905.         {
  1906.             MWContext *pContext = m_pFrameList->GetMainContext()->GetContext();
  1907.             CFE_CreateNewDocWindow(pContext, pUrl);
  1908.         }
  1909.         else
  1910.         {
  1911.             CFrameGlue * pFrame =
  1912.             CFrameGlue::GetLastActiveFrame(MWContextBrowser);
  1913.             if (pFrame != NULL && pFrame->GetMainContext()  && 
  1914.                 pFrame->GetMainContext()->GetContext()      &&
  1915.                 !pFrame->GetMainContext()->GetContext()->restricted_target)
  1916.             {
  1917.                 CAbstractCX * pCX = pFrame->GetMainContext();
  1918.                 if (pCX != NULL)
  1919.                 {
  1920.                     CFrameWnd * pFrameWnd = pFrame->GetFrameWnd();
  1921.                     if( pFrameWnd ){
  1922.                         // We need to bring window to the top
  1923.                         if(pFrameWnd->IsIconic())  {
  1924.                             pFrameWnd->ShowWindow(SW_RESTORE);
  1925.                         }
  1926.                         pFrameWnd->BringWindowToTop();
  1927.                     }
  1928.                     pCX->NormalGetUrl(csUrl);
  1929.                 }  /* end if */
  1930.             }  /* end if */
  1931.             else
  1932.             {
  1933.                 CFE_CreateNewDocWindow(NULL, pUrl);
  1934.             }  /* end else */
  1935.         }  /* end else */
  1936.     }
  1937.     else
  1938.     {
  1939.         CFE_CreateNewDocWindow(NULL, pUrl);
  1940.     }
  1941.  
  1942.     XP_FREE(pDelete);
  1943.     return(TRUE);
  1944. }
  1945.  
  1946. //
  1947. // Generic help handler
  1948. //
  1949. void CNetscapeApp::OnHelp()
  1950. {
  1951. #ifdef XP_WIN16
  1952.     if (SENT_MESSAGE!=m_helpstate)
  1953.     {
  1954.         if (m_pMainWnd)
  1955.         { 
  1956.             CWnd *t_wnd=m_pMainWnd->GetActiveWindow();
  1957.             if (t_wnd)
  1958.             {
  1959.                 m_helpstate=SENT_MESSAGE;
  1960.                 t_wnd->SendMessage(WM_COMMAND,ID_HELP);
  1961.                 m_helpstate=NOT_SENT;
  1962.             }
  1963.         }
  1964.     }
  1965. #endif
  1966. }
  1967. void CNetscapeApp::ReleaseAppFont(HFONT logFont)
  1968. {
  1969.     XP_List *theList =     m_appFontList;
  1970.     NsWinFont* theFont = (NsWinFont*)XP_ListNextObject(theList);
  1971.     while (theFont) {
  1972.         if (theFont->hFont == logFont)
  1973.             break;
  1974.         theFont = (NsWinFont*)XP_ListNextObject(theList);
  1975.     }
  1976.     if (theFont) {  // release the font use.
  1977.         theFont->refCount--;
  1978.         if (theFont->refCount == 0) { // no one use this font anymore, release it.
  1979.             XP_ListRemoveObject (m_appFontList, theFont);
  1980.             VERIFY(::DeleteObject(theFont->hFont));
  1981.             XP_DELETE(theFont);
  1982.             theFont = NULL;
  1983.         }
  1984.     }
  1985. }
  1986.         
  1987. HFONT CNetscapeApp::CreateAppFont(LOGFONT& logFont)
  1988. {
  1989.     NsWinFont* theFont;
  1990.     if (m_appFontList == NULL) {
  1991.         m_appFontList = XP_ListNew();
  1992.         theFont = XP_NEW( NsWinFont);
  1993.         memcpy(&theFont->logFontStruct, &logFont, sizeof(LOGFONT));
  1994.         theFont->hFont = CreateFontIndirect( &logFont );
  1995.         theFont->refCount = 1;
  1996.         XP_ListAddObject (m_appFontList, (void*)theFont);
  1997.     }
  1998.     else {
  1999.         XP_List *theList =     m_appFontList;
  2000.         theFont = (NsWinFont*)XP_ListNextObject(theList);
  2001.         while (theFont) {
  2002.             const LOGFONT& l1 = logFont;
  2003.             const LOGFONT& l2 = theFont->logFontStruct;
  2004.             if ((memcmp(&l1, &l2, sizeof(LOGFONT) - sizeof(l1.lfFaceName)) == 0) &&
  2005.                 (strcmp(l1.lfFaceName, l2.lfFaceName) == 0))
  2006.                 break;
  2007.             theFont = (NsWinFont*)XP_ListNextObject(theList);
  2008.         }
  2009.         if (!theFont) {  // we do not found a font cached fot this LOGFONT yet.  
  2010.             theFont = XP_NEW( NsWinFont);
  2011.             memcpy(&theFont->logFontStruct, &logFont, sizeof(LOGFONT));
  2012.             theFont->hFont = CreateFontIndirect( &logFont );
  2013.             XP_ListAddObject (m_appFontList, (void*)theFont);
  2014.             theFont->refCount = 1;
  2015.         }
  2016.         else {
  2017.             theFont->refCount++;
  2018.         }
  2019.     }
  2020.     return theFont->hFont;
  2021. }
  2022.  
  2023. CNSNavFrame* CNetscapeApp::CreateNewNavCenter(CNSGenFrame* pParentFrame, BOOL useViewType, HT_ViewType viewType)
  2024. {
  2025.     CNSNavFrame* theItem;
  2026.     theItem = new CNSNavFrame();
  2027.     theItem->CreateNewNavCenter(pParentFrame, useViewType, viewType);
  2028.     return theItem;
  2029. }
  2030.  
  2031.