none
他アプリのスクロールを制御したい RRS feed

  • 質問

  • 初めて投稿させていただきます。ご教授のほどお願いいたします。

    VS Express 2013、C#にてマウスジェスチャー機能を実現したいと考えています。

    マウスのイベントはキャッチできるようになりました。

    そこから他のウインドウやブラウザのスクロールを動かしたいのですが

    とっかかりが分からず難航しています。

    1. 自アプリ→他アプリにマウスイベントを送信させる

    2. マウスイベントはキャッチしたたまでたとえばAlt+Tabのように他アプリにフォーカスを切り替える

    のアプローチがあるかと考えていますが、API名などヒントをご教授いただけないでしょうか?

    何卒よろしくお願いいたします。(すでに重複ございましたら、それもご教授いただけると幸いです)

    2015年7月30日 8:13

回答

  • 返事が遅くなり申し訳ありません。情報をありがとうございます。

    >作成されているアプリでは、自アプリをアクティブにしておく必要があるのでしょうか。

    ご指摘のとおり必要はありません。

    自アプリを起動またはマウスでフォーカスを当てるとアクティブになるしかないと思い込んでおりました。。。

    >あるいは別案として、自アプリを「アクティブにならないウィンドウ」にしてしまうとか。

    >p.ExStyle = p.ExStyle | (WS_EX_NOACTIVATE);

    により、自アプリを非アクティブのままにできることを確認できました。その後、GetForegroundWindowにて

    期待通りのウインドウのハンドルを得ることができました!

    大変ありがとうございます。

    • 回答としてマーク T.yamada 2015年8月5日 15:35
    2015年7月31日 16:34

すべての返信

  • こんにちは。

    「マウスジェスチャー機能」を私が理解出来ているか怪しいですが。

    やりたいことは他アプリにホイールメッセージを投げてやれば解決しますか?
    フォーカスとか他の問題があるかもしれませんが…とりあえず方向性として。

    public partial class Form1 : Form
    {
    
        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        public static extern Int32 FindWindow(String lpClassName, String lpWindowName);
    
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        public static extern Int32 SendMessage(int hWnd, int Msg, int wParam, int lParam);
    
        public Form1()
        {
            InitializeComponent();
    
            //他アプリ
            hoka = FindWindow(null, "Hoge1");
        }
    
        private int hoka;
        private int WHEEL = 0x20A;
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WHEEL)
            {
                //他アプリにホイールメッセージなげる
                SendMessage(hoka, m.Msg, m.WParam.ToInt32(), m.LParam.ToInt32());
            }
            base.WndProc(ref m);
        }
    }
    

    2015年7月30日 9:10
    モデレータ
  • ご教授ありがとうございます。サンプルまでいただいてうれしいです。

    >やりたいことは他アプリにホイールメッセージを投げてやれば解決しますか?

    はい。合っております。

    >hoka = FindWindow(null, "Hoge1");

    このAPIで動作させたいウインドウを探せばよいと理解いたしました。

    まだ勉強段階ですが、これは事前にウインドウ名かクラス名を特定させる必要があると考えています。

    自アプリの直前までに動いていたウインドウ名を探し出す方法はありますでしょうか?

    GetForegroundWindowかな、と思ったのですがこれだと自身のウインドウハンドル

    を返されそうな気がします。

    ウインドウの名前で検索することも考えましたが、これだと複数起動されていると都合が

    悪くなってしまいます。

    追加質問となり恐縮ですがご教授いただけると幸いです。

    2015年7月30日 11:40
  • 直前にアクティブだったウインドウの取得する方法は聞いたことがありません。
    この辺りはAPIの深いところで私の知識が及ばなく申し訳ありませんが、
    調べてみたところ以下のスレッドが問題解決の切り口になるかもしれません。

    少し見てみてください。

    https://social.msdn.microsoft.com/forums/vstudio/ja-JP/1c755a62-7619-46ea-80cc-010b754b4dad/window

    2015年7月30日 12:08
    モデレータ
  • 拝見させていただきました。

    CBTフックというのが使えそうですね。

    あとは自分を非アクティブにさせたら都合よく直前のウインドウがアクティブにならないかな、

    というのを試してみます。

    丁寧なご解説ありがとうございました。もう少し頑張ってみます。

    2015年7月30日 14:12
  • GetForegroundWindowかな、と思ったのですがこれだと自身のウインドウハンドル
    を返されそうな気がします。

    作成されているアプリでは、自アプリをアクティブにしておく必要があるのでしょうか。他アプリに対するジェスチャー操作ということだったので、他アプリがアクティブな状態で使いたいのだと読み取ったのですが…。

    もし、自アプリをアクティブにしなくても構わないのであれば、DirectX を使うのは如何でしょう。バックグラウンド協調レベルを用いれば、自アプリがフォアグラウンドに無い時でも、マウスやキーボードの操作を自アプリで検知できますので、そこから GetForegroundWindow API なり WindowFromPoint API なりを用いて、操作対象のウィンドウハンドルを特定するとか。

    あるいは別案として、自アプリを「アクティブにならないウィンドウ」にしてしまうとか。

    http://mist-elisha.hatenablog.com/entry/2014/07/10/213808
    http://bbs.wankuma.com/index.cgi?mode=al2&namber=72850&KLOG=122




    2015年7月31日 1:31
  • 返事が遅くなり申し訳ありません。情報をありがとうございます。

    >作成されているアプリでは、自アプリをアクティブにしておく必要があるのでしょうか。

    ご指摘のとおり必要はありません。

    自アプリを起動またはマウスでフォーカスを当てるとアクティブになるしかないと思い込んでおりました。。。

    >あるいは別案として、自アプリを「アクティブにならないウィンドウ」にしてしまうとか。

    >p.ExStyle = p.ExStyle | (WS_EX_NOACTIVATE);

    により、自アプリを非アクティブのままにできることを確認できました。その後、GetForegroundWindowにて

    期待通りのウインドウのハンドルを得ることができました!

    大変ありがとうございます。

    • 回答としてマーク T.yamada 2015年8月5日 15:35
    2015年7月31日 16:34