gpt4 book ai didi

c++ - 将 WM_MOUSEWHEEL Delphi 代码转换为 C++ Builder

转载 作者:太空宇宙 更新时间:2023-11-04 14:04:43 28 4
gpt4 key购买 nike

我有这些代码链接:

WMMouseWheel not working in Delphi

How to disable MouseWheel if mouse is not over VirtualTreeView (TVirtualStringTree)

将它翻译成 C++ Builder 但它不起作用:

更新:缩小问题范围后,WM_MOUSEWHEEL 消息似乎仅在未聚焦的 TVirtualStringTree 控件上不起作用,它们在其他控件上起作用。当焦点在例如TMemo 控件,其他TMemo 控件在滚轮上滚动但不是TVirtualStringTree 控件。当焦点在 TVirtualStringTree 上时,它会滚动 TVirtualStringTree 但不会滚动其他控件。所以问题现在只针对 TVirtualStringTree

void __fastcall TForm1::ApplicationEventsMessage(tagMSG &Msg, bool &Handled)
{
TPoint Pt;
HWND Wnd;

if (Msg.message == WM_MOUSEWHEEL ||
Msg.message == WM_VSCROLL ||
Msg.message == WM_HSCROLL)
{
if (GetCursorPos(&Pt))
{
Wnd = WindowFromPoint(Pt);
// It must be a VCL control otherwise we could get access violations
if (IsWindowEnabled(Wnd) && FindControl(Wnd) != NULL)
{
Msg.hwnd = Wnd; // change the message receiver to the control under the cursor
}
}
}
}

类似代码的不同版本,同样不起作用:

TPoint       pnt;
TWinControl *ctrl;

if ((Msg.message == WM_MOUSEWHEEL ||
Msg.message == WM_VSCROLL ||
Msg.message == WM_HSCROLL) &&
GetCursorPos(&pnt))
{
ctrl = FindVCLWindow(pnt);
if (ctrl != NULL)
{
SendMessage(ctrl->Handle, Msg.message, Msg.wParam, Msg.lParam); // No effect
// SendMessage(ctrl->Handle, WM_VSCROLL, 1, 0); // This is the only thing that actually moves scrollbars but this is not exactly the same message like above

// Msg.hwnd = ctrl->Handle; // No effect
this->Caption=ctrl->Name; // This shows correct control name so the message IS GETTING THROUGH!
Handled = true;
}
}

它应该可以工作,但实际上没有。也尝试了其他代码。无效果 - 鼠标滚轮不会在未聚焦的控件上运行。如您所见,我检查了滚轮消息的所有 3 种变体,它在鼠标下获得了正确的控制,它显示了控件名称,但控件没有接收到滚轮消息。

想知道我缺少哪一 block 拼图才能让它发挥作用吗?

最佳答案

由于没有人提供任何合适的解决方案,因此我发布了自己的解决方案。该解决方案并不完美,但至少它完成了它需要做的事情——鼠标滚轮滚动它下面的所有控件,包括 VirtualTreeView 控件。解决方案中的代码是C++的,但Delphi版本非常相似(只需要翻译)。

我目前的解决方案是抓取 WM_MOUSEWHEEL 事件并将它们转换为 WM_VSCROLLWM_HSCROLLVirtualTreeView 对其作出 react 并滚动内容。此外,它需要考虑高精度鼠标滚轮,其值可能小于 WHEEL_DELTA(设置为 120)。最后,它需要考虑用户对滚动行数的设置(在 Windows 的控制面板中设置)。所以这里是:

TApplicationEvents 放入表单并在 OnMessage 事件中执行此操作:

void __fastcall TFormMain::ApplicationEventsMessage(tagMSG &Msg, bool &Handled)
{
// Check these 3 messages because some mouse drivers may use VSCROLL instead of MOUSESWHEEL message
if (Msg.message == WM_MOUSEWHEEL || Msg.message == WM_VSCROLL || Msg.message == WM_HSCROLL)
{
TPoint pnt;
TWinControl *ctrl;

if (!GetCursorPos(&pnt)) return;

ctrl = FindVCLWindow(pnt);

if (ctrl != NULL)
{
// ToDo: implement if user needs wheel-click - then we also need KEYSTATE but for this example it is not needed
// int fwKeys = GET_KEYSTATE_WPARAM(Msg.wParam);
int zDelta = GET_WHEEL_DELTA_WPARAM(Msg.wParam),
pvParam = 3; // Windows default value
unsigned MyMsg = WM_VSCROLL;


// ToDo: extract SystemParametersInfo somewhere else so it is not extracted for each WM_MOUSEWHEEL message which may not be needed
switch (Msg.message)
{
// This will translate WM_MOUSEWHEEL into WM_VSCROLL
case WM_MOUSEWHEEL:
case WM_VSCROLL:
// Windows setting which determines how many lines to scroll - we'll send that many WM_VSCROLL or WM_HSCROLL messages
SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &pvParam, 0);
MyMsg = WM_VSCROLL;
break;
case WM_HSCROLL:
// Same as above but for WM_HSCROLL (horizontal wheel)
SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &pvParam, 0);
MyMsg = WM_HSCROLL;
break;
}

// This calculation takes into account high-precision wheels with delta smaller than 120
// Possible TODO: Round up values smaller than 1 (e.g. 0.75 * pvParam) if pvParam is 1
int ScrollBy = ((double)zDelta / (double)WHEEL_DELTA) * pvParam;

// Send multiple messages based on how much the zDelta value was
if (zDelta > 0)
{
do
{
SendMessage(ctrl->Handle, MyMsg, SB_LINEUP, 0);
}
while (--ScrollBy > 0);
}
else
{
do
{
SendMessage(ctrl->Handle, MyMsg, SB_LINEDOWN, 0);
}
while (++ScrollBy < 0);
}

Handled = true;
}
}
}

关于c++ - 将 WM_MOUSEWHEEL Delphi 代码转换为 C++ Builder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17575200/

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