dhq_boiler
@dhq_boiler

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

PostMessageで別のウィンドウにWM_MOUSEMOVEを送りたい

解決したいこと

WinDesktopAppOnCloudというプロジェクトで、ブラウザ上で.NET デスクトップアプリ(WPFやWin Forms)をデバッグするシステムを開発しようとしています。正直言って実現できるかどうかわかりませんが、挑戦してみるつもりです。

発生している問題・エラー

前回の質問でAjaxによるimg要素の部分更新はできるようになりました。
しかし、画像上でマウスを動かしても、デバッグしているアプリにはマウスを動かしたという情報、すなわちWM_MOUSEMOVEメッセージが届いていないようで、画像は更新されているものの変化がないので更新されているように見えません。SendMessageやPostMessageで上手くデバッグしているアプリにWM_MOUSEMOVEメッセージを伝える必要があります。

どのようにすればデバッグしているアプリにWM_MOUSEMOVEメッセージを伝えることができますか?

Index.cshtml.cs
        public IActionResult OnPostMouseMove(int x, int y)
        {
            StartDesktopAppProcess();

            if (_process == null)
            {
                _process = Process.GetProcessesByName("boilersGraphics").First();
            }
            var point = new Point(x, y);
            //PostMessageでマウスポインタが移動したことをDesktopApp側に伝える
            Trace.WriteLine($"PostMessage hWnd={_process.MainWindowHandle}, Msg={WM_MOUSEMOVE}, wParam={0x0}, lParam={point}");
            PostMessage(_process.MainWindowHandle, WM_MOUSEMOVE, 0, new POINT() { x = (short)point.X, y = (short)point.Y });
            ShowIfError();

            PrintScreen();
            var data = new Dictionary<string, string>() { { "src", ViewData["ImgSrc"].ToString() } };
            return new JsonResult(data);
        }
        :
        public struct POINT
        {
            public short x;
            public short y;
        };

        //送信するためのメソッド(文字も可能)
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true )]
        public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern int SendMessage(IntPtr hWnd, int mssg, int wParam, POINT lParam);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern int SendMessage(IntPtr hWnd, int mssg, int wParam, int lParam);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern int PostMessage(IntPtr hWnd, int mssg, int wParam, POINT lParam);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern int PostMessage(IntPtr hWnd, int mssg, int wParam, int lParam);

        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern bool PostMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        public const int WM_MOUSEMOVE = 0x0200;
        public const int WM_LBUTTONDOWN = 0x201;
        public const int WM_LBUTTONUP = 0x202;
        public const int MK_LBUTTON = 0x0001;
        public const int WM_MOUSEHOVER = 0x02A1;

該当するソースコード

注意

当プロジェクトは現状デバッグ対象のアプリとして、boiler's Graphicsのバイナリに依存しており、boiler's Graphicsをビルドしておかないと上手く実行されません。
お手数ですが以下からコードをクローンすることをお試し下さい。

よろしくお願いいたします。

自分で試したこと

PostMessage(_process.MainWindowHandle, WM_MOUSEMOVE, 0, new POINT() { x = (short)point.X, y = (short)point.Y });
ShowIfError();

上記コードを実行して得られるログは以下になります。Javascriptのログを含まれていますが気にしないで下さい。
PostMessageの実行は正しく終了しているようなんですよね。何故だー???


outputSetPoint success

PostMessage hWnd=395444, Msg=512, wParam=0, lParam=(477, 202)
WinDesktopAppOnCloud.Pages.IndexModel: Information: この操作を正しく終了しました。


rendered
output
SetPoint success
PostMessage hWnd=395444, Msg=512, wParam=0, lParam=(480, 178)
WinDesktopAppOnCloud.Pages.IndexModel: Information: この操作を正しく終了しました。

rendered

outputSetPoint success

PostMessage hWnd=395444, Msg=512, wParam=0, lParam=(486, 148)
WinDesktopAppOnCloud.Pages.IndexModel: Information: この操作を正しく終了しました。

rendered

outputSetPoint success

PostMessage hWnd=395444, Msg=512, wParam=0, lParam=(500, 106)
WinDesktopAppOnCloud.Pages.IndexModel: Information: この操作を正しく終了しました。

