6

我想将鼠标悬停在图片框(或所有图片和主窗体)上并使用鼠标滚轮滚动。但是我没有运气。我写了 pictureBox1.MouseWheel 并检查了增量。我为它设置了一个断点!= 0。到目前为止,无论我做什么,我都无法发生任何事情。我也试过mousemove,但没有奏效。然而,打破 if 语句是有效的。我永远无法让轮子工作。

如何使图片框(或表单中的任何控件)调用鼠标滚轮事件?

-编辑-没关系。我将事件添加到大多数时间都有事件的对象。它工作得很好。我不知道为什么我在写这个问题之前没有想到这一点。我仍然对鼠标悬停+滚轮解决方案持开放态度。

4

5 回答 5

13

Windows 不会将鼠标滚动消息发送到悬停的控件,它会发送到具有焦点的控件。您已经知道如何固定焦点。

由于浏览器和 Office 程序的工作方式,这种行为变得不直观。你会在我的回答中找到代码来改变这个线程。请注意,它适用于您应用程序中的任何窗口。如果不希望这样做,您将不得不对句柄值添加过滤。


更新:此行为在 Win10 中已更改。它有一个名为“当我将鼠标悬停在非活动窗口上时滚动非活动窗口”的新系统设置,默认情况下是打开的。所以焦点不再重要,它现在的工作方式与它在浏览器中的行为方式非常相似。测试您的应用程序很重要,您可以通过暂时禁用系统选项来查看旧版 Windows 上发生的情况。

于 2010-08-03T20:09:19.753 回答
2

这个答案解释了如何做到这一点。简而言之,在仅聚焦图片框的图片框上创建一个 MouseEnter 事件。然后图片框将接收 MouseWheel 事件就好了。

于 2014-01-23T23:19:12.953 回答
0

这里的答案对我不起作用。我在一个可滚动的窗格中有图片框,为了正确运行,我还需要做更多的工作。

您需要做的是覆盖OnMouseWheel()表单中的函数。在那里你得到了滚轮事件,你必须检查鼠标是否在图片框内。但这还不够。想象一下,您在一个仅显示一小部分图像的可滚动窗格中显示 5000 x 5000 像素的图像。然后您还必须检查鼠标是否在窗格及其所有父项上。下面的代码与pictureBox 的任何父控件的滚动条的滚动位置无关。

/// <summary>
/// This must be overridden in the Form because the pictureBox never receives MouseWheel messages
/// </summary>
protected override void OnMouseWheel(MouseEventArgs e)
{
    // Do not use MouseEventArgs.X, Y because they are relative!
    Point pt_MouseAbs = Control.MousePosition; 
    Control i_Ctrl = pictureBox;
    do
    {
        Rectangle r_Ctrl = i_Ctrl.RectangleToScreen(i_Ctrl.ClientRectangle);
        if (!r_Ctrl.Contains(pt_MouseAbs))
        {
            base.OnMouseWheel(e);
            return; // mouse position is outside the picturebox or it's parents
        }
        i_Ctrl = i_Ctrl.Parent;
    }
    while (i_Ctrl != null && i_Ctrl != this);

    // here you have the mouse position relative to the pictureBox if you need it
    Point pt_MouseRel = pictureBox.PointToClient(pt_MouseAbs);

    // Do your work here
    ....
}
于 2015-05-20T17:45:49.393 回答
0

只需覆盖 Form 的 MouseWheel 并检查 eX 和 eY 是否在 PictureBox 的位置区域内

  protected override void OnMouseWheel(MouseEventArgs e)
    {
        if (e.X >= soundGraph.Location.X && e.X <= soundGraph.Location.X + soundGraph.Width
            &&
            e.Y >= soundGraph.Location.Y && e.Y <= soundGraph.Location.Y + soundGraph.Height)
        { // do what you have to
        }
        base.OnMouseWheel(e);
    }
于 2019-03-09T21:36:28.073 回答
0

This works also if the picturebox is not at the 0,0 position in the form.

' =====================================================================================
'  Windows10 has a new system setting 
'   named "Scroll inactive windows when I hover over them", turned on by default.
' -------------------------------------------------------------------------------------
'  The following correction does the same for Windows 8 / 7 / XP
' =====================================================================================
Protected Overrides Sub OnMouseWheel(ByVal e As MouseEventArgs)
    Dim p As Point
    p = pbox_Graph.PointToClient(Me.PointToScreen(e.Location))
    If pbox_Graph.ClientRectangle.Contains(p) Then
        pbox_TimeGraph_MouseWheel(Me, e)
    Else
        MyBase.OnMouseWheel(e)
    End If
End Sub
于 2020-05-02T09:46:15.163 回答