gpt4 book ai didi

c++ - MFC CListCtrl 吃鼠标松开事件?

转载 作者:太空宇宙 更新时间:2023-11-04 12:15:50 26 4
gpt4 key购买 nike

似乎 CListCtrl 不会发送鼠标弹起事件,除非双击。

我已经尝试从鼠标按下处理程序发送丢失的消息来补偿,但这会导致其他不良行为。然后我想我可以通过检查状态在鼠标移动处理程序中发送消息更准确一些。然而,这些都是可怕的 hack,除了丑陋之外,它们可能无法在派生控件的所有可能实现中正常工作。

如果有人知道为什么没有收到鼠标松开事件,我会很好奇。更重要的是,如何使用 LVS_OWNERDATA 样式让 CListCtrl 像其他控件一样发送鼠标弹起消息?

编辑:我知道 LVN_BEGINDRAGLVN_BEGINRDRAG 等,但是为了使用这些,我需要阻止 WM_LBUTTONDOWNWM_RBUTTONDOWNWM_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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com