📄 bcgpminiframewnd.cpp
字号:
// BCGPMiniFrameWnd.cpp : implementation file
//
#include "stdafx.h"
#include "bcgprores.h"
#include "BCGGlobals.h"
#include "BCGPGlobalUtils.h"
#include "BCGPFrameWnd.h"
#include "BCGPMDIFrameWnd.h"
#include "BCGPOleIPFrameWnd.h"
#include "BCGPOleDocIPFrameWnd.h"
#include "BCGPMDIChildWnd.h"
#include "BCGPOleCntrFrameWnd.h"
#include "BCGPControlBar.h"
#include "BCGPDockingControlBar.h"
#include "BCGPToolBar.h"
#include "BCGPToolbarButton.h"
#include "BCGPMiniFrameWnd.h"
#include "BCGPDockBar.h"
#include "BCGPDockManager.h"
#include "BCGPTabbedControlBar.h"
#include "BCGPVisualManager.h"
#include "BCGPToolbarMenuButton.h"
#include "BCGPTabbedToolbar.h"
#include "BCGPCaptionMenuButton.h"
#include "CustomizeButton.h"
#include "BCGPLocalResource.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
UINT CBCGPMiniFrameWnd::m_nRollTimeOut = 250;
BOOL CBCGPMiniFrameWnd::m_bUseSaveBits = TRUE;
UINT BCGPM_CHECKEMPTYMINIFRAME = ::RegisterWindowMessage (_T("BCGPMSG_CHECKEMPTYMINIFRAME"));
IMPLEMENT_SERIAL(CBCGPMiniFrameWnd, CWnd, VERSIONABLE_SCHEMA | 2)
/////////////////////////////////////////////////////////////////////////////
// CBCGPMiniFrameWnd
CMap<UINT,UINT,HWND,HWND> CBCGPMiniFrameWnd::m_mapFloatingBars;
CList<HWND, HWND> CBCGPMiniFrameWnd::m_lstFrames;
CFrameWnd* CBCGPMiniFrameWnd::m_pParentWndForSerialize = NULL;
CBCGPMiniFrameWnd::CBCGPMiniFrameWnd()
{
m_bActive = FALSE;
m_bCaptured = false;
m_bBlockMove = false;
m_bNoDelayedDestroy = FALSE;
m_preDockStateCurr = PDS_NOTHING;
m_pPreDockBar = NULL;
m_bTabDragRectDisplayed = false;
RecalcCaptionHeight ();
m_nHit = HTNOWHERE;
m_nHot = HTNOWHERE;
m_rectRedraw.SetRectEmpty ();
m_nDockTimerID = 0;
m_nRollTimerID = 0;
m_bRolledUp = FALSE;
m_nHeightBeforeRollUp = 0;
m_bPinned = FALSE;
m_hEmbeddedBar = NULL;
m_nRestoredEmbeddedBarID = 0;
m_dwCaptionButtons = 0;
m_rectRecentFloatingRect.SetRect (0, 0, 100, 100);
m_hParentWnd = NULL;
m_hWndToDestroyOnRelease = NULL;
m_hLastFocusWnd = NULL;
}
CBCGPMiniFrameWnd::~CBCGPMiniFrameWnd()
{
RemoveAllCaptionButtons ();
}
BEGIN_MESSAGE_MAP(CBCGPMiniFrameWnd, CWnd)
//{{AFX_MSG_MAP(CBCGPMiniFrameWnd)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_MOVING()
ON_WM_NCCALCSIZE()
ON_WM_NCPAINT()
ON_WM_NCHITTEST()
ON_WM_SETCURSOR()
ON_WM_SIZING()
ON_WM_WINDOWPOSCHANGING()
ON_WM_TIMER()
ON_WM_SIZE()
ON_WM_NCACTIVATE()
ON_WM_NCLBUTTONDBLCLK()
ON_WM_LBUTTONDBLCLK()
ON_WM_NCCREATE()
ON_WM_ERASEBKGND()
ON_WM_NCDESTROY()
ON_WM_CANCELMODE()
ON_WM_NCMOUSEMOVE()
ON_WM_GETMINMAXINFO()
ON_WM_CONTEXTMENU()
ON_WM_DESTROY()
ON_WM_CHAR()
ON_WM_CREATE()
ON_WM_CLOSE()
ON_WM_MOUSEACTIVATE()
ON_WM_SETFOCUS()
ON_WM_CANCELMODE()
ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
ON_WM_SETTINGCHANGE()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_FLOATSTATUS, OnFloatStatus)
ON_REGISTERED_MESSAGE(BCGPM_CHECKEMPTYMINIFRAME, OnCheckEmptyState)
ON_MESSAGE( WM_EXITSIZEMOVE, OnExitSizeMove )
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXT, 0, 0xFFFF, OnNeedTipText)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CBCGPMiniFrameWnd message handlers
//--------------------------------------------------------------------------------------//
BOOL CBCGPMiniFrameWnd::Create(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, CCreateContext* pContext)
{
// TODO: Add your specialized code here and/or call the base class
return CBCGPMiniFrameWnd::CreateEx(0, lpszWindowName, dwStyle, rect, pParentWnd, pContext);
}
//--------------------------------------------------------------------------------------//
BOOL CBCGPMiniFrameWnd::CreateEx(DWORD dwStyleEx, LPCTSTR lpszWindowName,
DWORD dwStyle, const RECT& rect,
CWnd* pParentWnd, CCreateContext* pContext)
{
//-----------------------------
// Register a new window class:
//-----------------------------
HINSTANCE hInst = AfxGetInstanceHandle();
UINT uiClassStyle = CS_DBLCLKS;
if (m_bUseSaveBits)
{
uiClassStyle |= CS_SAVEBITS;
}
HCURSOR hCursor = ::LoadCursor (NULL, IDC_ARROW);
HBRUSH hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
CString strClassName;
strClassName.Format (_T("BCGMiniWrame:%x:%x:%x:%x"),
(UINT)hInst, uiClassStyle, (UINT)hCursor, (UINT)hbrBackground);
//---------------------------------
// See if the class already exists:
//---------------------------------
WNDCLASS wndcls;
if (::GetClassInfo (hInst, strClassName, &wndcls))
{
//-----------------------------------------------
// Already registered, assert everything is good:
//-----------------------------------------------
ASSERT (wndcls.style == uiClassStyle);
}
else
{
//-------------------------------------------
// Otherwise we need to register a new class:
//-------------------------------------------
wndcls.style = uiClassStyle;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
wndcls.hInstance = hInst;
wndcls.hIcon = NULL;
wndcls.hCursor = hCursor;
wndcls.hbrBackground = hbrBackground;
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = strClassName;
if (!AfxRegisterClass (&wndcls))
{
AfxThrowResourceException();
}
}
dwStyle |= WS_POPUP;
m_hParentWnd = pParentWnd != NULL ? pParentWnd->m_hWnd : NULL;
if (!CWnd::CreateEx (dwStyleEx, strClassName, lpszWindowName, dwStyle, rect,
pParentWnd, 0, pContext))
{
return FALSE;
}
if (pParentWnd != NULL)
{
if (DYNAMIC_DOWNCAST (CFrameWnd, pParentWnd) == NULL)
{
TRACE0 ("Minframe parent must be derived from CFrameWnd. Creation failed.\n");
return FALSE;
}
// register with dock manager
CBCGPDockManager* pDockManager = globalUtils.GetDockManager (pParentWnd);
ASSERT_VALID (pDockManager);
if (pDockManager == NULL)
{
TRACE0 ("Minframe parent must be connected to dock manager. Creation failed.\n");
return FALSE;
}
pDockManager->AddMiniFrame (this);
}
m_dragFrameImpl.Init (this);
return TRUE;
}
//--------------------------------------------------------------------------------------//
void CBCGPMiniFrameWnd::SaveRecentFloatingState ()
{
GetWindowRect (m_rectRecentFloatingRect);
// save the recent floating rect
if (m_hEmbeddedBar != NULL)
{
CBCGPControlBar* pContainedBar = DYNAMIC_DOWNCAST (CBCGPControlBar, CWnd::FromHandlePermanent (m_hEmbeddedBar));
if (pContainedBar != NULL)
{
pContainedBar->m_recentDockInfo.m_rectRecentFloatingRect = m_rectRecentFloatingRect;
}
CPoint ptClientHotSpot;
GetCursorPos (&ptClientHotSpot);
pContainedBar->ScreenToClient (&ptClientHotSpot);
pContainedBar->SetClientHotSpot (ptClientHotSpot);
}
}
//--------------------------------------------------------------------------------------//
void CBCGPMiniFrameWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_nHot != HTNOWHERE)
{
CBCGPCaptionButton* pBtn = FindButton (m_nHot);
if (pBtn != NULL)
{
m_nHit = m_nHot;
pBtn->m_bPushed = TRUE;
RedrawCaptionButton (pBtn);
}
CWnd::OnLButtonDown(nFlags, point);
return;
}
EnterDragMode ();
SaveRecentFloatingState ();
CBCGPControlBar* pContainedBar = DYNAMIC_DOWNCAST (CBCGPControlBar, CWnd::FromHandlePermanent (m_hEmbeddedBar));
if (pContainedBar != NULL)
{
pContainedBar->m_bWasFloatingBeforeMove = TRUE;
if (!pContainedBar->IsKindOf (RUNTIME_CLASS (CBCGPToolBar)))
{
SetWindowPos (&wndTop, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
}
}
else
{
SetWindowPos (&wndTop, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
}
CWnd::OnLButtonDown(nFlags, point);
}
//--------------------------------------------------------------------------------------//
int CBCGPMiniFrameWnd::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
if (m_hEmbeddedBar != NULL && IsWindow (m_hEmbeddedBar))
{
CWnd* pWnd = CWnd::FromHandle (m_hEmbeddedBar);
CPoint pt;
GetCursorPos (&pt);
ScreenToClient (&pt);
UINT nHit = HitTest (pt, TRUE);
if (pWnd->IsKindOf (RUNTIME_CLASS (CBCGPToolBar)) &&
nHit != HTCLIENT)
{
SetWindowPos (&wndTop, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
return MA_NOACTIVATE;
}
}
return CWnd::OnMouseActivate (pDesktopWnd, nHitTest, message);
}
//--------------------------------------------------------------------------------------//
void CBCGPMiniFrameWnd::EnterDragMode (HWND hWndToDestroyOnRelease)
{
if (!m_bCaptured)
{
SetCapture ();
if (m_hWndToDestroyOnRelease == NULL)
{
m_hWndToDestroyOnRelease = hWndToDestroyOnRelease;
}
m_bCaptured = true;
OnCapture (TRUE);
GetCursorPos (&m_dragFrameImpl.m_ptHot);
if (GetDockMode () == DT_IMMEDIATE)
{
SetCursor (AfxGetApp ()->LoadStandardCursor (IDC_SIZEALL));
}
}
}
//--------------------------------------------------------------------------------------//
void CBCGPMiniFrameWnd::OnLButtonUp(UINT nFlags, CPoint point)
{
// m_bCaptured is true when the miniframe is being dragged
if (m_nHit != HTNOWHERE && !m_bCaptured)
{
UINT nHot = m_nHot;
UINT nHit = m_nHit;
StopCaptionButtonsTracking ();
if (nHot == nHit)
{
switch (nHit)
{
case HTCLOSE:
if (OnCloseMiniFrame ())
{
CloseMiniFrame ();
return;
}
break;
case HTMAXBUTTON:
m_bPinned = !m_bPinned;
break;
default:
if (!CBCGPToolBar::IsCustomizeMode())
{
OnPressButtons (nHit);
}
}
}
CWnd::OnLButtonUp(nFlags, point);
return;
}
if (m_bCaptured)
{
ReleaseCapture ();
m_bCaptured = false;
OnCapture (FALSE);
BOOL bWasDocked = FALSE;
if (DockControlBar (bWasDocked) || bWasDocked)
{
return;
}
m_dragFrameImpl.m_rectDrag.SetRectEmpty ();
}
CWnd::OnLButtonUp(nFlags, point);
}
//--------------------------------------------------------------------------------------//
CBCGPDockingControlBar* CBCGPMiniFrameWnd::DockControlBar (BOOL& bWasDocked)
{
CBCGPDockingControlBar* pBar = DYNAMIC_DOWNCAST (CBCGPDockingControlBar, GetControlBar ());
bWasDocked = FALSE;
if (GetDockMode () == DT_IMMEDIATE)
{
if (m_preDockStateCurr == PDS_DOCK_REGULAR)
{
ASSERT_VALID (pBar);
bWasDocked = pBar->DockByMouse (m_pPreDockBar);
}
else if (m_preDockStateCurr == PDS_DOCK_TO_TAB && m_pPreDockBar != NULL )
{
CBCGPDockingControlBar* pTabControlBarAttachTo = DYNAMIC_DOWNCAST (CBCGPDockingControlBar, m_pPreDockBar);
if (pBar == NULL || pTabControlBarAttachTo == NULL)
{
ASSERT (FALSE);
TRACE0 ("Attempt to attach a control bar that is not derived from CBCGPDockingControlBar to tab window. \r\n");
}
else
{
bWasDocked = TRUE;
return pBar->AttachToTabWnd (pTabControlBarAttachTo, DM_MOUSE);
}
}
m_preDockStateCurr = PDS_NOTHING;
return pBar;
}
else if (GetDockMode () == DT_STANDARD)
{
CRect rectFinal = m_dragFrameImpl.m_rectDrag;
m_dragFrameImpl.EndDrawDragFrame ();
CFrameWnd* pFrameWnd = BCGPGetParentFrame (this);
CBCGPDockManager::m_bDisableRecalcLayout = TRUE;
CBCGPDockingControlBar* pDockedBar = DockControlBarStandard (bWasDocked);
CBCGPDockManager::m_bDisableRecalcLayout = FALSE;
if (pFrameWnd != NULL)
{
pFrameWnd->RecalcLayout ();
}
if (!rectFinal.IsRectEmpty () &&
(pDockedBar == NULL || pDockedBar->GetParentMiniFrame () == this) &&
!bWasDocked)
{
MoveWindow (rectFinal);
if (!IsWindowVisible () && GetControlBarCount () > 0)
{
ShowWindow (SW_SHOW);
}
}
return pDockedBar;
}
return NULL;
}
//--------------------------------------------------------------------------------------//
CBCGPDockingControlBar* CBCGPMiniFrameWnd::DockControlBarStandard (BOOL& bWasDocked)
{
CBCGPDockingControlBar* pBar = DYNAMIC_DOWNCAST (CBCGPDockingControlBar, GetControlBar ());
if (pBar == NULL || !OnBeforeDock ())
{
return NULL;
}
if (!pBar->IsWindowVisible () && pBar->GetDockMode () == DT_STANDARD)
{
pBar->ShowWindow (SW_SHOW);
}
return DYNAMIC_DOWNCAST (CBCGPDockingControlBar,
pBar->DockControlBarStandard (bWasDocked));
}
//--------------------------------------------------------------------------------------//
void CBCGPMiniFrameWnd::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_bBlockMove)
{
m_bBlockMove = false;
return;
}
if (m_bCaptured)
{
if (GetDockMode () == DT_STANDARD)
{
m_dragFrameImpl.MoveDragFrame ();
}
else if (GetDockMode () == DT_IMMEDIATE)
{
if (MoveMiniFrame ())
{
CPoint ptMouse;
GetCursorPos (&ptMouse);
CPoint ptOffset = ptMouse - m_dragFrameImpl.m_ptHot;
CRect rect;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -