Sign in to follow this  
Followers 0
sbonacina

Using GetMenuItemInfo to retrieve menu item text

3 posts in this topic

#1 ·  Posted (edited)

Hello all

in my company, users use an industrial application with a dynamic menu, i.e., the menu changes depending on certain situation.

In some cases, the application is used only to display files in specific formats: since the file contains sensible information, we don't want the user to save it on the local PC, to print or to send it, functions embedded in the menu.

More, I've been asked to let some users not to print the file, to let some other users not to save the file, and so on. I mean, the user permissions on the displayed files may vary.

(of course, we examined other ways, and we cannot, for instance, implement a document management system or other kind of software for this)

The modification of the menu seems the only viable solution.

That's why I was asked to provide users with a sort of "reader" which is only able to display the file content, without letting the user to perform functions like "save as", "email to" and such.

My idea is to launch the program with autoit, but I need to catch the proper menu item to disable it. And, for this, I need to parse the menu items until I find the ones I want to disable.

The function _GUICtrlMenu_FindItem in GuiMenu.au3 is no more working, because it relies on _GUICtrlMenu_GetItemText which calls "GetMenuString" in User32.dll, which (unfortunately) has been superseded, as stated in http://msdn.microsoft.com/en-us/library/ms647983%28VS.85%29.aspx.

The MSDN page suggest to use the GetMenuItemInfo function to retrieve the menu item text.

Then the GetMenuItemInfo Function page explains:

Remarks

To retrieve a menu item of type MFT_STRING, first find the size of the string by setting the dwTypeData member of MENUITEMINFO to NULL and then calling GetMenuItemInfo. The value of cch+1 is the size needed. Then allocate a buffer of this size, place the pointer to the buffer in dwTypeData, increment cch by one, and then call GetMenuItemInfo once again to fill the buffer with the string.

If the retrieved menu item is of some other type, then GetMenuItemInfo sets the dwTypeData member to a value whose type is specified by the fTypefType member and sets cch to 0.

I must confess I'm not a real programmer, so I find some difficulties in those sentences.

Here's what I've done (which is actually not working) to get the text of the 2nd menu item in File menu running notepad:

#include <GuiMenu.au3>

Opt('MustDeclareVars', 1)
Opt("WinTitleMatchMode", 2)  
_Main()

Func _Main()
    Local $hWnd, $hMain, $hFile, $tInfo, $string, $cch, $tBuffer

    ; Open Notepad

    Run("notepad.exe")
    WinWaitActive("Blocco note")
    $hWnd = WinGetHandle("Blocco note")
    $hMain = _GUICtrlMenu_GetMenu($hWnd)
    $hFile = _GUICtrlMenu_GetItemSubMenu($hMain, 0)

    ; Get/Set Open command ID
    $tInfo = _GUICtrlMenu_GetItemInfo($hFile, 1)
    
    DllStructSetData($tInfo, "TypeData", "")
    _GUICtrlMenu_SetItemInfo($hFile, 1, $tInfo)
    $tInfo = _GUICtrlMenu_GetItemInfo($hFile, 1)
    $cch=DllStructGetData($tInfo, "CCH")
    $tBuffer = DllStructCreate("char Text[" & $cch + 1 & "]")
    DllStructSetData($tInfo, "TypeData",$tBuffer)
    DllStructSetData($tInfo, "CCH",$cch + 1)
    _GUICtrlMenu_SetItemInfo($hFile, 1, $tInfo)
    $tInfo = _GUICtrlMenu_GetItemInfo($hFile, 1)
    $string=DllStructGetData($tInfo, "TypeData")
    
    MsgBox(0,"tit",$string)

EndFunc   ;==>_Main

The result displayed by the last MsgBox looks like a pointer, displayed as 0x00000000

Any idea on what I'm doing wrong?

Any help will be appreciated

Thanks for your attention

stefano

Edited by sbonacina

Share this post


Link to post
Share on other sites



#include <GuiMenu.au3>

Opt('MustDeclareVars', 1)
Opt("WinTitleMatchMode", 2) 
_Main()

Func _Main()
    Local $hWnd, $hMain, $hFile, $tInfo, $string, $cch, $tBuffer

    ; Open Notepad

    Run("notepad.exe")
    WinWaitActive("[CLASS:Notepad]")
    $hWnd = WinGetHandle("")
    $hMain = _GUICtrlMenu_GetMenu($hWnd)
    $hFile = _GUICtrlMenu_GetItemSubMenu($hMain, 0)

    ; Get/Set Open command ID
    $tInfo = _GUICtrlMenu_GetItemInfo($hFile, 1)
    
    DllStructSetData($tInfo, "Mask", $MIIM_TYPE)
    DllStructSetData($tInfo, "Type", $MF_STRING)
    DllStructSetData($tInfo, "TypeData", "")
    _GetMenuItemInfo($tInfo, $hFile, 1)
    $cch=DllStructGetData($tInfo, "CCH")
    ConsoleWrite($cch & @CRLF)
    $tBuffer = DllStructCreate("char Text[" & $cch + 1 & "]")
    DllStructSetData($tInfo, "TypeData", DllStructGetPtr($tBuffer))
    DllStructSetData($tInfo, "CCH",$cch + 1)
    _GetMenuItemInfo($tInfo, $hFile, 1)
    
    MsgBox(0,"tit", DllStructGetData($tBuffer, 1))

EndFunc   ;==>_Main

Func _GetMenuItemInfo(ByRef $tInfo, $hMenu, $iItem, $fByPos = True)
    DllCall("User32.dll", "int", "GetMenuItemInfo", "hwnd", $hMenu, "int", $iItem, "int", $fByPos, "ptr", DllStructGetPtr($tInfo))
EndFunc

Share this post


Link to post
Share on other sites

Simply great!

Thanks a lot for your help: I'm gonna try to understand better the code now.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0