- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
似乎 CListCtrl
不会发送鼠标弹起事件,除非双击。
我已经尝试从鼠标按下处理程序发送丢失的消息来补偿,但这会导致其他不良行为。然后我想我可以通过检查状态在鼠标移动处理程序中发送消息更准确一些。然而,这些都是可怕的 hack,除了丑陋之外,它们可能无法在派生控件的所有可能实现中正常工作。
如果有人知道为什么没有收到鼠标松开事件,我会很好奇。更重要的是,如何使用 LVS_OWNERDATA
样式让 CListCtrl
像其他控件一样发送鼠标弹起消息?
编辑:我知道 LVN_BEGINDRAG
、LVN_BEGINRDRAG
等,但是为了使用这些,我需要阻止 WM_LBUTTONDOWN
、WM_RBUTTONDOWN
和 WM_MOUSEMOVE
从转到父窗口或 DragDropManager
连接到 CWinAppEx
/CMDIFrameWndEx
所以我可以为这个控件制作一个特殊的一次性案例,以便与现有系统一起工作。
这是因为我有一个中央拖放管理器,它可以通知各种类型的控件何时开始拖动操作、何时结束、取消、更改动画、在自定义消息中传递源和目标的显示对象等。它需要足够灵活,以具有不同的启动方式以及不同的操作,具体取决于控件、输入、所选或目标项目的类型、不同的控件类型(包括 3D),甚至不同的应用程序等。
最佳答案
作为引用,这里是我所拥有的有效的方法,但这是一个可耻的 hack。如果没有人能想出比这更好的东西,那就太可悲了。
标题:
#pragma once
// CListCtrlEx
class CListCtrlEx : public CListCtrl
{
DECLARE_DYNAMIC(CListCtrlEx)
public:
CListCtrlEx();
virtual ~CListCtrlEx();
bool IsSelected(int index);
BOOL SelectDropTarget(int item);
protected:
DECLARE_MESSAGE_MAP()
afx_msg void OnStateChanged(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
private:
bool m_lbDown;
bool m_rbDown;
};
实现:
#include "stdafx.h"
#include "ListCtrlEx.h"
// CListCtrlEx
IMPLEMENT_DYNAMIC(CListCtrlEx, CListCtrl)
CListCtrlEx::CListCtrlEx() : m_lbDown(false), m_rbDown(false)
{
}
CListCtrlEx::~CListCtrlEx()
{
}
BEGIN_MESSAGE_MAP(CListCtrlEx, CListCtrl)
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONUP()
ON_WM_MOUSEMOVE()
ON_NOTIFY_REFLECT(LVN_ODSTATECHANGED, &CListCtrlEx::OnStateChanged)
END_MESSAGE_MAP()
// CListCtrlEx message handlers
void CListCtrlEx::OnLButtonDown(UINT nFlags, CPoint point)
{
m_lbDown = true;
CListCtrl::OnLButtonDown(nFlags, point);
}
void CListCtrlEx::OnRButtonDown(UINT nFlags, CPoint point)
{
m_rbDown = true;
CListCtrl::OnRButtonDown(nFlags, point);
}
void CListCtrlEx::OnLButtonUp(UINT nFlags, CPoint point)
{
m_lbDown = false;
CListCtrl::OnLButtonUp(nFlags, point);
}
void CListCtrlEx::OnRButtonUp(UINT nFlags, CPoint point)
{
m_rbDown = false;
CListCtrl::OnRButtonUp(nFlags, point);
}
void CListCtrlEx::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_lbDown && ((nFlags & MK_LBUTTON) == 0))
{
PostMessage(WM_LBUTTONUP,
MAKEWPARAM(LOWORD(nFlags), HIWORD(nFlags)),
MAKELPARAM(point.x, point.y));
}
if (m_rbDown && ((nFlags & MK_RBUTTON) == 0))
{
PostMessage(WM_RBUTTONUP,
MAKEWPARAM(LOWORD(nFlags), HIWORD(nFlags)),
MAKELPARAM(point.x, point.y));
}
CListCtrl::OnMouseMove(nFlags, point);
}
bool CListCtrlEx::IsSelected(int index)
{
return (GetItemState(index, LVIS_SELECTED) & LVIS_SELECTED) != 0;
}
// highlight drop targets sort of like CTreeCtrl
BOOL CListCtrlEx::SelectDropTarget(int item)
{
static int prevHighlight(-1);
if (item >= 0 && item < GetItemCount())
{
if (item != prevHighlight)
{
if (prevHighlight >= 0)
{
SetItemState(prevHighlight, 0, LVIS_DROPHILITED); // remove highlight from previous target
RedrawItems(prevHighlight, prevHighlight);
}
prevHighlight = item;
SetItemState(item, LVIS_DROPHILITED, LVIS_DROPHILITED); // highlight target
RedrawItems(item, item);
UpdateWindow();
return TRUE;
}
}
else
{
for (int i(0); i < GetItemCount(); ++i)
SetItemState(i, 0, LVIS_DROPHILITED); // un-highlight all
prevHighlight = -1;
}
return FALSE;
}
void CListCtrlEx::OnStateChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
// MSDN:
// If a list-view control has the LVS_OWNERDATA style,
// and the user selects a range of items by holding down the SHIFT key and clicking the mouse,
// LVN_ITEMCHANGED notification codes are not sent for each selected or deselected item.
// Instead, you will receive a single LVN_ODSTATECHANGED notification code,
// indicating that a range of items has changed state.
NMLVODSTATECHANGE* pStateChanged = (NMLVODSTATECHANGE*)pNMHDR;
// redraw newly selected items
if (pStateChanged->uNewState == LVIS_SELECTED)
RedrawItems(pStateChanged->iFrom, pStateChanged->iTo);
}
关于c++ - MFC CListCtrl 吃鼠标松开事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7746594/
我有一个 MFC 项目,它链接到第三方 dll。在程序退出时,IDE 会报告“检测到内存泄漏!”并倾倒泄漏物。 这些泄漏来自第三方 dll。我很确定这些是错误的报道。 (Google 的快速检查表明
首先我想要的是:能够显示具有多列的网格,每个单元格都有一个自定义渲染回调。因此,您可以使用这样的控件在游戏中显示您的库存,或者类似于 Google Chrome 中的行为,它会显示您访问的热门页面的网
在新的 MFC 功能(功能包)中,菜单出现在三个地方: 在菜单栏中 (CMFCMenuBar) 在弹出菜单中 (CMFCPopupMenu) 在 CMFCButton 的“下拉菜单”版本中 我想在所有
在我的 MFC 项目中,我想动态生成标签。例如:我必须为它们生成 4 个编辑控件和相应的标签——比如“Label1”“Label2”...... CStatic *label[MAX_THREAD];
我有第一个对话框,上面有一个简单的按钮,单击该按钮时,使用 CDialog::Create(IDD,this) 创建了第二个对话框。我希望在销毁第二个对话框但不向第二个对话框添加任何代码时通知父级,即
我们的代码库中的添加到剪贴板代码非常低级 - 分配全局内存等等。对于简单的情况,我只想将一些纯文本放在剪贴板上,是否有任何例程可以包装所有这些内容? 一个例子是 CRichEditCtrl 具有 Co
我对 mfc 中事件和消息之间的区别有点困惑。 他们是一样的吗? 最佳答案 由于您专门询问 MFC,我假设您指的是可以在 MFC 类的属性窗口中定义的事件处理程序和消息处理程序。 在“事件”下,您可以
如何以编程方式检测我的 MFC 应用程序当前是否正在显示模式对话框或属性表?目前我正在使用以下内容,但我觉得该代码也会触发无模式对话框。 bool HasModalDialog(const CWnd*
我有两个按钮: 单选按钮:“十六进制” 按钮:“A” 我想在用户选中“十六进制”按钮时启用“A”(“A”在创建时的状态为“禁用”),我该怎么做?谢谢大家。 最佳答案 您需要使用 CButton 's
通常情况下,窗口的厚度为 4 个像素,可以通过 GetSystemMetrics 方法获取。我可以更改它的值,例如 2 个像素吗? 非常感谢! 最佳答案 简单的回答:不。不适用于特定窗口。 复杂的答案
我需要打开一个从同一个类实例化的对话框两次。当我尝试这个时 CdelmeDlg dlg; dlg.DoModal(); dlg.DoModal(); 第二个调用只打开对话框一瞬间,然后关闭。我敢打赌消
如何通过代码在 mfc 中减少标题栏的窗口? 最佳答案 用: ModifyStyle (WS_CAPTION, 0); // to hide ModifyStyle (0, WS_CAPTION);
我使用 AfxMessageBox 关键字显示消息框。基本的东西。 但是,由于路径的长度,它显示如下: 有什么方法可以阻止它以这种方式自动换行吗? 抱歉,如果这是一个愚蠢的问题。但如果我只有一个句子,
所以,我有一个 MFC 程序的插件。我正在使用鼠标事件 Hook (来自 SetWindowsHookEx)来捕获点击。主机应用程序可以打开任意数量的(可能重叠的)子窗口,但我只想拦截特定子窗口中的点
我正在尝试将图像添加到现有按钮..我在一定程度上做到了这一点,问题是我可以添加一个所有者绘制的图像,但无法添加我想要的确切图像..示例见下文代码 CButton* pBtn= (CButton*)Ge
我想在对话框的标题栏上放置一些控件。一种可能的解决方案是,我只是从对话框中删除标题栏并绘制自己的标题栏。 但是如果我自己画标题栏,标题栏的外观不会根据窗口的主题而改变。而且我也不得不忍受接近、最小化和
我已经使用 MinGW 开发了 WinAPI 应用程序,没有问题。现在,我可以用 MFC 做同样的事情吗? 最佳答案 你不能。 MFC 代表 Microsoft Foundation Classes,
(我正在使用VS ++ 2005) 我在对话框上放置了编辑框控件(ID为ID_edit_box),并为其关联了两个变量(使用处理程序向导):控件(c_editbox)和值(v_editbox)变量。我
我有一个自定义 MFC 对话框 CMyDialog,使用资源编辑器添加了一个类型为 CMyControl 的自定义控件 - 该对话框有一个控件的成员变量并且有 DDX设置。 该控件正在接收绘制消息,并
直到现在,我从未真正需要我正在开发的大型 MFC(如果重要,则为单文档界面)应用程序的 Winapp ExitInstance()。但现在我这样做了,主要是为了清理内存分配、卸载一些 DLL 等。好吧
我是一名优秀的程序员,十分优秀!