1

私はこの質問とまったく同じ状況を扱っています。

回答がなく、質問が古すぎたため、OPが解決策を見つけたかどうかを確認するためのコメントを残すことができませんでした。

私はちょうど今p/invokeの基本を学んでいて、少なくともそれをほとんど理解していません。

私はかなりの検索を行ってきました。この質問/回答にリンクしているこの質問を見つけましたが、それでも私が何をする必要があるのか​​理解できません。

WM_IMEコマンドを操作する方法、または少なくともマウスクリックでWM_IME_ENDCOMPOSITIONを無効にする方法を求めていると思います。

前もって感謝します

4

2 に答える 2

1

IME の専門家ではありませんが、「WndProc」をオーバーライドするだけで「メッセージ」を渡せませんでしたか?他のアプリケーション/コントロールが処理を妨げていたからです。WndProc は、オペレーティング システムによって生成される何百もの 'Windows メッセージ' をキャプチャします。これは、リッスンしている '誰でも' キャプチャすることができます。1 つのアプローチは、条件が正しいときにそのメッセージを選択的に無視することです...

protected override void WndProc(ref Message m)
  {
    switch(m.Msg)
    {
      case WM_IME_ENDCOMPOSITION :
        // Gobble this up or ignore
        break;
      default:
        // Continue as normal
        base.WndProc (ref m);
        break;
    }
  }

たとえば、コントロールを扱っている場合は、コントロールの WndProc をオーバーライドし、マウス ダウン イベント (または WM_MOUSEDOWN) をキャプチャし、変数を設定して WM_IME_ENDCOMPOSITION を無視し、マウス アップ (または WM_MOUSEUP) でその変数を再度有効にすることができます。 )? または、 MouseHookを利用することもできますが、これは少しやり過ぎかもしれません...

于 2012-02-21T16:20:35.683 に答える
0

WM_IME_ENDCOMPOSITION が明らかに起動していなかったため、代わりに mouseactivate winproc を無効にしてみました。

        private const int WM_MOUSEACTIVATE = 0x0021;
        private const int MA_NOACTIVATEANDEAT = 0x0004;

        protected override void WndProc(ref Message m)
        {
            if (mousestatus == 0)
            {
                if (m.Msg == WM_MOUSEACTIVATE)
                {
                    m.Result = (IntPtr)MA_NOACTIVATEANDEAT;
                    return;
                }
                base.WndProc(ref m);
            }
        }

次に、すべてのパネルクリックイベントハンドラーをマウスオーバーイベントに変更しました。クリックする必要のあるアプリケーションの部分があったため、mousestatus 変数を追加して、mousestatus が 0 の場合にのみマウス クリックが無効になるようにしました。これはマウスの位置によって定義されていました (マウスクリックが無効になっているため、何もクリックして有効にすることはできません)。

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

    private void timer1_Tick(object sender, EventArgs e)
    {
        if ((Cursor.Position.X - Location.X) >= 904 && (Cursor.Position.X - Location.X) <= 963 && (Cursor.Position.Y - Location.Y) >= 145 && (Cursor.Position.Y - Location.Y) <= 167)
        {
            mousestatus = 1;

            mouse_event(MOUSEEVENTF_LEFTDOWN, Cursor.Position.X, Cursor.Position.Y, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTUP, Cursor.Position.X, Cursor.Position.Y, 0, 0);


            timer4.Start();

        }
    }

mousestatus=1 が定義される前にクリックが発生すると確信していたので、必要な場所がクリックされたことを確認するために、仮想マウス クリックを設定しました。timer4 は、mousestatus を 0 に戻す単なるタイマーでした。

コードは少し乱雑かもしれません。使用できるショートカットがいくつかあると確信していますが、今のところ、必要なもので機能します。=D

于 2012-02-22T16:24:46.507 に答える