-1

I have a System.Windows.Forms.PictureBox inside System.Windows.Forms.Panel. The Panel has:

  1. fixed dimensions
  2. AutoScroll=true
  3. event handler is subscribed to MouseWheel which is used to zoom-in or zoom-out

On zoom-in/zoom-out I change the dims of the PictureBox and if it exceeds the Panel dimenstions the vertical and/or horizontal scrolls are shown since AutoScroll=true.

Now, on Windows 7 (I have Enterprise edition), once any or both scrollers appear and I continue zooming in with the mouse wheel, the subscribed event handler to MouseWheel continue to be called and the image gets bigger.
But, on Windows 10 (I have Home edition), if any of the scrollers appear, the event handler stopps to be called and the scrollers take over. Meaning the image is scrolled up/down or left/right.

theateist
  • 13,879
  • 17
  • 69
  • 109
  • Always give us the code. – LarsTech Jul 22 '19 at 23:03
  • I cannot share the code since it from work. I tracked down to the component that is being zoomed and inside what control it resides. I'm just confused what can be the reason that same event works differently on win10. – theateist Jul 22 '19 at 23:06
  • 2
    Then open a new project and recreate the same situation. If you can't recreate it there, then you have something else going on that we still can't see. – LarsTech Jul 22 '19 at 23:09
  • I understand that! I just wanted to check if anyone encountered with something similar before I'm diving in deeper. That's all. After all, if someone can tell "yes, I had same thing in Win10. You need to enabel/disable such and such..." it will save me a lot of time. After all, this is why forums like this one exist. – theateist Jul 22 '19 at 23:12
  • 1
    Still best to simplify it to a #mcve - for your own sake as well as the sake of the few dozen or so people that will click on this thinking "I might be able to help if s/he's got a repro ready to go". Moreover, by putting together a minimal example you'll pick up the issue yourself 80% of the time (then you can post a self-answered Q&A), or you'll find a bug which you can then easily send off a good bug report for. The remainder of the time people like me are willing to help! For now, though, I'm on my way... – pcdev Jul 22 '19 at 23:23
  • What's #mcve? In any case, that's what I planned to do next any way. Just, like I said, I hoped that some one has already encountered with similar issues in Windows10 and can contribute. – theateist Jul 22 '19 at 23:26
  • 1
    Google it. It's the first hit. – LarsTech Jul 22 '19 at 23:27
  • 2
    Win10 has the mouse setting "Scroll inactive windows when I hover over them" that if I remember correctly did not show up until Win 8. That may be part of the problem. Whose `MouseWheel` event are you subscribing to (Panel or PictureBox)? This event bubbles up to the control's container, but this can be prevented by casting the event argument to [HandledMouseEventArgs](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.handledmouseeventargs?view=netframework-4.8) and setting the `Handled` property to true. – TnTinMn Jul 23 '19 at 00:59
  • @TnTinMn That's one for sure. Both PictureBox and Panel are not selectable on their own. When a Panel is used this way, it's probably better to use a custom one with `ControlStyles.Selectable` set on the costructor. At some point, the PictureBox will fill the Panel's surface completly, here. Also, Windows 10 and Windows 7 have a different behaviour when detecting which control should handle scroll events (Windows 10 is more *WebBrowser style*). This is not exactly new. – Jimi Jul 23 '19 at 01:16
  • It could also be tested using [RegisterTouchWindow](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registertouchwindow) / [CloseTouchInputHandle](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-closetouchinputhandle). – Jimi Jul 23 '19 at 01:22
  • @Jimi, are the `Touh` events for touch screens? – theateist Jul 23 '19 at 01:35
  • You might also want to confirm that the observed behavior on other computers… While Windows 10 does have an option to enable/disable scrolling on inactive windows, your apps should works either way. Or you can as many program and require **Ctrl** key for zooming and avoid the problem (and make your application simpler to learn as it follows the standard) – Phil1970 Jul 23 '19 at 01:50
  • They are. Is you app meant to work just on non-touch screens? But WM_GESTURE messages are translated in a funny way. See also [Legacy Support for Panning with Scroll Bars](https://learn.microsoft.com/en-us/windows/win32/wintouch/legacy-support-for-panning-with-scrollbars) – Jimi Jul 23 '19 at 01:53
  • @TnTinMn, you're the best. Indeed, if I disable "Scroll inactive windows when I hover over them" in Win10 that it works as in Win7. Thank you so much. You saved me a lot of time. Put your comment as an answer so I'll be able to accept it! – theateist Jul 23 '19 at 19:34

1 Answers1

0

The OP has confirmed in the comments that disabling the Win10 mouse setting "Scroll inactive windows when I hover over them" resolves the issue, however I believe that this can also be handled by preventing the MouseWheel event from bubbling up to the containing Panel control. Asking users to change their preferred settings to make your code function is never a desirable situation.

The following code demonstrates preventing this event bubbling. Just create a new Winform project and replace the Form1 code with this. The code creates a TextBox, and a PictureBox contained in a Panel. The purpose of the TextBox is to just to show its loss of focus when you click on the PictureBox. For Win7, click on the PictureBox to activate it and then use the mousewheel to increase/decrease the PictureBox size.

public partial class Form1 : Form
{
    PictureBox pictureBox1;
    Panel panel1;

    public Form1()
    {
        InitializeComponent();
        Size = new Size(500, 500);
        Controls.Add(new TextBox() { TabIndex = 0, Location = new Point(350, 5)});
        panel1 = new Panel() {Size = new Size(300, 300), Location = new Point(5, 5), BorderStyle = BorderStyle.FixedSingle,Parent = this, AutoScroll = true};
        pictureBox1 = new PictureBox() {Size = new Size(200, 200) , Location = new Point(5,5), BorderStyle = BorderStyle.FixedSingle, Parent = panel1};
        pictureBox1.Click += pictureBox1_Click;
        pictureBox1.MouseWheel += pictureBox1_MouseWheel;
        panel1.MouseWheel += panel1_MouseWheel;
    }

    private void pictureBox1_Click(object sender, EventArgs e)
    {
        // On Win10 with "Scroll inactive windows when I hover over them" turned on,
        // this would not be needed for pictureBox1 to receive MouseWheel events

        pictureBox1.Select(); // activate the control
        // this makes pictureBox1 the form's ActiveControl
        // you could also use: 
        //   this.ActiveControl = pictureBox1;
    }

    private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
    {
        Rectangle r = pictureBox1.Bounds;
        int sizeStep = Math.Sign(e.Delta) * 10;
        r.Inflate(sizeStep, sizeStep);
        r.Location = pictureBox1.Location;
        pictureBox1.Bounds = r;

        // e is an instance of HandledMouseEventArgs
        HandledMouseEventArgs hme = (HandledMouseEventArgs)e;
        // setting to true prevents the bubbling of the event to the containing control (panel1)
        hme.Handled = true;
        // comment out the above line to observe panel1_MouseWheel
        // being called
    }


    private void panel1_MouseWheel(object sender, MouseEventArgs e)
    {
        System.Diagnostics.Debug.Print("bubbled wheel event");
    }
}

reference: HandledMouseEventArgs Class

TnTinMn
  • 11,522
  • 3
  • 18
  • 39
  • I'm aware that it's not an ideal resolution, but in this case it's for internal usage. The users get the hardware and software the way we configure. So, no one is going to ask users to change anything. – theateist Jul 23 '19 at 21:18