Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Windows 7 Explorer Right-Click Menu


  • Please log in to reply
5 replies to this topic
Puzzled Greatly
  • Members
  • 612 posts
  • Last active: May 22 2017 11:15 PM
  • Joined: 15 Aug 2009
I have an item containing the word "Move" on the context menu of every file listed in Windows Explorer. I'd like to be able to select that item automatically using a hotkey. The position of the item varies depending upon the type of file selected so it is difficult to locate. I need to be able toloop through the context menu until I find it and then select it. I searched through the forum and came across this code:

#SingleInstance, Force
SetBatchLInes, -1

WinWait, ahk_class #32768
SendMessage, 0x1E1, 0, 0      ; MN_GETHMENU
hMenu := ErrorLevel
sContents := GetMenu(hMenu)
WinWaitClose

MsgBox, % sContents


GetMenu(hMenu)
{
   Loop, % DllCall("GetMenuItemCount", "Uint", hMenu)
   {
      idx := A_Index - 1
      idn := DllCall("GetMenuItemID", "Uint", hMenu, "int", idx)
      nSize++ := DllCall("GetMenuString", "Uint", hMenu, "int", idx, "Uint", 0, "int", 0, "Uint", 0x400)
      VarSetCapacity(sString, nSize)
      DllCall("GetMenuString", "Uint", hMenu, "int", idx, "str", sString, "int", nSize, "Uint", 0x400)   ;MF_BYPOSITION
      If !sString
         sString := "---------------------------------------"
      sContents .= idx . " : " . idn . A_Tab . A_Tab . sString . "`n"
      If (idn = -1) && (hSubMenu := DllCall("GetSubMenu", "Uint", hMenu, "int", idx))
         sContents .= GetMenu(hSubMenu)
   }
   Return   sContents
}

But when I tried running it it crashed when I brought up a context menu. Did it crash because I'm using Windows 7 64 bit and AHK_L 64 bit?

How can I get info out of a context menu or select a particular menu item when I don't know its position. Thanks.

AutoHotkeyDragon
  • Members
  • 90 posts
  • Last active: Sep 01 2013 11:06 PM
  • Joined: 20 Oct 2012
If you can get the menu name somehow, maybe you could do this?

Menu, name here, Check, item name here

I'm kinda new to AHK, so I could be wrong. Best of luck! Also, I suggest using SciTE4AutoHotkey when coding AHK if you don't already; it prints errors in the output box at the bottom of the window. If you get an error and it does not make sense to you, post it here! ;)
AHKDragon

—I should be able to help with your AHK needs, unless it has something to do with anything GUI or complex. I hold no guarantees that I WILL be able to help, though.—

Coco
  • Members
  • 697 posts
  • Last active: Oct 31 2015 07:26 PM
  • Joined: 27 Jul 2012
Tried the code you posted, crashed AHK as well, I'm using Windows 7 x86..It has nothing to do with your system..I guess.

Coco
  • Members
  • 697 posts
  • Last active: Oct 31 2015 07:26 PM
  • Joined: 27 Jul 2012
This seems to work for me: (I added the line in red)
#SingleInstance, Force
SetBatchLInes, -1

WinWait, ahk_class #32768
SendMessage, 0x1E1, 0, 0      ; MN_GETHMENU
hMenu := ErrorLevel
sContents := GetMenu(hMenu)
WinWaitClose

MsgBox, % sContents


GetMenu(hMenu)
{
   Loop, % DllCall("GetMenuItemCount", "Uint", hMenu)
   {
      idx := A_Index - 1
      idn := DllCall("GetMenuItemID", "Uint", hMenu, "int", idx)
      nSize++ := DllCall("GetMenuString", "Uint", hMenu, "int", idx, "Uint", 0, "int", 0, "Uint", 0x400)
	  [color=#FF0000]nSize := (nSize * (A_IsUnicode ? 2 : 1))[/color]
      VarSetCapacity(sString, nSize)
      DllCall("GetMenuString", "Uint", hMenu, "int", idx, "str", sString, "int", nSize, "Uint", 0x400)   ;MF_BYPOSITION
      If !sString
         sString := "---------------------------------------"
      sContents .= idx . " : " . idn . A_Tab . A_Tab . sString . "`n"
      If (idn = -1) && (hSubMenu := DllCall("GetSubMenu", "Uint", hMenu, "int", idx))
         sContents .= GetMenu(hSubMenu)
   }
   Return   sContents
}


Puzzled Greatly
  • Members
  • 612 posts
  • Last active: May 22 2017 11:15 PM
  • Joined: 15 Aug 2009
Thnaks, that stopped AHK_L crashing. I still can't quite get it to work though. I was to assign a shortcut key so that when I press it the context menu is serached and a marticular item pressed. The code almost works:

#SingleInstance, Force
SetBatchLInes, -1

!m::
send {AppsKey}
WinWait, ahk_class #32768
;sleep 500
SendMessage, 0x1E1, 0, 0      ; MN_GETHMENU
hMenu := ErrorLevel
sContents := GetMenu(hMenu)

n = 0

loop, parse, sContents, `n
{
	n++
	ifinstring,  A_LoopField, Move
	ifinstring,  A_LoopField, `.`.`.
	break
}
send {down %n%}
send {enter}

return

GetMenu(hMenu)
{
   Loop, % DllCall("GetMenuItemCount", "Uint", hMenu)
   {
      idx := A_Index - 1
      idn := DllCall("GetMenuItemID", "Uint", hMenu, "int", idx)
      nSize++ := DllCall("GetMenuString", "Uint", hMenu, "int", idx, "Uint", 0, "int", 0, "Uint", 0x400)
     nSize := (nSize * (A_IsUnicode ? 2 : 1))
      VarSetCapacity(sString, nSize)
      DllCall("GetMenuString", "Uint", hMenu, "int", idx, "str", sString, "int", nSize, "Uint", 0x400)   ;MF_BYPOSITION
      If !sString
         sString := "---------------------------------------"
      sContents .= idx . " : " . idn . A_Tab . A_Tab . sString . "`n"
      If (idn = -1) && (hSubMenu := DllCall("GetSubMenu", "Uint", hMenu, "int", idx))
         sContents .= GetMenu(hSubMenu)
   }
   Return   sContents
}


If I use winwait it seems to ignore the presence of the hotkey and trigger when I manually right-click. If I replace Winwait with sleep then the function doesn't seem to work and the first menu item is triggered. Can someone help me fix this, please.

Puzzled Greatly
  • Members
  • 612 posts
  • Last active: May 22 2017 11:15 PM
  • Joined: 15 Aug 2009
Figured it out - the problem was that !m wasn't invoking the context menu. ^m works as expected.