Захватить параметр, выбранный пользователем в контекстном меню Windows по умолчанию?

Когда я щелкаю правой кнопкой мыши текстовое поле, которое имеет контекстное меню Windows по умолчанию, я хочу знать, выбирает ли пользователь параметр copy cut или paste, чтобы выполнять вторичные операции, когда пользователь выбрал определенный параметр контекстного меню.

У меня нет кода, потому что я не знаю, с чего начать, пытаясь распознать, какой параметр был выбран пользователем в контекстном меню, и как зафиксировать этот щелчок левой кнопкой мыши, потому что я пытался захватить контекстное меню по умолчанию. текстовое поле MouseDown/Mouseclick безуспешно, я знаю, что это не имеет особого смысла, потому что это щелчок мыши контекстного меню, а не щелчок мыши текстового поля, но... я не знаю, как управлять этим внешним контекстным меню.


person ElektroStudios    schedule 21.10.2013    source источник
comment
Поскольку вы хотите указать свои собственные действия, вы должны заменить контекстное меню по умолчанию, даже если эти действия являются «вторичными». Вероятно, меньше кода и это проще, чем пытаться подключиться или использовать Win/Net.   -  person Ňɏssa Pøngjǣrdenlarp    schedule 21.10.2013
comment
@Plutonix Я всегда с этим справлялся. Затем вы можете либо вручную добавить материал в буфер обмена, либо просто вызвать горячую клавишу SendKeys.SendWait("[CTRL]+C")   -  person Steve    schedule 21.10.2013
comment
Просто пример: предположим, что я хочу генерировать MsgBox только тогда, когда пользователь выбирает опцию копирования или вставки в контекстном меню по умолчанию, это то, о чем я прошу. Спасибо, что прочитали!   -  person ElektroStudios    schedule 21.10.2013
comment
@Plutonix Я не заинтересован в замене контекстного меню по умолчанию на пользовательское контекстное меню в этом приложении, Probably less code and easier than... зависит от того, будет ли это простой cm или полная замена, cm по умолчанию имеет несколько параметров IME, и вам действительно понадобится много код для воспроизведения всех этих параметров, таких как параметр управления Unicode... в противном случае просто создание контекстного меню с параметрами копирования/вырезания/вставки. Мне это не нравится, но да, нужны только небольшие строки кода, но это не кажется очень профессиональным ( для текстового поля). Мне это не нужно в этом приложении.   -  person ElektroStudios    schedule 21.10.2013
comment
непрофессионально?? Я пытаюсь вспомнить, когда в последний раз видел CTM по умолчанию в любом приложении. Если вам это нужно, хорошо, но не притворяйтесь, что это важно, большинство приложений могут «запретить формирование арабских форм».   -  person Ňɏssa Pøngjǣrdenlarp    schedule 21.10.2013
comment
Прошу прощения, никого не хотел обидеть, просто мне на мой взгляд не кажется профессиональным, кастомный CM для любого другого типа контрола считаю красивым, но не для контрола TextBox, я всегда видел на всех apps CM по умолчанию для TextBox, но мы отличаемся этим, в любом случае, я не могу представить, какие пользовательские параметры может добавить один человек в пользовательский CM текстового поля, потому что CM Textbox по умолчанию для Windows имеет все необходимые параметры !, спасибо за комментарий.   -  person ElektroStudios    schedule 21.10.2013
comment
@ElektroStudios the windows default Textbox CM has all needed options, но в нем отсутствуют нужные функции. По этой причине у @Plutonix есть хорошее решение.   -  person djv    schedule 23.10.2013
comment
@DanVerdolino Я собирался спросить, почему он начал тему / опубликовал награду, если она была такой идеальной. По-видимому, невозможно (AFAIK) получить ссылку на CTM по умолчанию и подключить к нему новые события. Но можно создать подкласс CTM и вызвать новое событие, чтобы уведомить о том, что операция должна произойти, и позволить коду формы прервать операцию. Оттуда это всего лишь небольшая детективная работа, чтобы сделать его более похожим на возвышенное значение по умолчанию (почти все, что связано с Unicode, — это просто вставка символов, а остальное является внутренним для элемента управления).   -  person Ňɏssa Pøngjǣrdenlarp    schedule 23.10.2013


Ответы (2)


Вы можете добавить в свой проект такой класс:

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

Затем вы можете заменить все вхождения «TextBox» в файлах Designer.vb на «MyTextBox». Тогда у вас будет доступ к 3 новым событиям для вырезания, копирования и вставки. Вы можете справиться с ними следующим образом:

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

Обратите внимание, что в данном случае я решил обрабатывать все 3 события в одной функции, но вы также можете обрабатывать их в отдельных функциях. Я заметил, что команда cut также вызывает событие команды копирования, но пока я предполагаю, что вы можете справиться с этим небольшим осложнением.

person BlueMonkMN    schedule 23.10.2013
comment
Отличное решение, большое спасибо! Сообщение WM_COPY отправляется раньше вместе с WM_CUT, когда я нажимаю опцию Cut CMT, это можно исправить? . - person ElektroStudios; 24.10.2013
comment
Да, я уже упоминал об этом поведении в своем ответе. Можно ли игнорировать wm_copy? Зачем вам захват wm_copy? Я не знаю, как это исправить, но я не уверен, что это действительно неправильно. Вырезать — это своего рода копия, за которой следует вырезание/удаление. Поэтому я не знаю, почему ваш код заботится. Что должен делать ваш код, если пользователь только что выбрал копию? - person BlueMonkMN; 24.10.2013
comment
Это трудно объяснить, но, думаю, я мог бы использовать таймер для измерения времени между wm_copy + wm_delete, чтобы распознать, когда пользователь нажимает кнопку «Вырезать». - person ElektroStudios; 24.10.2013
comment
Просто, может быть, вы могли бы сказать мне константу для wm_delete, чтобы сделать то, что мне нужно? Я не могу найти его в MSDN, спасибо за ваше время - person ElektroStudios; 24.10.2013
comment
Найдено: WM_CLEAR = & H303, но, к сожалению, ваш класс не будет работать при наследовании стороннего текстового поля (например, текстовое поле Krypton), см. здесь новый вопрос, если вы могли бы: stackoverflow.com/questions/19560844/ - person ElektroStudios; 24.10.2013

Если кому-то это нужно, это модификация кода @BlueMonkMN для правильной работы с опцией CUT, а также добавлена ​​опция DELETE.

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
person ElektroStudios    schedule 24.10.2013