[PPWI06726] Windows Vista 環境で[F10]キーを押下してもFunctionKeyDown イベントが発生しない

文書番号 : 25584     文書種別 : 制限事項     最終更新日 : 2008/03/27
文書を印刷する
対象製品
PlusPak for Windows Forms 5.0J
発生環境
Windows Vista
詳細
この問題はGcFunctionKeyコントロールで発生します。
Windows Vista上で、F10キーを押下した場合FunctionKeyDownイベントが発生しません。

この問題の原因は、ユーザーがF10キーを押下したとき、GcFunctionKeyコントロールがそのメッセージを受け取る前に、IMEがメッセージをフックしてしまいます。そのため、メッセージがGcFunctionKeyコントロールまで届かず、F10キー押下しても FunctionKeyDownイベントが発生しない問題が発生します。
回避方法
この現象を回避するには、FormのProcessKeyPreview メソッドをオーバーライドする方法が考えられます。

以下の例はFunctionKeyDownイベントのハンドルに加えてFormのProcessKeyPreviewをオーバーライドした実装例です。

[VB]
Public Class Form1
  ' F10キーが処理されたかどうかのフラグを設定します。
  Private isF10_Processed As Boolean = False

  Protected Overrides Function ProcessKeyPreview(ByRef m As Message) As Boolean

    If m.WParam = Keys.F10 Then
      ' F10が処理されていない場合、処理を実行します。
      If Not Me.isF10_Processed Then
        If m.Msg = 261 Then   ' "261"は"WM_SYSKEYUP"を表します。
          ' カスタマ処理を実行します。
          ProcessCustomLogic(m.WParam)
        End If
      End If
    End If

    ' フラグを常にクリアします。
    Me.isF10_Processed = False
    Return MyBase.ProcessKeyPreview(m)
  End Function

  Private Sub ProcessCustomLogic(ByVal key As Keys)
    ' カスタマ処理を実装します。
    MessageBox.Show(key.ToString() + " が押されました")
  End Sub

  Private Sub GcFunctionKey1_FunctionKeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles GcFunctionKey1.FunctionKeyDown
    If (e.KeyData = Keys.F10) Then
      Me.isF10_Processed = True
    End If

    ' カスタマ処理を実行します。
    Me.ProcessCustomLogic(e.KeyData)
  End Sub
End Class


[C#]
namespace Workaround
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }
    // F10キーが処理されたかどうかのフラグを設定します。
    bool isF10_Processed = false;

    // ProcessKeyPreviewメソッドをオーバーライドします。
    protected override bool ProcessKeyPreview(ref Message m)
    {
      if (m.WParam == (IntPtr)(Keys.F10))
      {
        // F10が処理されていない場合、処理を実行します。
        if (!isF10_Processed)
        {
          if (m.Msg == 0x105)   // "0x105"は"WM_SYSKEYUP"を表します。
          {
            // カスタマ処理を実行します。
            ProcessCustomLogic ((Keys)m.WParam);
          }
        }
      }

      // フラグを常にクリアします。
      isF10_Processed = false ;

      return base.ProcessKeyPreview(ref m);
    }

    private void GcFunctionKey1_FunctionKeyDown(object sender, KeyEventArgs e)
    {
      if (e.KeyData == Keys.F10)
      {
        // F10が処理されたことを記録します。
        isF10_Processed = true;
      }

      // カスタマ処理を実行します。
      ProcessCustomLogic(e.KeyData);
    }

    private void ProcessCustomLogic(Keys key)
    {
      // カスタマ処理を実装します。
      MessageBox.Show(key.ToString () + " が押されました");
    }
  }
}

この文書は、以前は次のFAQ IDで公開されていました : 7428