Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

694 lines
19 KiB

  1. // MainFrm.cpp : implementation of the CMainFrame class
  2. //
  3. #include "stdafx.h"
  4. #include <winsvc.h>
  5. #include "resource.h"
  6. #include <pwsdata.hxx>
  7. #include "Sink.h"
  8. #include "pwsdoc.h"
  9. #include "Title.h"
  10. #include "HotLink.h"
  11. #include "PWSChart.h"
  12. #include "pwsform.h"
  13. #include "EdDir.h"
  14. #include "FormAdv.h"
  15. #include "FormIE.h"
  16. #include "FormMain.h"
  17. #include "SelBarFm.h"
  18. #include "MainFrm.h"
  19. #include "ServCntr.h"
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. CMainFrame* g_frame = NULL;
  26. CPWSForm* g_pCurrentForm = NULL;
  27. extern WORD g_InitialPane;
  28. extern CPwsDoc* g_p_Doc;
  29. extern CFormMain* g_FormMain;
  30. // this flag indicates that we have gotten a server shutdown notification
  31. // and we have entered shutdown mode. In this mode, the only features that
  32. // are available anywhere include the start button, and the troubleshooting.
  33. // I suppose the tour would be OK too since that isn't served.
  34. BOOL g_fShutdownMode = FALSE;
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CMainFrame
  37. IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
  38. BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
  39. //{{AFX_MSG_MAP(CMainFrame)
  40. ON_WM_CREATE()
  41. ON_COMMAND(ID_PGE_MAIN, OnPgeMain)
  42. ON_COMMAND(ID_PGE_ADVANCED, OnPgeAdvanced)
  43. ON_COMMAND(ID_PGE_TOUR, OnPgeTour)
  44. ON_UPDATE_COMMAND_UI(ID_PGE_TOUR, OnUpdatePgeTour)
  45. ON_UPDATE_COMMAND_UI(ID_PGE_MAIN, OnUpdatePgeMain)
  46. ON_UPDATE_COMMAND_UI(ID_PGE_ADVANCED, OnUpdatePgeAdvanced)
  47. //}}AFX_MSG_MAP
  48. // Global help commands
  49. ON_COMMAND(ID_HELP_FINDER, CFrameWnd::OnHelpFinder)
  50. ON_COMMAND(ID_HELP, CFrameWnd::OnHelp)
  51. ON_COMMAND(ID_CONTEXT_HELP, CFrameWnd::OnContextHelp)
  52. ON_COMMAND(ID_DEFAULT_HELP, CFrameWnd::OnHelpFinder)
  53. END_MESSAGE_MAP()
  54. /////////////////////////////////////////////////////////////////////////////
  55. // CMainFrame construction/destruction
  56. //-----------------------------------------------------------------
  57. CMainFrame::CMainFrame():
  58. m_pIEView( NULL )
  59. {
  60. }
  61. //-----------------------------------------------------------------
  62. CMainFrame::~CMainFrame()
  63. {
  64. g_frame = NULL;
  65. }
  66. //-----------------------------------------------------------------
  67. int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  68. {
  69. if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
  70. return -1;
  71. // DISABLE TOOL BAR
  72. /*
  73. if (!m_wndToolBar.Create(this) ||
  74. !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
  75. {
  76. TRACE0("Failed to create toolbar\n");
  77. return -1; // fail to create
  78. }
  79. m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
  80. CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
  81. m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
  82. EnableDocking(CBRS_ALIGN_ANY);
  83. DockControlBar(&m_wndToolBar);
  84. */
  85. g_frame = this;
  86. return 0;
  87. }
  88. //-----------------------------------------------------------------
  89. BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
  90. {
  91. cs.style = WS_OVERLAPPED | WS_CAPTION | WS_BORDER | FWS_ADDTOTITLE
  92. | WS_SYSMENU | WS_MINIMIZEBOX;
  93. cs.cx = 78;
  94. cs.cy = 50;
  95. LONG base = GetDialogBaseUnits();
  96. WORD baseX = LOWORD(base);
  97. WORD baseY = LOWORD(base);
  98. cs.cx *= baseX;
  99. cs.cy *= baseY;
  100. // account for user-defined window size changes
  101. cs.cy += GetSystemMetrics( SM_CYMENU );
  102. cs.cy += GetSystemMetrics( SM_CYCAPTION );
  103. // do the normal thing
  104. return CFrameWnd::PreCreateWindow(cs);
  105. }
  106. /////////////////////////////////////////////////////////////////////////////
  107. // CMainFrame diagnostics
  108. #ifdef _DEBUG
  109. //-----------------------------------------------------------------
  110. void CMainFrame::AssertValid() const
  111. {
  112. CFrameWnd::AssertValid();
  113. }
  114. //-----------------------------------------------------------------
  115. void CMainFrame::Dump(CDumpContext& dc) const
  116. {
  117. CFrameWnd::Dump(dc);
  118. }
  119. #endif //_DEBUG
  120. /////////////////////////////////////////////////////////////////////////////
  121. // CMainFrame message handlers
  122. /////////////////////////////////////////////////////////////////////////////
  123. // CMainFrame message handlers
  124. //--------------------------------------------------------------
  125. // we just want the title of the app in the title bar
  126. void CMainFrame::OnUpdateFrameTitle(BOOL bAddToTitle)
  127. {
  128. CFrameWnd::OnUpdateFrameTitle(FALSE);
  129. }
  130. //--------------------------------------------------------------
  131. BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
  132. {
  133. // create the static splitter window
  134. if ( !m_wndSplitter.CreateStatic( this, 1, 2 ) )
  135. {
  136. TRACE0("Failed to CreateStaticSplitter\n");
  137. return FALSE;
  138. }
  139. // calculate the width of the first splitter window
  140. DWORD cpWidth = 11;
  141. cpWidth *= LOWORD(GetDialogBaseUnits());
  142. // the initial size of the first pane should be a function of the width of the view
  143. // add the first splitter pane - The machine tree view
  144. if (!m_wndSplitter.CreateView(0, 0,
  145. pContext->m_pNewViewClass, CSize(cpWidth, 500), pContext))
  146. {
  147. TRACE0("Failed to create machine tree pane\n");
  148. return FALSE;
  149. }
  150. switch( g_InitialPane )
  151. {
  152. case PANE_MAIN:
  153. if (!m_wndSplitter.CreateView(0, 1,
  154. RUNTIME_CLASS(CFormMain), CSize(0, 0), pContext))
  155. {
  156. TRACE0("Failed to create main form pane\n");
  157. return FALSE;
  158. }
  159. break;
  160. case PANE_IE:
  161. if (!m_wndSplitter.CreateView(0, 1,
  162. RUNTIME_CLASS(CFormIE), CSize(0, 0), pContext))
  163. {
  164. TRACE0("Failed to create main form pane\n");
  165. return FALSE;
  166. }
  167. // get the new ie view
  168. m_pIEView = (CFormIE *)m_wndSplitter.GetPane(0, 1);
  169. break;
  170. case PANE_ADVANCED:
  171. if (!m_wndSplitter.CreateView(0, 1,
  172. RUNTIME_CLASS(CFormAdvanced), CSize(0, 0), pContext))
  173. {
  174. TRACE0("Failed to create main form pane\n");
  175. return FALSE;
  176. }
  177. break;
  178. };
  179. return TRUE;
  180. }
  181. //--------------------------------------------------------------
  182. // Replace the specified pane in the splitter window, with the
  183. // new view window
  184. void
  185. CMainFrame::ReplaceView(
  186. int nRow,
  187. int nCol,
  188. CRuntimeClass * pNewView,
  189. CSize & size
  190. )
  191. {
  192. g_pCurrentForm = NULL;
  193. CView * pCurrentView = (CView *)m_wndSplitter.GetPane(nRow, nCol);
  194. CRect rc;
  195. pCurrentView->GetClientRect(rc);
  196. size = CSize(rc.Width(), rc.Height());
  197. BOOL fActiveView = (pCurrentView == GetActiveView());
  198. CDocument * pDoc= pCurrentView->GetDocument();
  199. //
  200. // set flag so that document will not be deleted when
  201. // view is destroyed
  202. //
  203. pDoc->m_bAutoDelete = FALSE;
  204. //
  205. // Delete existing view
  206. //
  207. pCurrentView->DestroyWindow();
  208. //
  209. // set flag back to default
  210. //
  211. pDoc->m_bAutoDelete = TRUE;
  212. //
  213. // Create new view
  214. //
  215. CCreateContext context;
  216. context.m_pNewViewClass = pNewView;
  217. context.m_pCurrentDoc = pDoc;
  218. context.m_pNewDocTemplate = NULL;
  219. context.m_pLastView = NULL;
  220. context.m_pCurrentFrame = NULL;
  221. m_wndSplitter.CreateView(nRow, nCol, pNewView, size, &context);
  222. pCurrentView = (CView *)m_wndSplitter.GetPane(nRow, nCol);
  223. pCurrentView->OnInitialUpdate();
  224. m_wndSplitter.RecalcLayout();
  225. if (fActiveView)
  226. {
  227. SetActiveView(pCurrentView);
  228. }
  229. }
  230. //--------------------------------------------------------------
  231. void CMainFrame::OnPgeMain()
  232. {
  233. m_pIEView = NULL;
  234. ReplaceView( 0, 1, RUNTIME_CLASS(CFormMain), CSize(0, 0) );
  235. }
  236. //--------------------------------------------------------------
  237. void CMainFrame::OnPgeAdvanced()
  238. {
  239. if ( g_fShutdownMode )
  240. {
  241. AfxMessageBox( IDS_ERR_SERV_ADVANCED );
  242. return;
  243. }
  244. m_pIEView = NULL;
  245. ReplaceView( 0, 1, RUNTIME_CLASS(CFormAdvanced), CSize(0, 0) );
  246. }
  247. //--------------------------------------------------------------
  248. BOOL CMainFrame::OnPgeIE()
  249. {
  250. // if we are already on the IE page, then we don't have to do anything
  251. if ( m_pIEView )
  252. return TRUE;
  253. // we have to swap in theIE pane
  254. CWaitCursor wait;
  255. ReplaceView( 0, 1, RUNTIME_CLASS(CFormIE), CSize(0, 0) );
  256. // get the new ie view
  257. m_pIEView = (CFormIE *)m_wndSplitter.GetPane(0, 1);
  258. if ( !m_pIEView ) return FALSE;
  259. // tell the user to sit tight
  260. m_pIEView->SetTitle( IDS_PLEASE_WAIT_IE_LOADING );
  261. m_pIEView->UpdateWindow( );
  262. return TRUE;
  263. }
  264. //--------------------------------------------------------------
  265. void CMainFrame::OnPgeTour()
  266. {
  267. // go to the IE page
  268. if ( !OnPgeIE() )
  269. return;
  270. // go to the URL
  271. m_pIEView->GoToTour();
  272. }
  273. /*
  274. //--------------------------------------------------------------
  275. void CMainFrame::OnPgeAboutMe()
  276. {
  277. // first, make sure the server is running
  278. CW3ServerControl serverController;
  279. if ( g_fShutdownMode || (serverController.GetServerState() != MD_SERVER_STATE_STARTED) )
  280. {
  281. AfxMessageBox( IDS_ERR_SERV_ABOUT );
  282. return;
  283. }
  284. // go to the IE page
  285. if ( !OnPgeIE() )
  286. return;
  287. // go to the correct URL
  288. m_pIEView->GoToPubWizard();
  289. }
  290. //--------------------------------------------------------------
  291. void CMainFrame::OnPgeWebSite()
  292. {
  293. // first, make sure the server is running
  294. CW3ServerControl serverController;
  295. if ( g_fShutdownMode || (serverController.GetServerState() != MD_SERVER_STATE_STARTED) )
  296. {
  297. AfxMessageBox( IDS_ERR_SERV_WEB );
  298. return;
  299. }
  300. // go to the IE page
  301. if ( !OnPgeIE() )
  302. return;
  303. // go to the correct URL
  304. m_pIEView->GoToWebsite();
  305. }
  306. */
  307. //--------------------------------------------------------------
  308. void CMainFrame::OnUpdatePgeTour(CCmdUI* pCmdUI)
  309. {
  310. pCmdUI->Enable( TRUE );
  311. }
  312. //--------------------------------------------------------------
  313. void CMainFrame::OnUpdatePgeMain(CCmdUI* pCmdUI)
  314. {
  315. pCmdUI->Enable( TRUE );
  316. }
  317. //--------------------------------------------------------------
  318. void CMainFrame::OnUpdatePgeAdvanced(CCmdUI* pCmdUI)
  319. {
  320. pCmdUI->Enable( !g_fShutdownMode );
  321. }
  322. /*
  323. //--------------------------------------------------------------
  324. void CMainFrame::OnUpdatePgeAboutMe(CCmdUI* pCmdUI)
  325. {
  326. BOOL fEnable = FALSE;
  327. // if we are not in shutdown mode, check the state of the server
  328. if ( !g_fShutdownMode )
  329. {
  330. CW3ServerControl serverController;
  331. DWORD dwState = serverController.GetServerState();
  332. fEnable = (dwState == MD_SERVER_STATE_STARTED);
  333. }
  334. // enable the item
  335. pCmdUI->Enable( fEnable );
  336. }
  337. //--------------------------------------------------------------
  338. void CMainFrame::OnUpdatePgeWebSite(CCmdUI* pCmdUI)
  339. {
  340. BOOL fEnable = FALSE;
  341. // if we are not in shutdown mode, check the state of the server
  342. if ( !g_fShutdownMode )
  343. {
  344. CW3ServerControl serverController;
  345. DWORD dwState = serverController.GetServerState();
  346. fEnable = (dwState == MD_SERVER_STATE_STARTED);
  347. }
  348. // enable the item
  349. pCmdUI->Enable( fEnable );
  350. }
  351. */
  352. //--------------------------------------------------------------
  353. void CMainFrame::WinHelp(DWORD dwData, UINT nCmd)
  354. {
  355. // if this is the context help for the main frame, get the context help for the
  356. // appropriate sub-dialog
  357. if ( g_pCurrentForm )
  358. {
  359. switch( LOWORD(dwData) )
  360. {
  361. case IDR_MAINFRAME:
  362. case IDD_DIRECTORY: // let the adv pane decide
  363. // clear out the lower word
  364. dwData &= 0xFFFF0000;
  365. // get the appropriate pane help id
  366. dwData |= g_pCurrentForm->GetContextHelpID();
  367. break;
  368. };
  369. }
  370. CFrameWnd::WinHelp(dwData, nCmd);
  371. }
  372. //--------------------------------------------------------------
  373. LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  374. {
  375. CFormSelectionBar* pSelView;
  376. // look for the server shutdown notification message
  377. switch( message )
  378. {
  379. case WM_PROCESS_REMOTE_COMMAND_INFO:
  380. ProcessRemoteCommand();
  381. break;
  382. case WM_UPDATE_SERVER_STATE:
  383. pSelView = (CFormSelectionBar*)m_wndSplitter.GetPane(0, 0);
  384. if ( pSelView )
  385. pSelView->ReflectAvailability();
  386. break;
  387. case WM_MAJOR_SERVER_SHUTDOWN_ALERT:
  388. if ( !g_fShutdownMode )
  389. EnterShutdownMode();
  390. break;
  391. case WM_TIMER: // only arrives if shutdown notify has happened
  392. CheckIfServerIsRunningAgain();
  393. break;
  394. };
  395. // do the inherited function
  396. return CFrameWnd::WindowProc(message, wParam, lParam);
  397. }
  398. //--------------------------------------------------------------
  399. void CMainFrame::EnterShutdownMode( void )
  400. {
  401. // first, shutdown the sink attached to the document
  402. if ( g_p_Doc )
  403. g_p_Doc->TerminateSink();
  404. // close the link to the metabase - it is going away after all
  405. FCloseMetabaseWrapper();
  406. // record that we are in shutdown mode
  407. g_fShutdownMode = TRUE;
  408. // go to the main page
  409. OnPgeMain();
  410. // reflect this in the selection bar
  411. CFormSelectionBar* pSelView = (CFormSelectionBar*)m_wndSplitter.GetPane(0, 0);
  412. if ( pSelView )
  413. pSelView->ReflectAvailability();
  414. // start the timer mechanism
  415. SetTimer( PWS_TIMER_CHECKFORSERVERRESTART, TIMER_RESTART, NULL );
  416. }
  417. //---------------------------------------------------------------------------
  418. // This routine is called on a timer event. The timer events only come if we
  419. // have received a shutdown notify callback from the metabase. So the server
  420. // is down. We need to wait around until it comes back up, then show ourselves.
  421. void CMainFrame::CheckIfServerIsRunningAgain()
  422. {
  423. // see if the server is running. If it is, show the icon and stop the timer.
  424. if ( FIsW3Running() && g_p_Doc )
  425. {
  426. // if we can't use the metabase, there is no point in this
  427. if ( !FInitMetabaseWrapper(NULL) )
  428. {
  429. return;
  430. }
  431. // if we can't use the sink, there is no point in this
  432. if ( !g_p_Doc->InitializeSink() )
  433. {
  434. FCloseMetabaseWrapper();
  435. return;
  436. }
  437. // clear the shutdown mode flag
  438. g_fShutdownMode = FALSE;
  439. // stop the timer mechanism
  440. KillTimer( PWS_TIMER_CHECKFORSERVERRESTART );
  441. // reflect this in the selection bar
  442. CFormSelectionBar* pSelView = (CFormSelectionBar*)m_wndSplitter.GetPane(0, 0);
  443. if ( pSelView )
  444. pSelView->ReflectAvailability();
  445. // tell the main page to update itself
  446. if ( g_FormMain )
  447. g_FormMain->PostMessage( WM_UPDATE_SERVER_STATE );
  448. }
  449. }
  450. // routine to see if w3svc is running
  451. //--------------------------------------------------------------------
  452. // the method we use to see if the service is running is different on
  453. // windows NT from win95
  454. BOOL CMainFrame::FIsW3Running()
  455. {
  456. OSVERSIONINFO info_os;
  457. info_os.dwOSVersionInfoSize = sizeof(info_os);
  458. if ( !GetVersionEx( &info_os ) )
  459. return FALSE;
  460. // if the platform is NT, query the service control manager
  461. if ( info_os.dwPlatformId == VER_PLATFORM_WIN32_NT )
  462. {
  463. BOOL fRunning = FALSE;
  464. // open the service manager
  465. SC_HANDLE sch = OpenSCManager(NULL, NULL, GENERIC_READ );
  466. if ( sch == NULL ) return FALSE;
  467. // get the service
  468. SC_HANDLE schW3 = OpenService(sch, _T("W3SVC"), SERVICE_QUERY_STATUS );
  469. if ( sch == NULL )
  470. {
  471. CloseServiceHandle( sch );
  472. return FALSE;
  473. }
  474. // query the service status
  475. SERVICE_STATUS status;
  476. ZeroMemory( &status, sizeof(status) );
  477. if ( QueryServiceStatus(schW3, &status) )
  478. {
  479. fRunning = (status.dwCurrentState == SERVICE_RUNNING);
  480. }
  481. CloseServiceHandle( schW3 );
  482. CloseServiceHandle( sch );
  483. // return the answer
  484. return fRunning;
  485. }
  486. // if the platform is Windows95, see if the object exists
  487. if ( info_os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
  488. {
  489. HANDLE hEvent;
  490. BOOL fFound = FALSE;
  491. hEvent = CreateEvent(NULL, TRUE, FALSE, _T(PWS_SHUTDOWN_EVENT));
  492. if ( hEvent != NULL )
  493. {
  494. fFound = (GetLastError() == ERROR_ALREADY_EXISTS);
  495. CloseHandle(hEvent);
  496. }
  497. return(fFound);
  498. }
  499. return FALSE;
  500. }
  501. //--------------------------------------------------------------
  502. // method only gets called when another instance of the application
  503. // as been invoked. Since we are only supposed to have one instance
  504. // of the apoplication running at a time, and also sine that other
  505. // instance may have been invoked with a command line, we should do
  506. // that that command line requested. The other instance has already
  507. // parsed the command and marshaled the parameters into a shared
  508. // memory space object. All we have to do is get it and act on the
  509. // commands
  510. void CMainFrame::ProcessRemoteCommand()
  511. {
  512. HANDLE hMap;
  513. PPWS_INSTANCE_TRANSFER pData;
  514. CString sz;
  515. CView *pView;
  516. // get the shared memory space object
  517. hMap = OpenFileMapping(
  518. FILE_MAP_READ,
  519. FALSE,
  520. PWS_INSTANCE_TRANSFER_SPACE_NAME
  521. );
  522. if ( hMap == NULL )
  523. return;
  524. pData = (PPWS_INSTANCE_TRANSFER)MapViewOfFile(
  525. hMap,
  526. FILE_MAP_READ,
  527. 0,
  528. 0,
  529. 0
  530. );
  531. if ( !pData )
  532. {
  533. CloseHandle(hMap);
  534. return;
  535. }
  536. // act on the command data we have just gotten
  537. switch( pData->iTargetPane )
  538. {
  539. case PANE_MAIN:
  540. OnPgeMain();
  541. // force the pane to update
  542. pView = (CView *)m_wndSplitter.GetPane(0, 1);
  543. if ( pView )
  544. {
  545. pView->PostMessage(WM_UPDATE_SERVER_STATE);
  546. pView->PostMessage(WM_UPDATE_LOCATIONS);
  547. }
  548. break;
  549. case PANE_IE:
  550. // go to the IE page
  551. if ( !OnPgeIE() )
  552. break;
  553. // go to the right IE page
  554. switch( pData->iTargetIELocation )
  555. {
  556. case INIT_IE_TOUR:
  557. m_pIEView->GoToTour();
  558. break;
  559. case INIT_IE_WEBSITE:
  560. m_pIEView->GoToWebsite();
  561. break;
  562. case INIT_IE_PUBWIZ:
  563. sz = &pData->tchIEURL;
  564. m_pIEView->GoToPubWizard( sz );
  565. break;
  566. };
  567. break;
  568. case PANE_ADVANCED:
  569. OnPgeAdvanced();
  570. // force the pane to update
  571. pView = (CView *)m_wndSplitter.GetPane(0, 1);
  572. if ( pView )
  573. {
  574. pView->PostMessage(WM_UPDATE_BROWSEINFO);
  575. pView->PostMessage(WM_UPDATE_LOGINFO);
  576. pView->PostMessage(WM_UPDATE_TREEINFO);
  577. }
  578. break;
  579. };
  580. // clean up the shared memory space
  581. UnmapViewOfFile(pData);
  582. CloseHandle(hMap);
  583. }