MFC(C++):为什么顶部的控件不接收事件?

MFC (C++): Why control on top does not receive event?

在设计阶段,

在运行时,一个按钮切换 A 的可见性,当 A 可见时将其置于 B 之上(使用 SetWindowPos(...))。

显示A时,在重叠区域没有接收到事件(比如我点击下图中的"item 4"和"item 5")。为什么以及如何修复它?

可以在此处访问示例代码https://138.197.210.223/test/test.zip

我确实检查了代码,发现问题是由OnBnClickedCheck1()中的::SetWindowPos()命令引起的。您调用它来解决绘图问题,但您是通过更改 Z-Order 来实现的,这会导致 B 控件改为捕获输入。所以必须去掉,OnBnClickedCheck1()中的代码可以改成如下所示(我简化了语法,使用MFC,而不是WinAPI命令):

void CTestDlgActXDlg::OnBnClickedCheck1()
{
        m_list_A.ShowWindow(m_list_A.IsWindowVisible() ? SW_HIDE : SW_SHOW);
}

绘图问题可以通过在资源脚本中设置WS_CLIPSIBLINGS样式来解决,如评论中所建议:

.
.
LISTBOX         IDC_LIST_A,114,36,48,42,LBS_SORT | LBS_NOINTEGRALHEIGHT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
CONTROL         "",IDC_LIST_B,"SysListView32",LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP | WS_CLIPSIBLINGS,108,60,60,54
.
.

这种方式对我有用,A 控件优先于 B,并发送 LBN_SELCHANGE 通知,对于它的任何被点击的项目。

我注意到一些奇怪的事情,testdlg.cpp 中的 DDX_Control(pDX, IDC_LIST_B, m_list_B); 命令是 运行 两次。删除第二个调用。

奇怪的 UI 设计顺便说一句。