Team Fortress 2 Source Code as on 22/4/2020
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.

1861 lines
53 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "stdafx.h"
  7. #include <afxadv.h>
  8. #include <oaidl.h>
  9. #include "hammer.h"
  10. #include "Box3D.h" // For units
  11. #include "FaceEditSheet.h"
  12. #include "MainFrm.h"
  13. #include "MessageWnd.h"
  14. #include "ControlBarIDs.h"
  15. #include "CustomMessages.h"
  16. #include "DynamicDialogWnd.h"
  17. #include "filesystem_tools.h"
  18. #include "GlobalFunctions.h"
  19. #include "Prefabs.h"
  20. #include "PrefabsDlg.h"
  21. #include "MapDoc.h"
  22. #include "Manifest.h"
  23. #include "StatusBarIDs.h"
  24. #include "Splash.h"
  25. #include "Options.h"
  26. #include "OptionProperties.h"
  27. #include "ObjectProperties.h"
  28. #include "OP_Groups.h"
  29. #include "MapView2D.h"
  30. #include "MapViewLogical.h"
  31. #include "MapView3D.h"
  32. #include "ChildFrm.h"
  33. #include "NewDocType.h"
  34. #include "SearchReplaceDlg.h"
  35. #include "TextureBrowser.h"
  36. #include "TextureSystem.h"
  37. #include "ToolManager.h"
  38. #include "Material.h"
  39. #include "materialsystem/imaterialsystem.h"
  40. #include "materialsystem/MaterialSystem_Config.h"
  41. #include "soundbrowser.h"
  42. #include "lprvwindow.h"
  43. // memdbgon must be the last include file in a .cpp file!!!
  44. #include <tier0/memdbgon.h>
  45. IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)
  46. BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
  47. //{{AFX_MSG_MAP(CMainFrame)
  48. ON_WM_CREATE()
  49. ON_COMMAND(ID_EDIT_PROPERTIES, OnEditProperties)
  50. ON_UPDATE_COMMAND_UI(ID_EDIT_PROPERTIES, OnUpdateEditFunction)
  51. ON_COMMAND(ID_VIEW_MESSAGES, OnViewMessages)
  52. ON_UPDATE_COMMAND_UI(ID_VIEW_MESSAGES, OnUpdateViewMessages)
  53. ON_WM_ACTIVATEAPP()
  54. ON_WM_SIZE()
  55. ON_WM_CLOSE()
  56. ON_WM_DESTROY()
  57. ON_WM_PAINT()
  58. ON_WM_TIMER()
  59. ON_COMMAND(ID_TOOLS_OPTIONS, OnToolsOptions)
  60. ON_COMMAND(ID_TOOLS_PREFABFACTORY, OnToolsPrefabfactory)
  61. ON_COMMAND_EX(ID_HELP_TOPICS, OnHelpOpenURL)
  62. ON_COMMAND_EX(ID_HELP_EDITINGSITE, OnHelpOpenURL)
  63. ON_COMMAND_EX(ID_HELP_WORLDCRAFT_SUPPORT_MAIL, OnHelpOpenURL)
  64. ON_COMMAND(ID_EDIT_UNDOREDOACTIVE, OnEditUndoredoactive)
  65. ON_UPDATE_COMMAND_UI(ID_EDIT_UNDOREDOACTIVE, OnUpdateEditUndoredoactive)
  66. ON_COMMAND_EX(ID_FILE_NEW, OnFileNew)
  67. ON_COMMAND(ID_SAVEWINDOWSTATE, OnSavewindowstate)
  68. ON_COMMAND(ID_LOADWINDOWSTATE, OnLoadwindowstate)
  69. ON_COMMAND_EX(ID_MAP_UNITS_NONE, OnUnits)
  70. ON_UPDATE_COMMAND_UI(ID_MAP_UNITS_NONE, OnUpdateUnits)
  71. ON_COMMAND_EX(ID_MAP_UNITS_INCHES, OnUnits)
  72. ON_UPDATE_COMMAND_UI(ID_MAP_UNITS_INCHES, OnUpdateUnits)
  73. ON_COMMAND_EX(ID_MAP_UNITS_FEET_INCHES, OnUnits)
  74. ON_UPDATE_COMMAND_UI(ID_MAP_UNITS_FEET_INCHES, OnUpdateUnits)
  75. ON_UPDATE_COMMAND_UI(ID_VIEW_OPAQUE_MATERIALS, OnUpdateOpaqueMaterials)
  76. ON_UPDATE_COMMAND_UI(ID_VIEW_2DXZ, OnUpdateView2d)
  77. ON_UPDATE_COMMAND_UI(ID_VIEW_2DYZ, OnUpdateView2d)
  78. ON_UPDATE_COMMAND_UI(ID_VIEW_2DXY, OnUpdateView2d)
  79. ON_UPDATE_COMMAND_UI(ID_VIEW_3DWIREFRAME, OnUpdateView3d)
  80. ON_UPDATE_COMMAND_UI(ID_VIEW_3DPOLYGON, OnUpdateView3d)
  81. ON_UPDATE_COMMAND_UI(ID_VIEW_3DTEXTURED, OnUpdateView3d)
  82. //ON_UPDATE_COMMAND_UI(ID_VIEW_3DENGINE, OnUpdateView3d)
  83. ON_COMMAND(ID_VIEW_OPAQUE_MATERIALS, OnOpaqueMaterials)
  84. ON_COMMAND_EX(ID_VIEW3D_BRIGHTER, OnView3dChangeBrightness)
  85. ON_COMMAND_EX(ID_VIEW3D_DARKER, OnView3dChangeBrightness)
  86. ON_UPDATE_COMMAND_UI(ID_VIEW_OBJECTBAR, CFrameWnd::OnUpdateControlBarMenu)
  87. ON_COMMAND_EX(ID_VIEW_OBJECTBAR, CFrameWnd::OnBarCheck)
  88. ON_UPDATE_COMMAND_UI(ID_VIEW_SELECTION_MODE_BAR, CFrameWnd::OnUpdateControlBarMenu)
  89. ON_COMMAND_EX(ID_VIEW_SELECTION_MODE_BAR, CFrameWnd::OnBarCheck)
  90. ON_UPDATE_COMMAND_UI(ID_VIEW_FILTERCONTROL, CFrameWnd::OnUpdateControlBarMenu)
  91. ON_COMMAND_EX(ID_VIEW_FILTERCONTROL, CFrameWnd::OnBarCheck)
  92. ON_UPDATE_COMMAND_UI(ID_VIEW_MAPVIEWBAR, CFrameWnd::OnUpdateControlBarMenu)
  93. ON_COMMAND_EX(ID_VIEW_MAPVIEWBAR, CFrameWnd::OnBarCheck)
  94. ON_UPDATE_COMMAND_UI(ID_VIEW_MAPTOOLSBAR, CFrameWnd::OnUpdateControlBarMenu)
  95. ON_COMMAND_EX(ID_VIEW_MAPTOOLSBAR, CFrameWnd::OnBarCheck)
  96. ON_UPDATE_COMMAND_UI(ID_VIEW_TEXTUREBAR, CFrameWnd::OnUpdateControlBarMenu)
  97. ON_COMMAND_EX(ID_VIEW_TEXTUREBAR, CFrameWnd::OnBarCheck)
  98. ON_UPDATE_COMMAND_UI(ID_VIEW_MANIFEST_BAR, CFrameWnd::OnUpdateControlBarMenu)
  99. ON_COMMAND_EX(ID_VIEW_MANIFEST_BAR, CFrameWnd::OnBarCheck)
  100. //ON_UPDATE_COMMAND_UI(ID_VIEW_ANIMATIONBAR, CFrameWnd::OnUpdateControlBarMenu)
  101. //ON_COMMAND_EX(ID_VIEW_ANIMATIONBAR, CFrameWnd::OnBarCheck)
  102. ON_UPDATE_COMMAND_UI(ID_VIEW_MAPOPSBAR, CFrameWnd::OnUpdateControlBarMenu)
  103. ON_COMMAND_EX(ID_VIEW_MAPOPSBAR, CFrameWnd::OnBarCheck)
  104. ON_COMMAND_EX(ID_TOOLS_POINTER, OnChangeTool)
  105. ON_UPDATE_COMMAND_UI(ID_TOOLS_POINTER, OnUpdateToolUI)
  106. ON_COMMAND_EX(ID_TOOLS_CAMERA, OnChangeTool)
  107. ON_UPDATE_COMMAND_UI(ID_TOOLS_CAMERA, OnUpdateToolUI)
  108. ON_COMMAND_EX(ID_TOOLS_MAGNIFY, OnChangeTool)
  109. ON_UPDATE_COMMAND_UI(ID_TOOLS_MAGNIFY, OnUpdateToolUI)
  110. ON_COMMAND_EX(ID_TOOLS_BLOCK, OnChangeTool)
  111. ON_UPDATE_COMMAND_UI(ID_TOOLS_BLOCK, OnUpdateToolUI)
  112. ON_COMMAND_EX(ID_TOOLS_ENTITY, OnChangeTool)
  113. ON_UPDATE_COMMAND_UI(ID_TOOLS_ENTITY, OnUpdateToolUI)
  114. ON_COMMAND_EX(ID_TOOLS_APPLYDECALS, OnChangeTool)
  115. ON_UPDATE_COMMAND_UI(ID_TOOLS_APPLYDECALS, OnUpdateToolUI)
  116. ON_COMMAND_EX(ID_TOOLS_MORPH, OnChangeTool)
  117. ON_UPDATE_COMMAND_UI(ID_TOOLS_MORPH, OnUpdateToolUI)
  118. ON_COMMAND_EX(ID_TOOLS_CLIPPER, OnChangeTool)
  119. ON_UPDATE_COMMAND_UI(ID_TOOLS_CLIPPER, OnUpdateToolUI)
  120. ON_COMMAND_EX(ID_TOOLS_EDITCORDON, OnChangeTool)
  121. ON_UPDATE_COMMAND_UI(ID_TOOLS_EDITCORDON, OnUpdateToolUI)
  122. ON_COMMAND_EX(ID_TOOLS_PATH, OnChangeTool)
  123. ON_UPDATE_COMMAND_UI(ID_TOOLS_PATH, OnUpdateToolUI)
  124. ON_COMMAND_EX(ID_TOOLS_OVERLAY, OnChangeTool)
  125. ON_UPDATE_COMMAND_UI(ID_TOOLS_OVERLAY, OnUpdateToolUI)
  126. ON_COMMAND_EX(ID_MODE_APPLICATOR, OnApplicator)
  127. ON_COMMAND_EX(ID_TOOLS_SOUND_BROWSER, OnSoundBrowser)
  128. ON_COMMAND_EX(ID_FILE_RELOAD_SOUNDS, OnReloadSounds)
  129. ON_UPDATE_COMMAND_UI(ID_MODE_APPLICATOR, OnUpdateApplicatorUI)
  130. ON_COMMAND(ID_HELP_FINDER, CMDIFrameWnd::OnHelpFinder)
  131. ON_COMMAND(ID_HELP, CMDIFrameWnd::OnHelp)
  132. ON_COMMAND(ID_CONTEXT_HELP, CMDIFrameWnd::OnContextHelp)
  133. ON_COMMAND(ID_DEFAULT_HELP, CMDIFrameWnd::OnHelpFinder)
  134. ON_COMMAND(ID_HDR, OnHDR)
  135. ON_WM_HELPINFO()
  136. ON_WM_SYSCOMMAND()
  137. ON_WM_ENTERMENULOOP()
  138. //}}AFX_MSG_MAP
  139. END_MESSAGE_MAP()
  140. static UINT indicators[] =
  141. {
  142. ID_SEPARATOR, // status line indicator
  143. ID_INDICATOR_SELECTION,
  144. ID_INDICATOR_COORDS,
  145. ID_INDICATOR_SIZE,
  146. ID_INDICATOR_GRIDZOOM,
  147. ID_INDICATOR_SNAP
  148. };
  149. const int NUMSTATUSPANES = 7;
  150. const char * WINSTATETAG = "WCWINSTATE";
  151. const int WINSTATEEND = -1;
  152. const int WINSTATE2DVIEW = 0;
  153. const int WINSTATE3DVIEW = 1;
  154. const int WINSTATELOGICALVIEW = 2;
  155. const float fVersion = 0.1f;
  156. struct
  157. {
  158. int nIndex;
  159. UINT nID;
  160. UINT nStyle;
  161. int cxWidth;
  162. } paneinfo[NUMSTATUSPANES] =
  163. {
  164. { SBI_PROMPT, ID_SEPARATOR, SBPS_STRETCH | SBPS_NOBORDERS, 0 },
  165. { SBI_SELECTION, ID_INDICATOR_SELECTION, SBPS_NORMAL, 300 },
  166. { SBI_COORDS, ID_INDICATOR_COORDS, SBPS_NORMAL, 100 },
  167. { SBI_SIZE, ID_INDICATOR_SIZE, SBPS_NORMAL, 180 },
  168. { SBI_GRIDZOOM, ID_INDICATOR_GRIDZOOM, SBPS_NORMAL, 80 },
  169. { SBI_SNAP, ID_INDICATOR_SNAP, SBPS_NORMAL, 135 },
  170. { SBI_LIGHTPROGRESS,ID_INDICATOR_LIGHTPROGRESS, SBPS_NORMAL, 50 }
  171. };
  172. static GameData gd;
  173. static CMainFrame *pMainWnd;
  174. //-----------------------------------------------------------------------------
  175. // Purpose: Constructor.
  176. //-----------------------------------------------------------------------------
  177. CMainFrame::CMainFrame(void)
  178. {
  179. pTextureBrowser = NULL;
  180. pObjectProperties = NULL;
  181. m_bUndoActive = TRUE;
  182. m_bShellSessionActive = false;
  183. m_pFaceEditSheet = NULL;
  184. m_bMinimized = false;
  185. m_pSearchReplaceDlg = NULL;
  186. m_pLightingPreviewOutputWindow = NULL;
  187. m_bLightingPreviewOutputWindowShowing = false;
  188. }
  189. //-----------------------------------------------------------------------------
  190. // Purpose: Destructor.
  191. //-----------------------------------------------------------------------------
  192. CMainFrame::~CMainFrame(void)
  193. {
  194. delete pObjectProperties;
  195. delete pTextureBrowser;
  196. delete m_pFaceEditSheet;
  197. delete m_pSearchReplaceDlg;
  198. delete m_pLightingPreviewOutputWindow;
  199. CPrefabLibrary::FreeAllLibraries();
  200. }
  201. //-----------------------------------------------------------------------------
  202. // Purpose: Called through the shell to begin a session of editing the map
  203. // via the shell. The user interface is disabled to prevent a mismatched
  204. // versions between Hammer and the shell client.
  205. //-----------------------------------------------------------------------------
  206. void CMainFrame::BeginShellSession(void)
  207. {
  208. m_bShellSessionActive = true;
  209. }
  210. //-----------------------------------------------------------------------------
  211. // Purpose: Called through the shell to end a session of editing the map
  212. // via the engine. The user interface is enabled.
  213. //-----------------------------------------------------------------------------
  214. void CMainFrame::EndShellSession(void)
  215. {
  216. m_bShellSessionActive = false;
  217. }
  218. //-----------------------------------------------------------------------------
  219. // Purpose: If we get here there is no active 3D view. Uncheck the button.
  220. //-----------------------------------------------------------------------------
  221. void CMainFrame::OnUpdateView3d(CCmdUI *pCmdUI)
  222. {
  223. pCmdUI->SetCheck(FALSE);
  224. }
  225. //-----------------------------------------------------------------------------
  226. // Purpose: If we get here there is no active 3D view. Uncheck the button.
  227. //-----------------------------------------------------------------------------
  228. void CMainFrame::OnUpdateOpaqueMaterials(CCmdUI *pCmdUI)
  229. {
  230. pCmdUI->SetCheck(MaterialSystemConfig().bNoTransparency);
  231. }
  232. void CMainFrame::OnOpaqueMaterials()
  233. {
  234. MaterialSystemConfig().bNoTransparency = !MaterialSystemConfig().bNoTransparency;
  235. MaterialSystemInterface()->OverrideConfig( MaterialSystemConfig(), false );
  236. }
  237. //-----------------------------------------------------------------------------
  238. // Purpose: If we get here there is no active 2D view. Uncheck the button.
  239. //-----------------------------------------------------------------------------
  240. void CMainFrame::OnUpdateView2d(CCmdUI *pCmdUI)
  241. {
  242. pCmdUI->SetCheck(FALSE);
  243. }
  244. void CMainFrame::OnEnterMenuLoop( BOOL bIsTrackPopupMenu )
  245. {
  246. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  247. // if we are translation objects with a tool right now, dont switch to Menu mode
  248. if ( pDoc )
  249. {
  250. CBaseTool *pTool = pDoc->GetTools()->GetActiveTool();
  251. if ( pTool && pTool->IsTranslating() )
  252. {
  253. SendMessage( WM_CANCELMODE );
  254. }
  255. }
  256. }
  257. //-----------------------------------------------------------------------------
  258. // Purpose:
  259. // Input : lpCreateStruct -
  260. // Output :
  261. //-----------------------------------------------------------------------------
  262. int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  263. {
  264. const DWORD dwDefStyles = WS_CHILD | WS_VISIBLE | CBRS_TOP;
  265. lpCreateStruct->lpszClass = "VALVEWORLDCRAFT";
  266. if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
  267. return -1;
  268. if(!wndMDIClient.SubclassWindow(m_hWndMDIClient))
  269. {
  270. TRACE ("Failed to subclass MDI client window\n");
  271. return (-1);
  272. }
  273. //
  274. // Map view toolbar.
  275. //
  276. if (!m_wndMapToolBar.Create(this, dwDefStyles, IDCB_MAPVIEWBAR) || !m_wndMapToolBar.LoadToolBar(IDR_MAPDOC_VALVE))
  277. {
  278. TRACE0("Failed to create toolbar\n");
  279. return -1; // fail to create
  280. }
  281. m_wndMapToolBar.ModifyStyle(0, TBSTYLE_FLAT);
  282. //
  283. // Undo redo toolbar.
  284. //
  285. if (!m_wndUndoRedoToolBar.Create(this, dwDefStyles, IDCB_UNDO_REDO_BAR) || !m_wndUndoRedoToolBar.LoadToolBar(IDR_UNDOREDO))
  286. {
  287. TRACE0("Failed to create toolbar\n");
  288. return -1; // fail to create
  289. }
  290. m_wndUndoRedoToolBar.ModifyStyle(0, TBSTYLE_FLAT);
  291. //
  292. // Map editing toolbar.
  293. //
  294. m_wndMapEditToolBar.Create(this, dwDefStyles, IDCB_MAPTOOLSBAR);
  295. m_wndMapEditToolBar.ModifyStyle(0, TBSTYLE_FLAT);
  296. m_wndMapEditToolBar.LoadToolBar(IDR_MAPEDITTOOLS_VALVE);
  297. m_bmMapEditTools256.LoadBitmap(IDB_MAPEDITTOOLS_256);
  298. m_wndMapEditToolBar.SetBitmap((HBITMAP)m_bmMapEditTools256);
  299. //
  300. // Map operations toolbar.
  301. //
  302. if (!m_wndMapOps.Create(this, dwDefStyles, IDCB_MAPOPERATIONS) || !m_wndMapOps.LoadToolBar(IDR_MAPOPERATIONS_VALVE))
  303. {
  304. TRACE0("Failed to create toolbar\n");
  305. return -1; // fail to create
  306. }
  307. m_wndMapOps.ModifyStyle(0, TBSTYLE_FLAT);
  308. //
  309. // Status bar.
  310. //
  311. if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(NULL, NUMSTATUSPANES))
  312. {
  313. TRACE0("Failed to create status bar\n");
  314. return -1; // fail to create
  315. }
  316. for(int i = 0; i < NUMSTATUSPANES; i++)
  317. {
  318. m_wndStatusBar.SetPaneInfo(paneinfo[i].nIndex, paneinfo[i].nID, paneinfo[i].nStyle, paneinfo[i].cxWidth);
  319. }
  320. EnableDocking(CBRS_ALIGN_ANY);
  321. m_wndMapToolBar.SetBarStyle(m_wndMapToolBar.GetBarStyle() |
  322. CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
  323. m_wndUndoRedoToolBar.SetBarStyle(m_wndUndoRedoToolBar.GetBarStyle() |
  324. CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
  325. m_wndMapEditToolBar.SetBarStyle(m_wndMapEditToolBar.GetBarStyle() |
  326. CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
  327. m_wndMapOps.SetBarStyle(m_wndMapOps.GetBarStyle() |
  328. CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
  329. m_wndMapToolBar.EnableDocking(CBRS_ALIGN_ANY);
  330. m_wndUndoRedoToolBar.EnableDocking(CBRS_ALIGN_ANY);
  331. m_wndMapEditToolBar.EnableDocking(CBRS_ALIGN_ANY);
  332. m_wndMapOps.EnableDocking(CBRS_ALIGN_ANY);
  333. DockControlBar(&m_wndMapEditToolBar, AFX_IDW_DOCKBAR_LEFT);
  334. // top bars
  335. DockControlBar(&m_wndMapToolBar, AFX_IDW_DOCKBAR_TOP);
  336. DockControlBarLeftOf(&m_wndUndoRedoToolBar, &m_wndMapToolBar );
  337. DockControlBarLeftOf(&m_wndMapOps, &m_wndUndoRedoToolBar);
  338. // rightside control bars
  339. m_ObjectBar.Create(this);
  340. m_ObjectBar.SetBarStyle(m_ObjectBar.GetBarStyle() |
  341. CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED);
  342. m_ObjectBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);
  343. DockControlBar(&m_ObjectBar, AFX_IDW_DOCKBAR_RIGHT);
  344. m_FilterControl.Create(this);
  345. m_FilterControl.SetBarStyle(m_FilterControl.GetBarStyle() |
  346. CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED);
  347. m_FilterControl.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);
  348. DockControlBarLeftOf(&m_FilterControl, &m_ObjectBar);
  349. m_TextureBar.Create(this);
  350. m_TextureBar.SetBarStyle(m_TextureBar.GetBarStyle() |
  351. CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED);
  352. m_TextureBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);
  353. DockControlBarLeftOf(&m_TextureBar, &m_FilterControl);
  354. m_ManifestFilterControl.Create(this);
  355. m_ManifestFilterControl.SetBarStyle(m_ManifestFilterControl.GetBarStyle() |
  356. CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED);
  357. m_ManifestFilterControl.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);
  358. DockControlBar(&m_ManifestFilterControl, AFX_IDW_DOCKBAR_RIGHT);
  359. m_pFaceEditSheet = new CFaceEditSheet( "Face Edit Sheet", this );
  360. m_pFaceEditSheet->Setup();
  361. m_pFaceEditSheet->Create( this );
  362. m_pFaceEditSheet->SetVisibility( false );
  363. m_pLightingPreviewOutputWindow = NULL;
  364. //
  365. // Create the animation dialog bar.
  366. //
  367. //m_AnimationDlg.Create(this);
  368. //m_AnimationDlg.SetBarStyle(m_TextureBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED);
  369. //m_AnimationDlg.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);
  370. //DockControlBarLeftOf(&m_AnimationDlg, &m_TextureBar);
  371. //
  372. // Create the selection mode dialog bar.
  373. //
  374. m_SelectModeDlg.Create(this);
  375. m_SelectModeDlg.SetBarStyle(m_TextureBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED);
  376. m_SelectModeDlg.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);
  377. DockControlBarLeftOf(&m_SelectModeDlg, &m_TextureBar);
  378. //
  379. // Create object properties sheet - not visible yet.
  380. //
  381. pObjectProperties = new CObjectProperties;
  382. pObjectProperties->SetupPages();
  383. pObjectProperties->Create(this, WS_SYSMENU | WS_POPUP | WS_CAPTION | DS_MODALFRAME | WS_THICKFRAME);
  384. pMainWnd = this;
  385. //
  386. // Create the smoothing group visualization dialog.
  387. //
  388. m_SmoothingGroupDlg.Create( IDD_SMOOTHING_GROUP_VISUAL, this );
  389. //
  390. // Create message window.
  391. //
  392. CRect clientrect;
  393. wndMDIClient.GetClientRect(clientrect);
  394. g_pwndMessage->CreateMessageWindow( this, CRect( 0, clientrect.Height() - 90, clientrect.Width(), clientrect.Height() ) );
  395. CPrefabLibrary::LoadAllLibraries();
  396. ToolManager()->SetTool(TOOL_POINTER);
  397. pTextureBrowser = new CTextureBrowser(this);
  398. // HACK: Spackle up the maximized window position to (0, 0) to fix an intermittent bug. =(
  399. WINDOWPLACEMENT wp;
  400. ZeroMemory(&wp, sizeof(wp));
  401. wp.length = sizeof(wp);
  402. SetWindowPlacement(&wp);
  403. //
  404. // !!!NOTE: Always do this last to ensure that the layout does not get recalculated before the
  405. // window is maximized. This prevents control bars from being incorrectly wrapped to
  406. // the next column.
  407. //
  408. if (VerifyBarState())
  409. {
  410. LoadBarState("Barstate");
  411. }
  412. return 0;
  413. }
  414. void CMainFrame::DockControlBarLeftOf(CControlBar* Bar, CControlBar* LeftOf)
  415. {
  416. CRect rect;
  417. DWORD dw;
  418. UINT n;
  419. // get MFC to adjust the dimensions of all docked ToolBars
  420. // so that GetWindowRect will be accurate
  421. RecalcLayout();
  422. LeftOf->GetWindowRect(&rect);
  423. rect.OffsetRect(1,0);
  424. dw=LeftOf->GetBarStyle();
  425. n = 0;
  426. n = (dw&CBRS_ALIGN_TOP) ? AFX_IDW_DOCKBAR_TOP : n;
  427. n = (dw&CBRS_ALIGN_BOTTOM && n==0) ? AFX_IDW_DOCKBAR_BOTTOM : n;
  428. n = (dw&CBRS_ALIGN_LEFT && n==0) ? AFX_IDW_DOCKBAR_LEFT : n;
  429. n = (dw&CBRS_ALIGN_RIGHT && n==0) ? AFX_IDW_DOCKBAR_RIGHT : n;
  430. // When we take the default parameters on rect, DockControlBar will dock
  431. // each Toolbar on a seperate line. By calculating a rectangle, we in effect
  432. // are simulating a Toolbar being dragged to that location and docked.
  433. DockControlBar(Bar,n,&rect);
  434. }
  435. BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
  436. {
  437. cs.style |= WS_MAXIMIZE;
  438. cs.lpszClass = "VALVEWORLDCRAFT";
  439. return CMDIFrameWnd::PreCreateWindow(cs);
  440. }
  441. /////////////////////////////////////////////////////////////////////////////
  442. // CMainFrame diagnostics
  443. #ifdef _DEBUG
  444. void CMainFrame::AssertValid() const
  445. {
  446. CMDIFrameWnd::AssertValid();
  447. }
  448. void CMainFrame::Dump(CDumpContext& dc) const
  449. {
  450. CMDIFrameWnd::Dump(dc);
  451. }
  452. #endif //_DEBUG
  453. //-----------------------------------------------------------------------------
  454. // Purpose: Maps menu IDs to tool IDs.
  455. // Input : uMsg - Menu ID from a WM_COMMAND message.
  456. //-----------------------------------------------------------------------------
  457. static ToolID_t _ToolMsgToEnum(UINT uMsg)
  458. {
  459. struct ToolIDMap_t
  460. {
  461. UINT uMsg;
  462. ToolID_t eToolID;
  463. };
  464. ToolIDMap_t nIDMap[] =
  465. {
  466. { ID_TOOLS_POINTER, TOOL_POINTER },
  467. { ID_TOOLS_BLOCK, TOOL_BLOCK },
  468. { ID_TOOLS_ENTITY, TOOL_ENTITY },
  469. { ID_TOOLS_CAMERA, TOOL_CAMERA },
  470. { ID_TOOLS_MAGNIFY, TOOL_MAGNIFY },
  471. { ID_TOOLS_MORPH, TOOL_MORPH },
  472. { ID_TOOLS_CLIPPER, TOOL_CLIPPER },
  473. { ID_TOOLS_EDITCORDON, TOOL_EDITCORDON },
  474. { ID_TOOLS_OVERLAY, TOOL_OVERLAY },
  475. { ID_TOOLS_APPLYDECALS, TOOL_DECAL },
  476. { ID_MODE_APPLICATOR, TOOL_FACEEDIT_MATERIAL },
  477. };
  478. for (int i = 0; i < sizeof(nIDMap) / sizeof(nIDMap[0]); i++)
  479. {
  480. if (uMsg == nIDMap[i].uMsg)
  481. {
  482. return nIDMap[i].eToolID;
  483. }
  484. }
  485. return TOOL_POINTER;
  486. }
  487. //-----------------------------------------------------------------------------
  488. // Purpose: activates the current tool toolbar button
  489. // Input : pUI - interface to button that has had a action happen
  490. //-----------------------------------------------------------------------------
  491. void CMainFrame::OnUpdateToolUI(CCmdUI *pUI)
  492. {
  493. if (IsShellSessionActive())
  494. {
  495. pUI->Enable(FALSE);
  496. }
  497. else
  498. {
  499. //
  500. // check for button enabling
  501. //
  502. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  503. bool bIsEditable = ( pDoc ? pDoc->IsSelectionEditable() : false );
  504. if ( pUI->m_nID == ID_TOOLS_APPLYDECALS ||
  505. pUI->m_nID == ID_TOOLS_OVERLAY ||
  506. pUI->m_nID == ID_TOOLS_CLIPPER ||
  507. pUI->m_nID == ID_TOOLS_MORPH )
  508. {
  509. }
  510. else
  511. {
  512. bIsEditable = ( pDoc ? true : false );
  513. }
  514. #if 0
  515. //
  516. // Only enable the displacement toolbar button while editing HalfLife 2 maps.
  517. //
  518. if ( pUI->m_nID == ID_TOOLS_DISPLACE )
  519. {
  520. if ( pDoc != NULL )
  521. {
  522. pUI->Enable(pDoc->GetMapFormat() == mfHalfLife2);
  523. }
  524. else
  525. {
  526. pUI->Enable( pDoc != NULL );
  527. }
  528. }
  529. else
  530. #endif
  531. {
  532. pUI->Enable( bIsEditable );
  533. }
  534. ToolID_t eToolID = _ToolMsgToEnum(pUI->m_nID);
  535. pUI->Enable( bIsEditable );
  536. pUI->SetCheck(eToolID == ToolManager()->GetActiveToolID());
  537. }
  538. }
  539. //-----------------------------------------------------------------------------
  540. // Purpose: Handles toolbar and menu messages that change the active tool.
  541. // Input : nMessageID - the id of the menu item
  542. // Output : Returns TRUE to indicate that the message was handled.
  543. //-----------------------------------------------------------------------------
  544. BOOL CMainFrame::OnChangeTool(UINT nMessageID)
  545. {
  546. //
  547. // Changing tool -- exit face edit mode if necessary.
  548. // This is here because face edit mode encompasses two tools: the
  549. // material tool and the displacement tool. Which tool we use is set
  550. // by the OnSetActive handler of each page of the face edit sheet.
  551. //
  552. if (IsInFaceEditMode())
  553. {
  554. EnableFaceEditMode(false);
  555. }
  556. //
  557. // Activate the new tool.
  558. //
  559. ToolID_t eToolID = _ToolMsgToEnum(nMessageID);
  560. ToolManager()->SetTool(eToolID);
  561. return TRUE;
  562. }
  563. //-----------------------------------------------------------------------------
  564. // Purpose: Brings up the
  565. //-----------------------------------------------------------------------------
  566. void CMainFrame::OnViewMessages(void)
  567. {
  568. g_pwndMessage->ToggleMessageWindow();
  569. }
  570. //-----------------------------------------------------------------------------
  571. // Purpose: Manages the state of the view messages menu item.
  572. //-----------------------------------------------------------------------------
  573. void CMainFrame::OnUpdateViewMessages(CCmdUI *pCmdUI)
  574. {
  575. pCmdUI->SetCheck( g_pwndMessage->IsVisible() );
  576. }
  577. //-----------------------------------------------------------------------------
  578. // Purpose: Brings up the Object Properties dialog.
  579. //-----------------------------------------------------------------------------
  580. void CMainFrame::OnEditProperties(void)
  581. {
  582. pObjectProperties->ShowWindow(pObjectProperties->IsWindowVisible() ? SW_HIDE : SW_SHOW);
  583. }
  584. //-----------------------------------------------------------------------------
  585. // Purpose: Tell all the documents to redraw all their views.
  586. //-----------------------------------------------------------------------------
  587. void CMainFrame::UpdateAllDocViews(DWORD dwCmd)
  588. {
  589. for ( int i=0; i<CMapDoc::GetDocumentCount(); i++ )
  590. {
  591. CMapDoc *pDoc = CMapDoc::GetDocument(i);
  592. if (pDoc->GetGame() != NULL)
  593. {
  594. pDoc->UpdateAllViews( dwCmd );
  595. }
  596. }
  597. if (dwCmd & MAPVIEW_UPDATE_VISGROUP_ALL)
  598. {
  599. // This updates everything, so it takes priority.
  600. m_FilterControl.UpdateGroupList();
  601. }
  602. else if (dwCmd & MAPVIEW_UPDATE_VISGROUP_STATE)
  603. {
  604. // Only update the hidden/shown state of the visgroups.
  605. m_FilterControl.UpdateGroupListChecks();
  606. }
  607. }
  608. //-----------------------------------------------------------------------------
  609. // Purpose: Informs our application object when we are activated or deactivated.
  610. // Input : bActive - TRUE to activate, FALSE to deactivate.
  611. // hTask - task becoming active.
  612. //-----------------------------------------------------------------------------
  613. #if _MSC_VER < 1300
  614. void CMainFrame::OnActivateApp(BOOL bActive, HTASK hTask)
  615. #else
  616. void CMainFrame::OnActivateApp(BOOL bActive, DWORD hTask)
  617. #endif
  618. {
  619. CMDIFrameWnd::OnActivateApp(bActive, hTask);
  620. // Had to change this code to not call GetWindowPlacement because for some reason
  621. // that prevented Hammer from maximizing properly -- it would leave space on top.
  622. // So I cache the minimized state instead, which fixes the problem. Sigh.
  623. if (!m_bMinimized)
  624. {
  625. MaterialSystemInterface()->EvictManagedResources();
  626. APP()->OnActivateApp(bActive == TRUE);
  627. }
  628. }
  629. //-----------------------------------------------------------------------------
  630. // Purpose:
  631. // Input : nID -
  632. // lParam -
  633. //-----------------------------------------------------------------------------
  634. void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
  635. {
  636. CMDIFrameWnd::OnSysCommand(nID, lParam);
  637. if (nID == SC_MINIMIZE)
  638. {
  639. m_bMinimized = true;
  640. APP()->OnActivateApp(false);
  641. }
  642. else if ((nID == SC_MAXIMIZE) || (nID == SC_RESTORE))
  643. {
  644. m_bMinimized = false;
  645. APP()->OnActivateApp(true);
  646. }
  647. }
  648. //-----------------------------------------------------------------------------
  649. // Purpose: Called when the active document is deleted.
  650. //-----------------------------------------------------------------------------
  651. void CMainFrame::OnDeleteActiveDocument(void)
  652. {
  653. pObjectProperties->MarkDataDirty();
  654. }
  655. //-----------------------------------------------------------------------------
  656. // Purpose: Handles resize messages. Resizes any children that depend on our size.
  657. // Input : nType -
  658. // cx -
  659. // cy -
  660. //-----------------------------------------------------------------------------
  661. void CMainFrame::OnSize(UINT nType, int cx, int cy)
  662. {
  663. CMDIFrameWnd::OnSize(nType, cx, cy);
  664. //
  665. // Resize the message window if it exists.
  666. //
  667. if ( g_pwndMessage != NULL )
  668. {
  669. CRect clientrect;
  670. wndMDIClient.GetClientRect(clientrect);
  671. g_pwndMessage->Resize(CRect(0, clientrect.Height() - 130, clientrect.Width(), clientrect.Height()));
  672. }
  673. }
  674. //-----------------------------------------------------------------------------
  675. // Purpose: Returns a pointer to the main frame window.
  676. //-----------------------------------------------------------------------------
  677. CMainFrame *GetMainWnd(void)
  678. {
  679. return pMainWnd;
  680. }
  681. //-----------------------------------------------------------------------------
  682. // Purpose:
  683. // Input : nIndex -
  684. // pszText -
  685. //-----------------------------------------------------------------------------
  686. void SetStatusText(int nIndex, LPCTSTR pszText)
  687. {
  688. GetMainWnd()->GetStatusBar()->SetPaneText(nIndex, pszText);
  689. }
  690. //-----------------------------------------------------------------------------
  691. // Purpose: Invokes the configuration dialog, saving the options if the user
  692. // hits the OK button.
  693. //-----------------------------------------------------------------------------
  694. void CMainFrame::Configure(void)
  695. {
  696. COptionProperties dlg("Configure Hammer", NULL, 0);
  697. if (dlg.DoModal() == IDOK)
  698. {
  699. Options.Write( TRUE, TRUE );
  700. }
  701. }
  702. //-----------------------------------------------------------------------------
  703. // Purpose: Invokes the configuration dialog.
  704. //-----------------------------------------------------------------------------
  705. void CMainFrame::OnToolsOptions(void)
  706. {
  707. Configure();
  708. }
  709. //-----------------------------------------------------------------------------
  710. // Purpose: Called when the main frame is closing. Cleans up the dialog bars
  711. // and saves the options to the registry.
  712. //-----------------------------------------------------------------------------
  713. void CMainFrame::OnClose()
  714. {
  715. // Copied from CFrameWnd::OnClose. We can't call APP()->BeginClosing if they
  716. // hit cancel in the Save Modified dialog, and CFrameWnd::OnClose doesn't have
  717. // a return code to let us know if we're actually closing. Preposterous.
  718. // Note: only queries the active document
  719. CDocument *pDocument = GetActiveDocument();
  720. if (pDocument != NULL && !pDocument->CanCloseFrame(this))
  721. {
  722. // document can't close right now -- don't close it
  723. return;
  724. }
  725. //
  726. // Save the splitter configuration of the first child window in our list.
  727. //
  728. CChildFrame *pChild = GetNextMDIChildWnd(NULL);
  729. if (pChild != NULL)
  730. {
  731. pChild->SaveOptions();
  732. }
  733. CWinApp *pApp = AfxGetApp();
  734. if (pApp != NULL && pApp->m_pMainWnd == this)
  735. {
  736. // attempt to save all documents
  737. if (pDocument == NULL && !pApp->SaveAllModified())
  738. {
  739. // don't close it
  740. return;
  741. }
  742. pApp->CloseAllDocuments( FALSE );
  743. }
  744. // End of copied stuff.
  745. APP()->BeginClosing();
  746. // want to save the faceeditor as hidden
  747. ShowFaceEditSheetOrTextureBar( false );
  748. SaveBarState("Barstate");
  749. //AfxGetApp()->WriteProfileInt("General", "NewBars", TRUE);
  750. // Remove the smoothing group dialog window.
  751. m_SmoothingGroupDlg.DestroyWindow();
  752. // save options
  753. Options.general.bClosedCorrectly = TRUE;
  754. Options.Write( TRUE, TRUE );
  755. CMDIFrameWnd::OnClose();
  756. }
  757. //-----------------------------------------------------------------------------
  758. //-----------------------------------------------------------------------------
  759. void CMainFrame::OnDestroy(void)
  760. {
  761. CMDIFrameWnd::OnDestroy();
  762. PostQuitMessage(-1);
  763. }
  764. //-----------------------------------------------------------------------------
  765. // Purpose: Sets a timer for destroying the splash screen.
  766. //-----------------------------------------------------------------------------
  767. void CMainFrame::OnPaint(void)
  768. {
  769. static bool bFirst = true;
  770. CPaintDC dc(this); // device context for painting
  771. if (bFirst)
  772. {
  773. bFirst = false;
  774. SetTimer(FIRST_TIMER, 500, NULL);
  775. }
  776. }
  777. //-----------------------------------------------------------------------------
  778. // Purpose: This is called ONCE when the splash wnd is to be destroyed. OnPaint()
  779. // sets the timer. This is now also called for the autosave timer.
  780. // Input : nIDEvent -
  781. //-----------------------------------------------------------------------------
  782. void CMainFrame::OnTimer(UINT nIDEvent)
  783. {
  784. if (!::IsWindow(m_hWnd))
  785. {
  786. return;
  787. }
  788. if( nIDEvent == AUTOSAVE_TIMER )
  789. {
  790. APP()->Autosave();
  791. }
  792. if( nIDEvent == FIRST_TIMER ) //for the splash scren window destruction
  793. {
  794. // only want it once
  795. KillTimer(nIDEvent);
  796. // Don't continue if Hammer isn't configured yet!
  797. if (Options.configs.nConfigs == 0)
  798. return;
  799. Options.SetClosedCorrectly( FALSE );
  800. SetBrightness(Options.textures.fBrightness);
  801. // repaint texture window
  802. m_TextureBar.Invalidate();
  803. //when hammer is ready, start the autosave timer.
  804. if ( Options.general.iMaxAutosavesPerMap != 0 )
  805. {
  806. SetTimer( AUTOSAVE_TIMER, Options.general.iTimeBetweenSaves * 60 * 1000, NULL );
  807. }
  808. }
  809. }
  810. //-----------------------------------------------------------------------------
  811. // Purpose: Called when timer value is changed in the options
  812. // Input : void
  813. //-----------------------------------------------------------------------------
  814. void CMainFrame::ResetAutosaveTimer( void )
  815. {
  816. if ( Options.general.iMaxAutosavesPerMap != 0 )
  817. {
  818. SetTimer( AUTOSAVE_TIMER, Options.general.iTimeBetweenSaves * 60 * 1000, NULL );
  819. }
  820. else
  821. {
  822. KillTimer( AUTOSAVE_TIMER );
  823. }
  824. }
  825. //-----------------------------------------------------------------------------
  826. // Purpose:
  827. // Input : fBrightness -
  828. //-----------------------------------------------------------------------------
  829. void CMainFrame::SetBrightness(float fBrightness)
  830. {
  831. if(fBrightness < 0.1f || fBrightness > 5.0f)
  832. return;
  833. // update options
  834. Options.textures.fBrightness = fBrightness;
  835. // update display
  836. for(int i = 0; i < Options.configs.nConfigs; i++)
  837. Options.configs.Configs[i]->Palette.SetBrightness(fBrightness);
  838. g_Textures.InformPaletteChanged();
  839. //
  840. // if current tool isn't the material tool, then redraw the texture bar
  841. //
  842. if ( ToolManager()->GetActiveToolID() != TOOL_FACEEDIT_MATERIAL )
  843. {
  844. m_TextureBar.RedrawWindow();
  845. }
  846. else
  847. {
  848. m_pFaceEditSheet->RedrawWindow();
  849. }
  850. // tell all the documents to redraw 3d views
  851. UpdateAllDocViews( MAPVIEW_UPDATE_ONLY_3D | MAPVIEW_UPDATE_COLOR );
  852. }
  853. //-----------------------------------------------------------------------------
  854. // Purpose:
  855. // Input : nID -
  856. // Output : Returns TRUE on success, FALSE on failure.
  857. //-----------------------------------------------------------------------------
  858. BOOL CMainFrame::OnView3dChangeBrightness(UINT nID)
  859. {
  860. float fBrightness = Options.textures.fBrightness;
  861. float fModify = (nID == ID_VIEW3D_BRIGHTER) ? 0.2f : -0.2f;
  862. SetBrightness(fBrightness + fModify);
  863. return TRUE;
  864. }
  865. //-----------------------------------------------------------------------------
  866. // Purpose: Brings up the sound browser
  867. //-----------------------------------------------------------------------------
  868. BOOL CMainFrame::OnSoundBrowser(UINT nID)
  869. {
  870. CSoundBrowser dlg("");
  871. dlg.DoModal();
  872. return TRUE;
  873. }
  874. //-----------------------------------------------------------------------------
  875. // Purpose: Brings up the sound browser
  876. //-----------------------------------------------------------------------------
  877. BOOL CMainFrame::OnReloadSounds(UINT nID)
  878. {
  879. for ( int i = 0; i < SOUND_TYPE_COUNT; ++i )
  880. {
  881. g_Sounds.BuildSoundList( (SoundType_t)i );
  882. }
  883. return TRUE;
  884. }
  885. //-----------------------------------------------------------------------------
  886. // Purpose: Toggles face edit mode, which encompasses two different tools, the
  887. // materials editing tool and the displacement editing tool.
  888. //
  889. // The tool itself is set by the OnSetActive handler for each property
  890. // page of the face properties sheet.
  891. //-----------------------------------------------------------------------------
  892. BOOL CMainFrame::OnApplicator(UINT nID)
  893. {
  894. bool bNewFaceEditMode = !IsInFaceEditMode();
  895. //
  896. // Show/hide face edit sheet/texturebar and update the selection set if need be.
  897. //
  898. EnableFaceEditMode(bNewFaceEditMode);
  899. if (!bNewFaceEditMode)
  900. {
  901. ToolManager()->SetTool(TOOL_POINTER);
  902. }
  903. return TRUE;
  904. }
  905. //-----------------------------------------------------------------------------
  906. // Purpose: Enables or disables face edit mode, updating the UI as necessary.
  907. // When we are in face edit mode, the texture bar is hidden and the
  908. // face edit property sheet is shown. The active tool is changed
  909. // to either the material tool or the displacement tool based on which
  910. // page in the property sheet is active.
  911. //-----------------------------------------------------------------------------
  912. void CMainFrame::EnableFaceEditMode(bool bEnable)
  913. {
  914. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  915. if (!pDoc)
  916. {
  917. return;
  918. }
  919. ShowFaceEditSheetOrTextureBar(bEnable);
  920. pDoc->UpdateForApplicator(bEnable);
  921. }
  922. //-----------------------------------------------------------------------------
  923. // Purpose: Returns true if we are in face edit mode, false if not.
  924. //-----------------------------------------------------------------------------
  925. bool CMainFrame::IsInFaceEditMode()
  926. {
  927. if ((ToolManager()->GetActiveToolID() == TOOL_FACEEDIT_MATERIAL) || (ToolManager()->GetActiveToolID() == TOOL_FACEEDIT_DISP))
  928. {
  929. return true;
  930. }
  931. return false;
  932. }
  933. //-----------------------------------------------------------------------------
  934. // Purpose: Manages the state of the texture applicator toobar button and menu item.
  935. //-----------------------------------------------------------------------------
  936. void CMainFrame::OnUpdateApplicatorUI(CCmdUI *pUI)
  937. {
  938. if (IsShellSessionActive())
  939. {
  940. pUI->Enable(FALSE);
  941. }
  942. else
  943. {
  944. pUI->SetCheck(IsInFaceEditMode());
  945. pUI->Enable(CMapDoc::GetActiveMapDoc() ? TRUE : FALSE);
  946. }
  947. }
  948. //-----------------------------------------------------------------------------
  949. // Purpose: Invokes the prefab manager dialog.
  950. //-----------------------------------------------------------------------------
  951. void CMainFrame::OnToolsPrefabfactory(void)
  952. {
  953. CPrefabsDlg dlg;
  954. dlg.DoModal();
  955. CPrefabLibrary::LoadAllLibraries();
  956. m_ObjectBar.UpdateListForTool( ToolManager()->GetActiveToolID());
  957. }
  958. //-----------------------------------------------------------------------------
  959. // Purpose:
  960. //-----------------------------------------------------------------------------
  961. void CMainFrame::OnHelpFinder(void)
  962. {
  963. APP()->OpenURL(ID_HELP_TOPICS, GetMainWnd()->GetSafeHwnd());
  964. }
  965. //-----------------------------------------------------------------------------
  966. // Purpose:
  967. // Input : pHelpInfo -
  968. // Output : Returns TRUE on success, FALSE on failure.
  969. //-----------------------------------------------------------------------------
  970. BOOL CMainFrame::OnHelpInfo(HELPINFO *pHelpInfo)
  971. {
  972. return(Default());
  973. }
  974. //-----------------------------------------------------------------------------
  975. // Purpose: Opens a URL in the default web browser.
  976. //-----------------------------------------------------------------------------
  977. void CMainFrame::OpenURL(const char *pszURL)
  978. {
  979. APP()->OpenURL(pszURL, m_hWnd);
  980. }
  981. //-----------------------------------------------------------------------------
  982. // Purpose: Opens a URL in the default web browser by string ID.
  983. //-----------------------------------------------------------------------------
  984. void CMainFrame::OpenURL(UINT nID)
  985. {
  986. APP()->OpenURL(nID, m_hWnd);
  987. }
  988. //-----------------------------------------------------------------------------
  989. // Purpose: Opens the URL that corresponds to the given string ID. This is used
  990. // to hook menu items to URLs in the string table.
  991. //-----------------------------------------------------------------------------
  992. BOOL CMainFrame::OnHelpOpenURL(UINT nID)
  993. {
  994. OpenURL(nID);
  995. return TRUE;
  996. }
  997. //-----------------------------------------------------------------------------
  998. // Purpose: Activates or deactivates Undo/Redo.
  999. //-----------------------------------------------------------------------------
  1000. void CMainFrame::SetUndoActive(BOOL bActive)
  1001. {
  1002. m_bUndoActive = bActive;
  1003. CMapDoc::GetActiveMapDoc()->SetUndoActive(bActive == TRUE);
  1004. }
  1005. //-----------------------------------------------------------------------------
  1006. // Purpose: Toggles the active state of Undo/Redo.
  1007. //-----------------------------------------------------------------------------
  1008. void CMainFrame::OnEditUndoredoactive(void)
  1009. {
  1010. SetUndoActive(!m_bUndoActive);
  1011. }
  1012. //-----------------------------------------------------------------------------
  1013. // Purpose: Manages the state of the Enable/Disable Undo/Redo menu item.
  1014. //-----------------------------------------------------------------------------
  1015. void CMainFrame::OnUpdateEditUndoredoactive(CCmdUI *pCmdUI)
  1016. {
  1017. pCmdUI->Enable(IsShellSessionActive() ? FALSE : TRUE);
  1018. pCmdUI->SetText(m_bUndoActive ? "Disable Undo/Redo" : "Enable Undo/Redo");
  1019. }
  1020. //-----------------------------------------------------------------------------
  1021. // Purpose:
  1022. // Input : nCode -
  1023. //-----------------------------------------------------------------------------
  1024. void CMainFrame::GlobalNotify(int nCode)
  1025. {
  1026. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  1027. switch (nCode)
  1028. {
  1029. //
  1030. // Active document changed. Update visgroup lists.
  1031. //
  1032. case WM_MAPDOC_CHANGED:
  1033. {
  1034. //
  1035. // Update the visgroups.
  1036. //
  1037. m_FilterControl.UpdateGroupList();
  1038. //
  1039. // If the Object Properties dialog has a Groups tab, update
  1040. // the groups tab.
  1041. //
  1042. if (pObjectProperties != NULL)
  1043. {
  1044. pObjectProperties->UpdateGrouplist();
  1045. }
  1046. if (pDoc != NULL)
  1047. {
  1048. pDoc->UpdateStatusbar();
  1049. //m_AnimationDlg.SelectionChanged(*pDoc->Selection_GetList());
  1050. }
  1051. m_ManifestFilterControl.UpdateManifestList();
  1052. break;
  1053. }
  1054. //
  1055. // Game configuration changed. Update texture and entity lists.
  1056. //
  1057. case WM_GAME_CHANGED:
  1058. {
  1059. pTextureBrowser->SetTextureFormat(g_pGameConfig->GetTextureFormat());
  1060. m_TextureBar.NotifyGraphicsChanged();
  1061. m_pFaceEditSheet->NotifyGraphicsChanged();
  1062. if (pDoc != NULL)
  1063. m_ObjectBar.UpdateListForTool( pDoc->GetTools()->GetActiveToolID());
  1064. break;
  1065. }
  1066. //
  1067. // Lighting preview window closed
  1068. //
  1069. case LPRV_WINDOWCLOSED:
  1070. {
  1071. m_bLightingPreviewOutputWindowShowing = false;
  1072. break;
  1073. }
  1074. }
  1075. }
  1076. //-----------------------------------------------------------------------------
  1077. // Purpose:
  1078. // Input : UINT -
  1079. // Output : Returns TRUE on success, FALSE on failure.
  1080. //-----------------------------------------------------------------------------
  1081. BOOL CMainFrame::OnFileNew(UINT)
  1082. {
  1083. return FALSE;
  1084. CNewDocType dlg;
  1085. dlg.m_iNewType = 0;
  1086. if(dlg.DoModal() != IDOK)
  1087. return TRUE;
  1088. return FALSE;
  1089. }
  1090. //-----------------------------------------------------------------------------
  1091. // Purpose: Saves the position and types of all 2D and 3D views in the active document.
  1092. // dvs: This really needs to be a text file instead of a binary file!
  1093. // Input : *pFile -
  1094. //-----------------------------------------------------------------------------
  1095. void CMainFrame::SaveWindowStates(std::fstream *pFile)
  1096. {
  1097. char szRootDir[MAX_PATH];
  1098. char szFullPath[MAX_PATH];
  1099. APP()->GetDirectory(DIR_PROGRAM, szRootDir);
  1100. Q_MakeAbsolutePath( szFullPath, MAX_PATH, "winstate.wc", szRootDir );
  1101. std::fstream file(szFullPath, std::ios::out | std::ios::binary);
  1102. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  1103. if (pDoc == NULL)
  1104. {
  1105. return;
  1106. }
  1107. file.write(WINSTATETAG, sizeof WINSTATETAG);
  1108. file.write((char*) &fVersion, sizeof fVersion);
  1109. CRect rectClient;
  1110. ::GetClientRect(m_hWndMDIClient, &rectClient);
  1111. // write out each view
  1112. POSITION p = pDoc->GetFirstViewPosition();
  1113. while (p != NULL)
  1114. {
  1115. CView *pView = pDoc->GetNextView(p);
  1116. //
  1117. // Determine what type of view it is.
  1118. //
  1119. int iDrawType;
  1120. if (pView->IsKindOf(RUNTIME_CLASS(CMapView2D)))
  1121. {
  1122. file.write((char*) &WINSTATE2DVIEW, sizeof WINSTATE2DVIEW);
  1123. iDrawType = (int)((CMapView2D*)pView)->GetDrawType();
  1124. }
  1125. else if (pView->IsKindOf(RUNTIME_CLASS(CMapView3D)))
  1126. {
  1127. file.write((char*) &WINSTATE3DVIEW, sizeof WINSTATE3DVIEW);
  1128. iDrawType = (int)((CMapView3D*)pView)->GetDrawType();
  1129. }
  1130. else if (pView->IsKindOf(RUNTIME_CLASS(CMapViewLogical)))
  1131. {
  1132. file.write((char*) &WINSTATELOGICALVIEW, sizeof WINSTATELOGICALVIEW);
  1133. iDrawType = (int)((CMapViewLogical*)pView)->GetDrawType();
  1134. }
  1135. else
  1136. {
  1137. //
  1138. // It's a view type whose state we do not save - skip it.
  1139. //
  1140. continue;
  1141. }
  1142. //
  1143. // Write view's draw type.
  1144. //
  1145. file.write((char*) &iDrawType, sizeof iDrawType);
  1146. //
  1147. // Write position of view.
  1148. //
  1149. CRect rectView;
  1150. pView->GetParentFrame()->GetWindowRect(&rectView);
  1151. CPoint pt1 = rectView.TopLeft(), pt2 = rectView.BottomRight();
  1152. ::ScreenToClient(m_hWndMDIClient, &pt1);
  1153. ::ScreenToClient(m_hWndMDIClient, &pt2);
  1154. double left, top, right, bottom;
  1155. left = double(pt1.x) / double(rectClient.right);
  1156. top = double(pt1.y) / double(rectClient.bottom);
  1157. right = double(pt2.x) / double(rectClient.right);
  1158. bottom = double(pt2.y) / double(rectClient.bottom);
  1159. file.write((char*) &left, sizeof left);
  1160. file.write((char*) &top, sizeof top);
  1161. file.write((char*) &right, sizeof right);
  1162. file.write((char*) &bottom, sizeof bottom);
  1163. }
  1164. file.write((char *)&WINSTATEEND, sizeof WINSTATEEND);
  1165. }
  1166. //-----------------------------------------------------------------------------
  1167. // Purpose:
  1168. // Input : pFile -
  1169. //-----------------------------------------------------------------------------
  1170. void CMainFrame::LoadWindowStates(std::fstream *pFile)
  1171. {
  1172. char szRootDir[MAX_PATH];
  1173. char szFullPath[MAX_PATH];
  1174. APP()->GetDirectory(DIR_PROGRAM, szRootDir);
  1175. Q_MakeAbsolutePath( szFullPath, MAX_PATH, "winstate.wc", szRootDir );
  1176. std::fstream file( szFullPath, std::ios::in | std::ios::binary );
  1177. if (!file.is_open())
  1178. {
  1179. return;
  1180. }
  1181. char tag[sizeof(WINSTATETAG)];
  1182. file.read(tag, sizeof tag);
  1183. if(memcmp(tag, WINSTATETAG, sizeof tag))
  1184. {
  1185. file.seekg(-int(sizeof(tag)));
  1186. return;
  1187. }
  1188. float fThisVersion;
  1189. file.read((char*) &fThisVersion, sizeof fThisVersion);
  1190. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  1191. if(!pDoc)
  1192. return;
  1193. // get client rect of MDI CHILD for relative positioning information
  1194. CRect rectClient;
  1195. ::GetClientRect(m_hWndMDIClient, &rectClient);
  1196. // keep list of views we've already modified, so if there
  1197. // are other views, we have to create them. this prevents
  1198. // us from having to delete all views and start over,
  1199. // which is a slower process than simply moving existing
  1200. // views.
  1201. CTypedPtrList<CPtrList, CView*> UsedViews;
  1202. SetDefaultChildType(FALSE);
  1203. while (1)
  1204. {
  1205. int iViewType;
  1206. file.read((char *)&iViewType, sizeof iViewType);
  1207. if ((file.eof()) || (iViewType == WINSTATEEND))
  1208. {
  1209. break;
  1210. }
  1211. int iDrawType;
  1212. file.read((char *)&iDrawType, sizeof iDrawType);
  1213. CView *pView = NULL;
  1214. // find a view we haven't used
  1215. POSITION p = pDoc->GetFirstViewPosition();
  1216. while (p != NULL)
  1217. {
  1218. CView *pThisView = pDoc->GetNextView(p);
  1219. // already used?
  1220. if (UsedViews.Find(pThisView))
  1221. continue;
  1222. // make sure it's the right type ..
  1223. if (iViewType == WINSTATE2DVIEW && !pThisView->IsKindOf(RUNTIME_CLASS(CMapView2D)))
  1224. continue;
  1225. if (iViewType == WINSTATELOGICALVIEW && !pThisView->IsKindOf(RUNTIME_CLASS(CMapViewLogical)))
  1226. continue;
  1227. if (iViewType == WINSTATE3DVIEW && !pThisView->IsKindOf(RUNTIME_CLASS(CMapView3D)))
  1228. continue;
  1229. // yes! so modify this one.
  1230. pView = pThisView;
  1231. UsedViews.AddTail(pView);
  1232. break;
  1233. }
  1234. CChildFrame *pFrame = NULL;
  1235. BOOL bNew = FALSE;
  1236. CDocTemplate *pTemplate = NULL;
  1237. if(!pView)
  1238. {
  1239. // if no view was created, we have to create a new one.
  1240. CMDIChildWnd* pActiveChild = MDIGetActive();
  1241. pTemplate = pDoc->GetDocTemplate();
  1242. pFrame = (CChildFrame*) pTemplate->CreateNewFrame(pDoc, pActiveChild);
  1243. pFrame->SetRedraw(FALSE);
  1244. pTemplate->InitialUpdateFrame(pFrame, pDoc, FALSE);
  1245. // find view in new frame
  1246. pView = pFrame->GetActiveView();
  1247. UsedViews.AddTail(pView);
  1248. bNew = TRUE;
  1249. }
  1250. else
  1251. {
  1252. // find frame based on this view
  1253. pFrame = (CChildFrame*) pView->GetParentFrame();
  1254. if(pFrame->bUsingSplitter)
  1255. pFrame->SetSplitterMode(FALSE);
  1256. }
  1257. // no redraws right now, please.
  1258. pFrame->SetRedraw(FALSE);
  1259. if (iViewType == WINSTATE3DVIEW)
  1260. {
  1261. //
  1262. // Handle import of old WinState files before draw types were consolidated
  1263. // into a single enumeration.
  1264. //
  1265. if ((iDrawType >= VIEW2D_XY) && (iDrawType <= VIEW2D_XZ))
  1266. {
  1267. iDrawType += 3;
  1268. }
  1269. pFrame->SetViewType((DrawType_t)iDrawType);
  1270. }
  1271. else if (iViewType == WINSTATE2DVIEW)
  1272. {
  1273. pFrame->SetViewType((DrawType_t)iDrawType);
  1274. }
  1275. else if (iViewType == WINSTATELOGICALVIEW)
  1276. {
  1277. pFrame->SetViewType( (DrawType_t)iDrawType );
  1278. }
  1279. // read positioning info
  1280. double left, top, right, bottom;
  1281. file.read((char*) &left, sizeof left);
  1282. file.read((char*) &top, sizeof top);
  1283. file.read((char*) &right, sizeof right);
  1284. file.read((char*) &bottom, sizeof bottom);
  1285. CRect r;
  1286. r.left = int(left * double(rectClient.right));
  1287. r.top = int(top * double(rectClient.bottom));
  1288. r.right = int(right * double(rectClient.right));
  1289. r.bottom = int(bottom * double(rectClient.bottom));
  1290. // Set the frame's position.
  1291. pFrame->MoveWindow(&r, FALSE);
  1292. // Call OnInitialUpdate before any rendering takes place.
  1293. if (bNew)
  1294. {
  1295. pTemplate->InitialUpdateFrame(pFrame, pDoc, TRUE);
  1296. }
  1297. // Enable WM_PAINT messages for the frame window.
  1298. pFrame->SetRedraw(TRUE);
  1299. // Update the window.
  1300. pFrame->Invalidate();
  1301. pFrame->UpdateWindow();
  1302. }
  1303. Invalidate();
  1304. UpdateWindow();
  1305. }
  1306. void CMainFrame::OnInitMenu( CMenu *pMenu )
  1307. {
  1308. }
  1309. void CMainFrame::OnHDR( void )
  1310. {
  1311. CMenu *pMenu= GetMenu();
  1312. UINT state = pMenu->GetMenuState(ID_HDR, MF_BYCOMMAND);
  1313. if (state & MF_CHECKED)
  1314. {
  1315. pMenu->CheckMenuItem(ID_HDR, MF_UNCHECKED | MF_BYCOMMAND);
  1316. g_bHDR = false;
  1317. }
  1318. else
  1319. {
  1320. pMenu->CheckMenuItem(ID_HDR, MF_CHECKED | MF_BYCOMMAND);
  1321. g_bHDR = true;
  1322. }
  1323. DrawMenuBar();
  1324. SignalUpdate( EVTYPE_LIGHTING_CHANGED );
  1325. }
  1326. //-----------------------------------------------------------------------------
  1327. // Purpose:
  1328. //-----------------------------------------------------------------------------
  1329. void CMainFrame::OnSavewindowstate(void)
  1330. {
  1331. SaveWindowStates();
  1332. }
  1333. //-----------------------------------------------------------------------------
  1334. // Purpose:
  1335. //-----------------------------------------------------------------------------
  1336. void CMainFrame::OnLoadwindowstate(void)
  1337. {
  1338. LoadWindowStates();
  1339. }
  1340. //-----------------------------------------------------------------------------
  1341. // Purpose: Changes the format of the units displayed in the status bar.
  1342. // Input : nID - Menu ID corresponding to a units format.
  1343. //-----------------------------------------------------------------------------
  1344. BOOL CMainFrame::OnUnits(UINT nID)
  1345. {
  1346. switch (nID)
  1347. {
  1348. case ID_MAP_UNITS_NONE:
  1349. {
  1350. Box3D::SetWorldUnits(Units_None);
  1351. break;
  1352. }
  1353. case ID_MAP_UNITS_INCHES:
  1354. {
  1355. Box3D::SetWorldUnits(Units_Inches);
  1356. break;
  1357. }
  1358. case ID_MAP_UNITS_FEET_INCHES:
  1359. {
  1360. Box3D::SetWorldUnits(Units_Feet_Inches);
  1361. break;
  1362. }
  1363. }
  1364. CMapDoc::GetActiveMapDoc()->UpdateStatusbar();
  1365. return TRUE;
  1366. }
  1367. //-----------------------------------------------------------------------------
  1368. // Purpose: Manages the state of decal application toolbar button.
  1369. //-----------------------------------------------------------------------------
  1370. void CMainFrame::OnUpdateUnits(CCmdUI *pCmdUI)
  1371. {
  1372. pCmdUI->Enable(!IsShellSessionActive());
  1373. if (pCmdUI->m_nID == ID_MAP_UNITS_NONE)
  1374. {
  1375. pCmdUI->SetCheck(Box3D::GetWorldUnits() == Units_None);
  1376. }
  1377. else if (pCmdUI->m_nID == ID_MAP_UNITS_INCHES)
  1378. {
  1379. pCmdUI->SetCheck(Box3D::GetWorldUnits() == Units_Inches);
  1380. }
  1381. else if (pCmdUI->m_nID == ID_MAP_UNITS_FEET_INCHES)
  1382. {
  1383. pCmdUI->SetCheck(Box3D::GetWorldUnits() == Units_Feet_Inches);
  1384. }
  1385. }
  1386. //-----------------------------------------------------------------------------
  1387. // Purpose:
  1388. // Input : pMsg -
  1389. // Output : Returns TRUE on success, FALSE on failure.
  1390. //-----------------------------------------------------------------------------
  1391. BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
  1392. {
  1393. //
  1394. // See if the message is a keydown and the current focus window is the
  1395. // ComboBox in the ObjectBar!
  1396. //
  1397. /*
  1398. if (pMsg->message == WM_KEYDOWN)
  1399. {
  1400. if ((GetFocus() == &m_ObjectBar) || (GetFocus() == &this->m_FilterControl))
  1401. {
  1402. AfxMessageBox("Ok");
  1403. return(TRUE);
  1404. }
  1405. }
  1406. */
  1407. return(CMDIFrameWnd::PreTranslateMessage(pMsg));
  1408. }
  1409. //-----------------------------------------------------------------------------
  1410. // Purpose: Finds the next CChildFrame in the list of MDI child windows.
  1411. // Input : pCurChild - Child to search from.
  1412. //-----------------------------------------------------------------------------
  1413. CChildFrame *CMainFrame::GetNextMDIChildWnd(CChildFrame *pCurChild)
  1414. {
  1415. return GetNextMDIChildWndRecursive(pCurChild);
  1416. }
  1417. //-----------------------------------------------------------------------------
  1418. // Purpose:
  1419. //-----------------------------------------------------------------------------
  1420. CChildFrame *CMainFrame::GetNextMDIChildWndRecursive(CWnd *pCurChild)
  1421. {
  1422. CWnd *pNextChild = NULL;
  1423. if (pCurChild == NULL)
  1424. {
  1425. // Get the first child window.
  1426. pNextChild = wndMDIClient.GetWindow(GW_CHILD);
  1427. }
  1428. else
  1429. {
  1430. // Get the next child window in the list.
  1431. pNextChild = pCurChild->GetWindow(GW_HWNDNEXT);
  1432. if (!pNextChild)
  1433. {
  1434. // No child windows exist in the MDIClient,
  1435. // or you are at the end of the list. This check
  1436. // will terminate any recursion.
  1437. return NULL;
  1438. }
  1439. }
  1440. // Check the kind of window
  1441. if (!pNextChild->GetWindow(GW_OWNER))
  1442. {
  1443. if (pNextChild->IsKindOf(RUNTIME_CLASS(CChildFrame)))
  1444. {
  1445. return (CChildFrame *)pNextChild;
  1446. }
  1447. }
  1448. // Not one we are interested in. Try the next one.
  1449. // Recurse over the window manager's list of windows.
  1450. return GetNextMDIChildWndRecursive(pNextChild);
  1451. }
  1452. //-----------------------------------------------------------------------------
  1453. // Purpose: Returns true if we are currently editing via the engine, false if not.
  1454. //-----------------------------------------------------------------------------
  1455. bool CMainFrame::IsShellSessionActive(void)
  1456. {
  1457. return(m_bShellSessionActive);
  1458. }
  1459. //-----------------------------------------------------------------------------
  1460. // Purpose: Manages the state of all Edit menu items and toolbar buttons.
  1461. //-----------------------------------------------------------------------------
  1462. void CMainFrame::OnUpdateEditFunction(CCmdUI *pCmdUI)
  1463. {
  1464. pCmdUI->Enable(!IsShellSessionActive());
  1465. }
  1466. //-----------------------------------------------------------------------------
  1467. //-----------------------------------------------------------------------------
  1468. void CMainFrame::ShowFaceEditSheetOrTextureBar( bool bShowFaceEditSheet )
  1469. {
  1470. if( bShowFaceEditSheet )
  1471. {
  1472. m_pFaceEditSheet->SetVisibility( true );
  1473. ShowControlBar( &m_TextureBar, FALSE, TRUE );
  1474. }
  1475. else
  1476. {
  1477. m_pFaceEditSheet->SetVisibility( false );
  1478. m_pFaceEditSheet->CloseAllPageDialogs();
  1479. ShowControlBar( &m_TextureBar, TRUE, TRUE );
  1480. }
  1481. }
  1482. //-----------------------------------------------------------------------------
  1483. // Purpose: Displays the search/replace dialog. It will be hide itself when the
  1484. // user closes it.
  1485. //-----------------------------------------------------------------------------
  1486. void CMainFrame::ShowSearchReplaceDialog(void)
  1487. {
  1488. if (m_pSearchReplaceDlg == NULL)
  1489. {
  1490. m_pSearchReplaceDlg = new CSearchReplaceDlg;
  1491. m_pSearchReplaceDlg->Create(this);
  1492. }
  1493. m_pSearchReplaceDlg->ShowWindow(SW_SHOW);
  1494. m_pSearchReplaceDlg->SetFocus();
  1495. }
  1496. //-----------------------------------------------------------------------------
  1497. // Purpose: Code found on codeproject.com.
  1498. //
  1499. // Makes sure we don't have bogus dialog bar information in the registry.
  1500. // This prevents a crash in the MFC code if a version of the editor with
  1501. // different toolbars was run before us.
  1502. //
  1503. // TODO: fix the registry settings if they are bad so we can still load the bar state
  1504. //
  1505. // Output : Returns true if it is safe to load the toolbar settings, false if not.
  1506. //-----------------------------------------------------------------------------
  1507. bool CMainFrame::VerifyBarState(void)
  1508. {
  1509. CDockState state;
  1510. state.LoadState("BarState");
  1511. for (int i = 0; i < state.m_arrBarInfo.GetSize(); i++)
  1512. {
  1513. CControlBarInfo* pInfo = (CControlBarInfo*)state.m_arrBarInfo[i];
  1514. Assert(pInfo != NULL);
  1515. int nDockedCount = pInfo->m_arrBarID.GetSize();
  1516. if (nDockedCount > 0)
  1517. {
  1518. for (int j = 0; j < nDockedCount; j++)
  1519. {
  1520. UINT nID = (UINT) pInfo->m_arrBarID[j];
  1521. if (nID == 0)
  1522. {
  1523. continue; // row separator
  1524. }
  1525. if (nID > 0xFFFF)
  1526. {
  1527. nID &= 0xFFFF; // placeholder - get the ID
  1528. }
  1529. if (GetControlBar(nID) == NULL)
  1530. {
  1531. return false;
  1532. }
  1533. }
  1534. }
  1535. if (!pInfo->m_bFloating) // floating dockbars can be created later
  1536. {
  1537. if (GetControlBar(pInfo->m_nBarID) == NULL)
  1538. {
  1539. return false; // invalid bar ID
  1540. }
  1541. }
  1542. }
  1543. return true;
  1544. }
  1545. //-----------------------------------------------------------------------------
  1546. // Purpose:
  1547. // Input : dwData -
  1548. // nCmd -
  1549. //-----------------------------------------------------------------------------
  1550. void CMainFrame::WinHelp(DWORD dwData, UINT nCmd)
  1551. {
  1552. // dvs: HACK: just punt them to the main help page
  1553. APP()->OpenURL(ID_HELP_TOPICS, m_hWnd);
  1554. }