📄 tabmanagerwnd.cpp
字号:
/***************************************************************************/
/* NOTE: */
/* This document is copyright (c) by Oz Solomonovich. All non-commercial */
/* use is allowed, as long as this document not altered in any way, and */
/* due credit is given. */
/***************************************************************************/
// TabManagerWindow.cpp : implementation file
//
// This class is used to subclass DevStudio's windows. It allows the
// plug-in to monitor various messages that reach the window.
// TabManagerWindow is mainly responsible for moving and sizing the tabs
// window to it's appropriate position relative to the DevStudio window.
// The DevStudio window is also resized if needed.
//
//this line was inserted and notified to you
//I remove some function or porpert which this addin do not use
//it cound not be replaced by original file
#include "stdafx.h"
#include "TabBars.h"
#include "TabManagerWnd.h"
#include "TabBarWnd.h"
#include "Commands.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTabManagerWindow
CTabManagerWindow::CTabManagerWindow(IGenericWindow *pGWindow,
HWND hSubclassWindow) : m_bManaging(false), m_bMakeSpace(false),
m_pGWindow(pGWindow), m_bUpdatePosted(false),
CSubclassWnd(hSubclassWindow)
{
m_LastPos = m_Border = CRect(0, 0, 0, 0);
UpdateTabSize();
DoSubclass();
}
CTabManagerWindow::~CTabManagerWindow()
{
if (pGlobalActiveManager == this)
{
pGlobalActiveManager = NULL;
}
SetManaging(FALSE);
DoUnsubclass();
pGlobalTabs->UpdateTabs();
}
BEGIN_MESSAGE_MAP(CTabManagerWindow, CSubclassWnd)
//{{AFX_MSG_MAP(CTabManagerWindow)
ON_WM_WINDOWPOSCHANGING()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_UPDATETABS, OnUpdateTabs)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTabManagerWindow message handlers
void CTabManagerWindow::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
CSubclassWnd::OnWindowPosChanging(lpwndpos);
if (m_bManaging)
{
CRect WndRect(lpwndpos->x,lpwndpos->y,lpwndpos->x + lpwndpos->cx,lpwndpos->y + lpwndpos->cy);
if (lpwndpos->flags & (SWP_NOSIZE | SWP_NOMOVE))
{
CRect WndRectOld;
GetWindowRect(WndRectOld);
GetParent()->ScreenToClient(WndRectOld);
if (lpwndpos->flags & SWP_NOSIZE)
{
WndRect.bottom = WndRect.top + WndRectOld.Height();
WndRect.right = WndRect.left + WndRectOld.Width();
}
if (lpwndpos->flags & SWP_NOMOVE)
{
WndRect.OffsetRect(WndRectOld.left - lpwndpos->x,WndRectOld.top - lpwndpos->y);
}
}
if (WndRect != m_LastPos)
{
UpdateTabSizeAndPosition(WndRect);
ASSERT(WndRect.left >= 0);
ASSERT(WndRect.top >= 0);
ASSERT(WndRect.right - WndRect.left <= 1024);
lpwndpos->x = WndRect.left;
lpwndpos->y = WndRect.top;
lpwndpos->cx = WndRect.right - WndRect.left;
lpwndpos->cy = WndRect.bottom - WndRect.top;
m_LastPos = WndRect;
}
}
}
// the message is used for delayed tab update
LRESULT CTabManagerWindow::OnUpdateTabs(WPARAM wParam, LPARAM lParam)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT(pGlobalTabs);
pGlobalTabs->UpdateTabs();
m_bUpdatePosted = false; // allow new posts
return Default();
}
/////////////////////////////////////////////////////////////////////////////
// CTabManagerWindow attributes
// true/false - is this object is responsible for handling the tabs.
// We will always have two tab managers: the MDI tab manager and the
// subclassed DevStudio window. Only one of them actually manages the tabs
// (according to the user's preference).
bool CTabManagerWindow::SetManaging(bool bManaging)
{
if (m_hWnd == NULL)
return m_bManaging;
if (bManaging == m_bManaging)
return m_bManaging;
bool bOldVal = m_bManaging;
m_bManaging = bManaging;
UpdateTabSize();
// add/remove the tabs
if (m_bManaging)
{
ForceRedraw();
}
else
{
// reclaim space used by the tabs
ReclameTabSpace();
}
return bOldVal;
}
// true - the manager shrinks the window so that both the tabs and
// the window occupy the original area of the window
// false - the tabs are aligned along side the window
bool CTabManagerWindow::SetMakeSpace(bool bMakeSpace)
{
if (m_bMakeSpace == bMakeSpace)
return bMakeSpace;
if (m_bManaging)
{
if (bMakeSpace)
{
ForceRedraw();
}
else
{
ReclameTabSpace();
}
}
bool bOldVal = m_bMakeSpace;
m_bMakeSpace = bMakeSpace;
return bOldVal;
}
// Call SetBorder() to set an empty border around the tabs. The tab
// window reads the border values from the tab manager and repaints
// accordingly.
CRect CTabManagerWindow::SetBorder(CRect Border)
{
CRect OldBorder = m_Border;
if (Border != m_Border)
{
bool bOldManaging = SetManaging(false);
m_Border = Border;
UpdateTabSize();
SetManaging(bOldManaging);
}
return OldBorder;
}
/////////////////////////////////////////////////////////////////////////////
// CTabManagerWindow operations
void CTabManagerWindow::PostUpdateMessage()
{
// make sure we don't have multiple update messages in the queue if we
// hadn't updated yet:
if (!m_bUpdatePosted)
{
m_bUpdatePosted = true;
// post a message to ourselves
PostMessage(WM_UPDATETABS);
}
}
/////////////////////////////////////////////////////////////////////////////
// CTabManagerWindow protected operations
// Checks if there are as many tabs as windows, and updates if needed.
// Useful in cases where DevStudio removes it's own undocked windows (such
// as Disassembly or Output), since we get no notification of it, and must
// check for it somehow
void CTabManagerWindow::CheckTabCount()
{
long cWindows;
CComPtr<IDispatch> pDisp;
CComQIPtr<IWindows, &IID_IWindows> pWindows;
ASSERT(pGlobalTabs);
pGlobalTabs->m_pApplication->get_Windows(&pDisp);
pWindows = pDisp;
pDisp = NULL;
pWindows->get_Count(&cWindows);
if (pGlobalTabs->m_TabCtrl.GetItemCount() != cWindows)
{
pGlobalTabs->UpdateTabs();
}
}
void CTabManagerWindow::ForceRedraw()
{
// we want to make sure the OnWindowPosChanging handler is called
CRect WndRect;
GetWindowRect(&WndRect);
GetParent()->ScreenToClient(&WndRect);
MoveWindow(WndRect, TRUE);
}
void CTabManagerWindow::ReclameTabSpace()
{
if (m_bMakeSpace)
{
CRect WndRect;
GetWindowRect(&WndRect);
GetParent()->ScreenToClient(&WndRect);
if (cfg_iOrientation == soTop)
{
WndRect.top -= m_iTabHeight;
}
else
{
WndRect.bottom += m_iTabHeight;
}
MoveWindow(WndRect, TRUE);
}
}
void CTabManagerWindow::UpdateTabSizeAndPosition(CRect& WndRect)
{
CRect TabsRect;
if (!CalcTabsPosition(WndRect, TabsRect, SnapOrientations(cfg_iOrientation)))
return;
UpdateTabSize();
pGlobalTabs->GetParent()->ScreenToClient(&TabsRect);
ASSERT(TabsRect.bottom >= TabsRect.top);
ASSERT(TabsRect.right >= TabsRect.left);
pGlobalTabs->SetWindowPos(&wndBottom,TabsRect.left,TabsRect.top,
TabsRect.right - TabsRect.left,TabsRect.bottom - TabsRect.top, SWP_DRAWFRAME);
// force redraw
pGlobalTabs->RedrawWindow();
pGlobalTabs->ShowWindow(SW_SHOW);
}
// TabsRect is returned in screen coordinates
bool CTabManagerWindow::CalcTabsPosition(CRect &WndRect, CRect &TabsRect,SnapOrientations o) const
{
if (WndRect.top == WndRect.bottom)
return false;
CSize szTabs = CalcTabsSize(o);
TabsRect = WndRect;
if(o == soTop)
{
if (m_bMakeSpace)
WndRect.top += szTabs.cy;
else
TabsRect.top -= szTabs.cy;
TabsRect.bottom = TabsRect.top + szTabs.cy;
}
else
{
if (m_bMakeSpace)
WndRect.bottom -= szTabs.cy;
else
TabsRect.bottom += szTabs.cy;
TabsRect.top = TabsRect.bottom - szTabs.cy;
}
GetParent()->ClientToScreen(&TabsRect);
return true;
}
CSize CTabManagerWindow::CalcTabsSize(SnapOrientations o) const
{
CSize sz(0,0);;
if (pGlobalTabs != NULL)
{
int iMinHeight = pGlobalTabs->m_iMinHeight;
sz.cy = TAB_HEIGHT + iMinHeight;
if (o == soTop || o == soBottom)
{
sz.cy += m_Border.left + m_Border.right;// + 4;
sz.cx = 0;
}
ASSERT(sz.cx >= 0);
ASSERT(sz.cy >= 0);
}
return sz;
}
void CTabManagerWindow::UpdateTabSize()
{
CSize szTab = CalcTabsSize(SnapOrientations(cfg_iOrientation));
m_iTabHeight = szTab.cy;
m_iTabWidth = szTab.cx;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -