用于过滤选择的复选框树控件






4.50/5 (11投票s)
2003 年 2 月 24 日
2分钟阅读

127646

3564
一个 ATL 过滤器控件
引言
一年前,我在文章“增强的 CCheckComboBox”中发布了一个 MFC 控件。 许多读者要求我将此控件制成可从 VB 或 .NET 访问的 COM 组件。 另一个要求是尽可能快速地添加新控件。 我决定创建一个包含一组带有复选框树下拉列表的组合框的 ATL 组件。 这些组合框是动态创建的,并显示在 2、3 或 4 列中。
Using the Code
要使用此代码,首先您需要在 VC++ 6.0 或 VC++ .NET 中构建“QuickFilter
”项目。 然后,您可以运行三个演示项目:“Test with VB”、“Test with HTML”和“Test with C#”。
填充第一个组合框的示例:(C#)
//## INIT Countries
QF.set_CheckLabel( 0, "Countries:" );
QF.set_Field( 0, "Countries.ID" );
QF.AddFolder( 0, "North America" );
QF.AddString( 0, "USA", 5, ROOT_LEVEL + 2 );
QF.AddString( 0, "Canada", 6, ROOT_LEVEL + 2 );
QF.AddFolder( 0, "Europe" );
QF.AddString( 0, "UK", 7, ROOT_LEVEL + 2 );
QF.AddString( 0, "Germany", 8, ROOT_LEVEL + 2 );
QF.AddString( 0, "Russia", 9, ROOT_LEVEL + 2 );
QF.AddFolder( 0, "Asia" );
QF.AddString( 0, "Israel", 10, ROOT_LEVEL + 2 );
QF.CheckAll( 0, true );
关注点
ComboBox
控件由 EditBox
、Button
和 TreeView
组成。 TreeView
是桌面窗口的子窗口,当用户按下组合框的按钮或编辑框时显示或隐藏(这是设计使然)。 我不再像在之前的文章中那样子类化组合框的父窗口,而是使用鼠标捕获和 LostFocus
事件在需要时隐藏下拉列表。
当用户按下组合框的按钮时,我显示下拉列表,并等待 WM_LBUTTONUP
消息以捕获鼠标。 此时,我知道在我的控件之外单击将必须隐藏下拉列表。 一切似乎都很容易,但存在一个问题:如果鼠标已经捕获,树下拉列表的滚动条将无法正常工作。 为了处理这种情况,只要用户使用滚动条,我们就会释放鼠标捕获,然后再次重新捕获鼠标
LRESULT CCheckTreeCtrl::OnLButtonDown(UINT uMsg, WPARAM wParam,
LPARAM lParam, BOOL& bHandled)
{
...
//## RELEASE Capture
if (hWnd == m_hWnd)
if (GetCapture() == hWnd){
LRESULT result = ::SendMessage( hWnd, WM_NCHITTEST, NULL,
MAKELONG(point.x, point.y));
if ((result == HTVSCROLL) || (result == HTHSCROLL)){
::ReleaseCapture();
m_bScroll = TRUE;
::SendMessage( hWnd, WM_NCLBUTTONDOWN, result,
MAKELONG(point.x, point.y));
}
}
...
}
当用户完成使用滚动条后,将发送 WM_CAPTURECHANGED
消息。 在这里,我们将再次捕获鼠标。
LRESULT CCheckTreeCtrl::OnCaptureChanged(UINT uMsg, WPARAM wParam,
LPARAM lParam, BOOL& bHandled)
{
...
//## SET Capture
if (IsWindowVisible())
if (lParam == NULL)
if (m_bScroll){
SetCapture();
m_bScroll = FALSE;
}
...
}
其余的就非常简单了。 尽情享用吧!
历史
这是第一个版本。
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。