rendered

outputSetPoint success

PostMessage hWnd=395444, Msg=512, wParam=0, lParam=(522, 61)
WinDesktopAppOnCloud.Pages.IndexModel: Information: この操作を正しく終了しました。

rendered

outputSetPoint success

PostMessage hWnd=395444, Msg=512, wParam=0, lParam=(550, 21)
WinDesktopAppOnCloud.Pages.IndexModel: Information: この操作を正しく終了しました。

rendered



outputSetPoint success

PostMessage hWnd=395444, Msg=512, wParam=0, lParam=(671, 0)
WinDesktopAppOnCloud.Pages.IndexModel: Information: この操作を正しく終了しました。

rendered
outputSetPoint success


PostMessage hWnd=395444, Msg=512, wParam=0, lParam=(629, 70)
WinDesktopAppOnCloud.Pages.IndexModel: Information: この操作を正しく終了しました。

rendered

outputSetPoint success

PostMessage hWnd=395444, Msg=512, wParam=0, lParam=(585, 163)
WinDesktopAppOnCloud.Pages.IndexModel: Information: この操作を正しく終了しました。

rendered

outputSetPoint success

PostMessage hWnd=395444, Msg=512, wParam=0, lParam=(520, 280)
WinDesktopAppOnCloud.Pages.IndexModel: Information: この操作を正しく終了しました。

rendered

outputSetPoint success

PostMessage hWnd=395444, Msg=512, wParam=0, lParam=(428, 416)
WinDesktopAppOnCloud.Pages.IndexModel: Information: この操作を正しく終了しました。

rendered

outputSetPoint success

PostMessage hWnd=395444, Msg=512, wParam=0, lParam=(375, 471)
WinDesktopAppOnCloud.Pages.IndexModel: Information: この操作を正しく終了しました。

rendered



outputSetPoint success

PostMessage hWnd=395444, Msg=512, wParam=0, lParam=(100, 613)
WinDesktopAppOnCloud.Pages.IndexModel: Information: この操作を正しく終了しました。

rendered
0

3Answer

以下の画像はデバッグ対象のウィンドウ上をMouseMoveした時のSpy++のログです。
MouseMoveOnDebuggingWindow.png

以下の画像はブラウザで表示しているウィンドウの画像上をMouseMoveした時のSpy++のログです。
MouseMoveOnWinDesktopAppOnCloud.png

WM_MOUSEMOVEメッセージは届いているようなんですが、デバッグ対象のウィンドウのマウスカーソル座標の値(画像左下の座標値)が更新されないのは何故でしょう...???

コードは下記のようになっています。(一部抜粋)

Index.cshtml.cs
        public IActionResult OnPostMouseMove(int x, int y)
        {
            StartDesktopAppProcess();

            if (_process == null)
            {
                _process = Process.GetProcessesByName("boilersGraphics").First();
            }
            var point = new Point(x, y);

            SendMessage(_process.MainWindowHandle, WM_NCHITTEST, 0, PointToParam(point));
            ShowIfError();
            SendMessage(_process.MainWindowHandle, WM_SETCURSOR, _process.MainWindowHandle, new IntPtr(WM_MOUSEMOVE << 16 | HTCLIENT));
            ShowIfError();
            PostMessage(_process.MainWindowHandle, WM_MOUSEMOVE, IntPtr.Zero, new IntPtr(PointToParam(point)));
            ShowIfError();

            PrintScreen();
            var data = new Dictionary<string, string>() { { "src", ViewData["ImgSrc"].ToString() } };
            return new JsonResult(data);
        }
0Like

mousemove_bug.gif

ウィンドウ画像上でマウスを動かしても反応がありません。何故WM_MOUSEMOVEメッセージは正しく認識されないのでしょうか?

0Like

WPFアプリはコントロールがウィンドウハンドルを持っていなかったり、従来のウィンドウアプリと色々構造が異なるので、ウィンドウメッセージ送信で制御しようとしても上手くいかないのでは。
SendInputでマウス操作そのものを送りつけてみましょう。

0Like

Your answer might help someone💌