[AutoHotkey] Custom queue menus & Rock-click (Left-Mouse-Down + Right-Mouse-Click) run XYplorer script

Discuss and share scripts and script files...
Post Reply
Norn
Posts: 416
Joined: 24 Oct 2021 16:10

[AutoHotkey] Custom queue menus & Rock-click (Left-Mouse-Down + Right-Mouse-Click) run XYplorer script

Post by Norn »

Code: Select all

/*
***************************************************************************************************
@Created : 2023-01-21
@Modified: 2023-01-31
@Function: AHK: Rock-click (Left-Mouse-Down + Right-Mouse-Click) run XYplorer script
@Version : v0.2
***************************************************************************************************
*/
#Requires AutoHotkey v2.0.2
#HotIf MouseIsOver("ahk_class ThunderRT6FormDC")


If WinActive("ahk_class ThunderRT6FormDC")
{

~LButton & RButton Up::
{

    MouseGetPos(&fX, &fY, &ID, &fWin)
    WinGetPos(&dX, &dY, &dW, &dH, "ahk_class ThunderRT6FormDC")


    If(fX > 300 && fX < dW-235) {                                      ; Hover area: 300 is the width of the tree and 235 is the width of the Catalog or Preview pane
       if(fY > 130 && fY < dH-35) {                                    ; Hover area: 130 is the height above the column header and 35 is the height of the status bar
          Run "D:\XYplorer\XYplorer.exe" ' /feed=|::#1400|'            ; Run XYplorer script: #1400
       }
          else Send("{RButton}")      ; Send keys if not in the hover area
       }
    return
}
}

MouseIsOver(WinTitle) {
    MouseGetPos ,, &Win
    return WinExist(WinTitle " ahk_id " Win)
}
XY script sample:

Code: Select all

 $menu = <<<MENU

 Open(&O)|Open
 Edit with Notepad++|Openwith """C:\Program Files\Notepad++\notepad++.exe"" ""<curitem>"""|C:\Program Files\Notepad++\notepad++.exe

 Task Manager|run "taskmgr.exe"|:queue
 Control Panel|run "control.exe"|:conf
 Set label "Red" to all selected items|tagitems(, "red")|:labels

 MENU;

    //$x_pos = 100;
    //$y_pos = 500;
 
// Display the context menu
    //$command = popupnested($menu, $x_pos, $y_pos,,,,,|);
    $command = popupnested($menu,,,,,,,|);
 
// Run the selected command or skip if it uses an id #
    if ($command) { load $command,, s; }
Last edited by Norn on 21 Apr 2023 10:36, edited 5 times in total.
Win10, Win11 @100% 2560x1440 22H2

Norn
Posts: 416
Joined: 24 Oct 2021 16:10

Re: AHK: Rock-click (Left-Mouse-Down + Right-Mouse-Click) run XYplorer script

Post by Norn »

Rock-click.png
Rock-click.png (23.75 KiB) Viewed 994 times

Code: Select all

;==================================================================================================
;AUTHOR   : https://www.xyplorer.com/xyfc/viewtopic.php?t=25763
;Function : Rock-click (Left-Mouse-Down + Right-Mouse-Click) run custom menu (Supports Desktop, Explorer, XYplorer)
;Created  : 2023-02-28
;Modified : 2023-03-03
;Version  : v1.2
;==================================================================================================
#Requires AutoHotkey v2.0.2
#HotIf MouseIsOver("ahk_class Progman") || MouseIsOver("ahk_class WorkerW") || MouseIsOver("ahk_class CabinetWClass") || MouseIsOver("ahk_class ThunderRT6FormDC")


MouseIsOver(WinTitle) {
    MouseGetPos ,, &Win
    return WinExist(WinTitle " ahk_id " Win)
}


; Get our own HWND (we have no visible window)
G_OwnHWND := A_ScriptHwnd + 0


; Get messages back from XYplorer
OnMessage(0x4a, Receive_WM_COPYDATA)

xyPath  := "D:\XYplorer2\XYplorer.exe"      ; XY path
if !FileExist(xyPath)
{
   TrayTip xyPath, "XYplorer path does not exist!"
   ;ExitApp
}
exHwnd  := ""
selMenu:="", selPos:="", selItem:=""






;==================================================================================================
; Create a popup menu
;==================================================================================================

; Create main menu
 MyMenu := Menu()
 MyMenu.Name := "Main menu"                                   ; Used to show which menu is selected

;  Add menu item
 MyMenu.Add "Focus in XYplorer", MenuHandler

 if FileExist(xyPath)
    MyMenu.SetIcon("Focus in XYplorer", xyPath)               ; Add icon to first menu item if icon file exists

 MyMenu.Add "Item 2", MenuHandler                             ; Add a second menu item
 MyMenu.Add                                                   ; Add a separator line


; Add submenu
 Submenu1 := Menu()
 Submenu1.Name := "Submenu1"                              ; Used to show which menu is selected
; Add items to submenu
 Submenu1.Add "Submenu item 1", MenuHandler
 Submenu1.Add "Submenu item 2", MenuHandler
; Create a submenu in the main menu
 MyMenu.Add "Submenu", Submenu1


 MyMenu.Add                                               ; Add a separator line
 MyMenu.Add "Item 3", MenuHandler                         ; Add a third menu item

 MyMenu.Default := "Focus in XYplorer"

; Global selected
MenuHandler(Item, ItemPos, MyMenu) {
	;MsgBox "You selected " Item " (position " ItemPos " in " MyMenu.Name ")"
	global selMenu:=MyMenu.Name, selPos:=ItemPos, selItem:=Item   ; Global varibles
}






;==================================================================================================
; Rock-click (Left-Mouse-Down + Right-Mouse-Click) run custom menu
;==================================================================================================

~LButton & RButton Up::      ; Left-Mouse-Down + Right-Mouse-Click
{

 if WinActive("ahk_class ThunderRT6FormDC")                          ; If in the XY window
 {
    MouseGetPos(&fX, &fY, &fID, &fWin)

    WinGetPos(&dX, &dY, &dW, &dH, "ahk_class ThunderRT6FormDC")

    If(fX > 300 && fX < dW-235 && fY > 100 && fY < dH-60) {          ; Hover area: 300 is the width of the tree and 235 is the width of the Catalog or Preview pane, 100 is the height above the column header and 60 is the height of the status bar
       xyHwnd := GetxyHwnd()
       Send_WM_COPYDATA(xyHwnd, '::`#1400')                          ; Send the script to XY
   }
   else Send("{RButton}")
   return
 }
 else ;if WinActive("ahk_class Progman") || WinActive("ahk_class CabinetWClass")      ; If on the desktop, Explorer, pop up the custom menu
 {
    MouseGetPos ,, &Win
    global exHwnd := Win || WinExist('A')                            ; Get HWND of the active window
    global selected := explorerGetSel(exHwnd)                        ; Get desktop, explorer selected items
    MyMenu.Show              ; Display menu
    ;MyMenu.Show(1000, 800)   ; Display menu at
 }


 if(!selItem || !exHwnd)                                             ; Return if no menu item is selected
     return






;==================================================================================================
; Perform different actions
;==================================================================================================

 switch selItem
 {
    case "Focus in XYplorer":
	 if(!selected || selected == "ERROR")
	 {
	     TrayTip "Nothing selected!", , 1
	      return
	 }

        if (xyHwnd := GetxyHwnd()) {                                                                                                       ; If xy is running
	    WinActivate("ahk_id " xyHwnd)                                                                                                      ; Active XY window
            Send_WM_COPYDATA(xyHwnd, '::tab`("new"`, gpc`("' selected '"`, "path"`)`)`; selectitems "' selected '"')                       ; Send the script to XY
        } else {
            Run xyPath ' /feed=|::tab("new"`, gpc("' selected '"`, "path"))`; goto "' selected '"|'                                        ; If XY is not running, run XY and run the script
	    WinWaitActive WinExist("ahk_class ThunderRT6FormDC")                                                                               ; Waiting to activate the window
	    sleep 3000
	    WinActivate("ahk_class ThunderRT6FormDC")
        }
    case "Item 2":
	    MsgBox "You selected " selItem " (position " selPos " in " selMenu ")"
    case "Submenu item 1":
	    MsgBox "You selected " selItem " (position " selPos " in " selMenu ")"
    case "Submenu item 2":
	    MsgBox "You selected " selItem " (position " selPos " in " selMenu ")"
    case "Item 3":
	    MsgBox "You selected " selItem " (position " selPos " in " selMenu ")"
    default:
	    Msgbox "Hello!"
 }

 global selMenu:="", selPos:="", selItem:=""
 return

}






;==================================================================================================
; Desktop, Explore get functions
;==================================================================================================

; Get the selected items, excluding shortcut item on the desktop
/*
 selNoDeskLnk := explorerGet(exHwnd,true)
 if(selNoDeskLnk != "ERROR" && selNoDeskLnk)
    msgbox selNoDeskLnk



; Get the selected items
 explorerSel := explorerGetSel(exHwnd)
 if(explorerSel != "ERROR" && explorerSel)
    msgbox explorerSel
*/

explorerGetSel(exHwnd, selection := True)
{
    hwWindow := ''
    ret := ""
    Switch window := explorerGetWindow(exHwnd)
    {
       Case '':
	      Return 'ERROR'
       Case 'desktop':
          Try hwWindow := ControlGetHwnd('SysListView321', 'ahk_class Progman')
          hwWindow := hwWindow || ControlGetHwnd('SysListView321', 'ahk_id ' exHwnd)
          Loop Parse ListViewGetContent((selection ? 'Selected' : '') ' Col1', hwWindow), '`n', '`r'
          {
		     SplitPath A_LoopField, , , &ext                            ; Get ext
		     if(!ext && !DirExist(A_Desktop '\' A_LoopField))           ; Get the target of the shortcut, and stack to the variable ret, if there is no ext and not a folder
		     {
		        shortcut := A_Desktop '\' A_LoopField ".lnk"
	            if !fileExist(shortcut)
			        shortcut := A_DesktopCommon '\' A_LoopField ".lnk"
		        FileGetShortcut shortcut, &OutTarget
			    ret .= OutTarget '`n'
		     } else {                                                   ; If it is a file or a folder, stack to the varibles ret
                ret .= A_Desktop '\' A_LoopField '`n'
		     }
         }
      Default:                                                          ; If it is not on the desktop, stack to the variable ret
         For item in selection ? window.document.selectedItems : window.document.Folder.Items
         ret .= item.path '`n'
    }
    Return Trim(ret, '`n')
}



; All items, excluding desktop shortcut items
/*
 items := explorerGet(exHwnd, false)
 if(items != "ERROR" && items)
    msgbox items
*/

explorerGet(exHwnd,selection:=false)
{
    hwWindow := ''
    ret := ""
    Switch window := explorerGetWindow(exHwnd)
	{
       Case '':
	      Return 'ERROR'
       Case 'desktop':
          Try hwWindow := ControlGetHwnd('SysListView321', 'ahk_class Progman')
          hwWindow := hwWindow || ControlGetHwnd('SysListView321', 'ahk_id ' exHwnd)
          Loop Parse ListViewGetContent((selection ? 'Selected' : '') ' Col1', hwWindow), '`n', '`r'
		  {
		    If FileExist(A_Desktop '\' A_LoopField) ; ignore special icons like Computer (at least for now)
            ret .= A_Desktop '\' A_LoopField '`n'
		  }
      Default:
         For item in selection ? window.document.selectedItems : window.document.Folder.Items
         ret .= item.path '`n'
    }
    Return Trim(ret, '`n')
}



; If it is on the desktop
explorerGetWindow(exHwnd)
{
 class := WinGetClass(exHwnd := exHwnd || WinExist('A'))
 Switch
 {
   Case WinGetProcessName(exHwnd) != 'explorer.exe': Return
   Case class ~= 'Progman|WorkerW': Return 'desktop'
   Case class ~= '(Cabinet|Explore)WClass':
   For window in ComObject('Shell.Application').Windows
      Try If window.hwnd = exHwnd
   Return window
 }
}






;==================================================================================================
; XYplorer Send and Get functions
;==================================================================================================

XY_Get(bAll:=false, bSelection:=false)
{
    xyQueryScript := '::if (!' bAll ' && !' bSelection ') {$return = "<curpath>"`;} elseif (' bAll ') {$return = listpane(, , , "<crlf>")`;} elseif (' bSelection ') {$return = get("SelectedItemsPathNames", "<crlf>")`;} copydata ' G_OwnHWND ', "$return", 2`;'

    if xyHwnd := GetXYHWND()
       Send_WM_COPYDATA(xyHwnd, xyQueryScript)

    return dataReceived
}


GetXYHWND() {
	static xyClass := 'ahk_class ThunderRT6FormDC'

	if hwnd := WinActive(xyClass)
		return hwnd
	else if WinExist(xyClass)
		return WinGetList(xyClass)[1]
}


Send_WM_COPYDATA(xyHwnd, message) {
   if !(xyHwnd)
       return

   size := StrLen(message)

   COPYDATA := Buffer(A_PtrSize * 3)
   NumPut("Ptr", 4194305, COPYDATA, 0)
   NumPut("UInt", size * 2, COPYDATA, A_PtrSize)
   NumPut("Ptr", StrPtr(message), COPYDATA, A_PtrSize * 2)

   return DllCall("User32.dll\SendMessageW", "Ptr", xyHwnd, "UInt", 74, "Ptr", 0, "Ptr", COPYDATA, "Ptr")
}


Receive_WM_COPYDATA(wParam, lParam, *) {
	global dataReceived := StrGet(
		NumGet(lParam + 2 * A_PtrSize, 'Ptr'),   ; COPYDATASTRUCT.lpData, ptr to a str presumably
		NumGet(lParam + A_PtrSize, 'UInt') / 2   ; COPYDATASTRUCT.cbData, count bytes of lpData, /2 to get count chars in unicode str
	)
}
Last edited by Norn on 21 Apr 2023 10:37, edited 2 times in total.
Win10, Win11 @100% 2560x1440 22H2

Norn
Posts: 416
Joined: 24 Oct 2021 16:10

Re: AHK: Custom queue menus & Rock-click (Left-Mouse-Down + Right-Mouse-Click) run XYplorer script

Post by Norn »

Attachments
Queue menus2.gif
Queue menus2.gif (127.6 KiB) Viewed 952 times
Last edited by Norn on 23 Aug 2023 20:58, edited 21 times in total.
Win10, Win11 @100% 2560x1440 22H2


Norn
Posts: 416
Joined: 24 Oct 2021 16:10

Re: AHK: Custom queue menus & Rock-click (Left-Mouse-Down + Right-Mouse-Click) run XYplorer script

Post by Norn »

Last edited by Norn on 23 Aug 2023 21:00, edited 17 times in total.
Win10, Win11 @100% 2560x1440 22H2


Post Reply