GcClassicFunctionKey/GcFunctionKeyを使用してF10キー押下時にメッセージボックスを表示するとイベントが2回実行される場合がある

文書番号 : 37077     文書種別 : 不具合     登録日 : 2014/03/05     最終更新日 : 2016/04/28
文書を印刷する
対象製品
PlusPak for Windows Forms 7.0J
状況
修正済み
詳細
GcClassicFunctionKey/GcFunctionKeyのFunctionKeyPress、FunctionKeyDown、FunctionKeyButton10.Clickイベントで F10キーを押下時にメッセージボックスを表示し、そのメッセージボックスの OKボタンを Enterキーで閉じた場合、イベントがもう一度呼び出されます。メッセージボックスの OKボタンをマウスクリックで閉じた場合には、この現象は発生しません。
回避方法
この問題はService Pack 3(v7.0.2016.0428)で修正されました。
不具合を修正した最新のサービスパックは、アップデートページ からダウンロードできます。

Service Pack 3より前のバージョンでは次の方法で回避可能です。

次のようにメッセージを表示するタイミングを変更することで現象を回避します。

【GcClassicFunctionKeyの FunctionKeyPressイベントでの回避方法】
[Visual Basic]
  Private Sub GcClassicFunctionKey1_FunctionKeyPress(ByVal sender As System.Object, ByVal e As GrapeCity.Win.Bars.FunctionKeyPressEventArgs) Handles GcClassicFunctionKey1.FunctionKeyPress
    If e.Key = GrapeCity.Win.Bars.ButtonKeys.F10 Then
      'MessageBox.Show("GcClassicFunctionKey1_FunctionKeyPress")

      ' メッセージを表示するタイミングを変更します。
      needProcessedNULLMessage = True
      PostMessage(Me.Handle, WM_NULL, "GcClassicFunctionKey1_FunctionKeyPress", IntPtr.Zero)
      e.Handled = True
    End If
  End Sub

  ' *** 回避コード ***
  Private needProcessedNULLMessage As Boolean = False

  <System.Runtime.InteropServices.DllImport("user32.dll", CharSet:=System.Runtime.InteropServices.CharSet.Auto)> _
  Private Shared Function PostMessage(ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal wparam As String, ByVal lparam As IntPtr) As Boolean
  End Function

  Private Const WM_NULL As Integer = 0
  Protected Overloads Overrides Sub WndProc(ByRef m As Message)
    If m.Msg = WM_NULL AndAlso needProcessedNULLMessage Then
      Dim str As String = System.Runtime.InteropServices.Marshal.PtrToStringAuto(m.WParam)
      MessageBox.Show(str)
      needProcessedNULLMessage = False
    End If
    MyBase.WndProc(m)
  End Sub
  ' ******

[C#]
  private void gcClassicFunctionKey1_FunctionKeyPress(object sender, GrapeCity.Win.Bars.FunctionKeyPressEventArgs e)
  {
    if (e.Key == GrapeCity.Win.Bars.ButtonKeys.F10)
    {
      //MessageBox.Show("gcClassicFunctionKey1_FunctionKeyPress");

      // メッセージを表示するタイミングを変更します。
      needProcessedNULLMessage = true;
      PostMessage(this.Handle, WM_NULL, "gcClassicFunctionKey1_FunctionKeyPress", IntPtr.Zero);
      e.Handled = true;
    }
  }
      
  // *** 回避コード ***
  private bool needProcessedNULLMessage = false;

  [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
  private static extern bool PostMessage(IntPtr hwnd, int msg, string wparam, IntPtr lparam);

  private const int WM_NULL = 0;    
  protected override void WndProc(ref Message m)
  {
    if (m.Msg == WM_NULL && needProcessedNULLMessage)
    {
      string str = System.Runtime.InteropServices.Marshal.PtrToStringAuto(m.WParam);
      MessageBox.Show(str);
      needProcessedNULLMessage = false;
    }
    base.WndProc(ref m);
  }
  // ******

【GcFunctionKeyの FunctionKeyDownイベントでの回避方法】
[Visual Basic]
  Private Sub GcFunctionKey1_FunctionKeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles GcFunctionKey1.FunctionKeyDown
    If e.KeyCode = Keys.F10 Then
      'MessageBox.Show("GcFunctionKey1_FunctionKeyDown")

      ' メッセージを表示するタイミングを変更します。
      needProcessedNULLMessage = True
      PostMessage(Me.Handle, WM_NULL, "GcFunctionKey1_FunctionKeyDown", IntPtr.Zero)
      e.Handled = True
    End If
  End Sub

  ' *** 回避コード ***
  Private needProcessedNULLMessage As Boolean = False

  <System.Runtime.InteropServices.DllImport("user32.dll", CharSet:=System.Runtime.InteropServices.CharSet.Auto)> _
  Private Shared Function PostMessage(ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal wparam As String, ByVal lparam As IntPtr) As Boolean
  End Function

  Private Const WM_NULL As Integer = 0
  Protected Overloads Overrides Sub WndProc(ByRef m As Message)
    If m.Msg = WM_NULL AndAlso needProcessedNULLMessage Then
      Dim str As String = System.Runtime.InteropServices.Marshal.PtrToStringAuto(m.WParam)
      MessageBox.Show(str)
      needProcessedNULLMessage = False
    End If
    MyBase.WndProc(m)
  End Sub
  ' ******

[C#]
  private void gcFunctionKey1_FunctionKeyDown(object sender, KeyEventArgs e)
  {
    if (e.KeyCode == Keys.F10)
    {
      //MessageBox.Show("gcFunctionKey1_FunctionKeyDown");

      // メッセージを表示するタイミングを変更します。
      needProcessedNULLMessage = true;
      PostMessage(this.Handle, WM_NULL, "gcFunctionKey1_FunctionKeyDown", IntPtr.Zero);
      e.Handled = true;
    }
  }
  
  // *** 回避コード ***
  private bool needProcessedNULLMessage = false;

  [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
  private static extern bool PostMessage(IntPtr hwnd, int msg, string wparam, IntPtr lparam);

  private const int WM_NULL = 0;    
  protected override void WndProc(ref Message m)
  {
    if (m.Msg == WM_NULL && needProcessedNULLMessage)
    {
      string str = System.Runtime.InteropServices.Marshal.PtrToStringAuto(m.WParam);
      MessageBox.Show(str);
      needProcessedNULLMessage = false;
    }
    base.WndProc(ref m);
  }
  // ******

【GcFunctionKeyの FunctionKeyButton10.Clickイベントでの回避方法】
[Visual Basic]
  Private Sub FunctionKeyButton10_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FunctionKeyButton10.Click
    'MessageBox.Show("FunctionKeyButton10_Click")

    ' メッセージを表示するタイミングを変更します。
    needProcessedNULLMessage = True
    PostMessage(Me.Handle, WM_NULL, "FunctionKeyButton10_Click", IntPtr.Zero)
  End Sub

  ' *** 回避コード ***
  Private needProcessedNULLMessage As Boolean = False

  <System.Runtime.InteropServices.DllImport("user32.dll", CharSet:=System.Runtime.InteropServices.CharSet.Auto)> _
  Private Shared Function PostMessage(ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal wparam As String, ByVal lparam As IntPtr) As Boolean
  End Function

  Private Const WM_NULL As Integer = 0
  Protected Overloads Overrides Sub WndProc(ByRef m As Message)
    If m.Msg = WM_NULL AndAlso needProcessedNULLMessage Then
      Dim str As String = System.Runtime.InteropServices.Marshal.PtrToStringAuto(m.WParam)
      MessageBox.Show(str)
      needProcessedNULLMessage = False
    End If
    MyBase.WndProc(m)
  End Sub
  ' ******

[C#]
  private void functionKeyButton10_Click(object sender, EventArgs e)
  {
    //MessageBox.Show("functionKeyButton10_Click");

    // メッセージを表示するタイミングを変更します。
    needProcessedNULLMessage = true;
    PostMessage(this.Handle, WM_NULL, "functionKeyButton10_Click", IntPtr.Zero);
  }
  
  // *** 回避コード ***
  private bool needProcessedNULLMessage = false;

  [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
  private static extern bool PostMessage(IntPtr hwnd, int msg, string wparam, IntPtr lparam);

  //[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
  //private static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

  private const int WM_NULL = 0;    
  protected override void WndProc(ref Message m)
  {
    if (m.Msg == WM_NULL && needProcessedNULLMessage)
    {
      string str = System.Runtime.InteropServices.Marshal.PtrToStringAuto(m.WParam);
      MessageBox.Show(str);
      needProcessedNULLMessage = false;
    }
    base.WndProc(ref m);
  }
  // ******
キーワード
PPWI08127