// pws.cpp : Defines the class behaviors for the application. // #include "stdafx.h" #include "pwsform.h" #include "resource.h" #include "Title.h" #include "FormIE.h" #include "MainFrm.h" #include "pwsDoc.h" #include "PWSChart.h" #include "SelBarFm.h" #include "ServCntr.h" #include #include "TipDlg.h" #include "pwsctrl.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define CMD_START _T("start") #define CMD_STOP _T("stop") #define CMD_OPEN _T("open:") #define CMD_OPEN_MAIN _T("main") #define CMD_OPEN_ADV _T("advanced") #define CMD_OPEN_TOUR _T("tour") //#define CMD_OPEN_WEBSITE _T("website") //#define CMD_OPEN_PUBWIZ _T("pubwiz") #define CMD_SEPS _T("/- ") #define FILES_QUERY_STRING _T("?dropStr="); // globals //extern CPwsForm* g_p_FormView; extern CPwsDoc* g_p_Doc; CString g_szHelpLocation; WORD g_InitialPane = PANE_MAIN; WORD g_InitialIELocation = INIT_IE_TOUR; CString g_AdditionalIEURL; ///////////////////////////////////////////////////////////////////////////// // CPwsApp BEGIN_MESSAGE_MAP(CPwsApp, CWinApp) //{{AFX_MSG_MAP(CPwsApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) //}}AFX_MSG_MAP // Standard file based document commands ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPwsApp construction //----------------------------------------------------- CPwsApp::CPwsApp() : m_fShowedStartupTips( FALSE ) { } //----------------------------------------------------- CPwsApp::~CPwsApp() { } ///////////////////////////////////////////////////////////////////////////// // The one and only CPwsApp object CPwsApp theApp; static const CLSID clsid = { 0x35c43df, 0x8464, 0x11d0, { 0xa9, 0x2d, 0x8, 0x0, 0x2b, 0x2c, 0x6f, 0x32 } }; ///////////////////////////////////////////////////////////////////////////// // CPwsApp initialization //----------------------------------------------------- // return FALSE to continue running the application BOOL CPwsApp::DealWithParameters() { BOOL fAnswer = FALSE; // under windows NT, we always just invoke the UI, no matter what the command line OSVERSIONINFO info_os; info_os.dwOSVersionInfoSize = sizeof(info_os); // check what sort of operating system we are running on if ( !GetVersionEx( &info_os ) ) return FALSE; CString sz = m_lpCmdLine; sz.TrimRight(); // the first one is easy. If there is no command line, invoke the UI and leave if ( sz.IsEmpty() ) return FALSE; /* The publishing wizard has been pulled from PWS for NT5 // The next one is also easy. If there is no '/' character, then the // parameters have to be file names for the publishing wizard. Also, the OS // gets rid of any spaces in the filenames for us. So we can just replace // them with ';' characters and be done with it if ( sz.Find(_T('/')) < 0 ) { // set up to go to the publishing wizard g_InitialPane = PANE_IE; g_InitialIELocation = INIT_IE_PUBWIZ; // build the additional string g_AdditionalIEURL = FILES_QUERY_STRING; // ?dropStr= // at this point it is desirous to convert the files listed in szAdditional, // which are in 8.3 format into long file names format. This means that they // will have to be put in quotes to handle spaces in the names. If a name // is already in quotes, then do not act on it in this way. Just add it to the // list as it is. CString szShortNames = sz; CString szTemp, szTemp2; BOOL fFoundOneFile = FALSE; // trim any trailing whitespace szShortNames.TrimRight(); // loop through all the files while( szShortNames.GetLength() ) { // trim any leading whitespace characters szShortNames.TrimLeft(); // if the name is already in quotes, just add it if ( szShortNames[0] == _T('\"') ) { // find the closing quote szShortNames = szShortNames.Right( szShortNames.GetLength() - 1 ); int ichClose = szShortNames.Find(_T('\"')); // build the name szTemp = _T('\"'); // if there was no closing quote use the whole string if ( ichClose < 0 ) { szTemp += szShortNames; szShortNames.Empty(); // close the qoutes szTemp += _T('\"'); } else { szTemp += szShortNames.Left(ichClose+1); // get this file name out of the szShortNames path so we don't do it again szShortNames = szShortNames.Right(szShortNames.GetLength() - (ichClose+1)); } } else // it is an 8.3 name, convert it { // find the space (could do inline, but this is faster) int ichSpace = szShortNames.Find(_T(' ')); // get just the one file name if ( ichSpace > 0 ) szTemp = szShortNames.Left(ichSpace); else szTemp = szShortNames; // prep the find file info block HANDLE hFindFile; WIN32_FIND_DATA findData; ZeroMemory( &findData, sizeof(findData) ); // find the file hFindFile = FindFirstFile( (LPCTSTR)szTemp, // pointer to name of file to search for &findData // pointer to returned information ); // if it was successful, extract the long file name if ( hFindFile != INVALID_HANDLE_VALUE ) { // enclose the path in quotes and go szTemp = _T('\"'); // start by adding the path portion of the original string if ( ichSpace >= 0 ) szTemp += szShortNames.Left(ichSpace); else szTemp += szShortNames; // chop off the file name - but leave the trailing '\' character if ( szTemp.ReverseFind(_T('\\')) > 0 ) szTemp = szTemp.Left( szTemp.ReverseFind(_T('\\')) + 1 ); // copy over the full path name szTemp += findData.cFileName; // close the qoutes szTemp += _T('\"'); } // if there are no more names, then empth the path, otherwise, just shorten it if ( ichSpace < 0 ) szShortNames.Empty(); else // get this file name out of the szShortNames path so we don't do it again szShortNames = szShortNames.Right(szShortNames.GetLength() - ichSpace); // we aren't really finding files here, so just close the find handle FindClose( hFindFile ); } // if we have already added a file, precede the one we are about to add with a ; if ( fFoundOneFile ) g_AdditionalIEURL += _T(';'); // add the string g_AdditionalIEURL += szTemp; fFoundOneFile = TRUE; } // prevent the tips dialog from coming up m_fShowedStartupTips = TRUE; // all done. return FALSE; } */ // copy the command line into a buffer TCHAR buff[MAX_PATH]; _tcscpy( buff, sz ); // just so we don't do it in the loop, initialize the open: string // length variable DWORD cchOpen = _tcslen( CMD_OPEN ); // parse out the arguments LPTSTR pTok; pTok = _tcstok( buff, CMD_SEPS ); while ( pTok ) { // the start and stop commands are for windows 95 only if ( info_os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) { // look for the start command if ( _tcsicmp(pTok, CMD_START) == 0 ) { W95StartW3SVC(); fAnswer = TRUE; goto nextToken; } // look for the stop command if ( _tcsicmp(pTok, CMD_STOP) == 0 ) { W95ShutdownW3SVC(); W95ShutdownIISADMIN(); fAnswer = TRUE; goto nextToken; } } // commands that work for all platforms // look for the open: command if ( _tcsnicmp(pTok, CMD_OPEN, cchOpen) == 0 ) { // just put the open parameter in a string CString szOpen = pTok; szOpen = szOpen.Right( szOpen.GetLength() - cchOpen ); // now test all the options if ( szOpen.CompareNoCase(CMD_OPEN_MAIN) == 0 ) { g_InitialPane = PANE_MAIN; } else if ( szOpen.CompareNoCase(CMD_OPEN_ADV) == 0 ) { g_InitialPane = PANE_ADVANCED; } else if ( szOpen.CompareNoCase(CMD_OPEN_TOUR) == 0 ) { g_InitialPane = PANE_IE; g_InitialIELocation = INIT_IE_TOUR; } /* else if ( szOpen.CompareNoCase(CMD_OPEN_WEBSITE) == 0 ) { g_InitialPane = PANE_IE; g_InitialIELocation = INIT_IE_WEBSITE; } else if ( szOpen.CompareNoCase(CMD_OPEN_PUBWIZ) == 0 ) { g_InitialPane = PANE_IE; g_InitialIELocation = INIT_IE_PUBWIZ; // prevent the tips dialog from coming up m_fShowedStartupTips = TRUE; } */ } // Get next token nextToken: pTok = _tcstok( NULL, CMD_SEPS ); } return fAnswer; } //----------------------------------------------------- // In the event that another instance of this application is already // running, we not only need to activate it and bring it to the foreground, // but it should also handle the command line that was passed into this // instance. The use may have dragged files only the publishing wizard for // example and that should be sent to the publishing wizard. // pWnd is the window of the other instance that we are targeting. The command // line information has already been parsed and can be found the the globals // declared above. // // In order to pass the command information from this instance to the other // requires that we set up a shared memory structure. Then when we send the // message to the other instance, it can get it. Upon return, we no longer // need the shared memory, so we can clean it up. void CPwsApp::SendCommandInfo( CWnd* pWnd ) { HANDLE hFileMap = NULL; PPWS_INSTANCE_TRANSFER pData = NULL; DWORD cbSharedSpace; // calculate how bit the shared space needs to be cbSharedSpace = sizeof(PWS_INSTANCE_TRANSFER); // add in enough to copy in the possibly wide character extra info string cbSharedSpace += (g_AdditionalIEURL.GetLength() + 1) * sizeof(WCHAR); // set up the shared memory space. hFileMap = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, cbSharedSpace, PWS_INSTANCE_TRANSFER_SPACE_NAME ); if ( hFileMap == NULL ) return; pData = (PPWS_INSTANCE_TRANSFER)MapViewOfFile( hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, cbSharedSpace ); if ( pData == NULL ) { CloseHandle(hFileMap); return; } // blank it all out ZeroMemory( pData, cbSharedSpace ); // copy in the parsed command line data pData->iTargetPane = g_InitialPane; pData->iTargetIELocation = g_InitialIELocation; _tcscpy( &pData->tchIEURL, (LPCTSTR)g_AdditionalIEURL ); // send the message pWnd->SendMessage( WM_PROCESS_REMOTE_COMMAND_INFO ); // clean up the shared memory UnmapViewOfFile( pData ); CloseHandle(hFileMap); } //----------------------------------------------------- BOOL CPwsApp::InitInstance() { BOOL fLeaveEarly = FALSE; // if there were options passed in to the command line, act on them without bringing // up any windows or anything if ( m_lpCmdLine[0] ) { if ( DealWithParameters() ) return FALSE; } // no parameters (or this is NT) - run normally CString sz; sz.LoadString( IDR_MAINFRAME ); sz = sz.Left( sz.Find('\n') ); // initialize the windows sockets layer WSADATA wsaData; INT err = WSAStartup(MAKEWORD(2,0), &wsaData); // see if another instance of this application is running CWnd* pPrevWind = CWnd::FindWindow( NULL, sz ); if ( pPrevWind ) { // pws is already running. Activate the previous one and quit pPrevWind->SetForegroundWindow(); pPrevWind->ShowWindow(SW_RESTORE); // tell it to handle the command line information SendCommandInfo( pPrevWind ); return FALSE; } // Initialize OLE libraries if (!AfxOleInit()) { AfxMessageBox(IDP_OLE_INIT_FAILED); return FALSE; } // initialize the metabase interface if ( !FInitMetabaseWrapper(NULL) ) return FALSE; AfxEnableControlContainer(); // Standard initialization //#ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL //#else // Enable3dControlsStatic(); // Call this when linking to MFC statically //#endif LoadStdProfileSettings(); // Load standard INI file options (including MRU) // Register document templates CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CPwsDoc), RUNTIME_CLASS(CMainFrame), // main SDI frame window RUNTIME_CLASS(CFormSelectionBar)); AddDocTemplate(pDocTemplate); m_server.ConnectTemplate(clsid, pDocTemplate, TRUE); // Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated) { COleTemplateServer::RegisterAll(); // Application was run with /Embedding or /Automation. Don't show the // main window in this case. return TRUE; } m_server.UpdateRegistry(OAT_DISPATCH_OBJECT); COleObjectFactory::UpdateRegistryAll(); // Dispatch commands specified on the command line if (!ProcessShellCommand(cmdInfo)) return FALSE; // finally, we need to redirect the winhelp file location to something more desirable sz.LoadString( IDS_HELPLOC_PWSHELP ); // expand the path ExpandEnvironmentStrings( sz, // pointer to string with environment variables g_szHelpLocation.GetBuffer(MAX_PATH + 1), // pointer to string with expanded environment variables MAX_PATH // maximum characters in expanded string ); g_szHelpLocation.ReleaseBuffer(); // free the existing path, and copy in the new one free((void*)m_pszHelpFilePath); m_pszHelpFilePath = _tcsdup(g_szHelpLocation); // set the name of the application correctly sz.LoadString( IDR_MAINFRAME ); // cut it off so it is just the app name sz = sz.Left( sz.Find(_T('\n')) ); // free the existing name, and copy in the new one free((void*)m_pszAppName); m_pszAppName = _tcsdup(sz); return TRUE; } //------------------------------------------------------------------ void CPwsApp::OnFinalRelease() { FCloseMetabaseWrapper(); WSACleanup(); CWinApp::OnFinalRelease(); } //------------------------------------------------------------------ void CPwsApp::ShowTipsAtStartup() { m_fShowedStartupTips = TRUE; // show the tips tdialog - if requested CTipDlg dlg; if ( dlg.FShowAtStartup() ) dlg.DoModal(); } ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) // No message handlers //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) //}}AFX_MSG_MAP END_MESSAGE_MAP() //------------------------------------------------------------------ // App command to run the dialog void CPwsApp::OnAppAbout() { // load the about strings CString szAbout1; CString szAbout2; szAbout1.LoadString(IDS_ABOUT_MAIN); szAbout2.LoadString(IDS_ABOUT_SECONDARY); // run the shell about dialog ShellAbout( AfxGetMainWnd()->GetSafeHwnd(), szAbout1,szAbout2, LoadIcon(IDR_MAINFRAME) ); } ///////////////////////////////////////////////////////////////////////////// // CPwsApp commands //------------------------------------------------------------------ BOOL CPwsApp::OnIdle(LONG lCount) { // if this is the startup - show the tips if ( !m_fShowedStartupTips ) ShowTipsAtStartup(); return FALSE; }