如何实现锁定解锁工具栏的功能,顶者有分
我们可以用CFrameWnd的EnableDocking让控制栏可停靠,但我们在CFrameWnd中却找不到DisableDocking之类的函数来移除控制栏的可停靠特性。那我们如何实现IE和Explore那样的锁定/解锁工具栏的功能呢?
MFC中并没有锁定/解锁控制栏的实现代码,那我们可不可以根据CFrameWnd::EnableDocking/CControlBar::EnableDocking的实现代码来实现DisableDocking的功能呢?我们发现CFrameWnd::EnableDocking和CControlBar::EnableDocking的实现代码相当难懂,想通过这种方式就要求我们对MFC的很多内部机制实现了解得很清楚才行(dwDockBarMap是?),非常困难。有没有更简单的方法呢?
我们可以想到的办法就是当工具栏被锁定后拦截会引用拖动的所有鼠标事件?我们需要拦截什么鼠标事件呢?在CControlBar的实现中我们可以找到答案;
void CControlBar::OnLButtonDown(UINT nFlags, CPoint pt)
{
// only start dragging if clicked in "void" space
if (m_pDockBar != NULL && OnToolHitTest(pt, NULL) == -1)
{
// start the drag
…
}
else
{
CWnd::OnLButtonDown(nFlags, pt);
}
}
void CControlBar::OnLButtonDblClk(UINT nFlags, CPoint pt)
{
// only toggle docking if clicked in "void" space
if (m_pDockBar != NULL && OnToolHitTest(pt, NULL) == -1)
{
// start the drag
…
}
else
{
CWnd::OnLButtonDblClk(nFlags, pt);
}
}
可以看到当在WM_LBUTTONDOWN和WM_LBUTTONDBCLK事件中并且OnToolHitTest(pt, NULL) == -1的时候将开始拖动,如果我过滤这两个事件,并判断OnToolHitTest的结果就可以阻止控制栏的拖动了。下面给出以ToolBar为例的实现代码
//------------------------------------------------------------------------------
// File: LockToolBar.h
//
// Desc: A lockable/unlockable toolbar.
//
// Copyright (c) 2004 DentistryDoctor. All rights reserved.
//------------------------------------------------------------------------------
// CLockToolBar
class CLockToolBar : public CToolBar
{
DECLARE_DYNAMIC(CLockToolBar)
public:
CLockToolBar();
virtual ~CLockToolBar();
void SetLocked(BOOL bLocked=TRUE);
BOOL GetLocked() const
{
return m_bLocked;
}
protected:
DECLARE_MESSAGE_MAP()
virtual BOOL PreTranslateMessage(MSG* pMsg);
BOOL m_bLocked;
};
//------------------------------------------------------------------------------
// File: LockToolBar.cpp
//
// Desc: A lockable/unlockable toolbar.
//
// Copyright (c) 2004 DentistryDoctor. All rights reserved.
//------------------------------------------------------------------------------
#include "stdafx.h"
#include "LockToolBar.h"
// CLockToolBar
IMPLEMENT_DYNAMIC(CLockToolBar, CToolBar)
CLockToolBar::CLockToolBar() : m_bLocked(FALSE)
{
}
CLockToolBar::~CLockToolBar()
{
}
BEGIN_MESSAGE_MAP(CLockToolBar, CToolBar)
END_MESSAGE_MAP()
// CLockToolBar Message handle functions
/////////////////////////////////////////////////
void CLockToolBar::SetLocked(BOOL bLocked)
{
CFrameWnd* pFrame = GetParentFrame();
ASSERT(pFrame);
m_bLocked = bLocked;
DWORD dwStyle = GetBarStyle();
if (bLocked) {
pFrame->DockControlBar(this); // dock if not already
dwStyle &= ~CBRS_GRIPPER; // turn off gripper
} else {
dwStyle |= CBRS_GRIPPER;
}
SetBarStyle(dwStyle);
pFrame->RecalcLayout(); // make frame recalc toolbar sizes
}
BOOL CLockToolBar::PreTranslateMessage(MSG* pMsg)
{
UINT msg = pMsg->message;
LPARAM lp = pMsg->lParam;
if ((pMsg->hwnd==GetSafeHwnd() || CWnd::FromHandle(pMsg->hwnd)->GetParent()==this) && (msg==WM_LBUTTONDOWN || msg==WM_LBUTTONDBLCLK) && m_bLocked)
{
CPoint pt(lp);
if (OnToolHitTest(pt, NULL) == -1)
return TRUE;
}
return CToolBar::PreTranslateMessage(pMsg);
}
这样用CLockToolBar代替CToolBar就可以实现锁定/解锁的功能了。
MFC中并没有锁定/解锁控制栏的实现代码,那我们可不可以根据CFrameWnd::EnableDocking/CControlBar::EnableDocking的实现代码来实现DisableDocking的功能呢?我们发现CFrameWnd::EnableDocking和CControlBar::EnableDocking的实现代码相当难懂,想通过这种方式就要求我们对MFC的很多内部机制实现了解得很清楚才行(dwDockBarMap是?),非常困难。有没有更简单的方法呢?
我们可以想到的办法就是当工具栏被锁定后拦截会引用拖动的所有鼠标事件?我们需要拦截什么鼠标事件呢?在CControlBar的实现中我们可以找到答案;
void CControlBar::OnLButtonDown(UINT nFlags, CPoint pt)
{
// only start dragging if clicked in "void" space
if (m_pDockBar != NULL && OnToolHitTest(pt, NULL) == -1)
{
// start the drag
…
}
else
{
CWnd::OnLButtonDown(nFlags, pt);
}
}
void CControlBar::OnLButtonDblClk(UINT nFlags, CPoint pt)
{
// only toggle docking if clicked in "void" space
if (m_pDockBar != NULL && OnToolHitTest(pt, NULL) == -1)
{
// start the drag
…
}
else
{
CWnd::OnLButtonDblClk(nFlags, pt);
}
}
可以看到当在WM_LBUTTONDOWN和WM_LBUTTONDBCLK事件中并且OnToolHitTest(pt, NULL) == -1的时候将开始拖动,如果我过滤这两个事件,并判断OnToolHitTest的结果就可以阻止控制栏的拖动了。下面给出以ToolBar为例的实现代码
//------------------------------------------------------------------------------
// File: LockToolBar.h
//
// Desc: A lockable/unlockable toolbar.
//
// Copyright (c) 2004 DentistryDoctor. All rights reserved.
//------------------------------------------------------------------------------
// CLockToolBar
class CLockToolBar : public CToolBar
{
DECLARE_DYNAMIC(CLockToolBar)
public:
CLockToolBar();
virtual ~CLockToolBar();
void SetLocked(BOOL bLocked=TRUE);
BOOL GetLocked() const
{
return m_bLocked;
}
protected:
DECLARE_MESSAGE_MAP()
virtual BOOL PreTranslateMessage(MSG* pMsg);
BOOL m_bLocked;
};
//------------------------------------------------------------------------------
// File: LockToolBar.cpp
//
// Desc: A lockable/unlockable toolbar.
//
// Copyright (c) 2004 DentistryDoctor. All rights reserved.
//------------------------------------------------------------------------------
#include "stdafx.h"
#include "LockToolBar.h"
// CLockToolBar
IMPLEMENT_DYNAMIC(CLockToolBar, CToolBar)
CLockToolBar::CLockToolBar() : m_bLocked(FALSE)
{
}
CLockToolBar::~CLockToolBar()
{
}
BEGIN_MESSAGE_MAP(CLockToolBar, CToolBar)
END_MESSAGE_MAP()
// CLockToolBar Message handle functions
/////////////////////////////////////////////////
void CLockToolBar::SetLocked(BOOL bLocked)
{
CFrameWnd* pFrame = GetParentFrame();
ASSERT(pFrame);
m_bLocked = bLocked;
DWORD dwStyle = GetBarStyle();
if (bLocked) {
pFrame->DockControlBar(this); // dock if not already
dwStyle &= ~CBRS_GRIPPER; // turn off gripper
} else {
dwStyle |= CBRS_GRIPPER;
}
SetBarStyle(dwStyle);
pFrame->RecalcLayout(); // make frame recalc toolbar sizes
}
BOOL CLockToolBar::PreTranslateMessage(MSG* pMsg)
{
UINT msg = pMsg->message;
LPARAM lp = pMsg->lParam;
if ((pMsg->hwnd==GetSafeHwnd() || CWnd::FromHandle(pMsg->hwnd)->GetParent()==this) && (msg==WM_LBUTTONDOWN || msg==WM_LBUTTONDBLCLK) && m_bLocked)
{
CPoint pt(lp);
if (OnToolHitTest(pt, NULL) == -1)
return TRUE;
}
return CToolBar::PreTranslateMessage(pMsg);
}
这样用CLockToolBar代替CToolBar就可以实现锁定/解锁的功能了。
...全文
相关推荐
Linux 中锁定和解锁用户帐户的三种方法
如果你已经在你的组织中实施了某种密码策略,你无需看这篇文章了。但是在这种情况下,如果你给账户设置了 24 小时的锁定期,你需要手动解锁用户帐户。 本教程将帮助你在 Linux 中手动锁定和解锁用户帐户。 这可以通过三种方式使用以下两个 Linux 命令来完成。 passwd usermod 为了说明这一点,我们选择 daygeek 用户帐户。让我们看看,怎么一步步来实现的。 请注意,你必须使用你需要锁定或解锁的用户的帐户,而不是我们的帐户。你可以使用 id 命令检查给定的用户帐户在系统中是否可用。是的,我的这个帐户在我的系统中是可用的。 # id daygeek uid=2240(da
Allegro软件入门系列-查询命令与锁定解锁命令
查询命令可以看到各种重要信息,诸如网络长度、长度、线宽、线距等等,可以快速辅助我们的PCB设计 而锁定命令是为了减少设计的过程人为的误操作造成相关的东西移动或者修改, 解锁命令则是相反操作,我们要编辑的时候就必须解锁才能进行操作。 《一》查询命令 查询命令在上图工具栏的感叹号图标 (1)查询线的类,长度,在Find栏目勾线Line,我们看到板框层属于什么什么Class、Subcl...
C#锁定和解锁窗体
C#锁定和解锁窗体
解锁keil中被锁定的文件 修改其中的代码
解锁keil中被锁定的文件 修改其中的代码
批量解锁锁定的域帐户工具
在启用帐户锁定策略后,因病毒或未更新关键补丁等原因造成域帐号大量锁定时可以使用此工具批量进行解锁,单击“系统-域用户查看及管理信息”,先查看锁定的帐户,再批量进行解锁即可。


界面
