2016-11-11 6 views
0

私は、複数の子フォームを持つグローバルな親フォームを持ち、それらの間を循環するためのショートカットキーの組み合わせを望みます。この論理を親フォームで処理して、子フォームをこれとは独立に保つようにしたいと思います。キープレスの組み合わせを所有者のフォームにトラップする最良の方法は何ですか?

これは明らかに一般的なシナリオです(たとえば、Visual Studioでアクティブな文書を切り替える、ブラウザでアクティブなタブなどを切り替えるなど)、実装することは驚くほど困難です。これまでのところ私が見つけた唯一の方法は、グローバルフックまたはホットキーを使用することです。このアプローチの問題点は、設定がシステム全体に適用されるため、他のアプリケーションが同じホットキーを使用するのを止めることです。

子フォームにフォーカスがあっても、オーナーフォームが特定のキー押下を待ち受ける最良の方法は何ですか?

+0

あなたはすべての子供の 'PreviewKeyDown'イベントをサブスクライブすることができ作成したウィンドウ、またはそれらを処理する共通のビューモデルにトンネルします。 –

+0

ctrl +タブがデフォルトで追加されているはずです。 –

+0

@AbdulRehmanSayed私はMDIフレームワークを使用していません。共通の所有者を持つ子ウィンドウだけです。私はMDIを避けるか、少なくともMDIがどのようにこれを実装しているかを理解することを好むでしょう。 – glopes

答えて

1

[OK]をクリックすると、メッセージフィルタを使用して簡単に行うことができます。 IMessageFilterインターフェイスを使用して、Applicationでグローバルメッセージフィルタを登録することができます。たとえば、

class HotKeyMessageFilter : IMessageFilter 
{ 
    const int WM_KEYDOWN = 0x100; 

    public bool PreFilterMessage(ref Message m) 
    { 
     if (m.Msg == WM_KEYDOWN) 
     { 
      var keyCode = (Keys)m.WParam; 
      if (keyCode == Keys.Tab && Form.ModifierKeys.HasFlag(Keys.Control)) 
      { 
       if (Form.ModifierKeys.HasFlag(Keys.Shift)) CycleActiveForm(-1); 
       else CycleActiveForm(1); 
      } 
     } 

     return false; 
    } 
} 

このメッセージフィルタは特定のキーの組み合わせをリッスンし、開いているすべてのウィンドウ間を移動するために静的メソッドまたはクラスメソッドを呼び出します。メッセージフィルタに引数として渡す特定のウィンドウハンドルは、通常のクラスのように渡すことができます。

あなたは次のように任意の時点でアプリケーションとフィルタを登録することができます。

Application.AddMessageFilter(filter); 

し、次でそれを削除します。

Application.RemoveMessageFilter(filter); 
0

リサイズにMDIフォームを使用している場合は、Ctrlキー + タブショートカットが自動的に変化する窓用に登録されます。他のキーの組み合わせをトラップしようとしている場合は、MDIフォームでKeyPreviewをtrueに設定し、そこでキーを処理してください。

+0

私はMDIフレームワークを直接使用していませんでした。これらのショートカットをどのように実装していますか?それは本当に単なるMDI特有のものですか?または、MdiParentを設定したときにKeyPreviewにフックしていますか? – glopes

関連する問題