📄 bcgframeimpl.cpp
字号:
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// This source code is a part of BCGControlBar library.
// You may use, compile or redistribute it as part of your application
// for free. You cannot redistribute it as a part of a software development
// library without the agreement of the author. If the sources are
// distributed along with the application, you should leave the original
// copyright notes in the source code without any changes.
// This code can be used WITHOUT ANY WARRANTIES on your own risk.
//
// Stas Levin <stas@iet.co.il>
//*******************************************************************************
// BCGFrameImpl.cpp: implementation of the CBCGFrameImpl class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "BCGFrameImpl.h"
#include "BCGToolBar.h"
#include "BCGDialogBar.h"
#include "BCGSizingControlBar.h"
#include "BCGMenuBar.h"
#include "bcglocalres.h"
#include "bcgbarres.h"
#include "BCGPopupMenu.h"
#include "BCGToolbarMenuButton.h"
#include "BCGWorkspace.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
extern CObList gAllToolbars;
extern CBCGWorkspace* g_pWorkspace;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBCGFrameImpl::CBCGFrameImpl(CFrameWnd* pFrame) :
m_pFrame (pFrame),
m_pActivePopupMenu (NULL),
m_uiUserToolbarFirst ((UINT)-1),
m_uiUserToolbarLast ((UINT)-1),
m_pMenuBar (NULL),
m_hDefaultMenu (NULL),
m_nIDDefaultResource (0)
{
ASSERT_VALID (m_pFrame);
}
//**************************************************************************************
CBCGFrameImpl::~CBCGFrameImpl()
{
//-----------------------------
// Clear user-defined toolbars:
//-----------------------------
while (!m_listUserDefinedToolbars.IsEmpty ())
{
delete m_listUserDefinedToolbars.RemoveHead ();
}
}
//**************************************************************************************
void CBCGFrameImpl::OnCloseFrame()
{
//----------------------------------------------------------------------
// Automatically load state and frame position if CBCGWorkspace is used:
//----------------------------------------------------------------------
if (g_pWorkspace != NULL)
{
g_pWorkspace->OnClosingMainFrame (this);
//---------------------------
// Store the Windowplacement:
//---------------------------
if (::IsWindow (m_pFrame->GetSafeHwnd ()))
{
WINDOWPLACEMENT wp;
wp.length = sizeof (WINDOWPLACEMENT);
if (m_pFrame->GetWindowPlacement (&wp))
{
//---------------------------
// Make sure we don't pop up
// minimized the next time
//---------------------------
if (wp.showCmd != SW_SHOWMAXIMIZED)
{
wp.showCmd = SW_SHOWNORMAL;
}
g_pWorkspace->StoreWindowPlacement (
wp.rcNormalPosition, wp.flags, wp.showCmd);
}
}
}
}
//**************************************************************************************
void CBCGFrameImpl::RestorePosition(CREATESTRUCT& cs)
{
if (g_pWorkspace != NULL)
{
CRect rectNormal (CPoint (cs.x, cs.y), CSize (cs.cx, cs.cy));
int nFlags = 0;
int nShowCmd = SW_SHOWNORMAL;
if (!g_pWorkspace->LoadWindowPlacement (rectNormal, nFlags, nShowCmd))
{
return;
}
if (nShowCmd != SW_MAXIMIZE)
{
nShowCmd = SW_SHOWNORMAL;
}
switch (AfxGetApp()->m_nCmdShow)
{
case SW_MAXIMIZE:
case SW_MINIMIZE:
break; // don't change!
default:
AfxGetApp()->m_nCmdShow = nShowCmd;
}
CRect rectDesktop;
if (::SystemParametersInfo (SPI_GETWORKAREA, 0, &rectDesktop, 0) &&
rectNormal.IntersectRect (&rectDesktop, &rectNormal))
{
cs.x = rectNormal.left;
cs.y = rectNormal.top;
cs.cx = rectNormal.Width ();
cs.cy = rectNormal.Height ();
}
}
}
//**************************************************************************************
void CBCGFrameImpl::OnLoadFrame()
{
//---------------------------------------------------
// Automatically load state if CBCGWorkspace is used:
//---------------------------------------------------
if (g_pWorkspace != NULL)
{
g_pWorkspace->LoadState (0, this);
}
}
//**************************************************************************************
void CBCGFrameImpl::LoadUserToolbars ()
{
if (m_uiUserToolbarFirst == (UINT) -1 ||
m_uiUserToolbarLast == (UINT) -1)
{
return;
}
for (UINT uiNewToolbarID = m_uiUserToolbarFirst;
uiNewToolbarID <= m_uiUserToolbarLast;
uiNewToolbarID ++)
{
CBCGToolBar* pNewToolbar = new CBCGToolBar;
if (!pNewToolbar->Create (m_pFrame,
dwDefaultToolbarStyle,
uiNewToolbarID))
{
TRACE0 ("Failed to create a new toolbar!\n");
delete pNewToolbar;
continue;
}
if (!pNewToolbar->LoadState (m_strControlBarRegEntry))
{
pNewToolbar->DestroyWindow ();
delete pNewToolbar;
}
else
{
pNewToolbar->SetBarStyle (pNewToolbar->GetBarStyle () |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
pNewToolbar->EnableDocking (CBRS_ALIGN_ANY);
m_pFrame->DockControlBar (pNewToolbar);
m_listUserDefinedToolbars.AddTail (pNewToolbar);
}
}
}
//**********************************************************************************************
void CBCGFrameImpl::SaveUserToolbars ()
{
for (POSITION pos = m_listUserDefinedToolbars.GetHeadPosition (); pos != NULL;)
{
CBCGToolBar* pUserToolBar =
(CBCGToolBar*) m_listUserDefinedToolbars.GetNext (pos);
ASSERT_VALID(pUserToolBar);
pUserToolBar->SaveState (m_strControlBarRegEntry);
}
}
//**********************************************************************************************
CBCGToolBar* CBCGFrameImpl::GetUserBarByIndex (int iIndex) const
{
POSITION pos = m_listUserDefinedToolbars.FindIndex (iIndex);
if (pos == NULL)
{
return NULL;
}
CBCGToolBar* pUserToolBar =
(CBCGToolBar*) m_listUserDefinedToolbars.GetAt (pos);
ASSERT_VALID (pUserToolBar);
return pUserToolBar;
}
//**********************************************************************************************
BOOL CBCGFrameImpl::IsUserDefinedToolbar (const CBCGToolBar* pToolBar) const
{
ASSERT_VALID (pToolBar);
UINT uiCtrlId = pToolBar->GetDlgCtrlID ();
return uiCtrlId >= m_uiUserToolbarFirst &&
uiCtrlId <= m_uiUserToolbarLast;
}
//*******************************************************************************************
BOOL CBCGFrameImpl::IsDockStateValid (const CDockState& state)
{
//----------------------------------------------------------------
// This function helps to avoid GPF during CFrameWnd::LoadBarState
// execution: when one of the previously saved toolbars is not
// created, LoadBarState fails.
//----------------------------------------------------------------
for (int i = 0; i < state.m_arrBarInfo.GetSize (); i ++)
{
CControlBarInfo* pInfo = (CControlBarInfo*) state.m_arrBarInfo [i];
ASSERT (pInfo != NULL);
if (!pInfo->m_bFloating)
{
//---------------------------------------
// Find the control bar with the same ID:
//---------------------------------------
if (m_pFrame->GetControlBar (pInfo->m_nBarID) == NULL)
{
TRACE (_T("CBCGFrameImpl::IsDockStateValid ControlBar %x is not valid!\n"), pInfo->m_nBarID);
return FALSE;
}
}
}
return TRUE;
}
//**********************************************************************************
void CBCGFrameImpl::InitUserToobars ( LPCTSTR lpszRegEntry,
UINT uiUserToolbarFirst,
UINT uiUserToolbarLast)
{
ASSERT (uiUserToolbarLast >= uiUserToolbarFirst);
if (uiUserToolbarFirst == (UINT) -1 ||
uiUserToolbarFirst == (UINT) -1)
{
ASSERT (FALSE);
return;
}
m_uiUserToolbarFirst = uiUserToolbarFirst;
m_uiUserToolbarLast = uiUserToolbarLast;
// ET: get Path automatically from workspace if needed
m_strControlBarRegEntry = (lpszRegEntry == NULL) ?
( g_pWorkspace ? g_pWorkspace->GetRegSectionPath() : _T("") )
: lpszRegEntry;
}
//**************************************************************************************
const CBCGToolBar* CBCGFrameImpl::CreateNewToolBar (LPCTSTR lpszName)
{
ASSERT (lpszName != NULL);
if (m_uiUserToolbarFirst == (UINT)-1 ||
m_uiUserToolbarLast == (UINT)-1)
{
TRACE (_T("User-defined toolbars IDs are none defined!\n"));
return NULL;
}
int iMaxToolbars = m_uiUserToolbarLast - m_uiUserToolbarFirst + 1;
if (m_listUserDefinedToolbars.GetCount () == iMaxToolbars)
{
CBCGLocalResource locaRes;
CString strError;
strError.Format (IDS_BCGBARRES_TOO_MANY_TOOLBARS_FMT, iMaxToolbars);
AfxMessageBox (strError, MB_OK | MB_ICONASTERISK);
return NULL;
}
//-----------------------
// Find a new toolbar id:
//-----------------------
UINT uiNewToolbarID;
for (uiNewToolbarID = m_uiUserToolbarFirst;
uiNewToolbarID <= m_uiUserToolbarLast;
uiNewToolbarID ++)
{
BOOL bUsed = FALSE;
for (POSITION pos = m_listUserDefinedToolbars.GetHeadPosition ();
!bUsed && pos != NULL;)
{
CBCGToolBar* pUserToolBar =
(CBCGToolBar*) m_listUserDefinedToolbars.GetNext (pos);
ASSERT_VALID(pUserToolBar);
bUsed = (pUserToolBar->GetDlgCtrlID () == (int) uiNewToolbarID);
}
if (!bUsed)
{
break;
}
}
if (uiNewToolbarID >= m_uiUserToolbarLast)
{
TRACE0 ("Can't find non-used toolbar number!\n");
return NULL;
}
CBCGToolBar* pNewToolbar = new CBCGToolBar;
if (!pNewToolbar->Create (m_pFrame,
dwDefaultToolbarStyle,
uiNewToolbarID))
{
TRACE0 ("Failed to create a new toolbar!\n");
delete pNewToolbar;
return NULL;
}
pNewToolbar->SetWindowText (lpszName);
pNewToolbar->SetBarStyle (pNewToolbar->GetBarStyle () |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
pNewToolbar->EnableDocking (CBRS_ALIGN_ANY);
m_pFrame->FloatControlBar (pNewToolbar,
CPoint (::GetSystemMetrics (SM_CXFULLSCREEN) / 2,
::GetSystemMetrics (SM_CYFULLSCREEN) / 2));
m_pFrame->RecalcLayout ();
m_listUserDefinedToolbars.AddTail (pNewToolbar);
return pNewToolbar;
}
//**************************************************************************************
BOOL CBCGFrameImpl::DeleteToolBar (CBCGToolBar* pToolBar)
{
ASSERT_VALID (pToolBar);
POSITION pos = m_listUserDefinedToolbars.Find (pToolBar);
if (pos == NULL)
{
return FALSE;
}
m_listUserDefinedToolbars.RemoveAt (pos);
pToolBar->RemoveStateFromRegistry (m_strControlBarRegEntry);
pToolBar->DestroyWindow ();
delete pToolBar;
m_pFrame->RecalcLayout ();
return TRUE;
}
//*******************************************************************************************
void CBCGFrameImpl::SetMenuBar (CBCGMenuBar* pMenuBar)
{
ASSERT_VALID (pMenuBar);
ASSERT (m_pMenuBar == NULL); // Method should be called once!
m_pMenuBar = pMenuBar;
m_hDefaultMenu=*m_pFrame->GetMenu();
// ET: Better support for dynamic menu
m_pMenuBar->OnDefaultMenuLoaded (m_hDefaultMenu);
m_pMenuBar->CreateFromMenu (m_hDefaultMenu, TRUE /* Default menu */);
m_pFrame->SetMenu (NULL);
m_pMenuBar->SetDefaultMenuResId (m_nIDDefaultResource);
}
//*******************************************************************************************
BOOL CBCGFrameImpl::ProcessKeyboard (int nKey)
{
if (m_pActivePopupMenu != NULL &&
::IsWindow (m_pActivePopupMenu->m_hWnd))
{
m_pActivePopupMenu->SendMessage (WM_KEYDOWN, nKey);
return TRUE;
}
return FALSE;
}
//*******************************************************************************************
BOOL CBCGFrameImpl::ProcessMouseClick (UINT uiMsg, POINT pt, HWND hwnd)
{
//------------------------------------------------
// Maybe user start drag the button with control?
//------------------------------------------------
if (uiMsg == WM_LBUTTONDOWN &&
(CBCGToolBar::IsCustomizeMode () ||
(::GetAsyncKeyState (VK_MENU) & 0x8000))) // ALT is pressed
{
for (POSITION posTlb = gAllToolbars.GetHeadPosition (); posTlb != NULL;)
{
CBCGToolBar* pToolBar = (CBCGToolBar*) gAllToolbars.GetNext (posTlb);
ASSERT (pToolBar != NULL);
if (CWnd::FromHandlePermanent (pToolBar->m_hWnd) != NULL)
{
ASSERT_VALID(pToolBar);
CPoint ptToolBar = pt;
pToolBar->ScreenToClient (&ptToolBar);
int iHit = pToolBar->HitTest (ptToolBar);
if (iHit >= 0)
{
CBCGToolbarButton* pButton = pToolBar->GetButton (iHit);
ASSERT_VALID (pButton);
if (pButton->GetHwnd () != NULL &&
pButton->GetHwnd () == hwnd &&
pButton->Rect ().PtInRect (ptToolBar))
{
pToolBar->SendMessage (WM_LBUTTONDOWN,
0, MAKELPARAM (ptToolBar.x, ptToolBar.y));
return TRUE;
}
break;
}
}
}
}
if (!CBCGToolBar::IsCustomizeMode () &&
m_pActivePopupMenu != NULL &&
::IsWindow (m_pActivePopupMenu->m_hWnd))
{
CRect rectMenu;
m_pActivePopupMenu->GetWindowRect (rectMenu);
if (!rectMenu.PtInRect (pt))
{
//--------------------------------------------
// Maybe secondary click on the parent button?
//--------------------------------------------
CBCGToolbarMenuButton* pParentButton =
m_pActivePopupMenu->GetParentButton ();
if (pParentButton != NULL)
{
CBCGPopupMenuBar* pWndParent = DYNAMIC_DOWNCAST (
CBCGPopupMenuBar, pParentButton->GetParentWnd ());
if (pWndParent != NULL)
{
CPoint ptClient = pt;
pWndParent->ScreenToClient (&ptClient);
if (pParentButton->Rect ().PtInRect (ptClient))
{
//-----------------------------
// Secondary click, do nothing!
//-----------------------------
return TRUE;
}
}
}
m_pActivePopupMenu->SendMessage (WM_CLOSE);
return TRUE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -