Xtreme Toolkit Pro是MFC开发中最全面界面控件套包,它提供了Windows开发所需要的11种主流的Visual C++ MFC控件,包括Command Bars、Controls、Chart Pro、Calendar、Docking Pane、Property Grid、Report Control、Shortcut Bar、Syntax Edit、Skin Framework 和Task Panel。
在版本19.2之前,不能够将控件的主题应用于ToolkitPro控件(例如CXTPEdit,CXTPTree,CXTPListBox,CXTPListCtrl和CXTPPropertyGrid)中的滚动条。因为通用Windows控件拥有自己显示和处理的滚动条的方式,并且覆盖Windows通用控件的行为以及保持完全的向后兼容性在技术上非常具有挑战性,因此导致需要考虑一定的可使用进的解决方案。本文介绍了关键点,并试图回答可能出现的常见问题。
解决方案
实际上,以下类保持不变,并且仍使用未应用主题的标准Windows滚动条:
- CXTPEdit
- CXTPTreeCtrl
- CXTPListBox
- CXTPListCtrl
为了能够应用滚动条主题或自定义滚动条类,必须使用或派生新特殊适配器模板类的新控件类CXTPScrollable。
对于最常见的用例,将应用程序中使用的控件类名替换为对应的类名就足够了,这些类名源自CXTPScrollable:
- CXTPScrollableEdit
- CXTPScrollableTreeCtrl
- CXTPScrollableListBox
- CXTPScrollableListCtrl
CXTPPropertyGrid这是一种特殊情况,它没有其他CXTPScrollable派生版本,仅在内部使用新方法,保持完全向后兼容,并且除非确认新添加会引起阻塞问题,否则不需要任何特殊考虑。如果从版本19.3开始是这种情况,则可以禁用PropertyGrid滚动条主题。
如果从版本19.3开始是这种情况,则可以选择禁用滚动条主题,以回退到19.2之前的行为。对于这个无论是取消对XTPPropertyGrid.h 文件中 (C:\Program Files (x86)\Codejock Software\MFC\Xtreme ToolkitPro v19.3.0\Source\PropertyGrid\XTPPropertyGrid.h) 的XTP_PROPERTY_GRID_DISABLE_SCROLLBAR_THEMES 宏或将宏定义为ToolkitPro或PropertyGrid库项目的C ++编译器属性,然后重新构建ToolkitPro或PropertyGrid项目,以使更改生效。
使用这些类将确保控件将自动具有合适的滚动条主题,并可以使用新方法设置自定义滚动条主题:
void SetScrollBarTheme(XTPScrollBarTheme nTheme);
使用从CXTPScrollable派生的类同时也会施加某些限制:
- 如果控件是使用MFC基类公开的CreateEx方法手动创建的,应该只调用CWnd::Creat或者CWND::CreateEx由于微软C++编译器的旧版本中缺少C++支持而重写,从MFC CtReCtRL、CEDIT、CclitBox和CListCtrl调用重载CREATE或CREATETX方法将导致使用这些编译器时的编译错误。
CXTPTreeCtrl m_tree;
// As CXTPTreeCtrl is derived from CTreeCtrl it uses CTreeCtrl::Create overloaded
// method which has signature different from CWnd::Create and thus should not be used for CXTPScrollableTreeCtrl
m_tree.Create(WS_CHILD | TVS_LINESATROOT, rc, this, IDC_TREE);
Example of the fixed code:
CXTPScrollableTreeCtrl m_tree;
// Call CWnd::Create overridden method to ensure it can be compiled using all Microsoft C++ compilers
m_tree.Create(_T("SysTreeView32"), NULL, WS_CHILD | TVS_LINESATROOT, rc, this, IDC_TREE);
- 从CXTPScrollable派生的所有控件将在初始创建时销毁并重新创建。对于常规用例,这个过程是绝对透明的,但是如果句柄在早期被客户端代码缓存,它可能很快就会失效,这些地方包括但不限于:窗口创建挂钩在默认CDialog::OnInitDialog调用之前完成的任何句柄操作
- 在设计派生自定义控件的方法时,如果CXTPScrollable尝试使控件的初始化逻辑尽可能简单和轻巧,则后续控件的重新创建可能会导致控件重新创建期间的CPU和内存负担加倍,从而导致应用程序启动速度变慢。
- 派生cxtScrollable的所有类都必须是默认可构造的,即公开一个不带参数的公共构造函数或提供了默认值的所有参数。
- 为了修改派生自CXTPScrollable该控件的控件,必须设置标志位进行调用 RedrawWindow,RDW_ALLCHILDREN因为调用UpdateWindow 不会产生任何效果。
- 如果从中派生的控件CXTPScrollable需要在创建后访问其父窗口,则它必须调用GetParent两次,因为它将被放置在中间宿主控件上。
- 使用从CXTPScrollableResizer 控件派生的控件需要使用CXTPResize::SetResize除控件的ID值外还带有 控件的窗口句柄的方法,例如
CXTPEdit m_edtSingleLine;
CXTPScrollableEdit m_edtMultiline;
// IDC_EDIT_SINGLELINE is NOT derived from CXTPScrollable and thus can be referenced by Resize control by ID only.
SetResize(IDC_EDIT_SINGLELINE, XTP_ANCHOR_TOPLEFT, CXTPResizePoint(1.f / 3.f, 0));
// IDC_EDIT_MULTILINE is derived from CXTPScrollable and thus must be referenced by Resize control by both ID and handle value.
SetResize(IDC_EDIT_MULTILINE, m_edtMultiline, XTP_ANCHOR_TOPLEFT, CXTPResizePoint(1.f / 3.f, 0));
从CXTPScrollable派生自定义控件
如果控件来自于受支持的类并使用标准的Windows滚动条,则可以使用CXTPScrollable自定义控件来将其应用于滚动条。
有两种可能的用例:
- 使用衍生自对照CEdit,CListBox,CTreeCtrl或 CListCtrl
- 使用控件衍生自其他控件 CWnd
对于第一种情况,ToolkitPro为相应的基类提供了适配器模板:
- CXTPScrollableEditT
- CXTPScrollableListBoxT
- CXTPScrollableTreeCtrlT
- CXTPScrollableListCtrlT
例:
// Your existing classes
class CCustomEdit : public CEdit { /*...*/ };
class CCustomTreeCtrl : public CXTPTreeCtrl { /*...*/ };
// Your new derived classes
class CScrollableCustomEdit : public CXTPScrollableEditT { /*...*/ };
class CScrollableTreeCtrl : public CXTPScrollableEditT { /*...*/ };
在其他情况下,当您需要派生另一种自定义控件时,则需要实现 IXTPScrollable接口:
// Your existing class
class CCustomControl : public CWnd
{
public:
void InitializeCustomState();
// ...
};
// Your new derived class.
// Some or all method may have default implementation, the example demonstrates overloading of all methods.
class CScrollableCustomControl : public CXTPScrollable
{
public:
// IXTPScrollable overrides
virtual BOOL HasVScroll(DWORD dwStyle, DWORD dwExStyle) const
{
// Determine if control has vertical scroll.
return 0 != (GetStyle() & WS_VSCROLL);
}
virtual BOOL HasHScroll(DWORD dwStyle, DWORD dwExStyle) const
{
// Determine if control has horizontal scroll.
return 0 != (GetStyle() & WS_HSCROLL);
}
virtual BOOL HasLeftScrollbar(DWORD dwStyle, DWORD dwExStyle) const
{
// Determine if control has scroll bar on the lets.
return 0 != (GetExStyle() & WS_EX_LEFTSCROLLBAR);
}
virtual void DisableScrollbars()
{
// Force default scroll bars to hide.
DisableScrollbars(*this);
}
virtual void DisableScrollbars(CWnd& wnd)
{
// Force default scroll bars to hide for a specific window.
wnd.ModifyStyle(WS_VSCROLL | WS_HSCROLL, 0);
}
virtual CScrollBar* CreateBar() const
{
// Create scroll bar instance.
return new CXTPScrollBarCtrl();
}
virtual CWnd* CreateControl() const
{
// Re-create custom control instance and perform default initialization if necessary.
CCustomControl* pNewCtrl = new CCustomControl();
VERIFY(NULL != pNewCtrl);
pNewCtrl->InitializeCustomState();
return pNewCtrl;
}
virtual DWORD FilterStyle(DWORD dwStyle) const
{
return dwStyle;
}
virtual DWORD FilterExStyle(DWORD dwExStyle) const
{
return dwExStyle;
}
virtual BOOL RequiresMouseWheelOverriding() const
{
return true;
}
// ...
};
今天的内容就是这些了,赶快前往慧都网下载最新版Xtreme ToolKit Pro体验并在下方评论区分享您对该产品的想法。