-1

コントロールをサブクラス化する必要がないように、このコードを通常のクラス (例: Form1 クラス) 内で使用するように適応できるかどうかを知りたいです。

コードはBlueMonkMNこちらからWindows の既定のコンテキスト メニューでユーザーが選択したオプションをキャプチャしますか?

Class MyTextBox : Inherits TextBox
  Public Enum ContextCommands
     WM_CUT = &H300
     WM_COPY = &H301
     WM_PASTE = &H302
  End Enum

  Public Class ContextCommandEventArgs
     Inherits EventArgs
     Public Property Command As ContextCommands
  End Class

  Event OnCut(sender As Object, e As ContextCommandEventArgs)
  Event OnCopy(sender As Object, e As ContextCommandEventArgs)
  Event OnPaste(sender As Object, e As ContextCommandEventArgs)

  Protected Overrides Sub WndProc(ByRef m As Message)
     MyBase.WndProc(m)
     Select Case m.Msg
        Case ContextCommands.WM_CUT
           RaiseEvent OnCut(Me, New ContextCommandEventArgs() With {.Command = ContextCommands.WM_CUT})
        Case ContextCommands.WM_COPY
           RaiseEvent OnCopy(Me, New ContextCommandEventArgs() With {.Command = ContextCommands.WM_COPY})
        Case ContextCommands.WM_PASTE
           RaiseEvent OnPaste(Me, New ContextCommandEventArgs() With {.Command = ContextCommands.WM_PASTE})
     End Select
  End Sub
End Class

私の問題をよりよく理解するために、私がそれを適応させようとしたことを示します。

Public Class Form1

    Public Enum ContextCommands
        WM_CUT = &H300
        WM_COPY = &H301
        WM_PASTE = &H302
    End Enum

    Public Class ContextCommandEventArgs
        Inherits EventArgs
        Public Property Command As ContextCommands
    End Class

    Event OnCut(TextBox1 As Object, e As ContextCommandEventArgs)
    Event OnCopy(TextBox1 As Object, e As ContextCommandEventArgs)
    Event OnPaste(TextBox1 As Object, e As ContextCommandEventArgs)

    Protected Overrides Sub WndProc(ByRef m As Message)
        MyBase.WndProc(m)
        Select Case m.Msg
            Case ContextCommands.WM_CUT
                RaiseEvent OnCut(TextBox1, New ContextCommandEventArgs() With {.Command = ContextCommands.WM_CUT})
            Case ContextCommands.WM_COPY
                RaiseEvent OnCopy(TextBox1, New ContextCommandEventArgs() With {.Command = ContextCommands.WM_COPY})
            Case ContextCommands.WM_PASTE
                RaiseEvent OnPaste(TextBox1, New ContextCommandEventArgs() With {.Command = ContextCommands.WM_PASTE})
        End Select
    End Sub

Private Sub TextBox1_OnTextCommand() Handles TextBox1.TextChanged
    If WM_CUT then...
    Elseif WM_COPY then...
    Elseif WM_Paste then...
    End if
End Sub

Private Sub TextBox1_OnTextCommand() Handles Me.OnPaste, Me.OnCopy, Me.OnCut
    MsgBox("Activated")
End Sub

End Class
4

1 に答える 1

1

これは VB 開発者にとって簡単な作業ではありませんが、お役に立てば幸いです。コードは特定のテキスト ボックスに関連しなくなりましたが、必要に応じて値を比較cwp.hWndすることで、イベントの原因となったテキスト ボックスを特定できるはずです。フックをオンにするためにアプリケーションの最初に 1 回だけ呼び出し、フックをオフにするために最後に 1 回だけ呼び出す必要があります。TextBox.HandleEditMenuHook.Enable

Imports System.Runtime.InteropServices

Public Class Form1
   Protected Overrides Sub OnLoad(e As EventArgs)
      MyBase.OnLoad(e)
      EditMenuHook.Enable(True)
   End Sub

   Protected Overrides Sub OnClosed(e As EventArgs)
      EditMenuHook.Enable(False)
      MyBase.OnClosed(e)
   End Sub
End Class

Friend Class EditMenuHook
   Public Structure CWPSTRUCT
      Public lParam As IntPtr
      Public wParam As IntPtr
      Public message As UInt32
      Public hWnd As IntPtr
   End Structure

   Public Delegate Function CallBack( _
       ByVal nCode As Integer, _
       ByVal wParam As IntPtr, _
       ByVal lParam As IntPtr) As Integer

   Shared hHook As Integer = 0

   'Import for the SetWindowsHookEx function.
   <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
   Public Overloads Shared Function SetWindowsHookEx _
          (ByVal idHook As Integer, ByVal HookProc As CallBack, _
           ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
   End Function

   'Import for the CallNextHookEx function.
   <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
   Public Overloads Shared Function CallNextHookEx _
          (ByVal idHook As Integer, ByVal nCode As Integer, _
           ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
   End Function

   'Import for the UnhookWindowsHookEx function.
   <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
   Public Overloads Shared Function UnhookWindowsHookEx _
              (ByVal idHook As Integer) As Boolean
   End Function

   Private Const WH_CALLWNDPROC = 4

   Public Enum TextCommandMessage
      WM_CUT = &H300
      WM_COPY = &H301
      WM_PASTE = &H302
   End Enum

   'Keep the reference so that the delegate is not garbage collected.
   Private Shared hookproc As CallBack

   Shared Sub Enable(enable As Boolean)
      If hHook = 0 AndAlso enable = True Then
         hookproc = AddressOf EditCommandHook
         hHook = SetWindowsHookEx(WH_CALLWNDPROC, _
                                  hookproc, _
                                  IntPtr.Zero, _
                                  AppDomain.GetCurrentThreadId())
         If hHook.Equals(0) Then
            MsgBox("SetWindowsHookEx Failed")
            Return
         End If
      ElseIf hHook <> 0 AndAlso enable = False Then
         Dim ret As Boolean = UnhookWindowsHookEx(hHook)

         If ret.Equals(False) Then
            MsgBox("UnhookWindowsHookEx Failed")
            Return
         Else
            hHook = 0
         End If
      End If
   End Sub

   Public Shared Function EditCommandHook( _
      ByVal nCode As Integer, _
      ByVal wParam As IntPtr, _
      ByVal lParam As IntPtr) As Integer

      If nCode < 0 Then
         Return CallNextHookEx(hHook, nCode, wParam, lParam)
      End If

      Dim cwp = DirectCast(System.Runtime.InteropServices.Marshal.PtrToStructure(lParam, GetType(CWPSTRUCT)), CWPSTRUCT)

      Select Case cwp.message
         Case TextCommandMessage.WM_CUT
            System.Diagnostics.Debug.WriteLine(String.Format("Cut {0}", cwp.hWnd))
         Case TextCommandMessage.WM_COPY
            System.Diagnostics.Debug.WriteLine(String.Format("Copy {0}", cwp.hWnd))
         Case TextCommandMessage.WM_PASTE
            System.Diagnostics.Debug.WriteLine(String.Format("Paste {0}", cwp.hWnd))
      End Select

      Return CallNextHookEx(hHook, nCode, wParam, lParam)
   End Function
End Class
于 2013-10-24T15:53:27.453 に答える