Переглянути джерело

侧边导航栏、标题栏;

sat23 4 роки тому
батько
коміт
55c2f9e97c

+ 4 - 0
CTSManager/CTSManager/CTSManager.vcxproj

@@ -205,12 +205,14 @@
     <ClInclude Include="FileView.h" />
     <ClInclude Include="framework.h" />
     <ClInclude Include="MainFrm.h" />
+    <ClInclude Include="Navbar.h" />
     <ClInclude Include="OutputWnd.h" />
     <ClInclude Include="pch.h" />
     <ClInclude Include="PropertiesWnd.h" />
     <ClInclude Include="Resource.h" />
     <ClInclude Include="table.h" />
     <ClInclude Include="targetver.h" />
+    <ClInclude Include="TitleBar.h" />
     <ClInclude Include="ViewTree.h" />
   </ItemGroup>
   <ItemGroup>
@@ -225,6 +227,7 @@
     <ClCompile Include="EnBitmap.cpp" />
     <ClCompile Include="FileView.cpp" />
     <ClCompile Include="MainFrm.cpp" />
+    <ClCompile Include="Navbar.cpp" />
     <ClCompile Include="OutputWnd.cpp" />
     <ClCompile Include="pch.cpp">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
@@ -233,6 +236,7 @@
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
     </ClCompile>
     <ClCompile Include="PropertiesWnd.cpp" />
+    <ClCompile Include="TitleBar.cpp" />
     <ClCompile Include="ViewTree.cpp" />
   </ItemGroup>
   <ItemGroup>

+ 12 - 0
CTSManager/CTSManager/CTSManager.vcxproj.filters

@@ -75,6 +75,12 @@
     <ClInclude Include="EnBitmap.h">
       <Filter>头文件</Filter>
     </ClInclude>
+    <ClInclude Include="TitleBar.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="Navbar.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="CTSManager.cpp">
@@ -122,6 +128,12 @@
     <ClCompile Include="EnBitmap.cpp">
       <Filter>源文件</Filter>
     </ClCompile>
+    <ClCompile Include="TitleBar.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="Navbar.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="CTSManager.rc">

+ 28 - 1
CTSManager/CTSManager/MainFrm.cpp

@@ -132,6 +132,7 @@ int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
 	// 导航窗格将创建在左侧,因此将暂时禁用左侧的停靠: 
 	EnableDocking(CBRS_ALIGN_TOP | CBRS_ALIGN_BOTTOM | CBRS_ALIGN_RIGHT);
 
+#if ENABLE_OUTBAR
 	// 创建并设置“Outlook”导航栏: 
 	if (!CreateOutlookBar(m_wndNavigationBar, ID_VIEW_NAVIGATION, m_wndTree, m_wndCalendar, 250))
 	{
@@ -142,7 +143,7 @@ int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
 	// 已创建 Outlook 栏,应允许在左侧停靠。
 	EnableDocking(CBRS_ALIGN_LEFT);
 	EnableAutoHidePanes(CBRS_ALIGN_RIGHT);
-
+#endif
 	// 加载菜单项图像(不在任何标准工具栏上): 
 	CMFCToolBar::AddToolBarForImageCollection(IDR_MENU_IMAGES, theApp.m_bHiColorIcons ? IDB_MENU_IMAGES_24 : 0);
 
@@ -162,6 +163,12 @@ int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
 	m_wndClassView.AttachToTabWnd(&m_wndFileView, DM_SHOW, TRUE, &pTabbedBar);
 #endif
 
+	m_wndTitleBar.EnableDocking(CBRS_ALIGN_TOP);
+	DockPane(&m_wndTitleBar);
+
+	m_wndNavBar.EnableDocking(CBRS_ALIGN_LEFT);
+	DockPane(&m_wndNavBar);	
+
 #if ENABLE_OUTPUT
 	m_wndOutput.EnableDocking(CBRS_ALIGN_ANY);
 	DockPane(&m_wndOutput);
@@ -262,6 +269,26 @@ BOOL CMainFrame::CreateDockingWindows()
 	}
 #endif
 
+	// 标题栏
+	CString strFileView;
+	bNameValid = strFileView.LoadString(IDS_FILE_VIEW);
+	ASSERT(bNameValid);
+	if (!m_wndTitleBar.Create(strFileView, this, CRect(0, 0, 200, 200), FALSE, ID_VIEW_FILEVIEW, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_TOP))
+	{
+		TRACE0("未能创建“文件视图”窗口\n");
+		return FALSE; // 未能创建
+	}
+
+	// 左导航栏
+	CString strClassView;
+	bNameValid = strClassView.LoadString(IDS_CLASS_VIEW);
+	ASSERT(bNameValid);
+	if (!m_wndNavBar.Create(strFileView, this, CRect(0, 0, 200, 200), FALSE, ID_VIEW_CLASSVIEW, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT))
+	{
+		TRACE0("未能创建“文件视图”窗口\n");
+		return FALSE; // 未能创建
+	}
+
 #if ENABLE_OUTPUT
 	// 创建输出窗口
 	CString strOutputWnd;

+ 7 - 0
CTSManager/CTSManager/MainFrm.h

@@ -5,6 +5,8 @@
 #pragma once
 #include "FileView.h"
 #include "ClassView.h"
+#include "TitleBar.h"
+#include "Navbar.h"
 #include "OutputWnd.h"
 #include "PropertiesWnd.h"
 #include "CalendarBar.h"
@@ -50,11 +52,16 @@ protected:  // 控件条嵌入成员
 	CFileView         m_wndFileView;
 	CClassView        m_wndClassView;
 #endif
+	CNavbar			  m_wndNavBar;
+	CTitleBar		  m_wndTitleBar;
+
 #if ENABLE_OUTPUT
 	COutputWnd        m_wndOutput;
 #endif
 	CPropertiesWnd    m_wndProperties;
+#if ENABLE_OUTBAR
 	COutlookBar       m_wndNavigationBar;
+#endif
 #if ENABLE_TREE
 	CMFCShellTreeCtrl m_wndTree;
 	CCalendarBar      m_wndCalendar;

+ 323 - 0
CTSManager/CTSManager/Navbar.cpp

@@ -0,0 +1,323 @@
+
+#include "pch.h"
+#include "framework.h"
+#include "MainFrm.h"
+#include "NavBar.h"
+#include "Resource.h"
+#include "CTSManager.h"
+
+class CNvaBarMenuButton : public CMFCToolBarMenuButton
+{
+	friend class CNavbar;
+
+	DECLARE_SERIAL(CNvaBarMenuButton)
+
+public:
+	CNvaBarMenuButton(HMENU hMenu = nullptr) noexcept : CMFCToolBarMenuButton((UINT)-1, hMenu, -1)
+	{
+	}
+
+	virtual void OnDraw(CDC* pDC, const CRect& rect, CMFCToolBarImages* pImages, BOOL bHorz = TRUE,
+		BOOL bCustomizeMode = FALSE, BOOL bHighlight = FALSE, BOOL bDrawBorder = TRUE, BOOL bGrayDisabledButtons = TRUE)
+	{
+		pImages = CMFCToolBar::GetImages();
+
+		CAfxDrawState ds;
+		pImages->PrepareDrawImage(ds);
+
+		CMFCToolBarMenuButton::OnDraw(pDC, rect, pImages, bHorz, bCustomizeMode, bHighlight, bDrawBorder, bGrayDisabledButtons);
+
+		pImages->EndDrawImage(ds);
+	}
+};
+
+IMPLEMENT_SERIAL(CNvaBarMenuButton, CMFCToolBarMenuButton, 1)
+
+//////////////////////////////////////////////////////////////////////
+// 构造/析构
+//////////////////////////////////////////////////////////////////////
+
+CNavbar::CNavbar() noexcept
+{
+	m_nCurrSort = ID_SORTING_GROUPBYTYPE;
+}
+
+CNavbar::~CNavbar()
+{
+}
+
+BEGIN_MESSAGE_MAP(CNavbar, CDockablePane)
+	ON_WM_CREATE()
+	ON_WM_SIZE()
+	ON_WM_CONTEXTMENU()
+	ON_COMMAND(ID_CLASS_ADD_MEMBER_FUNCTION, OnClassAddMemberFunction)
+	ON_COMMAND(ID_CLASS_ADD_MEMBER_VARIABLE, OnClassAddMemberVariable)
+	ON_COMMAND(ID_CLASS_DEFINITION, OnClassDefinition)
+	ON_COMMAND(ID_CLASS_PROPERTIES, OnClassProperties)
+	ON_COMMAND(ID_NEW_FOLDER, OnNewFolder)
+	ON_WM_PAINT()
+	ON_WM_SETFOCUS()
+	ON_COMMAND_RANGE(ID_SORTING_GROUPBYTYPE, ID_SORTING_SORTBYACCESS, OnSort)
+	ON_UPDATE_COMMAND_UI_RANGE(ID_SORTING_GROUPBYTYPE, ID_SORTING_SORTBYACCESS, OnUpdateSort)
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CNavbar 消息处理程序
+
+int CNavbar::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+	if (CDockablePane::OnCreate(lpCreateStruct) == -1)
+		return -1;
+
+	CRect rectDummy;
+	rectDummy.SetRectEmpty();
+
+	// 创建视图: 
+	const DWORD dwViewStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
+
+	if (!m_wndClassView.Create(dwViewStyle, rectDummy, this, 2))
+	{
+		TRACE0("未能创建类视图\n");
+		return -1;      // 未能创建
+	}
+
+	// 加载图像: 
+	m_wndToolBar.Create(this, AFX_DEFAULT_TOOLBAR_STYLE, IDR_SORT);
+	m_wndToolBar.LoadToolBar(IDR_SORT, 0, 0, TRUE /* 已锁定*/);
+
+	OnChangeVisualStyle();
+
+	m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() | CBRS_TOOLTIPS | CBRS_FLYBY);
+	m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() & ~(CBRS_GRIPPER | CBRS_SIZE_DYNAMIC | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));
+
+	m_wndToolBar.SetOwner(this);
+
+	// 所有命令将通过此控件路由,而不是通过主框架路由: 
+	m_wndToolBar.SetRouteCommandsViaFrame(FALSE);
+
+	CMenu menuSort;
+	menuSort.LoadMenu(IDR_POPUP_SORT);
+
+	m_wndToolBar.ReplaceButton(ID_SORT_MENU, CNvaBarMenuButton(menuSort.GetSubMenu(0)->GetSafeHmenu()));
+
+	CNvaBarMenuButton* pButton =  DYNAMIC_DOWNCAST(CNvaBarMenuButton, m_wndToolBar.GetButton(0));
+
+	if (pButton != nullptr)
+	{
+		pButton->m_bText = FALSE;
+		pButton->m_bImage = TRUE;
+		pButton->SetImage(GetCmdMgr()->GetCmdImage(m_nCurrSort));
+		pButton->SetMessageWnd(this);
+	}
+
+	// 填入一些静态树视图数据(此处只需填入虚拟代码,而不是复杂的数据)
+	FillClassView();
+
+	return 0;
+}
+
+void CNavbar::OnSize(UINT nType, int cx, int cy)
+{
+	CDockablePane::OnSize(nType, cx, cy);
+	AdjustLayout();
+}
+
+void CNavbar::FillClassView()
+{
+	HTREEITEM hRoot = m_wndClassView.InsertItem(_T("FakeApp 类"), 0, 0);
+	m_wndClassView.SetItemState(hRoot, TVIS_BOLD, TVIS_BOLD);
+
+	HTREEITEM hClass = m_wndClassView.InsertItem(_T("CFakeAboutDlg"), 1, 1, hRoot);
+	m_wndClassView.InsertItem(_T("CFakeAboutDlg()"), 3, 3, hClass);
+
+	m_wndClassView.Expand(hRoot, TVE_EXPAND);
+
+	hClass = m_wndClassView.InsertItem(_T("CFakeApp"), 1, 1, hRoot);
+	m_wndClassView.InsertItem(_T("CFakeApp()"), 3, 3, hClass);
+	m_wndClassView.InsertItem(_T("InitInstance()"), 3, 3, hClass);
+	m_wndClassView.InsertItem(_T("OnAppAbout()"), 3, 3, hClass);
+
+	hClass = m_wndClassView.InsertItem(_T("CFakeAppDoc"), 1, 1, hRoot);
+	m_wndClassView.InsertItem(_T("CFakeAppDoc()"), 4, 4, hClass);
+	m_wndClassView.InsertItem(_T("~CFakeAppDoc()"), 3, 3, hClass);
+	m_wndClassView.InsertItem(_T("OnNewDocument()"), 3, 3, hClass);
+
+	hClass = m_wndClassView.InsertItem(_T("CFakeAppView"), 1, 1, hRoot);
+	m_wndClassView.InsertItem(_T("CFakeAppView()"), 4, 4, hClass);
+	m_wndClassView.InsertItem(_T("~CFakeAppView()"), 3, 3, hClass);
+	m_wndClassView.InsertItem(_T("GetDocument()"), 3, 3, hClass);
+	m_wndClassView.Expand(hClass, TVE_EXPAND);
+
+	hClass = m_wndClassView.InsertItem(_T("CFakeAppFrame"), 1, 1, hRoot);
+	m_wndClassView.InsertItem(_T("CFakeAppFrame()"), 3, 3, hClass);
+	m_wndClassView.InsertItem(_T("~CFakeAppFrame()"), 3, 3, hClass);
+	m_wndClassView.InsertItem(_T("m_wndMenuBar"), 6, 6, hClass);
+	m_wndClassView.InsertItem(_T("m_wndToolBar"), 6, 6, hClass);
+	m_wndClassView.InsertItem(_T("m_wndStatusBar"), 6, 6, hClass);
+
+	hClass = m_wndClassView.InsertItem(_T("Globals"), 2, 2, hRoot);
+	m_wndClassView.InsertItem(_T("theFakeApp"), 5, 5, hClass);
+	m_wndClassView.Expand(hClass, TVE_EXPAND);
+}
+
+void CNavbar::OnContextMenu(CWnd* pWnd, CPoint point)
+{
+	CTreeCtrl* pWndTree = (CTreeCtrl*)&m_wndClassView;
+	ASSERT_VALID(pWndTree);
+
+	if (pWnd != pWndTree)
+	{
+		CDockablePane::OnContextMenu(pWnd, point);
+		return;
+	}
+
+	if (point != CPoint(-1, -1))
+	{
+		// 选择已单击的项: 
+		CPoint ptTree = point;
+		pWndTree->ScreenToClient(&ptTree);
+
+		UINT flags = 0;
+		HTREEITEM hTreeItem = pWndTree->HitTest(ptTree, &flags);
+		if (hTreeItem != nullptr)
+		{
+			pWndTree->SelectItem(hTreeItem);
+		}
+	}
+
+	pWndTree->SetFocus();
+	CMenu menu;
+	menu.LoadMenu(IDR_POPUP_SORT);
+
+	CMenu* pSumMenu = menu.GetSubMenu(0);
+
+	if (AfxGetMainWnd()->IsKindOf(RUNTIME_CLASS(CMDIFrameWndEx)))
+	{
+		CMFCPopupMenu* pPopupMenu = new CMFCPopupMenu;
+
+		if (!pPopupMenu->Create(this, point.x, point.y, (HMENU)pSumMenu->m_hMenu, FALSE, TRUE))
+			return;
+
+		((CMDIFrameWndEx*)AfxGetMainWnd())->OnShowPopupMenu(pPopupMenu);
+		UpdateDialogControls(this, FALSE);
+	}
+}
+
+void CNavbar::AdjustLayout()
+{
+	if (GetSafeHwnd() == nullptr)
+	{
+		return;
+	}
+
+	CRect rectClient;
+	GetClientRect(rectClient);
+
+	int cyTlb = m_wndToolBar.CalcFixedLayout(FALSE, TRUE).cy;
+
+	m_wndToolBar.SetWindowPos(nullptr, rectClient.left, rectClient.top, rectClient.Width(), cyTlb, SWP_NOACTIVATE | SWP_NOZORDER);
+	m_wndClassView.SetWindowPos(nullptr, rectClient.left + 1, rectClient.top + cyTlb + 1, rectClient.Width() - 2, rectClient.Height() - cyTlb - 2, SWP_NOACTIVATE | SWP_NOZORDER);
+}
+
+BOOL CNavbar::PreTranslateMessage(MSG* pMsg)
+{
+	return CDockablePane::PreTranslateMessage(pMsg);
+}
+
+void CNavbar::OnSort(UINT id)
+{
+	if (m_nCurrSort == id)
+	{
+		return;
+	}
+
+	m_nCurrSort = id;
+
+	CNvaBarMenuButton* pButton =  DYNAMIC_DOWNCAST(CNvaBarMenuButton, m_wndToolBar.GetButton(0));
+
+	if (pButton != nullptr)
+	{
+		pButton->SetImage(GetCmdMgr()->GetCmdImage(id));
+		m_wndToolBar.Invalidate();
+		m_wndToolBar.UpdateWindow();
+	}
+}
+
+void CNavbar::OnUpdateSort(CCmdUI* pCmdUI)
+{
+	pCmdUI->SetCheck(pCmdUI->m_nID == m_nCurrSort);
+}
+
+void CNavbar::OnClassAddMemberFunction()
+{
+	AfxMessageBox(_T("添加成员函数..."));
+}
+
+void CNavbar::OnClassAddMemberVariable()
+{
+	// TODO: 在此处添加命令处理程序代码
+}
+
+void CNavbar::OnClassDefinition()
+{
+	// TODO: 在此处添加命令处理程序代码
+}
+
+void CNavbar::OnClassProperties()
+{
+	// TODO: 在此处添加命令处理程序代码
+}
+
+void CNavbar::OnNewFolder()
+{
+	AfxMessageBox(_T("新建文件夹..."));
+}
+
+void CNavbar::OnPaint()
+{
+	CPaintDC dc(this); // 用于绘制的设备上下文
+
+	CRect rectTree;
+	m_wndClassView.GetWindowRect(rectTree);
+	ScreenToClient(rectTree);
+
+	rectTree.InflateRect(1, 1);
+	dc.Draw3dRect(rectTree, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DSHADOW));
+}
+
+void CNavbar::OnSetFocus(CWnd* pOldWnd)
+{
+	CDockablePane::OnSetFocus(pOldWnd);
+
+	m_wndClassView.SetFocus();
+}
+
+void CNavbar::OnChangeVisualStyle()
+{
+	m_ClassViewImages.DeleteImageList();
+
+	UINT uiBmpId = theApp.m_bHiColorIcons ? IDB_CLASS_VIEW_24 : IDB_CLASS_VIEW;
+
+	CBitmap bmp;
+	if (!bmp.LoadBitmap(uiBmpId))
+	{
+		TRACE(_T("无法加载位图: %x\n"), uiBmpId);
+		ASSERT(FALSE);
+		return;
+	}
+
+	BITMAP bmpObj;
+	bmp.GetBitmap(&bmpObj);
+
+	UINT nFlags = ILC_MASK;
+
+	nFlags |= (theApp.m_bHiColorIcons) ? ILC_COLOR24 : ILC_COLOR4;
+
+	m_ClassViewImages.Create(16, bmpObj.bmHeight, nFlags, 0, 0);
+	m_ClassViewImages.Add(&bmp, RGB(255, 0, 0));
+
+	m_wndClassView.SetImageList(&m_ClassViewImages, TVSIL_NORMAL);
+
+	m_wndToolBar.CleanUpLockedImages();
+	m_wndToolBar.LoadBitmap(theApp.m_bHiColorIcons ? IDB_SORT_24 : IDR_SORT, 0, 0, TRUE /* 锁定*/);
+}

+ 54 - 0
CTSManager/CTSManager/Navbar.h

@@ -0,0 +1,54 @@
+
+#pragma once
+
+#include "ViewTree.h"
+
+class CNavToolBar : public CMFCToolBar
+{
+	virtual void OnUpdateCmdUI(CFrameWnd* /*pTarget*/, BOOL bDisableIfNoHndler)
+	{
+		CMFCToolBar::OnUpdateCmdUI((CFrameWnd*) GetOwner(), bDisableIfNoHndler);
+	}
+
+	virtual BOOL AllowShowOnList() const { return FALSE; }
+};
+
+class CNavbar : public CDockablePane
+{
+public:
+	CNavbar() noexcept;
+	virtual ~CNavbar();
+
+	void AdjustLayout();
+	void OnChangeVisualStyle();
+
+protected:
+	CNavToolBar m_wndToolBar;
+	CViewTree m_wndClassView;
+	CImageList m_ClassViewImages;
+	UINT m_nCurrSort;
+
+	void FillClassView();
+
+// 重写
+public:
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+protected:
+	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
+	afx_msg void OnClassAddMemberFunction();
+	afx_msg void OnClassAddMemberVariable();
+	afx_msg void OnClassDefinition();
+	afx_msg void OnClassProperties();
+	afx_msg void OnNewFolder();
+	afx_msg void OnPaint();
+	afx_msg void OnSetFocus(CWnd* pOldWnd);
+	afx_msg LRESULT OnChangeActiveTab(WPARAM, LPARAM);
+	afx_msg void OnSort(UINT id);
+	afx_msg void OnUpdateSort(CCmdUI* pCmdUI);
+
+	DECLARE_MESSAGE_MAP()
+};
+

+ 261 - 0
CTSManager/CTSManager/TitleBar.cpp

@@ -0,0 +1,261 @@
+
+#include "pch.h"
+#include "framework.h"
+#include "mainfrm.h"
+#include "TitleBar.h"
+#include "Resource.h"
+#include "CTSManager.h"
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[]=__FILE__;
+#define new DEBUG_NEW
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CTitleBar
+
+CTitleBar::CTitleBar() noexcept
+{
+}
+
+CTitleBar::~CTitleBar()
+{
+}
+
+BEGIN_MESSAGE_MAP(CTitleBar, CDockablePane)
+	ON_WM_CREATE()
+	ON_WM_SIZE()
+	ON_WM_CONTEXTMENU()
+	ON_COMMAND(ID_PROPERTIES, OnProperties)
+	ON_COMMAND(ID_OPEN, OnFileOpen)
+	ON_COMMAND(ID_OPEN_WITH, OnFileOpenWith)
+	ON_COMMAND(ID_DUMMY_COMPILE, OnDummyCompile)
+	ON_COMMAND(ID_EDIT_CUT, OnEditCut)
+	ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
+	ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
+	ON_WM_PAINT()
+	ON_WM_SETFOCUS()
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CWorkspaceBar 消息处理程序
+
+int CTitleBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+	if (CDockablePane::OnCreate(lpCreateStruct) == -1)
+		return -1;
+
+	CRect rectDummy;
+	rectDummy.SetRectEmpty();
+
+	// 创建视图: 
+	const DWORD dwViewStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS;
+
+	if (!m_wndFileView.Create(dwViewStyle, rectDummy, this, 4))
+	{
+		TRACE0("未能创建文件视图\n");
+		return -1;      // 未能创建
+	}
+
+
+	// 加载视图图像: 
+	m_FileViewImages.Create(IDB_FILE_VIEW, 16, 0, RGB(255, 0, 255));
+	m_wndFileView.SetImageList(&m_FileViewImages, TVSIL_NORMAL);
+#if 0
+	m_wndToolBar.Create(this, AFX_DEFAULT_TOOLBAR_STYLE, IDR_EXPLORER);
+	m_wndToolBar.LoadToolBar(IDR_EXPLORER, 0, 0, TRUE /* 已锁定*/);
+#endif
+	OnChangeVisualStyle();
+#if 0
+	m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() | CBRS_TOOLTIPS | CBRS_FLYBY);
+
+	m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() & ~(CBRS_GRIPPER | CBRS_SIZE_DYNAMIC | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));
+
+	m_wndToolBar.SetOwner(this);
+
+	// 所有命令将通过此控件路由,而不是通过主框架路由: 
+	m_wndToolBar.SetRouteCommandsViaFrame(FALSE);
+#endif
+	// 填入一些静态树视图数据(此处只需填入虚拟代码,而不是复杂的数据)
+	FillFileView();
+	AdjustLayout();
+
+	return 0;
+}
+
+void CTitleBar::OnSize(UINT nType, int cx, int cy)
+{
+	CDockablePane::OnSize(nType, cx, cy);
+	AdjustLayout();
+}
+
+void CTitleBar::FillFileView()
+{
+	HTREEITEM hRoot = m_wndFileView.InsertItem(_T("FakeApp 文件"), 0, 0);
+	m_wndFileView.SetItemState(hRoot, TVIS_BOLD, TVIS_BOLD);
+
+	HTREEITEM hSrc = m_wndFileView.InsertItem(_T("FakeApp 源文件"), 0, 0, hRoot);
+
+	m_wndFileView.InsertItem(_T("FakeApp.cpp"), 1, 1, hSrc);
+	m_wndFileView.InsertItem(_T("FakeApp.rc"), 1, 1, hSrc);
+	m_wndFileView.InsertItem(_T("FakeAppDoc.cpp"), 1, 1, hSrc);
+	m_wndFileView.InsertItem(_T("FakeAppView.cpp"), 1, 1, hSrc);
+	m_wndFileView.InsertItem(_T("MainFrm.cpp"), 1, 1, hSrc);
+	m_wndFileView.InsertItem(_T("pch.cpp"), 1, 1, hSrc);
+
+	HTREEITEM hInc = m_wndFileView.InsertItem(_T("FakeApp 头文件"), 0, 0, hRoot);
+
+	m_wndFileView.InsertItem(_T("FakeApp.h"), 2, 2, hInc);
+	m_wndFileView.InsertItem(_T("FakeAppDoc.h"), 2, 2, hInc);
+	m_wndFileView.InsertItem(_T("FakeAppView.h"), 2, 2, hInc);
+	m_wndFileView.InsertItem(_T("Resource.h"), 2, 2, hInc);
+	m_wndFileView.InsertItem(_T("MainFrm.h"), 2, 2, hInc);
+	m_wndFileView.InsertItem(_T("pch.h"), 2, 2, hInc);
+
+	HTREEITEM hRes = m_wndFileView.InsertItem(_T("FakeApp 资源文件"), 0, 0, hRoot);
+
+	m_wndFileView.InsertItem(_T("FakeApp.ico"), 2, 2, hRes);
+	m_wndFileView.InsertItem(_T("FakeApp.rc2"), 2, 2, hRes);
+	m_wndFileView.InsertItem(_T("FakeAppDoc.ico"), 2, 2, hRes);
+	m_wndFileView.InsertItem(_T("FakeToolbar.bmp"), 2, 2, hRes);
+
+	m_wndFileView.Expand(hRoot, TVE_EXPAND);
+	m_wndFileView.Expand(hSrc, TVE_EXPAND);
+	m_wndFileView.Expand(hInc, TVE_EXPAND);
+}
+
+void CTitleBar::OnContextMenu(CWnd* pWnd, CPoint point)
+{
+	CTreeCtrl* pWndTree = (CTreeCtrl*) &m_wndFileView;
+	ASSERT_VALID(pWndTree);
+
+	if (pWnd != pWndTree)
+	{
+		CDockablePane::OnContextMenu(pWnd, point);
+		return;
+	}
+
+	if (point != CPoint(-1, -1))
+	{
+		// 选择已单击的项: 
+		CPoint ptTree = point;
+		pWndTree->ScreenToClient(&ptTree);
+
+		UINT flags = 0;
+		HTREEITEM hTreeItem = pWndTree->HitTest(ptTree, &flags);
+		if (hTreeItem != nullptr)
+		{
+			pWndTree->SelectItem(hTreeItem);
+		}
+	}
+
+	pWndTree->SetFocus();
+	theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EXPLORER, point.x, point.y, this, TRUE);
+}
+
+void CTitleBar::AdjustLayout()
+{
+	if (GetSafeHwnd() == nullptr)
+	{
+		return;
+	}
+
+	CRect rectClient;
+	GetClientRect(rectClient);
+
+	int cyTlb = 0;//m_wndToolBar.CalcFixedLayout(FALSE, TRUE).cy;
+#if 0
+	m_wndToolBar.SetWindowPos(nullptr, rectClient.left, rectClient.top, rectClient.Width(), cyTlb, SWP_NOACTIVATE | SWP_NOZORDER);
+#endif
+	m_wndFileView.SetWindowPos(nullptr, rectClient.left + 1, rectClient.top + cyTlb + 1, rectClient.Width() - 2, rectClient.Height() - cyTlb - 2, SWP_NOACTIVATE | SWP_NOZORDER);
+
+}
+
+void CTitleBar::OnProperties()
+{
+	AfxMessageBox(_T("属性...."));
+
+}
+
+void CTitleBar::OnFileOpen()
+{
+	// TODO: 在此处添加命令处理程序代码
+}
+
+void CTitleBar::OnFileOpenWith()
+{
+	// TODO: 在此处添加命令处理程序代码
+}
+
+void CTitleBar::OnDummyCompile()
+{
+	// TODO: 在此处添加命令处理程序代码
+}
+
+void CTitleBar::OnEditCut()
+{
+	// TODO: 在此处添加命令处理程序代码
+}
+
+void CTitleBar::OnEditCopy()
+{
+	// TODO: 在此处添加命令处理程序代码
+}
+
+void CTitleBar::OnEditClear()
+{
+	// TODO: 在此处添加命令处理程序代码
+}
+
+void CTitleBar::OnPaint()
+{
+	CPaintDC dc(this); // 用于绘制的设备上下文
+
+	CRect rectTree;
+	m_wndFileView.GetWindowRect(rectTree);
+	ScreenToClient(rectTree);
+
+	rectTree.InflateRect(1, 1);
+	dc.Draw3dRect(rectTree, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DSHADOW));
+}
+
+void CTitleBar::OnSetFocus(CWnd* pOldWnd)
+{
+	CDockablePane::OnSetFocus(pOldWnd);
+
+	m_wndFileView.SetFocus();
+}
+
+void CTitleBar::OnChangeVisualStyle()
+{
+#if 0
+	m_wndToolBar.CleanUpLockedImages();
+	m_wndToolBar.LoadBitmap(theApp.m_bHiColorIcons ? IDB_EXPLORER_24 : IDR_EXPLORER, 0, 0, TRUE /* 锁定*/);
+#endif
+	m_FileViewImages.DeleteImageList();
+
+	UINT uiBmpId = theApp.m_bHiColorIcons ? IDB_FILE_VIEW_24 : IDB_FILE_VIEW;
+
+	CBitmap bmp;
+	if (!bmp.LoadBitmap(uiBmpId))
+	{
+		TRACE(_T("无法加载位图: %x\n"), uiBmpId);
+		ASSERT(FALSE);
+		return;
+	}
+
+	BITMAP bmpObj;
+	bmp.GetBitmap(&bmpObj);
+
+	UINT nFlags = ILC_MASK;
+
+	nFlags |= (theApp.m_bHiColorIcons) ? ILC_COLOR24 : ILC_COLOR4;
+
+	m_FileViewImages.Create(16, bmpObj.bmHeight, nFlags, 0, 0);
+	m_FileViewImages.Add(&bmp, RGB(255, 0, 255));
+
+	m_wndFileView.SetImageList(&m_FileViewImages, TVSIL_NORMAL);
+}
+
+

