OSDN Git Service

WM_MOUSEWHEELのwParamが負の値になるとOverflowExceptionが発生する不具合を修正
authorKimura Youichi <kim.upsilon@bucyou.net>
Tue, 22 Sep 2015 10:32:33 +0000 (19:32 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Tue, 22 Sep 2015 10:37:46 +0000 (19:37 +0900)
f63fbac9e93daa4f15a924634b3c9fb464c10491 の修正では lParam が負の値になる場合しか考慮されていないため不十分
https://msdn.microsoft.com/ja-jp/library/windows/desktop/ms645617%28v=vs.85%29.aspx

OpenTween.Tests/MouseWheelMessageFilterTest.cs [new file with mode: 0644]
OpenTween.Tests/OpenTween.Tests.csproj
OpenTween/MouseWheelMessageFilter.cs

diff --git a/OpenTween.Tests/MouseWheelMessageFilterTest.cs b/OpenTween.Tests/MouseWheelMessageFilterTest.cs
new file mode 100644 (file)
index 0000000..3d246ef
--- /dev/null
@@ -0,0 +1,52 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2015 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// All rights reserved.
+//
+// This file is part of OpenTween.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Xunit;
+
+namespace OpenTween
+{
+    public class MouseWheelMessageFilterTest
+    {
+        [Fact]
+        public void ParseMessage_MinusTest()
+        {
+            const int WM_MOUSEWHEEL = 0x020A;
+
+            var message = new Message
+            {
+                Msg = WM_MOUSEWHEEL,
+                LParam = (IntPtr)0xffffffffff29ff22,
+                WParam = (IntPtr)0xffffffffff880000,
+            };
+            var ret = MouseWheelMessageFilter.ParseMessage(message);
+
+            Assert.Equal(-222, ret.ScreenLocation.X); // (short)0xff29
+            Assert.Equal(-215, ret.ScreenLocation.Y); // (short)0xff22
+            Assert.Equal(-120, ret.WheelDelta); // (short)0xff88
+        }
+    }
+}
index bbd4b73..b853f14 100644 (file)
@@ -71,6 +71,7 @@
     <Compile Include="HttpMessageHandlerMock.cs" />
     <Compile Include="MediaSelectorTest.cs" />
     <Compile Include="MemoryImageTest.cs" />
+    <Compile Include="MouseWheelMessageFilterTest.cs" />
     <Compile Include="MyApplicationTest.cs" />
     <Compile Include="OTBaseFormTest.cs" />
     <Compile Include="OTPictureBoxTest.cs" />
index a32295b..9dc2198 100644 (file)
@@ -64,14 +64,13 @@ namespace OpenTween
                     if (control.Focused)
                         return false;
 
-                    var screenLocation = new Point((int)(m.LParam.ToInt64() & 0xffffffff));
+                    var details = ParseMessage(m);
                     var controlRectangle = control.Parent.RectangleToScreen(control.DisplayRectangle);
-                    if (controlRectangle.Contains(screenLocation))
+                    if (controlRectangle.Contains(details.ScreenLocation))
                     {
-                        var clientLocation = control.PointToClient(screenLocation);
-                        var wheelDelta = (int)m.WParam >> 16;
+                        var clientLocation = control.PointToClient(details.ScreenLocation);
 
-                        var ev = new HandledMouseEventArgs(MouseButtons.None, 0, clientLocation.X, clientLocation.Y, wheelDelta);
+                        var ev = new HandledMouseEventArgs(MouseButtons.None, 0, clientLocation.X, clientLocation.Y, details.WheelDelta);
                         this.RaiseMouseWheelEvent(control, ev);
 
                         return true;
@@ -82,6 +81,26 @@ namespace OpenTween
             return false;
         }
 
+        internal class MouseEvent
+        {
+            public Point ScreenLocation { get; }
+            public int WheelDelta { get; }
+
+            public MouseEvent(Point location, int delta)
+            {
+                this.ScreenLocation = location;
+                this.WheelDelta = delta;
+            }
+        }
+
+        internal static MouseEvent ParseMessage(Message m)
+        {
+            var screenLocation = new Point((int)(m.LParam.ToInt64() & 0xffffffff));
+            var wheelDelta = (int)(m.WParam.ToInt64() & 0xffff0000) >> 16;
+
+            return new MouseEvent(screenLocation, wheelDelta);
+        }
+
         public void RaiseMouseWheelEvent(Control control, MouseEventArgs e)
         {
             var method = typeof(Control).GetMethod("OnMouseWheel", BindingFlags.Instance | BindingFlags.NonPublic);