我可以编辑文本字段的上下文菜单(而不是资源管理器上下文菜单)吗?

时间:2016-10-03 08:26:21

标签: windows registry contextmenu

我想在文本字段的上下文菜单中添加一个条目,例如:

text field context menu

我有一个AutoHotkey可执行文件,可以将突出显示的文本放入剪贴板,然后使用剪贴板在Chrome中执行Google搜索。我想要一个注册表添加,让我在菜单中单击一下,运行该可执行文件。我已经在Explorer上下文菜单中实现了这一点(用于处理带有第三方应用程序的文件等),但我没有发现任何能够更改此特定菜单的功能。

3 个答案:

答案 0 :(得分:0)

我将首先描述编辑文件的菜单,然后编辑编辑控件的菜单。

文件菜单:

如果您知道如何安全地使用RegEdit, 创建此注册表项,将“我的脚本”选项添加到所有文件的右键单击上下文菜单中:

HKEY_CLASSES_ROOT\*\Shell\My Script\command
(Default)   REG_SZ  "C:\Program Files\AutoHotkey\AutoHotkey.exe" "C:\Program Files\AutoHotkey\My Script.ahk" "%1"

单击菜单项将启动脚本。

如果您想对单击的文件执行某些操作,可以通过以下方式检索其路径:

vPath = %1%

要同时操作多个文件需要shell扩展,这更复杂。

编辑控件的菜单:

图像中的上下文菜单是编辑控件的上下文菜单。 要更改 菜单会更困难。重命名文件时,您正在编辑小编辑控件上的文本。

要“添加”菜单项,最简单的方法是用您自己的自定义上下文菜单替换整个菜单。将自定义菜单项置于顶部,您可能希望重新创建在“编辑”控件上操作的“撤消/剪切/复制/粘贴/删除/选择所有项目”。例如,使用ControlGet, vText, Selected重新创建复制功能。您还需要通过RButton热键捕获右键单击,并使用ControlGetFocus检查Edit控件是否处于焦点,并MouseGetPos检查Edit控件是否在光标下。所以会涉及一些工作。关于捕获右键单击,请参阅下面的链接,您将使用RButton替换LButton。祝你好运!

Is it possible to catch the close button and minimize the window instead? AutoHotKey

答案 1 :(得分:0)

问题是如何编辑Edit控件的上下文菜单, 并提供显示编辑控件上下文菜单的图像 在资源管理器中重命名文件时。

一种方法是显示自定义上下文菜单, 右键单击Edit控件时 或者当聚焦编辑控件并按下AppsKey时。

下面的AutoHotkey脚本提供了此类功能 对于资源管理器(在Windows 7上测试),它会复制 编辑控制菜单并添加一个打开所选内容的按钮 默认Web浏览器中的文本。

注意:Explorer地址栏也使用Edit控件, 但是,脚本会将此考虑在内。

;AutoHotkey script for:
;windows - Can I edit the context menu of a text field (not Explorer context menu)? - Stack Overflow
;http://stackoverflow.com/questions/39827324/can-i-edit-the-context-menu-of-a-text-field-not-explorer-context-menu/41343741#41343741

;see also:
;contextmenu - Can I add a custom paste option to the windows text editing context menu? - Stack Overflow
;http://stackoverflow.com/questions/17370415/can-i-add-a-custom-paste-option-to-the-windows-text-editing-context-menu/41343891#41343891

;tested on Windows 7

GroupAdd, WinGroupFolder, ahk_class CabinetWClass ;explorer
#IfWinActive, ahk_group WinGroupFolder
$RButton Up:: ;explorer - custom Edit control menu
$AppsKey:: ;explorer - custom Edit control menu
;#IfWinActive, ahk_class Notepad
;$RButton Up:: ;notepad - custom Edit control menu
;$AppsKey:: ;notepad - custom Edit control menu

;STAGE - create menu if not already created
if !vIsReady
{
    Menu, EditMenu, Add, &My Item, MyItem
    Menu, EditMenu, Add ;------------------------------
    Menu, EditMenu, Add, &Undo, EditUndo
    Menu, EditMenu, Add ;------------------------------
    Menu, EditMenu, Add, Cu&t, EditCut
    Menu, EditMenu, Add, &Copy, EditCopy
    Menu, EditMenu, Add, &Paste, EditPaste
    Menu, EditMenu, Add, &Delete, EditDelete
    Menu, EditMenu, Add ;------------------------------
    Menu, EditMenu, Add, Select &All, EditSelectAll

    VarSetCapacity(vPos1, 4), VarSetCapacity(vPos2, 4)
    VarSetCapacity(vPos1X, 4), VarSetCapacity(vPos2X, 4)
    vIsReady := 1
}

