When right-click on a textbox which has the default Windows contextmenu I want to know if the user selects copy
cut
or paste
option, to perform secondary operations when user has selected an specific contextmenu option.
I have no code 'cause I don't know where to start trying to recognize what option was selected by the user in the contextmenu, and how to capture that left click 'cause I've tried to capture the default contextmenu mouseleft click on the textbox MouseDown/Mouseclick
events without success, I know that has not much sense 'cause it is a contextmenu mouseclick, not a Textbox mouseclick, but well... I don't know how to manage that external contextmenu.
You can add a class like this to your project:
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
Then you can replace all occurrences of "TextBox" in the Designer.vb files with "MyTextBox". Then you will have access to 3 new events for Cut, Copy and Paste. You can handle them like this:
Private Sub TextBox1_OnTextCommand(sender As Object, e As MyTextBox.ContextCommandEventArgs) _
Handles TextBox1.OnCut, TextBox1.OnPaste, TextBox1.OnCopy
MessageBox.Show("Activated " & e.Command.ToString())
End Sub
Notice how I've chosen to handle all 3 events in one function in this case, but you could handle them in separate functions as well. I noticed that the cut command seems to also cause a copy command event, but I will assume for now that you can deal with that slight complication.
If someone need this, This is a modification of @BlueMonkMN code to work properly with the CUT option, and also added the DELETE option.
Class MyTextBox : Inherits TextBox
Private Last_Command As ContextCommands = Nothing
Private WithEvents CopyOrCut_Timer As New Timer _
With {.Interval = 5, .Enabled = False}
Public Enum ContextCommands
WM_CUT = &H300
WM_COPY = &H301
WM_PASTE = &H302
WM_DELETE = &H303
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)
Event OnDelete(sender As Object, e As ContextCommandEventArgs)
Protected Overrides Sub WndProc(ByRef m As Message)
MyBase.WndProc(m)
Select Case m.Msg
Case ContextCommands.WM_COPY
Last_Command = ContextCommands.WM_COPY
CopyOrCut_Timer.Enabled = True
Case ContextCommands.WM_CUT
Last_Command = ContextCommands.WM_CUT
Case ContextCommands.WM_PASTE
RaiseEvent OnPaste(Me, New ContextCommandEventArgs() _
With {.Command = ContextCommands.WM_PASTE})
Case ContextCommands.WM_DELETE
RaiseEvent OnDelete(Me, New ContextCommandEventArgs() _
With {.Command = ContextCommands.WM_DELETE})
End Select
End Sub
Private Sub Cut_Timer_Tick(sender As Object, e As EventArgs) _
Handles CopyOrCut_Timer.Tick
sender.enabled = False
Select Case Last_Command
Case ContextCommands.WM_COPY
RaiseEvent OnCopy(Me, New ContextCommandEventArgs() _
With {.Command = ContextCommands.WM_COPY})
Case ContextCommands.WM_CUT
RaiseEvent OnCut(Me, New ContextCommandEventArgs() _
With {.Command = ContextCommands.WM_CUT})
End Select
Last_Command = Nothing
End Sub
End Class