[F10]キーを押下してもFunctionkeyPress/FunctionKeyDownイベントが発生しない

文書番号 : 29140     文書種別 : 技術情報     最終更新日 : 2010/05/13
文書を印刷する
対象製品
PlusPak for Windows Forms 6.0J
詳細
Windows Vistaや Windows 7上で F10キーを押下した場合、GcClassicFunctionKey、および GcFunctionKeyの FunctionkeyPress/FunctionKeyDownイベントが発生しません。
ユーザーが F10キーを押下したとき、GcClassicFunctionKey/GcFunctionKeyコントロールがそのメッセージを受け取る前に、IMEが半角英数変換しようとしてメッセージをフックしてしまいます。そのため、メッセージが GcClassicFunctionKey/GcFunctionKeyコントロールまで届かず、F10キーを押下しても FunctionkeyPress/FunctionKeyDownイベントが発生しない問題が発生します。

Service Pack 1 では F10キー押下の処理に改善を加えることで、GcClassicFunctionKey、および GcFunctionKeyの FunctionkeyPress/FunctionKeyDownイベントを発生させることが可能になりました。Windows Vistaや Windows 7上でも回避コード等の対応は不要となりました。
最新のService Packは こちら からダウンロードできます。

Service Pack 1 ではなく初版を継続してご利用いただく場合、この現象を回避するために IMessageFilterインターフェイスを実装し、PreFilterMessageメソッドに処理を追加する必要があります。下記のコードを参考に対応を行ってください。

【GcClassicFunctionKeyの場合】
[Visual Basic]
Public Class Form1
  Implements IMessageFilter

  <System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)> _
  Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) _
                   As Boolean Implements IMessageFilter.PreFilterMessage

    Const WM_SYSKEYUP As Integer = 261

    ' F10キーが押下された場合で、F10が処理されていない場合処理を実行します。
    If m.Msg = WM_SYSKEYUP And CType(m.WParam, Keys) = Keys.F10 Then
      If Not isF10_Processed Then
        ProcessCustomLogic(CType(m.WParam, Keys))
      End If
    End If

    ' フラグを常にクリアします。
    isF10_Processed = False
    Return False
  End Function

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

  Private Sub GcClassicFunctionKey1_FunctionKeyPress(ByVal sender As System.Object, ByVal e As GrapeCity.Win.Bars.FunctionKeyPressEventArgs) Handles GcClassicFunctionKey1.FunctionKeyPress
    ' WindowsXPなどでの重複を防止します。
    If (e.Key = GrapeCity.Win.Bars.ButtonKeys.F10) Then
      isF10_Processed = True
    End If

    ' 処理を実行します。
    ProcessCustomLogic(CType(e.Key, Keys))
  End Sub

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

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Application.AddMessageFilter(Me)
  End Sub
End Class

[C#]
using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
  public partial class Form1 : Form, IMessageFilter
  {
    public Form1()
    {
      InitializeComponent();
    }

    [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
    public bool PreFilterMessage(ref System.Windows.Forms.Message m)
    {
      const int WM_SYSKEYUP = 261;

      // F10キーが押下された場合で、F10が処理されていない場合処理を実行します。
      if (m.Msg == WM_SYSKEYUP & (Keys)m.WParam == Keys.F10)
      {
        if (!isF10_Processed)
        {
          ProcessCustomLogic((Keys)m.WParam);
        }
      }

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

    // F10キーが処理されたかどうかのフラグを設定します。
    private bool isF10_Processed = false;

    private void gcClassicFunctionKey1_FunctionKeyPress(object sender, GrapeCity.Win.Bars.FunctionKeyPressEventArgs e)
    {
      // WindowsXPなどでの重複を防止します。
      if (e.Key == GrapeCity.Win.Bars.ButtonKeys.F10)
      {
        isF10_Processed = true;
      }

      // 処理を実行します。
      ProcessCustomLogic((Keys)e.Key);
    }

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

    private void Form1_Load(object sender, EventArgs e)
    {
      Application.AddMessageFilter(this);
    }
  }
}


【GcFunctionKeyの場合】
[Visual Basic]
Public Class Form1
  Implements IMessageFilter

  <System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)> _
  Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) _
                   As Boolean Implements IMessageFilter.PreFilterMessage

    Const WM_SYSKEYUP As Integer = 261

    ' F10キーが押下された場合で、F10が処理されていない場合処理を実行します。
    If m.Msg = WM_SYSKEYUP And CType(m.WParam, Keys) = Keys.F10 Then
      If Not isF10_Processed Then
        ProcessCustomLogic(CType(m.WParam, Keys))
      End If
    End If

    ' フラグを常にクリアします。
    isF10_Processed = False
    Return False
  End Function

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

  Private Sub GcFunctionKey1_FunctionKeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles GcFunctionKey1.FunctionKeyDown
    ' WindowsXPなどでの重複を防止します。
    If (e.KeyData = Keys.F10) Then
      isF10_Processed = True
    End If

    ' 処理を実行します。
    ProcessCustomLogic(e.KeyData)
  End Sub

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

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Application.AddMessageFilter(Me)
  End Sub
End Class

[C#]
using System.Windows.Forms

namespace WindowsFormsApplication1
{
  public partial class Form1 : Form, IMessageFilter
  {
    public Form1()
    {
      InitializeComponent();
    }

    [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
    public bool PreFilterMessage(ref System.Windows.Forms.Message m)
    {

      const int WM_SYSKEYUP = 261;

      // F10キーが押下された場合で、F10が処理されていない場合処理を実行します。
      if (m.Msg == WM_SYSKEYUP & (Keys)m.WParam == Keys.F10)
      {
        if (!isF10_Processed)
        {
          ProcessCustomLogic((Keys)m.WParam);
        }
      }

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

    // F10キーが処理されたかどうかのフラグを設定します。
    private bool isF10_Processed = false;

    private void GcFunctionKey1_FunctionKeyDown(System.Object sender, System.Windows.Forms.KeyEventArgs e)
    {
      // WindowsXPなどでの重複を防止します。
      if (e.KeyData == Keys.F10)
      {
        isF10_Processed = true;
      }

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

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

    private void Form1_Load(System.Object sender, System.EventArgs e)
    {
      Application.AddMessageFilter(this);
    }
  }
}

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