;STAGE - perform certain checks, if any of them fail
;then let hotkeys perform their normal function,
;start by stating that, so far, the checks have not failed
vRet := 1

;check - if active control is an Edit/RichEdit control
if vRet
{
    WinGet, hWnd, ID, A
    ControlGetFocus, vCtlClassNN, ahk_id %hWnd%
    ControlGet, hCtl, Hwnd, , %vCtlClassNN%, ahk_id %hWnd%
    WinGetClass, vWinClass, ahk_id %hCtl%
    if !(SubStr(vWinClass, 1, 4) = "Edit") && !(SubStr(vWinClass, 1, 8) = RichEdit)
    vRet := 0
}

;check - if a right-click was performed, the control
;under the cursor must be the active control
if vRet && InStr(A_ThisHotkey, "RButton")
{
    CoordMode, Mouse, Screen
    MouseGetPos, vPosX, vPosY, , hCtl2, 3
    if !(hCtl2 = hCtl)
    vRet := 0
}

;check - the Edit control must be for a file icon and not the address bar
if vRet
{
    ;hWndParent := DllCall("user32\GetParent", Ptr,hCtl, Ptr)
    hWndParent := DllCall("user32\GetAncestor", Ptr,hCtl, UInt,1, Ptr) ;GA_PARENT := 1
    WinGetClass, vWinClassParent, ahk_id %hWndParent%
    if (vWinClassParent = "ComboBox")
    vRet := 0
}

;if a check has failed, then let hotkeys perform their normal function
if !vRet
{
    if InStr(A_ThisHotkey, "RButton")
        SendInput {Click right}
    if InStr(A_ThisHotkey, "AppsKey")
        SendInput {AppsKey}
    Return
}

;STAGE - if clicked Edit control, menu will appear
;relative to cursor coordinates retrieved earlier,
;if pressed AppsKey, menu will appear in centre of Edit control
if !InStr(A_ThisHotkey, "RButton")
{
    WinGetPos, vPosX, vPosY, vPosW, vPosH, ahk_id %hCtl%
    vPosX += vPosW/2, vPosY += vPosH/2
}

;STAGE - retrieve information from Edit control
;and disable menu items accordingly
;Undo - check undo status (is undo available)
;Cut - check text selection > 0
;Copy - check text selection > 0
;Paste - check clipboard not empty
;Delete - check text selection > 0
;Select All - always available

SendMessage, 0xC6, 0, 0, , ahk_id %hCtl% ;EM_CANUNDO := 0xC6
vOptU := ErrorLevel ? "En" : "Dis" ;1=undo available/0=undo not available
ControlGet, vText, Selected, , , ahk_id %hCtl%
vOptT := StrLen(vText) ? "En" : "Dis"
vOptC := StrLen(Clipboard) ? "En" : "Dis"

Menu, EditMenu, % vOptU "able", &Undo, EditUndo
Menu, EditMenu, % vOptT "able", Cu&t, EditCut
Menu, EditMenu, % vOptT "able", &Copy, EditCopy
Menu, EditMenu, % vOptC "able", &Paste, EditPaste
Menu, EditMenu, % vOptT "able", &Delete, EditDelete

;STAGE - get Edit control character positions
;(unfortunately showing the custom menu ends the rename mode,
;we get the Edit control character positions in order to restore them later)
SendMessage, 0xB0, &vPos1, &vPos2, , ahk_id %hCtl% ;EM_GETSEL := 0xB0
vPos1 := NumGet(vPos1), vPos2 := NumGet(vPos2)

;STAGE - show menu
CoordMode, Menu, Screen
Menu, EditMenu, Show, %vPosX%, %vPosY%
Return

;==============================

;STAGE - replicate standard Edit control menu items
;(or perform custom menu function)
;(unfortunately showing the custom menu ends the rename mode,
;so the Edit control has to be put into rename again,
;and the character positions restored)
EditUndo:
EditCut:
EditCopy:
EditPaste:
EditDelete:
EditSelectAll:
MyItem:

