水曜日, 6月 01, 2011

フォームで、まとめてイベントを管理 AddMessageFilter()

Windows フォームで、まとめてイベントを管理したいとします。

その場でテキストエディターを立ち上げて、文字列を編集するときなど、部品全てについてイベント処理しなければなりません。

テキストエディターで編集して、コンポーネントからフォーカスが外れたとき、イベントを管理する必要があります。

これが意外な難関で、WinProcをオーバーライドしても、このメソッドではイベントが処理されません。個々のコンポーネントで処理しなければなりません。

そこで用意されているのが、ApplicationクラスにあるAddMessageFilter()メソッドです。

Application.AddMessageFilter(new MyMessageFilter())

このような形で、MessageFilter派生クラスを指定してやります。

イベント処理は、MessageFilterクラスのPreFilterMessage()メソッドで行います。

ここで、WM_NCLBUTTONDBLCLK 、WM_NCLBUTTONDOWN はタイトルバーでのイベントで、WM_LBUTTONDOWNはクライアントエリアで発生するイベントを指します。

こんな感じです。


       private const int WM_LBUTTONDOWN = 0x201;
       private const int WM_NCLBUTTONDBLCLK = 0x00A3;
       private const int WM_NCLBUTTONDOWN = 0x00A1;

       public bool PreFilterMessage(ref Message msg)
        {
            switch (msg.Msg)
            {
                case WM_NCLBUTTONDBLCLK:
                case WM_NCLBUTTONDOWN:
                case WM_LBUTTONDOWN:
                    {
                        int lparam = (int)msg.LParam;
                        int x = lparam & 0xffff;
                        int y = lparam >> 16;

                        Simulator simulator = (Simulator)sender;
                        Point pos = simulator.RichTextBox1.PointToClient(new Point(x, y));
                        Rectangle rect = new Rectangle(0, 0, simulator.RichTextBox1.Bounds.Width
                            , simulator.RichTextBox1.Bounds.Height + SystemInformation.HorizontalScrollBarThumbWidth);
                        if (!rect.Contains(pos))
                        {
                            simulator.focusOff();
                        }
                    }
                    break;
            }
            return false;
        }

Qt: 外部プログラムを起動する

  Qt/C++ のアプリは、外部へ直接アクセスできます。これはネットアプリでは不可能な Qt のメリットです。 外部プログラムを起動することもできます。QProcess::startDetached() を使うと独立したプロセスを立ち上げることができます。 この QProces...