+ 55 - 0
CTSManager/CTSManager/TitleBar.h

@@ -0,0 +1,55 @@
+
+#pragma once
+
+#include "ViewTree.h"
+
+class CTitleToolBar : public CMFCToolBar
+{
+	virtual void OnUpdateCmdUI(CFrameWnd* /*pTarget*/, BOOL bDisableIfNoHndler)
+	{
+		CMFCToolBar::OnUpdateCmdUI((CFrameWnd*) GetOwner(), bDisableIfNoHndler);
+	}
+
+	virtual BOOL AllowShowOnList() const { return FALSE; }
+};
+
+class CTitleBar : public CDockablePane
+{
+// 构造
+public:
+	CTitleBar() noexcept;
+
+	void AdjustLayout();
+	void OnChangeVisualStyle();
+
+// 特性
+protected:
+
+	CViewTree m_wndFileView;
+	CImageList m_FileViewImages;
+	CTitleToolBar m_wndToolBar;
+
+protected:
+	void FillFileView();
+
+// 实现
+public:
+	virtual ~CTitleBar();
+
+protected:
+	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
+	afx_msg void OnProperties();
+	afx_msg void OnFileOpen();
+	afx_msg void OnFileOpenWith();
+	afx_msg void OnDummyCompile();
+	afx_msg void OnEditCut();
+	afx_msg void OnEditCopy();
+	afx_msg void OnEditClear();
+	afx_msg void OnPaint();
+	afx_msg void OnSetFocus(CWnd* pOldWnd);
+
+	DECLARE_MESSAGE_MAP()
+};
+

+ 3 - 1
CTSManager/CTSManager/pch.h

@@ -17,12 +17,14 @@
 // 弃用函数;
 #define DEPRECATED 0
 // 隐藏菜单栏;
-#define HIDE_MENU_BAR 1
+#define HIDE_MENU_BAR 0
 // 启用显示文件/类;
 #define ENABLE_FILE_CLASS 0
 // 启用输出;
 #define ENABLE_OUTPUT 0
 // 日历及文件树;
 #define ENABLE_TREE 1
+// 默认的Outbar;
+#define ENABLE_OUTBAR 0
 
 #endif //PCH_H