;STAGE - enter rename mode again
IfWinActive, ahk_group WinGroupFolder
{
    SendInput {F2}
    Loop, 20
    {
        ControlGetFocus, vCtlClassNN, ahk_id %hWnd%
        if (SubStr(vCtlClassNN, 1, 4) = "Edit")
            break
        Sleep 50
    }
    if !(SubStr(vCtlClassNN, 1, 4) = "Edit")
    {
        MsgBox % "error"
        Return
    }
    ControlGet, hCtl, Hwnd, , % vCtlClassNN, ahk_id %hWnd%

    ;STAGE - restore character positions
    if !InStr(A_ThisLabel, "SelectAll") && !InStr(A_ThisLabel, "MyItem")
    {
        vRet := 0
        Loop, 100
        {
            SendMessage, 0xB1, vPos1, vPos2, , ahk_id %hCtl% ;EM_SETSEL := 0xB1
            SendMessage, 0xB0, &vPos1X, &vPos2X, , ahk_id %hCtl% ;EM_GETSEL := 0xB0
            vPos1X := NumGet(vPos1X), vPos2X := NumGet(vPos2X)
            if (vPos1 = vPos1X) && (vPos2 = vPos2X)
            {
                vRet := 1
                break
            }
            Sleep 50
            if !vRet
            {
                MsgBox % "error"
                Return
            }
        }
    }
}

;STAGE - perform standard Edit control menu functions
if InStr(A_ThisLabel , "Undo")
    SendMessage, 0x304, , , , ahk_id %hCtl% ;WM_UNDO := 0x304
if InStr(A_ThisLabel , "Cut")
    SendMessage, 0x300, , , , ahk_id %hCtl% ;WM_CUT := 0x300
if InStr(A_ThisLabel , "Copy")
    SendMessage, 0x301, , , , ahk_id %hCtl% ;WM_COPY := 0x301
if InStr(A_ThisLabel , "Paste")
    SendMessage, 0x302, , , , ahk_id %hCtl% ;WM_PASTE := 0x302
if InStr(A_ThisLabel , "Delete")
    SendMessage, 0x303, , , , ahk_id %hCtl% ;WM_CLEAR := 0x303
if InStr(A_ThisLabel , "SelectAll")
    SendMessage, 0xB1, 0, -1, , ahk_id %hCtl% ;EM_SETSEL := 0xB1

;STAGE - actions to take if user chooses custom menu item
if 0 ;this comments out the 6 lines below
if InStr(A_ThisLabel , "MyItem")
{
    vText := "My String"
    ;ControlSend, , % vText, ahk_id %hCtl% ;use SendInput instead since capitalisation can be unreliable
    SendInput {Raw}%vText%
}

;STAGE - actions to take if user chooses custom menu item
if InStr(A_ThisLabel , "MyItem") && !(vText = "")
{
    MsgBox, 0x40003, , % "Choose 'Yes' to search for:`r`n" vText
    IfMsgBox Yes
    {
        vUrl := "http://www.google.co.uk/search?q=" UriEncode(vText)
        Run, "%vUrl%"
        ;Run, chrome.exe "%vUrl%"
    }
}

Return
#IfWinActive

;==================================================

;URL encoding - Rosetta Code
;https://www.rosettacode.org/wiki/URL_encoding#AutoHotkey

; Modified from https://autohotkey.com/board/topic/75390-ahk-l-unicode-uri-encode-url-encode-function/?p=480216
UriEncode(Uri)
{
    VarSetCapacity(Var, StrPut(Uri, "UTF-8"), 0)
    StrPut(Uri, &Var, "UTF-8")
    f := A_FormatInteger
    SetFormat, IntegerFast, H
    While Code := NumGet(Var, A_Index - 1, "UChar")
        If (Code >= 0x30 && Code <= 0x39 ; 0-9
            || Code >= 0x41 && Code <= 0x5A ; A-Z
            || Code >= 0x61 && Code <= 0x7A) ; a-z
            Res .= Chr(Code)
        Else
            Res .= "%" . SubStr(Code + 0x100, -1)
    SetFormat, IntegerFast, %f%
    Return, Res
}

;==================================================

答案 2 :(得分:0)

;菜单Google搜索自动热键脚本:在任何文本编辑字段中选择任何文本,然后按 AppsKey和RButton :: ^ + g ::;或按Ctrl + Shift + g 菜单,Google搜索,添加,使用Google搜索,Google搜索 菜单,Google搜索,显示 返回

GoogleSearch: { 发送,^ c 睡觉50 运行http://www.google.com/search?q=%clipboard% 返回 }