Jump to content
Sign in to follow this  

Recommended Posts

(The title of this example was originally "The Shell/Custom Favorites/Programs Menus".)

TheFavoritesMenu_zps2e52cc56.jpg

This is an implementation of the Shell Favorites and Programs menus with the IShellMenu interface.

The purpose of this menu system is to create a popup menu from a directory structure consisting of subfolders and internet or program links. The menu will look like the Favorites menu in Internet or Windows Explorer (as it looked when XP SP2 was released in August 2004).

The IShellMenu interface can generally be used to create a menu from a directory structure. The menu items will be supplied with the same icons as the link files and they will be supplied with tooltips too. When you click a menu item the command associated with the internet or program link will be executed.

The Favorites and Programs menus will create popup menus from the directory structures given by $CSIDL_FAVORITES, $CSIDL_PROGRAMS, $CSIDL_STARTMENU, $CSIDL_COMMON_PROGRAMS, $CSIDL_COMMON_STARTMENU.

The Custom Favorites and Custom Programs menus can be used to create custom popup menus from custom directory structures.

Note that the context (right click) menu is working in the Favorites menu.

Update #4 2014-05-03: AutoIt 3.3.10

This example was created under 3.3.8 and based on APIConstants.au3 and WinAPIEx.au3 by Yashied.

The original example runs under 3.3.10 without any changes at all. But a lot of unused constants and functions are included.

In 3.3.10 the two UDFs are divided into several smaller UDFs. This makes it much easier to just include, what is needed. This update only includes the necessary UDFs. You find the new and old zip in bottom of the post.

Update #3 2012-11-06: Programs menus

Added the Programs menus from the directory structures given by $CSIDL_PROGRAMS, $CSIDL_STARTMENU, $CSIDL_COMMON_PROGRAMS, $CSIDL_COMMON_STARTMENU.

To create a menu like the "All Programs" menu copy the two "Start Menu" folders (your own + "All Users") to the "Custom Programs 1" folder and overwrite the existing "Start Menu" folder. Then select the menu item "Custom Programs | Custom Programs 1".

Update #2 2012-11-03: Custom Favorites menus

If you are creating an AutoIt program and want to add a custom Favorites menu with relevant internet links all you have to do is to create a directory structure, add the subfolders (optional) and links and call the ShowFavsProgsMenu() function with a path to the directory. And you will get a menu that looks like and works like the Favorites menu in Internet Explorer.

You can see two custom Favorites menus in the examples.

Added two small directory structures to the zip to be used for the custom Favorites menus.

Fixed an error: OleInitialize() is used to initialize COM in stead of CoInitialize() (necessary to make the Copy command in the context menu work).

Update #1 2012-11-01: Window procedure

Because a popup menu like the Favorites menu is modal, it's necessary to use some kind of a window procedure to catch the menu messages. When it's a popup menu it should be enough to have the window procedure running while the popup menu is displayed.

In the original scripts the window procedure was created with these commands:

$hNewWinProc = DllCallbackRegister( "NewWindowProc", "int", "hwnd;uint;wparam;lparam" )        ; New window procedure
$hOldWinProc = _WinAPI_SetWindowLong( $hGui, $GWL_WNDPROC, DllCallbackGetPtr( $hNewWinProc ) ) ; Old window procedure
The procedure was started in the main script in the example and was running as long as the script was running.

In this update the menu messages is catched with a hook procedure:

$hFavMenuMsg = DllCallbackRegister( "FavMenuMsg", "long", "int;wparam;lparam" )
$hFavMenuMsgHook = _WinAPI_SetWindowsHookEx( $WH_MSGFILTER, DllCallbackGetPtr( $hFavMenuMsg ), 0, _WinAPI_GetCurrentThreadId() )
; $WH_MSGFILTER installs a hook procedure that monitors messages generated as a
; result of an input event in a dialog box, message box, menu, or scroll bar.
The procedure is started in the bottom of the ShowFavoritesMenu() function immediately after the Favorites menu is displayed on the screen, and the procedure is stopped when the menu disappears from the screen. Either because the menu is cancelled or a selection is made.

(If you comment out these commands in ShellFavoritesMenu.au3 the Favorites menu will still show up. But the submenus will not be expanded if you keep the mouse steady over a submenu or use the arrow keys.)

This hook procedure is much better than the original window procedure. It's much easier to integrate the Favorites menu in other programs when it isn't depending on a "global" window procedure.

A "global" window procedure can also have some influence on the GUI (at least on XP, I think it's better on 7). In the original example you saw it clearly when the GUI lost focus. When the GUI got focus back the upper line of the edit box could be behind the toolbar. This is not a problem with a hook procedure only running when the Favorites menu is displayed.

Added an example with a menu. Zip updated.

First post 2012-10-30

This is an implementation of the Favorites menu primary with the IShellMenu interface but several other interfaces are used as well.

The main function:

Func ShowFavoritesMenu( $hWnd, $hMenu, $xCoord, $yCoord )

; --- Create a menu band object and the IShellMenu interface ---

Local $oIShellMenu, $pIShellMenu
; Create a menu band object and get a pointer to the IShellMenu interface
CoCreateInstance( $tCLSID_MenuBand, $NULL, $CLSCTX_INPROC_SERVER, $tRIID_IShellMenu, $pIShellMenu )
$oIShellMenu = ObjCreateInterface( $pIShellMenu, $sIID_IShellMenu, $dtag_IShellMenu )
If Not IsObj( $oIShellMenu ) Then Return SetError(1,0,0)

; --- Initialize the interface ---

If $oIShellMenu.Initialize( $NULL, -1, $ANCESTORDEFAULT, BitOR( $SMINIT_TOPLEVEL, $SMINIT_VERTICAL ) ) <> $S_OK Then Return SetError(2,0,0)

; --- Specify the folder for the menu band to browse ---

; Get a pointer to the IShellFolder interface for the desktop
Local $pIShellFolder = $NULL, $oIShellFolderDesktop, $pIShellFolderDesktop, $pidlRel
SHGetDesktopFolder( $pIShellFolderDesktop )
SHGetSpecialFolderLocation( $NULL, $CSIDL_FAVORITES, $pidlRel )
$oIShellFolderDesktop = ObjCreateInterface( $pIShellFolderDesktop, $sIID_IShellFolder, $dtag_IShellFolder )
$oIShellFolderDesktop.BindToObject( $pidlRel, $NULL, $tRIID_IShellFolder, $pIShellFolder )
If $pIShellFolder = $NULL Then Return SetError(3,0,0)

; Get the registry key with the "Order" value of the Favorites folder
Local $hRegOrder = _WinAPI_RegOpenKey( $HKEY_CURRENT_USER, "Software\Microsoft\Windows\CurrentVersion\Explorer\MenuOrder\Favorites", $KEY_READ )
If $hRegOrder = 0 Then Return SetError(4,0,0)

; Specify the folder for the menu band to browse
If $oIShellMenu.SetShellFolder( $pIShellFolder, $pidlRel, $hRegOrder, BitOR( $SMSET_BOTTOM, $SMSET_USEBKICONEXTRACTION ) ) <> $S_OK Then Return SetError(5,0,0)
_WinAPI_CoTaskMemFree( $pidlRel )
_WinAPI_RegCloseKey( $hRegOrder )

; --- Append a static menu to the menu band ---

If $oIShellMenu.SetMenu( $hMenu, $hWnd, $SMSET_TOP ) <> $S_OK Then Return SetError(6,0,0)

; --- Get access to IMenuPopup, IDeskBar and IDeskBand interfaces ---

Local $pIMenuPopup, $pIDeskBar, $pIDeskBand

; The IMenuPopup interface
If $pIShellMenu Then
If $oIShellMenu.QueryInterface( $tRIID_IMenuPopup, $pIMenuPopup ) <> $S_OK Then Return SetError(7,0,0)
EndIf

; The IDeskBar interface
If $pIMenuPopup Then
Local $oIMenuPopup = ObjCreateInterface( $pIMenuPopup, $sIID_IMenuPopup, $dtag_IMenuPopup )
If $oIMenuPopup.QueryInterface( $tRIID_IDeskBar, $pIDeskBar ) <> $S_OK Then Return SetError(8,0,0)
EndIf

; The IDeskBand interface
If $pIDeskBar Then
Local $oIDeskBar = ObjCreateInterface( $pIDeskBar, $sIID_IDeskBar, $dtag_IDeskBar )
If $oIDeskBar.QueryInterface( $tRIID_IDeskBand, $pIDeskBand ) <> $S_OK Then Return SetError(9,0,0)
EndIf

; --- Create a menu desk bar object and the IMenuPopup interface ---

Local $oIUnknown, $pIUnknown, $oIMenuPopup, $pIMenuPopup

; Create a menu desk bar object and get a pointer to the IUnknown interface
CoCreateInstance( $tCLSID_MenuDeskBar, $NULL, $CLSCTX_INPROC_SERVER, $tRIID_IUnknown, $pIUnknown )
$oIUnknown = ObjCreateInterface( $pIUnknown, $sIID_IUnknown, $dtag_IUnknown )

; Create the IMenuPopup interface
$oIUnknown.QueryInterface( $tRIID_IMenuPopup, $pIMenuPopup )
$oIMenuPopup = ObjCreateInterface( $pIMenuPopup, $sIID_IMenuPopup, $dtag_IMenuPopup )
If Not IsObj( $oIMenuPopup ) Then Return SetError(10,0,0)

; --- Create a menu band site object and the IBandSite interface ---

Local $oIBandSite, $pIBandSite
; Create a menu band site object and get a pointer to the IBandSite interface
CoCreateInstance( $tCLSID_MenuBandSite, $NULL, $CLSCTX_INPROC_SERVER, $tRIID_IBandSite, $pIBandSite )
$oIBandSite = ObjCreateInterface( $pIBandSite, $sIID_IBandSite, $dtag_IBandSite )
If Not IsObj( $oIBandSite ) Then Return SetError(11,0,0)

; --- Set the band site object as client for the desk bar object ---

If $oIMenuPopup.SetClient( $pIBandSite ) <> $S_OK Then Return SetError(12,0,0)

; --- Add the desk band object to the band site object ---

If $oIBandSite.AddBand( $pIDeskBand ) <> $S_OK Then Return SetError(13,0,0)

; --- Show the Favorites menu ---

Local $tPOINT = DllStructCreate( $tagPOINT )
DllStructSetData( $tPOINT, "X", $xCoord )
DllStructSetData( $tPOINT, "Y", $yCoord )

Local $tRECT = DllStructCreate( $tagRECT )
DllStructSetData( $tRECT, "Left", $xCoord )
DllStructSetData( $tRECT, "Top", $yCoord+1 )
DllStructSetData( $tRECT, "Right", $xCoord )
DllStructSetData( $tRECT, "Bottom", $yCoord+1 )

$oIMenuPopup.Popup( $tPOINT, $tRECT, $MPPF_ALIGN_RIGHT )

; --- Create the IMenuBand interface ---

Local $oIDeskBand
$oIDeskBand = ObjCreateInterface( $pIDeskBand, $sIID_IDeskBand, $dtag_IDeskBand )
$oIDeskBand.QueryInterface( $tRIID_IMenuBand, $pIMenuBand )
$oIMenuBand = ObjCreateInterface( $pIMenuBand, $sIID_IMenuBand, $dtag_IMenuBand )
If Not IsObj( $oIMenuBand ) Then Return SetError(14,0,0)

; $oIMenuBand and $pIMenuBand are global variables
; $oIMenuBand is used to handle the messages from the Favorites menu in the function below
; $pIMenuBand is used to test if the Favorites menu is open ($pIMenuBand <> $NULL)

Return 0

EndFunc

Example

The zip contains the example as you can see in the picture. There are two versions of the example: A version based on a toolbar (ExShellFavsProgsMenus.au3), and a version based on a menu bar (ExShellFavsProgsMenus2.au3). The purpose of the text box is just to have something to put in the window.

The zip contains also the ShellFavsProgsMenus.au3 UDF.

This zip contains the original scripts for 3.3.8. You need APIConstants.au3 and WinAPIEx.au3 by Yashied. The UDFs are not included in the zip. The zip can be opened with 7-Zip.

ShellFavsProgsMenus.zip

This zip contains the updated scripts for 3.3.10. Only a matter of UDFs. These scripts will not run under 3.3.8.

TheFavoritesMenu.7z

Testet on XP 32 bit and Win 7 32/64 bit.

Edited by LarsJ

Share this post


Link to post
Share on other sites

JScript, Added an example with a menu. Thank you for the stars.

The "global" window procedure that runs all the time is replaced with a hook procedure that only runs when the Favorites menu is displayed.

Lars.

Edited by LarsJ

Share this post


Link to post
Share on other sites

This is fantastic :thumbsup: , I searched for such a menu for years and and always planned to programm my own

I have some questions for a bit more of control:

- Is it possible to better control the menu, like selecting items programmaticly and determine the current path ( especially when entering submenus... )

- It it possible to add own entrys directly in such a menu ( for example a recent folders entry or favourites )

 

Thanks in advance

Bluesmaster


My UDF: [topic='156155']_shellExecuteHidden[/topic]

Share this post


Link to post
Share on other sites

Bluesmaster, The purpose of this menu system is to create a popup menu from a directory structure consisting of subfolders and internet or program links. The menu will look like the Favorites menu in Internet or Windows Explorer (as they looked when XP SP2 was released in August 2004).

To control the menu you need menu handles. But menu handles are generated internally and you get new handles every time the menu is shown. So there is no easy way to control the menu.

If you add new links and subfolders to the directory structure they will be shown as new menu items and submenus. Because the entire directory structure is read each time the menu is shown you can do it dynamically.

This menu cannot replace an entire menu system. But it can be used as a part of a menu system to create a menu similar to the Favorites menu or Programs menu.

I'm using the code in this OpenGL example to create a Links menu with links to information.

Lars.

Share this post


Link to post
Share on other sites

Hello Lars,

I am glad you care for this after one year has passed. I am planning to transform this into a more general menu for moving and browsing files fast and efficent.

Just started, and its quite promising. Main hurdle is to know, the path corresponding to the object currently selected by the user.

Figured out, that the menu is represented by a "toolbar32" but I failed to get the handles :ermm: .

And even if I could get them, the other task is to get the full path of the item and not just its name in one of the submenus.

Here some attempts to get infos from the menu ( all failed )

    local $hPopupWin
    $oIMenuPopup.GetWindow( $hPopupWin )

or

$oIShellMenu.GetShellFolder( $hMenu, $hWnd, $SMSET_TOP )

or

$hToolbar = ControlGetHandle(  WinGetHandle( "[CLASS:BaseBar" ) , "" , "[CLASS:ToolbarWindow32; INSTANCE:1]" )

Can you please give me  some small tips I really got stuck for a  day now.

 

Here is a first snippet showing the direction of my attempt ( please ignore the missing error-handling for now )
ContextBrowser.au3


My UDF: [topic='156155']_shellExecuteHidden[/topic]

Share this post


Link to post
Share on other sites

Bluesmaster, I'm pretty sure you can get the path of the selected item if you implement the IShellMenuCallback interface and look for SMC_SFSELECTITEM notifications. From the documentation of SMC_SFSELECTITEM notifications: "The user has selected the item specified by the accompanying SMDATA structure." From this SMDATA structure you can get all the information you need.

I have not looked at your code yet, but the project seems to be quite interesting.

Regards Lars.

Share this post


Link to post
Share on other sites

Thanks for your answer. I will try. But I really struggle with those IInterfaces... I never really understood the difference to the "objectCreate"-method and it seems nobody can really explain it to me.

I can get the "$IID_IShellMenuCallback =  "{4CA300A1-9B8D-11d1-8B22-00C04FD918D0}"  but how to get those mysterious vTables. For me it seems like google fortune and I had no in this case.

There seem to be professional solutions like TypeLibInspector ( '?do=embed' frameborder='0' data-embedContent> title=""> ) but I never get that to run, and my question was never answerd.

Where do you get your vTables and clsids from?

 

regards Blues


My UDF: [topic='156155']_shellExecuteHidden[/topic]

Share this post


Link to post
Share on other sites

Microsoft provides info. It's documented on MSDN. If web page lacks info about v-table order or identifiers it wouldn't miss to tell you in which file those definitions are. The files are part of Microsoft SDKs.

In case you don't program for Windows and don't use Visual Studio and don't have SDK then you can allways google, for example IShellMenuCallback ReactOS or maybe IShellMenuCallback Wine and get definition from there. Former will very quickly lead you to http://doxygen.reactos.org/d4/d3f/shobjidl_8idl_source.html where you can see definition for your interface and list of functions in, of course, v-table order together with parameters definitions.

Edited by trancexx

Share this post


Link to post
Share on other sites

Bluesmaster, Here is an implementation of IShellMenuCallback. It's not completely trivial. It'll write the paths in Scite console.

Download IShellMenuCallback.au3 below.

Edit ShellFavsProgsMenus.au3 from the the zip in the first post.

Include IShellMenuCallback.au3:

; Dynamic Link Libraries
Global Const $dllOle32    = DllOpen( "ole32.dll" )
Global Const $dllShell32  = DllOpen( "shell32.dll" )
Global Const $dllUser32   = DllOpen( "user32.dll" )

#include "IShellMenuCallback.au3" ; <<<<<<<<<<<<<<<<

Comment out this line:

;Global Const $NULL = 0x0000

Comment out this section:

#cs
; IShellFolder Interface
Global Const $sIID_IShellFolder = "{000214E6-0000-0000-C000-000000000046}"
Global Const $tRIID_IShellFolder = CLSIDFromString( $sIID_IShellFolder )
Global Const $dtag_IShellFolder = _
    "ParseDisplayName hresult(hwnd;ptr;wstr;dword*;ptr*;dword*);" & _
    "EnumObjects hresult(hwnd;dword;ptr*);" & _
    "BindToObject hresult(ptr;ptr;struct*;ptr*);" & _
    "BindToStorage hresult(ptr;ptr;ptr;ptr*);" & _
    "CompareIDs hresult(lparam;ptr;ptr);" & _
    "CreateViewObject hresult(hwnd;struct*;ptr*);" & _
    "GetAttributesOf hresult(uint;struct*;ulong*);" & _
    "GetUIObjectOf hresult(hwnd;uint;struct*;struct*;uint*;ptr*);" & _
    "GetDisplayNameOf hresult(ptr;uint;struct*);" & _
    "SetNameOf hresult(hwnd;ptr;wstr;dword;ptr*);"
#ce

Comment out a line and add a line:

;If $oIShellMenu.Initialize( $NULL, -1, $ANCESTORDEFAULT, BitOR( $SMINIT_TOPLEVEL, $SMINIT_VERTICAL ) ) <> $S_OK Then Return SetError(2,0,0)
If $oIShellMenu.Initialize( $pIShellMenuCallback, -1, $ANCESTORDEFAULT, BitOR( $SMINIT_TOPLEVEL, $SMINIT_VERTICAL ) ) <> $S_OK Then Return SetError(2,0,0)

Open and run one of the examples in Scite and you'll see the paths in the console.

V-table: I get the information from the same sources as trancexx.

Regards Lars.

IShellMenuCallback.au3

Edit: See next post.

Edited by LarsJ

Share this post


Link to post
Share on other sites

You can replace oIShellMenuCallback_CallbackSM in IShellMenuCallback.au3 with this:

Func oIShellMenuCallback_CallbackSM( $pSelf, $psmd, $uMsg, $wParam, $lParam )
    ;ConsoleWrite( "oIShellMenuCallback_CallbackSM" & @CRLF )
    Switch $uMsg
        Case $SMC_SFSELECTITEM
            Local $tSMDATA = DllStructCreate( $tagSMDATA, $psmd ), $sPath
            Local $pPidl = ILClone( DllStructGetData( $tSMDATA, "pidlFolder" ) )
            $pPidl = ILCombine( $pPidl, DllStructGetData( $tSMDATA, "pidlItem" ) )
            SHGetPathFromIDList( $pPidl, $sPath )
            _WinAPI_CoTaskMemFree( $pPidl )
            ConsoleWrite( $sPath & @CRLF )
            Return $S_FALSE
        Case Else
            Return $S_FALSE
    EndSwitch
EndFunc

Add these two functions to the bottom of the file:

Func ILClone( $pidl )
    Local $aRet = DllCall( $dllShell32, "ptr", "ILClone", "ptr", $pidl )
    If @error Then Return SetError(1, 0, 0)
    Return $aRet[0]
EndFunc

Func ILCombine( $pidlAbs, $pidlRel )
    Local $aRet = DllCall( $dllShell32, "ptr", "ILCombine", "ptr", $pidlAbs, "ptr", $pidlRel )
    If @error Then Return SetError(1, 0, 0)
    Return $aRet[0]
EndFunc

Then you can delete the following:

Global Const $dllShlwapi = DllOpen( "shlwapi.dll" )

Global $iIShellFolder = 0, $apIShellFolder[1], $aoIShellFolder[1]

Func StrRetToBuf( $pSTRRET, $pidl, ByRef $sBuf, $iBuf = 512 )
    Local $aRet = DllCall( $dllShlwapi, "long", "StrRetToBufW", "ptr", $pSTRRET, "ptr", $pidl, "wstr", $sBuf, "uint", $iBuf )
    If @error Then Return SetError(1, 0, 0)
    $sBuf = $aRet[3]
    Return $aRet[0]
EndFunc

Share this post


Link to post
Share on other sites

Hello Lars,

Sorry for my late respose. Its very hard to find time at the moment. Your code is amazing. And it works :)

Honestly I would never had been able to implement this. I will need some time to develop the full context-menu-explorer.

I will post the result here. And again: Thank you so much

Bluesmaster

Edited by Bluesmaster

My UDF: [topic='156155']_shellExecuteHidden[/topic]

Share this post


Link to post
Share on other sites

Hi Lars,

I found some time to continue working on the "context-menu-explorer" based on your "ShowFavsProgsMenu". And...I am desperate.

My purpose is to merge 2 of those menus in 1 menu to augment the first menu with some "most recent folders" ... and so  on.
I build an example that should merge "c:" and "c:users" but they popup separatly, or alone or do not even popup whatever I try.

The code is extra unreadable :sweating:  because I condensed it a lot for overview reasons. But its more a  question of basic understanding.

In Point 1 ( line 90 ) I create a menu. In Point 2 ( line 120 ) I create a second one...I could write a thousand words, I think you know what I mean.

Can you please give me  some small advice again?

#include-once
#include <GuiMenu.au3>
#include "APIConstants.au3"
#include "WinAPIEx.au3"


HotKeySet( "{ESC}" , "_exit" )
Func _exit()
    Exit
EndFunc


ShowFavsProgsMenu( "C:\" )

While 1
    Sleep( 1000 )
WEnd


Func ShowFavsProgsMenu( $targetFolder , $xCoord  = "" , $yCoord  = "" , $pasteAndLeaveMode = 0 , $nFavouritesToShow = 1 )



    ; 0 - PREPARE - ( define constants and vTables )
    #region PREPARE
    Global $NULL  = 0x0000, $S_FALSE = 0x00000001, $MAX_PATH = 260, $iIShellFolder = 0, $apIShellFolder[1], $aoIShellFolder[1]
    Global $hFavsProgsMenu , $oIMenuBand, $pIMenuBand = 0x0000, $S_OK = 0, $hFavsProgsMenuMsg = 0x0000, $tFavsProgsMenuMsg, $hFavsProgsMenuMsgHook, $idFavsProgsMenuMsgUnHook = 0
    Global Const $dllOle32    = DllOpen( "ole32.dll"   )
    DllCall( $dllOle32 , "long", "OleInitialize", "ptr", 0)
    Global $tagMSG = "hwnd hwnd;uint message;wparam wParam;lparam lParam;dword time;int X;int Y"
    $IID_IShellMenuCallback =  "{4CA300A1-9B8D-11d1-8B22-00C04FD918D0}"
    $tCLSID = DllStructCreate("dword;word;word;byte[8]")    ; CLSID_MenuBand
    Global Const $tCLSID_MenuBand = $tCLSID
    Global Const $sCLSID_MenuBand = "{5B4DAE26-B807-11D0-9815-00C04FD91972}"
    DllCall( $dllOle32 , "long", "CLSIDFromString", "wstr", $sCLSID_MenuBand, "ptr", DllStructGetPtr($tCLSID))
    $tCLSID = DllStructCreate("dword;word;word;byte[8]")    ; CLSID_MenuDeskBar
    Global Const $sCLSID_MenuDeskBar = "{ECD4FC4F-521C-11D0-B792-00A0C90312E1}"
    DllCall( $dllOle32 , "long", "CLSIDFromString", "wstr", $sCLSID_MenuDeskBar, "ptr", DllStructGetPtr($tCLSID))
    Global Const $tCLSID_MenuDeskBar = $tCLSID
    $tCLSID = DllStructCreate("dword;word;word;byte[8]")    ; CLSID_MenuBandSite
    Global Const $sCLSID_MenuBandSite = "{E13EF4E4-D2F2-11D0-9816-00C04FD91972}"
    DllCall( $dllOle32 , "long", "CLSIDFromString", "wstr", $sCLSID_MenuBandSite, "ptr", DllStructGetPtr($tCLSID))
    Global Const $tCLSID_MenuBandSite = $tCLSID
    $tCLSID = DllStructCreate("dword;word;word;byte[8]")    ; IShellMenu
    Global Const $sIID_IShellMenu = "{EE1F7637-E138-11d1-8379-00C04FD918D0}"
    DllCall( $dllOle32 , "long", "CLSIDFromString", "wstr", $sIID_IShellMenu, "ptr", DllStructGetPtr($tCLSID))
    Global Const $tRIID_IShellMenu = $tCLSID
    Global Const $dtag_IShellMenu = "Initialize hresult(ptr;uint;uint;dword);GetMenuInfo hresult(ptr*;uint*;uint*;dword*);SetShellFolder hresult(ptr;ptr;handle;dword);GetShellFolder hresult(ptr*;ptr*;struct*;ptr*);" & _
    "Setmenu hresult(handle;hwnd;dword);GetMenu hresult(handle*;hwnd*;dword*);InvalidateItem hresult(ptr;dword);GetState hresult(ptr);SetMenuToolbar hresult(ptr*;dword);"
    $tCLSID = DllStructCreate("dword;word;word;byte[8]")    ; IShellFolder
    Global Const $sIID_IShellFolder = "{000214E6-0000-0000-C000-000000000046}"
    DllCall( $dllOle32 , "long", "CLSIDFromString", "wstr", $sIID_IShellFolder, "ptr", DllStructGetPtr($tCLSID))
    Global Const $tRIID_IShellFolder = $tCLSID
    Global Const $dtag_IShellFolder = "ParseDisplayName hresult(hwnd;ptr;wstr;dword*;ptr*;dword*);EnumObjects hresult(hwnd;dword;ptr*);BindToObject hresult(ptr;ptr;struct*;ptr*);BindToStorage hresult(ptr;ptr;ptr;ptr*);" & _
    "CompareIDs hresult(lparam;ptr;ptr);CreateViewObject hresult(hwnd;struct*;ptr*);GetAttributesOf hresult(uint;struct*;ulong*);GetUIObjectOf hresult(hwnd;uint;struct*;struct*;uint*;ptr*);GetDisplayNameOf hresult(ptr;uint;struct*);SetNameOf hresult(hwnd;ptr;wstr;dword;ptr*);"
    $tCLSID = DllStructCreate("dword;word;word;byte[8]")    ; IMenuPopup
    Global Const $sIID_IMenuPopup = "{D1E7AFEB-6A2E-11d0-8C78-00C04FD918B4}"
    DllCall( $dllOle32 , "long", "CLSIDFromString", "wstr", $sIID_IMenuPopup, "ptr", DllStructGetPtr($tCLSID))
    Global Const $tRIID_IMenuPopup = $tCLSID
    Global Const $dtag_IMenuPopup =     "GetWindow hresult(hwnd);ContextSensitiveHelp hresult(bool);SetClient hresult(ptr);GetClient hresult(ptr*);OnPosRectChangeDB hresult(struct*);Popup hresult(struct*;struct*;dword);OnSelect hresult(dword);SetSubMenu hresult(ptr;bool);"
    $tCLSID = DllStructCreate("dword;word;word;byte[8]")    ; IDeskBar
    Global Const $sIID_IDeskBar = "{EB0FE173-1A3A-11D0-89B3-00A0C90A90AC}"
    DllCall( $dllOle32 , "long", "CLSIDFromString", "wstr", $sIID_IDeskBar, "ptr", DllStructGetPtr($tCLSID))
    Global Const $tRIID_IDeskBar = $tCLSID
    Global Const $dtag_IDeskBar = "SetClient hresult(ptr);GetClient hresult(ptr*);OnPosRectChangeDB hresult(struct*);"
    $tCLSID = DllStructCreate("dword;word;word;byte[8]")    ; IDeskBand
    Global Const $sIID_IDeskBand = "{EB0FE172-1A3A-11D0-89B3-00A0C90A90AC}"
    DllCall( $dllOle32 , "long", "CLSIDFromString", "wstr", $sIID_IDeskBand, "ptr", DllStructGetPtr($tCLSID))
    Global Const $tRIID_IDeskBand = $tCLSID
    Global Const $dtag_IDeskBand ="GetBandInfo hresult(dword;dword;struct*);"
    $tCLSID = DllStructCreate("dword;word;word;byte[8]")    ; IUnknown
    Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}"
    DllCall( $dllOle32 , "long", "CLSIDFromString", "wstr", $sIID_IUnknown, "ptr", DllStructGetPtr($tCLSID))
    Global Const $tRIID_IUnknown = $tCLSID
    Global Const $dtag_IUnknown = "QueryInterface hresult(struct*;ptr*);AddRef ulong();Release ulong();"
    $tCLSID = DllStructCreate("dword;word;word;byte[8]")    ; IBandSite
    Global Const $sIID_IBandSite = "{4CF504B0-DE96-11D0-8B3F-00A0C911E8E5}"
    DllCall( $dllOle32 , "long", "CLSIDFromString", "wstr", $sIID_IBandSite, "ptr", DllStructGetPtr($tCLSID))
    Global Const $tRIID_IBandSite = $tCLSID
    Global Const $dtag_IBandSite =  "AddBand hresult(ptr);EnumBands hresult(uint;dword*);QueryBand hresult(dword;ptr*;dword*;wstr;int);SetBandState hresult(dword;dword;dword);RemoveBand hresult(dword);GetBandObject hresult(dword;struct*;ptr*);SetBandSiteInfo hresult(ptr);GetBandSiteInfo hresult(ptr*);"                                         ; BANDSITEINFO* pbsinfo
    $tCLSID = DllStructCreate("dword;word;word;byte[8]")    ; IMenuBand
    Global Const $sIID_IMenuBand = "{568804CD-CBD7-11d0-9816-00C04FD91972}"
    DllCall( $dllOle32 , "long", "CLSIDFromString", "wstr", $sIID_IMenuBand, "ptr", DllStructGetPtr($tCLSID))
    Global Const $tRIID_IMenuBand = $tCLSID
    Global Const $dtag_IMenuBand = "IsMenuMessage hresult(struct*);TranslateMenuMessage hresult(struct*;lresult*);"
    #endregion PREPARE



    ; 1 - MENU 1  ( "c:\" )
    Local $oMainFolderMenu, $pIShellMenu , $CLSCTX_INPROC_SERVER = 0x1
    $pIShellMenu = DllCall( $dllOle32, "long_ptr", "CoCreateInstance", "ptr", DllStructGetPtr($tCLSID_MenuBand), "ptr", $NULL, "dword", $CLSCTX_INPROC_SERVER, "ptr", DllStructGetPtr($tRIID_IShellMenu), "ptr*", 0 )
    $oMainFolderMenu = ObjCreateInterface( $pIShellMenu[5] , $sIID_IShellMenu, $dtag_IShellMenu )
    ;~  $SMINIT_RESTRICT_DRAGDROP  = 0x00000002  ; Don't allow Drag and Drop  | $SMINIT_TOPLEVEL = 0x00000004  ; This is the top band. | $SMSET_DONTOWN   = 0x00000001  ; The Menuband doesn't own the non-ref counted object
    Local $SMINIT_VERTICAL = 0x10000000, $ANCESTORDEFAULT  = 0xFFFFFFFF, $SMSET_USEBKICONEXTRACTION = 0x00000008 , $SMSET_TOP = 0x10000000 ,$SMINIT_TOPLEVEL  = 0x00000004  ,$SMSET_BOTTOM  = 0x20000000  ; Bias this namespace to the bottom of the menu
    $oMainFolderMenu.Initialize(  ObjCreateInterfaceEx( "oIShellMenuCallback_", "CallbackSM hresult(ptr;uint;wparam;lparam);", True ) , -1, $ANCESTORDEFAULT, BitOR( $SMINIT_TOPLEVEL, $SMINIT_VERTICAL ) ) ; Callback installieren
    $r = DllCall( "shell32.dll" , "uint", "SHILCreateFromPath", "wstr",   $targetFolder  , "ptr*", 0, "dword*", 0 ) ; set Folder
    $oMainFolderMenu.SetShellFolder( $NULL , $r[2] , $NULL , BitOR( $SMSET_BOTTOM, $SMSET_USEBKICONEXTRACTION ) )

    ;  IMenuPopup  >>  IDeskBar  >> IDeskBand  >>  IShellMenu )
    Local $pIMenuPopup, $pIDeskBar, $pIDeskBand
    $oMainFolderMenu.QueryInterface( $tRIID_IMenuPopup, $pIMenuPopup )               ; IShellMenu  >> ... >>  IMenuPopup ???
    $oIMenuPopup = ObjCreateInterface( $pIMenuPopup, $sIID_IMenuPopup, $dtag_IMenuPopup )
    $oIMenuPopup.QueryInterface( $tRIID_IDeskBar, $pIDeskBar )
    $oIDeskBar   = ObjCreateInterface( $pIDeskBar, $sIID_IDeskBar, $dtag_IDeskBar )
    $oIDeskBar.QueryInterface( $tRIID_IDeskBand, $pIDeskBand )                       ; IBandSite  >>  IDeskbar
    $pIUnknown   = DllCall( $dllOle32, "long_ptr", "CoCreateInstance", "ptr", DllStructGetPtr($tCLSID_MenuDeskBar), "ptr", $NULL, "dword", $CLSCTX_INPROC_SERVER, "ptr", DllStructGetPtr($tRIID_IUnknown), "ptr*", 0 )
    $oIUnknown   = ObjCreateInterface( $pIUnknown[5] , $sIID_IUnknown, $dtag_IUnknown )
    $oIUnknown.QueryInterface( $tRIID_IMenuPopup, $pIMenuPopup )
    $oIMenuPopup = ObjCreateInterface( $pIMenuPopup, $sIID_IMenuPopup, $dtag_IMenuPopup )
    $pIBandSite  = DllCall( $dllOle32, "long_ptr", "CoCreateInstance", "ptr", DllStructGetPtr($tCLSID_MenuBandSite), "ptr", $NULL, "dword", $CLSCTX_INPROC_SERVER, "ptr", DllStructGetPtr($tRIID_IBandSite), "ptr*", 0 )
    $oIBandSite  = ObjCreateInterface( $pIBandSite[5] , $sIID_IBandSite, $dtag_IBandSite )
    $oIMenuPopup.SetClient( $pIBandSite[5] ) ;                IBandSite  >>  IMenuPopup
    $oIBandSite.AddBand( $pIDeskBand )       ; IDeskBand  >>  IBandSite





    ; 2 - MENU 2 ( "C:\Users" )
    Local $oAppendixMenu, $pIShellMenu2 , $CLSCTX_INPROC_SERVER = 0x1
    $pIShellMenu2  = DllCall( $dllOle32, "long_ptr", "CoCreateInstance", "ptr", DllStructGetPtr($tCLSID_MenuBand), "ptr", $NULL, "dword", $CLSCTX_INPROC_SERVER, "ptr", DllStructGetPtr($tRIID_IShellMenu), "ptr*", 0 )
    $oAppendixMenu = ObjCreateInterface( $pIShellMenu2[5] , $sIID_IShellMenu, $dtag_IShellMenu )
    ;~  $SMINIT_RESTRICT_DRAGDROP  = 0x00000002  ; Don't allow Drag and Drop  | $SMINIT_TOPLEVEL = 0x00000004  ; This is the top band. | $SMSET_DONTOWN   = 0x00000001  ; The Menuband doesn't own the non-ref counted object
    Local $SMINIT_VERTICAL = 0x10000000, $ANCESTORDEFAULT  = 0xFFFFFFFF, $SMSET_USEBKICONEXTRACTION = 0x00000008 , $SMSET_TOP = 0x10000000 ,$SMINIT_TOPLEVEL  = 0x00000004  ,$SMSET_BOTTOM  = 0x20000000  ; Bias this namespace to the bottom of the menu
    $oAppendixMenu.Initialize(  ObjCreateInterfaceEx( "oIShellMenuCallback2_", "CallbackSM hresult(ptr;uint;wparam;lparam);", True ) , -1, $ANCESTORDEFAULT, BitOR( $SMINIT_TOPLEVEL, $SMINIT_VERTICAL ) ) ; Callback installieren
    $r = DllCall( "shell32.dll" , "uint", "SHILCreateFromPath", "wstr",     "C:\Users"    , "ptr*", 0, "dword*", 0 ) ; set Folder
    $oAppendixMenu.SetShellFolder( $NULL , $r[2] , $NULL , BitOR( $SMSET_BOTTOM, $SMSET_USEBKICONEXTRACTION ) )

    ; IMenuPopup  >>  IDeskBar  >> IDeskBand  >>  IShellMenu )
    Local $pIMenuPopup2, $pIDeskBar2, $pIDeskBand2
    $oAppendixMenu.QueryInterface( $tRIID_IMenuPopup, $pIMenuPopup2 )
    $oIMenuPopup2 = ObjCreateInterface( $pIMenuPopup2, $sIID_IMenuPopup, $dtag_IMenuPopup )
    $oIMenuPopup2.QueryInterface( $tRIID_IDeskBar, $pIDeskBar2 )
    $oIDeskBar2 = ObjCreateInterface( $pIDeskBar2, $sIID_IDeskBar, $dtag_IDeskBar )
    $oIDeskBar2.QueryInterface( $tRIID_IDeskBand, $pIDeskBand2 )
    $pIUnknown2 = DllCall( $dllOle32, "long_ptr", "CoCreateInstance", "ptr", DllStructGetPtr($tCLSID_MenuDeskBar), "ptr", $NULL, "dword", $CLSCTX_INPROC_SERVER, "ptr", DllStructGetPtr($tRIID_IUnknown), "ptr*", 0 )
    $oIUnknown2 = ObjCreateInterface( $pIUnknown2[5] , $sIID_IUnknown, $dtag_IUnknown )
    $oIUnknown2.QueryInterface( $tRIID_IMenuPopup, $pIMenuPopup2 )
    $oIMenuPopup2 = ObjCreateInterface( $pIMenuPopup2, $sIID_IMenuPopup, $dtag_IMenuPopup )
    $pIBandSite2 = DllCall( $dllOle32, "long_ptr", "CoCreateInstance", "ptr", DllStructGetPtr($tCLSID_MenuBandSite), "ptr", $NULL, "dword", $CLSCTX_INPROC_SERVER, "ptr", DllStructGetPtr($tRIID_IBandSite), "ptr*", 0 )
    $oIBandSite2 = ObjCreateInterface( $pIBandSite2[5] , $sIID_IBandSite, $dtag_IBandSite )
    $oIMenuPopup2.SetClient( $pIBandSite2[5] ) ; IBandSite  >>  IMenuPopup
    $oIBandSite2.AddBand( $pIDeskBand2 )       ; IDeskBand  >>  IBandSite
;~  $oIBandSite.AddBand( $pIDeskBand2 )       ; IDeskBand  >>  IBandSite



    ; 3 - APPEND  -   ( ...to exsiting menu = optional )
    $hWnd   = GUICreate( "" )
    $hMenu  = _GUICtrlMenu_CreatePopup()
    _GUICtrlMenu_InsertMenuItem( $hMenu , 0 , "&custom command 2" , 55 )
    _GUICtrlMenu_InsertMenuItem( $hMenu , 0 , "&custom command 1" , 55 )
    _GUICtrlMenu_AddMenuItem(  $hMenu  , ""  ) ; Separator
    _GUICtrlMenu_AddMenuItem(  $hMenu  , ""  )
    $oMainFolderMenu.SetMenu( $hMenu, $hWnd, $SMSET_TOP )
    $oAppendixMenu.SetMenu(   $hMenu, $hWnd, $SMSET_TOP )



    ; 4 - SHOW    -  ( position )
    ; Flags > IMenuPopup::Popup method
    Global Enum _
        $MPPF_SETFOCUS          = 0x1, _        ; The menu should have focus when it appears.
        $MPPF_INITIALSELECT     = 0x2, _        ; The first item in the menu should be selected.
        $MPPF_NOANIMATE         = 0x4, _        ; Do not animate this show.
        $MPPF_KEYBOARD          = 0x10, _       ; The menu is activated by the keyboard.
        $MPPF_REPOSITION        = 0x20, _       ; Reposition the displayed bar.
        $MPPF_FORCEZORDER       = 0x40, _       ; The menu bar should ignore submenu positions.
        $MPPF_FINALSELECT       = 0x80, _       ; The last item in the menu should be selected.
        $MPPF_TOP               = 0x20000000, _ ; Display the pop-up menu above the point specified in ppt.
        $MPPF_LEFT              = 0x40000000, _ ; Display the pop-up menu to the left of the point specified in ppt.
        $MPPF_RIGHT             = 0x60000000, _ ; Display the pop-up menu to the right of the point specified in ppt.
        $MPPF_BOTTOM            = 0x80000000, _ ; Display the pop-up menu below the point specified in ppt.
        $MPPF_POS_MASK          = 0xE0000000, _ ; Mask for position values MPPF_TOP, MPPF_LEFT, and MPPF_RIGHT.
        $MPPF_ALIGN_LEFT        = 0x2000000, _  ; Default alignment.
        $MPPF_ALIGN_RIGHT       = 0x4000000     ; The pop-up menu should be aligned to the right of the excluded rectangle specified by prcExclude.

    if $xCoord  = "" Then    ; falls keine Position gegeben > am Mauszeiger erstellen
        $xCoord = MouseGetPos( 0 )
        $yCoord = MouseGetPos( 1 )
    EndIf
    Local $tPOINT = DllStructCreate( $tagPOINT )
    DllStructSetData( $tPOINT, "X", $xCoord )
    DllStructSetData( $tPOINT, "Y", $yCoord )
    Local $tRECT = DllStructCreate( $tagRECT )
    DllStructSetData( $tRECT, "Left", $xCoord )
    DllStructSetData( $tRECT, "Top", $yCoord+1 )
    DllStructSetData( $tRECT, "Right", $xCoord )
    DllStructSetData( $tRECT, "Bottom", $yCoord+1 )
    $oIMenuPopup.Popup( $tPOINT, $tRECT, $MPPF_ALIGN_RIGHT )
    $oIMenuPopup2.Popup( $tPOINT, $tRECT, $MPPF_ALIGN_RIGHT )
;~  $oIMenuPopup2.SetSubMenu( $oIMenuPopup , 1 )



    ; 5 - MESSAGE HOOK  - ( messages to expand the submenus and other user interaction )
    Local $oIDeskBand
    $oIDeskBand = ObjCreateInterface( $pIDeskBand, $sIID_IDeskBand, $dtag_IDeskBand )
    $oIDeskBand.QueryInterface( $tRIID_IMenuBand, $pIMenuBand )
    $oIMenuBand = ObjCreateInterface( $pIMenuBand, $sIID_IMenuBand, $dtag_IMenuBand )
    If $idFavsProgsMenuMsgUnHook = 0 Then $idFavsProgsMenuMsgUnHook = GUICtrlCreateDummy()
    $hFavsProgsMenuMsg = DllCallbackRegister( "FavsProgsMenuMsg", "long", "int;wparam;lparam" )
    $hFavsProgsMenuMsgHook = _WinAPI_SetWindowsHookEx( $WH_MSGFILTER, DllCallbackGetPtr( $hFavsProgsMenuMsg ), 0, _WinAPI_GetCurrentThreadId() )

    Return 0

EndFunc




Func FavsProgsMenuMsg( $nCode, $wParam, $lParam )

;~  If $nCode <=  0 Then Return
;~  ConsoleWrite( $nCode & @CRLF )

    If $pIMenuBand Then  ; Falls das Menü noch existiert > Windowmessages auswerten

        $tFavsProgsMenuMsg = DllStructCreate( $tagMSG, $lParam )
        $msg = DllStructGetData( $tFavsProgsMenuMsg, "message" )
        if $msg = $WM_NULL OR $msg = $WM_PAINT OR $msg = $WM_TIMER  OR $msg = 0x0118 OR ( $msg > $WM_MOUSEFIRST AND $msg < $WM_XBUTTONDBLCLK ) Then  Return False   ; 0x0118 ~ WM_SYSTIMER

        ; TRANSLATE MESSAGE ( menü auffordern, die Nachricht auszuwerten )
        $i = $oIMenuBand.IsMenuMessage( $tFavsProgsMenuMsg )
        If $i >= 0 Then
            $tLRESULT = DllStructCreate( "lresult" )
            If $oIMenuBand.TranslateMenuMessage( $tFavsProgsMenuMsg, $tLRESULT ) = $S_OK Then Return True
        ElseIf $i = $E_FAIL Then
            ; The menu has exited the menu mode and can be destroyed
            $pIMenuBand = $NULL
            Return False
        EndIf
        Return False


    Else; Falls das Menü nicht mehr existiert

        If $hFavsProgsMenuMsg <> $NULL Then

        _GUICtrlMenu_DestroyMenu( $hFavsProgsMenu )
        _WinAPI_UnhookWindowsHookEx( $hFavsProgsMenuMsgHook )
;~      DllCallbackFree( $hFavsProgsMenuMsg )  ; Aufhänger, grund unbekannt

        EndIf

        Return False

    EndIf


EndFunc




    Func ObjCreateInterfaceEx( $sFunctionPrefix, $dtag_Interface, $fNoUnknown = False )
    ; ObjCreateInterfaceEx creates custom object defined with "dtag" interface description string.
    ; Main purpose of this function is to create custom objects that serve as event handlers for other objects.
    ; Registered callback functions (defined methods) are left for AutoIt to free at its convenience on exit.

        ; Original is _AutoItObject_ObjectFromDtag in AutoItObject.au3 by the AutoItObject-Team
        ; (http://www.autoitscript.com/forum/index.php?showtopic=110379, v1.2.8.3 in post 302)
        ; Modified by Ward (http://www.autoitscript.com/forum/index.php?showtopic=138372)

        If $fNoUnknown Then $dtag_Interface = "QueryInterface hresult(ptr;ptr*);AddRef ulong();Release ulong();" & $dtag_Interface ; Inherits from IUnknown
        Local $sMethods = StringTrimRight(StringReplace(StringRegExpReplace($dtag_Interface, "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF), ";" & @LF, @LF), 1)
        If $sMethods = $dtag_Interface Then $sMethods = StringTrimRight(StringReplace(StringRegExpReplace($dtag_Interface, "\h*(\w+)\h*(;|;*\z)", "$1\|" & @LF), ";" & @LF, @LF), 1)
        $sMethods = StringReplace(StringReplace(StringReplace(StringReplace($sMethods, "object", "idispatch", 0, 1), "variant*", "ptr"), "hresult", "long"), "bstr", "ptr")

        Local $aMethods = StringSplit($sMethods, @LF, 3)
        Local $iUbound = UBound($aMethods)
        Local $sMethod, $aSplit, $sNamePart, $aTagPart, $sTagPart, $sRet, $sParams, $hCallback

        Local $PtrSize = DllStructGetSize(DllStructCreate("ptr", 1))
        Local $AllocSize = $PtrSize * ($iUbound + 1)
        Local $AllocPtr = _WinAPI_CoTaskMemAlloc( $AllocSize )
        If @error Or $AllocPtr = 0 Then Return SetError(1, 0, 0)

        Local $tInterface = DllStructCreate("ptr[" & $iUbound + 1 & "]", $AllocPtr)
        If @error Then Return SetError(1, 0, 0)
        For $i = 0 To $iUbound - 1
            $aSplit = StringSplit($aMethods[$i], "|", 2)
            If UBound($aSplit) <> 2 Then ReDim $aSplit[2]
            $sNamePart = $aSplit[0]
            $sTagPart = $aSplit[1]
            $sMethod = $sFunctionPrefix & $sNamePart
            $aTagPart = StringSplit($sTagPart, ";", 2)
            $sRet = $aTagPart[0]
            $sParams = StringReplace($sTagPart, $sRet, "", 1)
            $sParams = "ptr" & $sParams
            $hCallback = Eval(":Callback:" & $sMethod)
            If Not $hCallback Then
                $hCallback = DllCallbackRegister($sMethod, $sRet, $sParams)
                Assign(":Callback:" & $sMethod, $hCallback, 2)
            EndIf
            DllStructSetData($tInterface, 1, DllCallbackGetPtr($hCallback), $i + 2)
        Next
        DllStructSetData($tInterface, 1, $AllocPtr + $PtrSize) ; Interface method pointers are actually pointer size away
        Return $AllocPtr
    EndFunc



    Func SHGetPathFromIDList( $pidl, ByRef $sPath )
        Local $stPath = DllStructCreate( "wchar[" & $MAX_PATH & "]" )
        Local $aRet = DllCall( "shell32.dll", "int", "SHGetPathFromIDListW", "ptr", $pidl, "ptr", DllStructGetPtr( $stPath ) )
        If @error Then Return SetError(1, 0, 0)
        $sPath = DllStructGetData( $stPath, 1 )
        Return $aRet[0]
    EndFunc



    Func StrRetToBuf( $pSTRRET, $pidl, ByRef $sBuf, $iBuf = 512 )
        Local $aRet = DllCall( "shlwapi.dll", "long", "StrRetToBufW", "ptr", $pSTRRET, "ptr", $pidl, "wstr", $sBuf, "uint", $iBuf )
        If @error Then Return SetError(1, 0, 0)
        $sBuf = $aRet[3]
        Return $aRet[0]
    EndFunc





#region CALLBACK


    Func oIShellMenuCallback_CallbackSM( $pSelf, $psmd, $uMsg, $wParam, $lParam )

        ;ConsoleWrite( "oIShellMenuCallback_CallbackSM" & @CRLF )
        Local $pIShellFolder, $oIShellFolder


        ; SMC_XXX messages and notifications
        ;~  $SMC_INITMENU                = 0x00000001
        ;~  $SMC_CREATE                  = 0x00000002
        ;~  $SMC_EXITMENU                = 0x00000003
        ;~  $SMC_GETINFO                 = 0x00000005
        ;~  $SMC_GETSFINFO               = 0x00000006
        ;~  $SMC_GETOBJECT               = 0x00000007
        ;~  $SMC_GETSFOBJECT             = 0x00000008
        ;~  $SMC_SFEXEC                  = 0x00000009
            $SMC_SFSELECTITEM            = 0x0000000A
        ;~  $SMC_REFRESH                 = 0x00000010
        ;~  $SMC_DEMOTE                  = 0x00000011
        ;~  $SMC_PROMOTE                 = 0x00000012
        ;~  $SMC_DEFAULTICON             = 0x00000016
        ;~  $SMC_NEWITEM                 = 0x00000017
        ;~  $SMC_CHEVRONEXPAND           = 0x00000019
        ;~  $SMC_DISPLAYCHEVRONTIP       = 0x0000002A
        ;~  $SMC_SETSFOBJECT             = 0x0000002D
        ;~  $SMC_SHCHANGENOTIFY          = 0x0000002E
        ;~  $SMC_CHEVRONGETTIP           = 0x0000002F
        ;~  $SMC_SFDDRESTRICTED          = 0x00000030
        ;~  $SMC_SFEXEC_MIDDLE           = 0x00000031
        ;~  $SMC_GETAUTOEXPANDSTATE      = 0x00000041
        ;~  $SMC_AUTOEXPANDCHANGE        = 0x00000042
        ;~  $SMC_GETCONTEXTMENUMODIFIER  = 0x00000043
        ;~  $SMC_GETBKCONTEXTMENU        = 0x00000044
        ;~  $SMC_OPEN                    = 0x00000045


            $SHGDN_NORMAL        = 0x0000
        ;~  $SHGDN_INFOLDER      = 0x0001
        ;~  $SHGDN_FOREDITING    = 0x1000
        ;~  $SHGDN_FORADDRESSBAR = 0x4000
        ;~  $SHGDN_FORPARSING    = 0x8000

        Switch $uMsg

                Case $SMC_SFSELECTITEM  ;SESESESESESESESESESESESESESESESESESE   SELECTED  SESESESESESESESESESESESESESESESESESESESESESE

                    $tagSMDATA = "dword dwMask;dword dwFlags;handle hmenu;hwnd hwnd;uint uId;uint UIDParent;uint uIdAncestor;ptr punk;ptr pidlFolder;ptr pidlItem;ptr psf;ptr pvUserData"   ; SMDATA struct
                    Local $tSMDATA = DllStructCreate( $tagSMDATA, $psmd )
                    ; New IShellFolder interface?
                    $pIShellFolder = DllStructGetData( $tSMDATA, "psf" )
                    For $i = 0 To $iIShellFolder - 1
                        If $pIShellFolder = $apIShellFolder[$i] Then ExitLoop
                    Next
                    If $i < $iIShellFolder Then
                        $oIShellFolder = $aoIShellFolder[$i]
                    Else
                        If Mod( $iIShellFolder, 10 ) = 0 Then
                            ReDim $apIShellFolder[$iIShellFolder+10]
                            ReDim $aoIShellFolder[$iIShellFolder+10]
                        EndIf
                        $apIShellFolder[$iIShellFolder] = $pIShellFolder
                        $oIShellFolder = ObjCreateInterface( $pIShellFolder, $sIID_IShellFolder, $dtag_IShellFolder )
                        $aoIShellFolder[$iIShellFolder] = $oIShellFolder
                        $iIShellFolder += 1
                    EndIf
                    ; Parent folder
                    Local $pParentFolder = DllStructGetData( $tSMDATA, "pidlFolder" ), $sPath
                    SHGetPathFromIDList( $pParentFolder, $sPath )
                    ; Current file or folder

                    Local $tSTRRET = DllStructCreate( "uint uType;ptr data;" ), $sName
                    $oIShellFolder.GetDisplayNameOf( DllStructGetData( $tSMDATA, "pidlItem" ), $SHGDN_NORMAL, $tSTRRET )
                    StrRetToBuf( DllStructGetPtr( $tSTRRET ), $NULL, $sName )

                    ; Full path

                    $fullPath = StringReplace(  $sPath & "\" & $sName , "\\" , "\"  )
                    ConsoleWrite( $fullPath & @CRLF )

                    Return $S_FALSE

            Case Else

                Return $S_FALSE
        EndSwitch

    EndFunc


    Func oIShellMenuCallback_QueryInterface( $pSelf, $pRIID, $pObj )
        Return $E_NOTIMPL
    EndFunc

    Func oIShellMenuCallback_AddRef( $pSelf )  ; neues Untermenü erstellen
        ConsoleWrite( "oIShellMenuCallback_AddRef" & @CRLF )
        $iIShellMenuCallback_Ref = 0
        $iIShellMenuCallback_Ref += 1
        Return $iIShellMenuCallback_Ref
    EndFunc

    Func oIShellMenuCallback_Release( $pSelf )
        ConsoleWrite( "oIShellMenuCallback_Release" & @CRLF )
        $iIShellMenuCallback_Ref = 0
        $iIShellMenuCallback_Ref -= 1
        Return $iIShellMenuCallback_Ref
    EndFunc


#endregion CALLBACK




#region CALLBACK 2


    Func oIShellMenuCallback2_CallbackSM( $pSelf, $psmd, $uMsg, $wParam, $lParam )

        ;ConsoleWrite( "oIShellMenuCallback_CallbackSM" & @CRLF )
        Local $pIShellFolder, $oIShellFolder


        ; SMC_XXX messages and notifications
        ;~  $SMC_INITMENU                = 0x00000001
        ;~  $SMC_CREATE                  = 0x00000002
        ;~  $SMC_EXITMENU                = 0x00000003
        ;~  $SMC_GETINFO                 = 0x00000005
        ;~  $SMC_GETSFINFO               = 0x00000006
        ;~  $SMC_GETOBJECT               = 0x00000007
        ;~  $SMC_GETSFOBJECT             = 0x00000008
        ;~  $SMC_SFEXEC                  = 0x00000009
            $SMC_SFSELECTITEM            = 0x0000000A
        ;~  $SMC_REFRESH                 = 0x00000010
        ;~  $SMC_DEMOTE                  = 0x00000011
        ;~  $SMC_PROMOTE                 = 0x00000012
        ;~  $SMC_DEFAULTICON             = 0x00000016
        ;~  $SMC_NEWITEM                 = 0x00000017
        ;~  $SMC_CHEVRONEXPAND           = 0x00000019
        ;~  $SMC_DISPLAYCHEVRONTIP       = 0x0000002A
        ;~  $SMC_SETSFOBJECT             = 0x0000002D
        ;~  $SMC_SHCHANGENOTIFY          = 0x0000002E
        ;~  $SMC_CHEVRONGETTIP           = 0x0000002F
        ;~  $SMC_SFDDRESTRICTED          = 0x00000030
        ;~  $SMC_SFEXEC_MIDDLE           = 0x00000031
        ;~  $SMC_GETAUTOEXPANDSTATE      = 0x00000041
        ;~  $SMC_AUTOEXPANDCHANGE        = 0x00000042
        ;~  $SMC_GETCONTEXTMENUMODIFIER  = 0x00000043
        ;~  $SMC_GETBKCONTEXTMENU        = 0x00000044
        ;~  $SMC_OPEN                    = 0x00000045


            $SHGDN_NORMAL        = 0x0000
        ;~  $SHGDN_INFOLDER      = 0x0001
        ;~  $SHGDN_FOREDITING    = 0x1000
        ;~  $SHGDN_FORADDRESSBAR = 0x4000
        ;~  $SHGDN_FORPARSING    = 0x8000

        Switch $uMsg

                Case $SMC_SFSELECTITEM  ;SESESESESESESESESESESESESESESESESESE   SELECTED  SESESESESESESESESESESESESESESESESESESESESESE

                    $tagSMDATA = "dword dwMask;dword dwFlags;handle hmenu;hwnd hwnd;uint uId;uint UIDParent;uint uIdAncestor;ptr punk;ptr pidlFolder;ptr pidlItem;ptr psf;ptr pvUserData"   ; SMDATA struct
                    Local $tSMDATA = DllStructCreate( $tagSMDATA, $psmd )
                    ; New IShellFolder interface?
                    $pIShellFolder = DllStructGetData( $tSMDATA, "psf" )
                    For $i = 0 To $iIShellFolder - 1
                        If $pIShellFolder = $apIShellFolder[$i] Then ExitLoop
                    Next
                    If $i < $iIShellFolder Then
                        $oIShellFolder = $aoIShellFolder[$i]
                    Else
                        If Mod( $iIShellFolder, 10 ) = 0 Then
                            ReDim $apIShellFolder[$iIShellFolder+10]
                            ReDim $aoIShellFolder[$iIShellFolder+10]
                        EndIf
                        $apIShellFolder[$iIShellFolder] = $pIShellFolder
                        $oIShellFolder = ObjCreateInterface( $pIShellFolder, $sIID_IShellFolder, $dtag_IShellFolder )
                        $aoIShellFolder[$iIShellFolder] = $oIShellFolder
                        $iIShellFolder += 1
                    EndIf
                    ; Parent folder
                    Local $pParentFolder = DllStructGetData( $tSMDATA, "pidlFolder" ), $sPath
                    SHGetPathFromIDList( $pParentFolder, $sPath )
                    ; Current file or folder

                    Local $tSTRRET = DllStructCreate( "uint uType;ptr data;" ), $sName
                    $oIShellFolder.GetDisplayNameOf( DllStructGetData( $tSMDATA, "pidlItem" ), $SHGDN_NORMAL, $tSTRRET )
                    StrRetToBuf( DllStructGetPtr( $tSTRRET ), $NULL, $sName )

                    ; Full path

                    $fullPath = StringReplace(  $sPath & "\" & $sName , "\\" , "\"  )
                    ConsoleWrite( $fullPath & @CRLF )

                    Return $S_FALSE

            Case Else

                Return $S_FALSE
        EndSwitch

    EndFunc


    Func oIShellMenuCallback2_QueryInterface( $pSelf, $pRIID, $pObj )
        Return $E_NOTIMPL
    EndFunc

    Func oIShellMenuCallback2_AddRef( $pSelf )  ; neues Untermenü erstellen
        ConsoleWrite( "oIShellMenuCallback2_AddRef" & @CRLF )
        $iIShellMenuCallback_Ref = 0
        $iIShellMenuCallback_Ref += 1
        Return $iIShellMenuCallback_Ref
    EndFunc

    Func oIShellMenuCallback2_Release( $pSelf )
        ConsoleWrite( "oIShellMenuCallback2_Release" & @CRLF )
        $iIShellMenuCallback_Ref = 0
        $iIShellMenuCallback_Ref -= 1
        Return $iIShellMenuCallback_Ref
    EndFunc


#endregion CALLBACK 2

ContexMenuBrowser.au3

Edited by Bluesmaster

My UDF: [topic='156155']_shellExecuteHidden[/topic]

Share this post


Link to post
Share on other sites

Why on earth do you think you can put menus together in that way? What you can do is to add a Recent Folders menu to the static part of the menu. The menu you are using in SetMenu. You can do this with the usual functions in GuiMenu.au3. Add the folders to the static menu before you call SetMenu.

Share this post


Link to post
Share on other sites

Sorry that was just a guess. I thought if one can append it to another menu, then the purpose of this must be to append multiple menus.

Are you absolutly sure this is not possible? If so I would have to find a workaround with the static part of the menu of course, but I see some disadvantages.

However you are the expert and I trust your word and start implementing the static solution.

Thanks.

Blues


My UDF: [topic='156155']_shellExecuteHidden[/topic]

Share this post


Link to post
Share on other sites

Hello LarsJ,

Do you think those menus will work for virtual folder too? ( like the control panel  = )

I cannot try because I dunno how to get the PIDL of such a folder as:

$r = DllCall( "shell32.dll" , "uint", "SHILCreateFromPath", "wstr",   $targetFolder  , "ptr*", 0, "dword*", 0 )

only works with paths. And virtual folders only got CLSIDS as far as I know.

Do you know a CLSID > PIDL method? Or any other suggestion?

Thank you

PS: CLSID for control panel:

ShellExecute( "explorer" , "shell:::{7be9d83c-a729-4d97-b5a7-1b7313c39e0a}" )
Edited by Bluesmaster

My UDF: [topic='156155']_shellExecuteHidden[/topic]

Share this post


Link to post
Share on other sites

_WinAPI_ShellGetKnownFolderIDList will get the PIDL.

http://msdn.microsoft.com/en-us/library/windows/desktop/bb762187(v=vs.85).aspx


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

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  

  • Similar Content

    • By nacerbaaziz
      hi dears, i have a question please
      am now working for an audio player for the blind users
      and i added an option to open a file from the right click context menu.
      but here there is a small problem, i hope that you can help me to find a solution for it.
      the problem is as follow :
      when i added the problem into the context menu it work with successfuly if the user select just one file.
      but if the user selected more then one file, here the problem
      a multiple sections of the program will open.
      my question is :
      how i can detect the multiple selection from the context menu?
      i know that it so  hard, but i know also that you are harder than it
      for that dears please try to give me an solution for that problem.
      thanks in advance
    • By wolflake
      I've used PowerPro for years and it had a feature that let you turn an array into a menu.  It also let you know if it got a right click. I liked the right click feature because it doubled the menu item usage ie left/right on the same menu item.  I tried recreate that usage with a context menu.   With _ArrayToMenu you can pass menu items for 1 and 2 dimensional arrays. Note you can indicate sub-menu but using a -> at the end of the item.  Use a - to make a separater. Optionally you can pass Tooltips by passing a second array. This array must have the same dimensions as the items array even if not all the elements contain tips. The UDF returns an array with this index of row (and if submenus column), the third element is 1 if right clicked otherwise 0 and the fourth element of the array is the label of the menu item. If the user escapes without choosing an item the the first element returns a -1.  Same thing if the user clicks on another window.   @error returns 1 if there was no array passed, 2 if the second array has different dimensions than the first.   If you use the same label in two parts of your menu you will have to distinguish them.  You can do that by additionally making sure that the selection matches the index number(s).  Note that you'll have to match the index number plus label before you match just the label because Switch will use the first match it can find.  In the example below I am using a check on which column the data is in.  If it's not in the first column then it must be the other "Beef".   Beef
      Fruit
      Col2 > Beef
                  Bread   $aR = _ArrayToMenu($aM) Switch $aR[3]
      Case "Beef" and $aR[2] = 0
             Beef1()
       Case "Beef"
             Beef2()
      EndSwitch   On a technical note I attached the context menu to the window itself not a dummy control and I didn't use _GUICtrlMenu_TrackPopupMenu.  Instead I launched the context menu with "send shift-F10" and waited for GuiGetMsg() to give me the selection. Right click is picked up by GUIRegisterMsg WM_RBUTTONUP and Tooltips are done with GUIRegisterMsg WM_MENUSELECT. The whole thing is done with 3 functions. 
      I won't tell you how long it took me to figure this out but I'll say that on one of my early attempts it had two windows running at once and one was just to recieve the right click an tell the other it got it.  Suffice it to say I'm no wiz at Autoit but I really appreciate the support the community offers and I hope someone finds this useful. BTW I wrote a script to produce 1d and 2d auotit array code from excel in case you want to model your menu in excel. Here is the link.
      https://www.autoitscript.com/forum/topic/139260-autoit-snippets/?do=findComment&comment=1412314
      _ArrayToMenu() UDF
      ;ArrayToMenu with submenus, tooltips, rightclick and esc to close. ; #INDEX# ======================================================================================================================= ; Title .........: _ArrayToMenu ; AutoIt Version : 3.3.14.2 ; Description ...: Show an array as a popup menu optionally with tooltips and right click. ; Author(s) .....: Rick Sharp ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name..........: _ArrayToMenu($aArray_menu[,$aArray_tooltips]) ; Description...: Display an array as a menu and return the users choice, display tooltips(optional), return right click. ; Syntax........: _ArrayToMenu($aArray_menu[,$aArray_tooltips]) ; ; Parameters....: ; Required......: A 1d or 2d array of menu items ; Use a minus sign in the item to indicate a menu separator. ; Use -> at the end of an item to indicate a sub-menu. ; Optional......: A 1d or 2d array of tooltips. The array must use the same dimensions as the menu items array. ; ; Return values.: An Array ; $aArray[0] is index of the row (-1 if exited with no choice) ; $aArray[1] is index of the column ; $aArray[2] is 1 if right clicked ; $aArray[3] is the selected item (if any) ; Notes.........: If the user clicks on another window the ArrayToMenu returns as if esc were pressed. ; Sub-Menus are limited to 10 levels if you need more change $ahM[10] ; =============================================================================================================================== ; #VARIABLES# =================================================================================================================== ; Global $__g_iRT = 0, $__g_aTT1, $__g_ahi ; "$__g_iRT" for right click flag, "$__g_aTT1" for tips, "$__g_ahi" for index of id's in menu and tips ; =============================================================================================================================== ; #@error# ====================================================================================================================== ; 1 - First parameter is Not an array ; 2 - The Menu/Items array and the Tips array are not the same number of dimensions ; =============================================================================================================================== #include-once #include <WindowsConstants.au3> #include <GuiMenu.au3> #include <array.au3> #include <misc.au3> Func _ArrayToMenu($aMenu, $att = "") If Not IsArray($aMenu) Then Return SetError(1, 0, -1) Global $__g_iRT = 0 Local $ahM[10], $iCcnt = UBound($aMenu, 2), $iRcnt = UBound($aMenu), $iRow, $iCol, $b_Esc If UBound($aMenu, 2) = 0 Then _ArrayColInsert($aMenu, 1) ;if 1d array make it 2d EndIf ;Prep Loop to make Menus and Sub-Menus $iRcnt = UBound($aMenu) ;Count of Rows/Items $iCcnt = UBound($aMenu, 2) ;Count of Cols/Menus GUIRegisterMsg($WM_RBUTTONUP, "WM_RBUTTONUP") ;handles Right Click If IsArray($att) Then If UBound($att, 2) = 0 Then _ArrayColInsert($att, 1) If UBound($att, 2) <> $iCcnt Or UBound($att) <> $iRcnt Then Return SetError(2, 0, -1) ;$amenu and $att not same dimensions Global $__g_aTT1 = $att ;added $__g_aTT1 because $att was not seen by WM_MenuSelect for tooltips GUIRegisterMsg($WM_MENUSELECT, "WM_MENUSELECT") ;handles tooltips EndIf Local $mPos = MouseGetPos() #Region ### START Koda GUI section ### Form= $hMenu = GUICreate("C_menu", 10, 10, $mPos[0], $mPos[1], $WS_POPUP, $WS_EX_TOPMOST) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### ;Build Menus Global $__g_ahi[$iRcnt + 1][$iCcnt + 1] ;array to hold Menu Item id's $iMcnt = 0 ;Menu count $ahM[$iMcnt] = GUICtrlCreateContextMenu() ;if the array element is null then it falls through and nothing happens For $j = 0 To $iCcnt - 1 ;for each Column/Menu For $i = 0 To $iRcnt - 1 ;for each Row/Item If StringRight($aMenu[$i][$j], 2) = "->" Then ;Sub-Menu $aMenu[$i][$j] = StringTrimRight($aMenu[$i][$j], 2) ;remove -> $iMcnt += 1 $ahM[$iMcnt] = GUICtrlCreateMenu($aMenu[$i][$j], $ahM[$j]) ; $__g_ahi[$i][$j] = $ahM[$iMcnt] ElseIf $aMenu[$i][$j] > "" Then ;Normal item If StringLeft($aMenu[$i][$j], 1) = "-" Then $aMenu[$i][$j] = "" $__g_ahi[$i][$j] = GUICtrlCreateMenuItem($aMenu[$i][$j], $ahM[$j]) EndIf Next Next Send("+{F10}") ;sends right click to open context menu While 1 $nMsg = GUIGetMsg() If $nMsg > 0 Then ;ConsoleWrite("nMsg= " & $nMsg & @CRLF) $iRow = _ArraySearch($__g_ahi, $nMsg) $iCol = _ArraySearch($__g_ahi, $nMsg, 0, 0, 0, 0, 0, $iRow, True) ExitLoop EndIf If _IsPressed("1B") = 1 Or WinActive("C_menu") = 0 Then $b_Esc = -1 ExitLoop EndIf WEnd ;*** Done *** GUIDelete($hMenu) Local $aAr1[4] $aAr1[0] = $iRow $aAr1[1] = $iCol $aAr1[2] = $__g_iRT If Not $b_Esc = -1 Then $aAr1[3] = $aMenu[$aAr1[0]][$aAr1[1]] Else $aAr1[0] = -1 EndIf Return $aAr1 EndFunc ;==>_ArrayToMenu ;Check for Right Click Func WM_RBUTTONUP($hMenu, $iMsg, $iwParam, $ilParam) $__g_iRT = 1 ;Mark as rclicked Send("{Enter}") ;choose the item EndFunc ;==>WM_RBUTTONUP ;Tooltips Func WM_MENUSELECT($hMenu, $iMsg, $iwParam, $ilParam) Local $idMenu = BitAND($iwParam, 0xFFFF) Local $iRow, $iCol If $idMenu > 0 Then $iRow = _ArraySearch($__g_ahi, $idMenu) If $iRow > -1 Then $iCol = _ArraySearch($__g_ahi, $idMenu, 0, 0, 0, 0, 0, $iRow, True) EndIf If $iCol > -1 And $iRow > -1 And $__g_aTT1[$iRow][$iCol] > " " Then ToolTip($__g_aTT1[$iRow][$iCol]) Else ToolTip("") EndIf EndIf EndFunc ;==>WM_MENUSELECT Example 1 Simple 1d array with tooltips, item separator and right click.
      #include "ArrayToMenu.au3" ;Simple 1d array with tooltips item separator and right click. $aM = StringSplit("Zero,One,-,Two/Two_R", ",", 3) ;make an array for the menu items $aT = StringSplit("Zero,One,-,", ",", 3) ;make an array for the menu Tooltips $aR = _ArrayToMenu($aM,$aT) if @error then ConsoleWrite(@error & @CRLF) EndIf ConsoleWrite("R: " & $aR[0] & " " & "C: " & $aR[1] & " " & "Rclick: " & $aR[2] & " " & "Item: " & $aR[3] & @CRLF) If $aR[0] = -1 Then ;either hit escape or clicked on another window ConsoleWrite("Esc" & @CRLF) Exit EndIf ;_ArrayDisplay($aR) Switch $aR[3] Case "Zero" Zero() Case "One" One() Case "Two/Two_R" And $aR[2] = 0 ;No Rclick Two() Case "Two/Two_R" And $aR[2] = 1 ;Rclick Two_R() EndSwitch Func Zero() ConsoleWrite("You chose: Zero" & @CRLF) EndFunc ;==>Zero Func One() ConsoleWrite("You chose: One" & @CRLF) EndFunc ;==>One Func Two() ConsoleWrite("You chose: Two" & @CRLF) EndFunc ;==>Two Func Two_R() ConsoleWrite("You chose: Two_R" & @CRLF) EndFunc ;==>Two_R Example 2 2d array with sub-menu
      #include "ArrayToMenu.au3" ;2d array with a sub-menu dim $aM[4][2] = [["Beef", "Orange"], ["Pork", "Apple"], ["Chicken", "Grape"], ["Fruit->", ""]] ;Note you don't need a tooltip for every item but you at least need a place holder in the array dim $aT[4][2] = [["Red Meat", "Fruit"], ["Other white meat", "Fruit"], ["White meat", "Fruit"], ["", ""]] $aR = _ArrayToMenu($aM,$aT) if @error Then ConsoleWrite(@error & @CRLF) Exit EndIf If $aR[0] = -1 Then ConsoleWrite("Esc" & @CRLF) Exit EndIf ConsoleWrite("R: " & $aR[0] & " " & "C: " & $aR[1] & " " & "Rclick: " & $aR[2] & " " & "Item: " & $aR[3] & @CRLF) Switch $aR[3] Case "Beef" Beef() Case "Pork" Pork() Case "Chicken" Chicken() Case "Orange" ConsoleWrite("Oranges are good for you!" & @CRLF) ConsoleWrite("Oranges" & " $aR[0] = " & $aR[0] & " $aR[1] = " & $aR[1] & @CRLF) Case "Apple" ConsoleWrite("Apples are good for you!" & @CRLF) Case "Grape" ConsoleWrite("Grapes are good for you!" & @CRLF) EndSwitch Func Beef() ConsoleWrite("Beef" & " $aR[0] = " & $aR[0] & " $aR[1] = " & $aR[1] & @CRLF) EndFunc ;==>Beef Func Pork() ConsoleWrite("Pork" & " $aR[0] = " & $aR[0] & " $aR[1] = " & $aR[1] & @CRLF) EndFunc ;==>Pork Func Chicken() ConsoleWrite("Chicken" & @CRLF) EndFunc ;==>Chicken  
    • By nacerbaaziz
      Hello my friends
      Can we create a single context menu on more than one item?
      For example, a context menu includes standardized options on more than one control, such as buttons or check boxes
      to Create a context menu on one item am using this function
      GUICtrlCreateContextMenu ($ HWND)
      How to link it with more than one element please?
      or if we can't do that, please give me a solution
      so i tried to add an context menus to all the controls but the script will be long, for that if their are any solutions i hope to give it to me
      thanks in advanced
    • By junkew
      Working on a new version of iuiautomation and uia wrappers I needed a better way of getting my interface's
      Concept version 0.6 to generate based on idl file an au3 file with the definitions.
      As allways its more complicated then I thought ;-) due to small differences in the idl files on closing braces, separating inheritance colon inconsistencies in the idl tool that generates them so most likely its better to write a lexer/parser then the search/replace I do now
      Alternatives
      typelibinspector but could not generate them all at once aiowrappergenerator was generating for aio and not for objcreateinterface based on tli interfaces / xml but seemed incomplete Known issues
      Enums without given constant values to be filled in manually Enum adding fix first parameter to have a $ Empty interfaces fail on _ to be replaced with "" propput and propget deal with methods with same name Must be wrapped in main function $i counting to be done differently Working on the typedef's and replacements of identifiers in the string (some are replaced) enum automatically is a long typedefs are automatically assumed an int (which is not perfect but a start) struct like POINT pt is now generated as int Testing/debugging Choices done
      get_ and put_ prefixing only for put_ as that will have less impact on existing scripts that do not use get_ like ControlViewWalker, Current.. properties etc.

      So instead of Global Const $sIID_IUIAutomationCacheRequest = "{B32A92B5-BC25-4078-9C08-D7EE95C48E03}" Global $dtagIUIAutomationCacheRequest = _ "AddProperty hresult(int);" & _ "AddPattern hresult(int);" & _ "Clone hresult(ptr*);" & _ "get_TreeScope hresult(long*);" & _ "put_TreeScope hresult(long);" & _ "get_TreeFilter hresult(ptr*);" & _ "put_TreeFilter hresult(ptr);" & _ "get_AutomationElementMode hresult(long*);" & _ "put_AutomationElementMode hresult(long);" it will be like (see for example TreeScope and put_TreeScope)
      Global Const $sIID_IUIAutomationCacheRequest = "{b32a92b5-bc25-4078-9c08-d7ee95c48e03}" Global $dtagIUIAutomationCacheRequest= _ "AddProperty hresult(struct);" & _ "AddPattern hresult(int);" & _ "Clone hresult(ptr*);" & _ "TreeScope hresult(long*);" & _ "put_TreeScope hresult(long);" & _ "TreeFilter hresult(ptr*);" & _ "put_TreeFilter hresult(ptr);" & _ "AutomationElementMode hresult(long*);" & _ "put_AutomationElementMode hresult(long);"  
      Prerequisites
      Win 10 SDK installed at location as given in constants to have IDL file Output
      File with same name as idl in scriptdir with  extension au3 having the definitions for OBJCreateInterface
        Example output
      ;~ // ;~ // IUIAutomation ;~ // ;~[object, uuid(30cbe57d-d9d0-452a-ab13-7ac5ac4825ee), pointer_default(unique)] ;~interface IUIAutomation : IUnknown Global Const $sIID_IUIAutomation = "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}" Global $dtag_IUIAutomation= _ "CompareElements hresult(IUIAutomationElement*el1,IUIAutomationElement*el2,int*);" & _ "CompareRuntimeIds hresult(SAFEARRAY(int)runtimeId1,SAFEARRAY(int)runtimeId2,intareSame);" & _ "GetRootElement hresult(IUIAutomationElement**);" & _ "ElementFromHandle hresult(UIA_inthwnd,IUIAutomationElement**);" & _ "ElementFromPoint hresult(intpt,IUIAutomationElement**);" & _ "GetFocusedElement hresult(IUIAutomationElement**);" & _ "GetRootElementBuildCache hresult(IUIAutomationCacheRequest*cacheRequest,IUIAutomationElement**);" & _ "ElementFromHandleBuildCache hresult(UIA_inthwnd,IUIAutomationCacheRequest*cacheRequest,IUIAutomationElement**);" & _ "ElementFromPointBuildCache hresult(intpt,IUIAutomationCacheRequest*cacheRequest,IUIAutomationElement**);" & _ "GetFocusedElementBuildCache hresult(IUIAutomationCacheRequest*cacheRequest,IUIAutomationElement**);" & _ "CreateTreeWalker hresult(IUIAutomationCondition*pCondition,IUIAutomationTreeWalker**);" & _ "ControlViewWalker hresult(IUIAutomationTreeWalker**);" & _ "ContentViewWalker hresult(IUIAutomationTreeWalker**);" & _ "RawViewWalker hresult(IUIAutomationTreeWalker**);" & _ "RawViewCondition hresult(IUIAutomationCondition**);" & _ "ControlViewCondition hresult(IUIAutomationCondition**);" & _ "ContentViewCondition hresult(IUIAutomationCondition**);" & _ "CreateCacheRequest hresult(IUIAutomationCacheRequest**);" & _ "CreateTrueCondition hresult(IUIAutomationCondition**);" & _ "CreateFalseCondition hresult(IUIAutomationCondition**);" & _ "CreatePropertyCondition hresult(intpropertyId,variantvalue,IUIAutomationCondition**);" & _ "CreatePropertyConditionEx hresult(intpropertyId,variantvalue,longflags,IUIAutomationCondition**);" & _ "CreateAndCondition hresult(IUIAutomationCondition*condition1,IUIAutomationCondition*condition2,IUIAutomationCondition**);" & _ "CreateAndConditionFromArray hresult(SAFEARRAY(IUIAutomationCondition)conditions,IUIAutomationCondition**);" & _ "CreateAndConditionFromNativeArray hresult(IUIAutomationCondition**conditions,intconditionCount,IUIAutomationCondition**);" & _ "CreateOrCondition hresult(IUIAutomationCondition*condition1,IUIAutomationCondition*condition2,IUIAutomationCondition**);" & _ "CreateOrConditionFromArray hresult(SAFEARRAY(IUIAutomationCondition)conditions,IUIAutomationCondition**);" & _ "CreateOrConditionFromNativeArray hresult(IUIAutomationCondition**conditions,intconditionCount,IUIAutomationCondition**);" & _ "CreateNotCondition hresult(IUIAutomationCondition*condition,IUIAutomationCondition**);" & _ "AddAutomationEventHandler hresult(inteventId,IUIAutomationElement*element,longscope,IUIAutomationCacheRequest*cacheRequest,IUIAutomationEventHandler*);" & _ "RemoveAutomationEventHandler hresult(inteventId,IUIAutomationElement*element,IUIAutomationEventHandler*);" & _ "AddPropertyChangedEventHandlerNativeArray hresult(IUIAutomationElement*element,longscope,IUIAutomationCacheRequest*cacheRequest,IUIAutomationPropertyChangedEventHandler*handler,int*propertyArray,int);" & _ "AddPropertyChangedEventHandler hresult(IUIAutomationElement*element,longscope,IUIAutomationCacheRequest*cacheRequest,IUIAutomationPropertyChangedEventHandler*handler,SAFEARRAY(PROPERTYID));" & _ "RemovePropertyChangedEventHandler hresult(IUIAutomationElement*element,IUIAutomationPropertyChangedEventHandler*);" & _ "AddStructureChangedEventHandler hresult(IUIAutomationElement*element,longscope,IUIAutomationCacheRequest*cacheRequest,IUIAutomationStructureChangedEventHandler*);" & _ "RemoveStructureChangedEventHandler hresult(IUIAutomationElement*element,IUIAutomationStructureChangedEventHandler*);" & _ "AddFocusChangedEventHandler hresult(IUIAutomationCacheRequest*cacheRequest,IUIAutomationFocusChangedEventHandler*);" & _ "RemoveFocusChangedEventHandler hresult(IUIAutomationFocusChangedEventHandler*);" & _ "RemoveAllEventHandlers hresult);" & _ "IntNativeArrayToSafeArray hresult(int*array,intarrayCount,SAFEARRAY(int)*);" & _ "IntSafeArrayToNativeArray hresult(SAFEARRAY(int)intArray,int**array,int*);" & _ "RectTovariant hresult(intrc,variant*);" & _ "variantToRect hresult(variantvar,int*);" & _ "SafeArrayToRectNativeArray hresult(SAFEARRAY(double)rects,int**rectArray,int*);" & _ "CreateProxyFactoryEntry(IUIAutomationProxyFactory hresult*factory,IUIAutomationProxyFactoryEntry);" & _ "ProxyFactoryMapping(IUIAutomationProxyFactoryMapping hresult);" & _ "GetPropertyProgrammaticName(int hresultproperty,int*);" & _ "GetPatternProgrammaticName(int hresultpattern,int*);" & _ "PollForPotentialSupportedPatterns(IUIAutomationElement hresult*pElement,SAFEARRAY(int)*patternIds,SAFEARRAY(BSTR)patternNames);" & _ "PollForPotentialSupportedProperties(IUIAutomationElement hresult*pElement,SAFEARRAY(int)*propertyIds,SAFEARRAY(BSTR)propertyNames);" & _ "CheckNotSupported(variant hresultvalue,intisNotSupported);" & _ "ReservedNotSupportedValue(IUnknown hresult**notSupportedValue);" & _ "ReservedMixedAttributeValue(IUnknown hresult**mixedAttributeValue);" & _ "ElementFromIAccessible hresult(IAccessible*accessible,intchildId,IUIAutomationElement**);" & _ "ElementFromIAccessibleBuildCache hresult(IAccessible*accessible,intchildId,IUIAutomationCacheRequest*cacheRequest,IUIAutomationElement**);" ;~}  
      Script
      #include <FileConstants.au3> #include <MsgBoxConstants.au3> #include <StringConstants.au3> #include <Array.au3> ;~ testit() ;~ Exit Local $IDLFolder="C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um\" Local $IDLFileName="UIAutomationClient.idl" Local $IDLFullFileName = $IDLFolder & $IDLFileName Local $IDLArray = FileReadToArray($IDLFullFileName) Local $iLineCount = @extended Local $IDLAU3FullFileName=@ScriptDir & "\" & $IDLFileName $IDLAU3FullFileName=stringreplace($IDLAU3FullFileName,".idl",".au3") If @error Then MsgBox($MB_SYSTEMMODAL, "", "There was an error reading the file. @error: " & @error) ; An error occurred reading the current script file. exit EndIf Local $hFileOpen = FileOpen($IDLAU3FullFileName, $FO_OVERWRITE ) If $hFileOpen = -1 Then MsgBox($MB_SYSTEMMODAL, "", "An error occurred whilst writing the new au3 file.") exit EndIf ;~TODO: Naming prefixing Global $interfaceName Global $GUID Global $i=0 while $i < $iLineCount - 1 ;~ consolewrite($i) $tLine=$IDLArray[$i] $blockType=0 if stringleft($tLine,2)="//" then $blockType=1 if stringleft($tLine,4)="cpp_" then $blockType=1 if stringleft($tLine,1)="#" then $blockType=1 if stringleft($tLine,6)="import" then $blockType=1 if stringleft($tLine,4)="midl" then $blockType=1 if $blockType=1 Then writeCommentedLine() continueloop; EndIf if stringleft($tLine,4)="enum" then $blockType=2 handleEnumBlock() EndIf if stringinstr($tLine, "module ") > 0 then $blockType=3 handleModuleBlock() EndIf if stringinstr($tLine, "[object") > 0 then $blockType=4 handleObjectBlock() EndIf if stringinstr($tLine, "interface ") > 0 then $blockType=5 handleInterfaceBlock() EndIf if $blockType=0 Then writeUnhandledLine() EndIf WEnd func writeUnhandledLine() filewriteline($hFileOpen,";~" & $tline) $i=$i+1 EndFunc func writeCommentedLine() $tLineOut=stringstripws($tLine, $STR_STRIPLEADING + $STR_STRIPTRAILING) if $tLineOut <> "" Then $tLineOut=";~" & $tLineOut filewriteline($hFileOpen, $tLineOut) $i=$i+1 EndFunc func handleEnumBlock() writeCommentedLine() ;~ Copy enum line $tLine=$IDLArray[$i] writeCommentedLine() ;~ Copy curly brace line $tLine=$IDLArray[$i] while stringstripws($tLine, $STR_STRIPLEADING + $STR_STRIPTRAILING) <> "};" $tPos=getPosFirstNonWhiteSpace($tLine) if ($tpos=0) or (stringmid($tLine,$tPos+1,2)="//") Then writeCommentedLine() Else $tLine=stringleft($tLine,$tPos) & "Global Const $" & stringmid($tline,$tPos+1) $tLine=stringreplace($tLine, ",","") $tLine=stringreplace($tLine, "| ","+ $") writeEnumLine() EndIf $tLine=$IDLArray[$i] WEnd EndFunc func writeEnumLine() filewriteline($hFileOpen, $tline) $i=$i+1 EndFunc func handleModuleBlock() writeCommentedLine() ;~ Copy module line $tLine=$IDLArray[$i] writeCommentedLine() ;~ Copy curly brace line $tLine=$IDLArray[$i] $tValue=stringstripws($tLine, $STR_STRIPLEADING + $STR_STRIPTRAILING) ;~ Some end with }; and some with } while stringleft($tValue,1) <> "}" $tPos=getPosFirstNonWhiteSpace($tLine) if ($tpos=0) or (stringmid($tLine,$tPos+1,2)="//") Then if ($tpos=0) then $i=$i+1 ;~ Do no output Else writeCommentedLine() EndIf Else $tLine=stringreplace($tline,"const long ", "Global Const $") $tLine=stringreplace($tLine, ";","") writeModuleLine() EndIf $tLine=$IDLArray[$i] $tValue=stringstripws($tLine, $STR_STRIPLEADING + $STR_STRIPTRAILING) WEnd writeCommentedLine() ;~ Copy curly closing brace line EndFunc func writeModuleLine() filewriteline($hFileOpen, $tline) $i=$i+1 EndFunc func handleObjectBlock() writeCommentedLine() $tPos=stringinstr($tLine,"(") $tPos2=stringinstr($tLine,")") $GUID=stringmid($tLine,$tpos+1, $tPos2-1 - $tpos) ;~ consolewrite($GUID & @CRLF) EndFunc func handleInterfaceBlock() if stringright($tLine,1)=";" Then writeCommentedLine() ;~ Copy Interface line its just a definition line Return EndIf writeCommentedLine() ;~ Copy interface line $interfaceName=getInterfaceName() writeInterFaceLine1() $tLine=$IDLArray[$i] ;~ writeCommentedLine() ;~ Copy curly brace line $i=$i+1 ;~ Do no output $tLine=$IDLArray[$i] $tValue=stringstripws($tLine, $STR_STRIPLEADING + $STR_STRIPTRAILING) ;~ Some end with }; and some with } while stringleft($tValue,1) <> "}" $tPos=getPosFirstNonWhiteSpace($tLine) if ($tpos=0) or (stringmid($tLine,$tPos+1,2)="//") Then if ($tpos=0) then $i=$i+1 ;~ Do no output Else $i=$i+1 ;~ Do no output, AU3 does not like it in multiline strings ;~ writeCommentedLine() EndIf Else while stringright($tLine,1) <> ";" $i=$i+1 $tLine=$tLine & stringstripws($IDLArray[$i], $STR_STRIPLEADING + $STR_STRIPTRAILING) wend writeInterfaceLine() EndIf $tLine=$IDLArray[$i] $tValue=stringstripws($tLine, $STR_STRIPLEADING + $STR_STRIPTRAILING) WEnd ;~ consolewrite($IDLArray[$i-1] & @CRLF) ;~ consolewrite($IDLArray[$i] & @CRLF) ;~ consolewrite($IDLArray[$i+1] & @CRLF) writeCommentedLine() ;~ Copy curly closing brace line EndFunc func writeInterFaceLine1() $tOutputLine="Global Const $sIID_" & getInterfaceName() & " = " $tOutputLine=$tOutputLine & """" $tOutputLine=$tOutputLine & "{" & $GUID & "}" $tOutputLine=$tOutputLine & """" filewriteline($hFileOpen, $tOutputLine) $toutputLine = "Global $dtag" & getInterfaceName() & "= _" & @CRLF filewriteline($hFileOpen, $tOutputLine) EndFunc func writeInterfaceLine() $tmpLine=stringstripws($tLine, $STR_STRIPLEADING + $STR_STRIPTRAILING) if stringleft($tmpLine,1)="}" Then filewriteline($hFileOpen, $tmpLine) $i=$i+1 return EndIf ;~ Handle get/put properties prefix local $strPrefix="" if stringinstr($tmpLine,"[propget]")>0 then ;~ no prefix for the get as its more logical/natural in AutoIt to do it without (as oppossed to C where get_ is more logical ;~ $strPrefix="get_" ;~ consolewrite($tmpLine & @CRLF) $tmpLine=stringreplace($tmpLine, "[propget] ", "", 0, $STR_CASESENSE) EndIf if stringinstr($tmpLine,"[propput]")>0 then ;~ prefix for the put as it can get in conflict with the get duplicate name $strPrefix="put_" ;~ consolewrite($tmpLine & @CRLF) $tmpLine=stringreplace($tmpLine, "[propput] ", "", 0, $STR_CASESENSE) EndIf ; $tmpLine ="HRESULT FindAll ([in] enum TreeScope scope,[in] IUIAutomationCondition * condition, [out, retval] IUIAutomationElementArray ** found );" ;~ $tmpLine="[propget] HRESULT PropertyId ([out, retval] PROPERTYID * propertyId );" ;~ $tmpLine="HRESULT GetCurrentPropertyValue ([in] PROPERTYID propertyId,[out, retval] VARIANT * retVal);" ;~ $tmpLine="HRESULT FindAllBuildCache ([in] enum TreeScope scope,[in] IUIAutomationCondition * condition,[in] IUIAutomationCacheRequest * cacheRequest,[out, retval] IUIAutomationElementArray ** found );" $tmpLine=stringreplace($tmpLine, "HRESULT", "hresult", 0, $STR_CASESENSE) $tmpLine=stringreplace($tmpLine, "VARIANT", "variant", 0, $STR_CASESENSE) $tmpLine=stringreplace($tmpLine, "BSTR", "bstr", 0, $STR_CASESENSE) $tmpLine=stringreplace($tmpLine, "BOOL", "bool", 0, $STR_CASESENSE) $tmpLine=stringreplace($tmpLine, "void", "none", 0, $STR_CASESENSE) ;~ Some where we are sure it should not be an int $tmpLine=stringreplace($tmpLine, "POINT", "struct", 0, $STR_CASESENSE) $tmpLine=stringreplace($tmpLine, "PROPERTYID", "struct", 0, $STR_CASESENSE) $tmpLine=stringreplace($tmpLine, "RECT", "struct", 0, $STR_CASESENSE) $tmpLine=stringreplace($tmpLine, "UIA_HWND", "hwnd", 0, $STR_CASESENSE) ;~ Some cleanup for parsing later $tmpLine=stringreplace($tmpLine, "(", " (") $tmpLine=stringreplace($tmpLine, " (", " (") $tmpLine=stringreplace($tmpLine, " );", ");") ;~ remove the pointer references for in/out parameters if stringinstr($tmpLine,"[in")>0 then $tmpLine=stringreplace($tmpLine, "[propget] ", "", 0, $STR_CASESENSE) $tmpLine=stringreplace($tmpLine, "**", "SINGLESTAR") $tmpLine=stringreplace($tmpLine, "*", "") $tmpLine=stringreplace($tmpLine, "SINGLESTAR", "*") EndIf ;~ For out parameter we keep the pointer * if stringinstr($tmpLine,"[out")>0 then $tmpLine=stringreplace($tmpLine, "[propget] ", "", 0, $STR_CASESENSE) $tmpLine=stringreplace($tmpLine, "**", "SINGLESTAR") ;~ $tmpLine=stringreplace($tmpLine, "*", "") $tmpLine=stringreplace($tmpLine, "SINGLESTAR", "*") EndIf $tmpLine=StringRegExpReplace($tmpLine,"[A-Z]+ ","int ") ;~ TODO: assumption full uppercase is a TYPEDEF frequently int but definitily not sure $tmpLine=StringRegExpReplace($tmpLine,"enum [A-Za-z_]+ ","long ") ;~ An enum followed by an identifier is normally a long $tmpLine=StringRegExpReplace($tmpLine,"\[.*?] "," ") ;~ [in, out] stuff followed by space we normally ignore, space we keep for separator ;~ reshuffle and remove varnames $aArray=stringsplit($tmpLine," ") if ($aArray[0] < 2) then _arraydisplay($aArray) consolewrite(stringstripws($tLine, $STR_STRIPLEADING + $STR_STRIPTRAILING)) consolewrite($tmpLine) EndIf $tOutputLine= $strPrefix & $aArray[2] & " " & $aArray[1] For $j = 3 To $aArray[0] $strAppend= $aArray[$j] if (stringright($aArray[$j],1))= "," then $strAppend= ";" if (stringright($aArray[$j],1))= ";" then if $aArray[$j]<>"();" then $strAppend= ");" EndIf $strAppend=getnewtype($strAppend) $tOutputLine= $tOutputLine & $strAppend Next ;~ $tOutputLine= $tOutputLine & $aarray[$aArray[0]] $tOutputline = @TAB & """" & $tOutputLine & """" $tValue=stringstripws($IDLArray[$i+1], $STR_STRIPLEADING + $STR_STRIPTRAILING) ;~ sometimes its not just 1 line ahead for closing but 2 lines ahead if $tValue="" then $tValue=stringstripws($IDLArray[$i+2], $STR_STRIPLEADING + $STR_STRIPTRAILING) endif if (stringleft($tValue,1) <> "}") then $tOutputLine= $tOutputLine & " & _ " filewriteline($hFileOpen, $tOutputLine) $i=$i+1 EndFunc func getPosFirstNonWhiteSpace($str) Local $aArray = StringToASCIIArray($str) for $i=0 to ubound($aArray)-1 if $aArray[$i]<>32 Then return $i Next return 0 EndFunc func getInterfaceName() $tmpLine=stringstripws($tLine, $STR_STRIPLEADING + $STR_STRIPTRAILING) $tArr=stringsplit($tmpLine," ") $tName=$tarr[2] if stringright($tname,1)=":" then $tName=stringleft($tname,stringlen($tname)-1) return $tname EndFunc func testIt() ;~ $tmpline="HRESULT SetFocus ( );" ; $tmpLine ="HRESULT FindAll ([in] enum TreeScope scope,[in] IUIAutomationCondition * condition, [out, retval] IUIAutomationElementArray ** found );" $tmpLine="[propget] HRESULT PropertyId ([out, retval] PROPERTYID * propertyId );" ;~ $tmpLine="HRESULT GetCurrentPropertyValue ([in] PROPERTYID propertyId,[out, retval] VARIANT * retVal);" ;~ $tmpLine="HRESULT FindAllBuildCache ([in] enum TreeScope scope,[in] IUIAutomationCondition * condition,[in] IUIAutomationCacheRequest * cacheRequest,[out, retval] IUIAutomationElementArray ** found );" $strPrefix="" if stringinstr($tmpLine,"[propget]")>0 then $strPrefix="get_" if stringinstr($tmpLine,"[propput]")>0 then $strPrefix="put_" consolewrite($strPrefix) ;~ consolewrite($tOutputline & @CRLF) ;~ consolewrite($tmpLine) ;~ _arraydisplay($aArray) EndFunc func getNewType($str) $retVal=stringregexp($str, "[A-Za-z0-9_]+", $STR_REGEXPMATCH) ;~ if stringleft($str,"3") = "ret" then consolewrite($retVal & $str & @CRLF) if $retval=0 then return $str $tStr=$str & "," $objTypes="none,byte,boolean,short,word,ushort,int,long,bool,dword," & _ "ulong,uint,hresult,int64,uint64,ptr,hwnd,handle,float," & _ "double,int_ptr,long_ptr,lresult,lparam,uint_ptr,ulong_ptr,"& _ "dword_ptr,wparam,str,wstr,bstr,variant,idispatch,object," & _ "clsid,struct,*,**" if stringinstr($objtypes,$tstr)>0 Then return $str return "ptr" EndFunc  
    • By Pagi
      <a href="index.php=4143b27b41db0a40c499202865c3e24d" class="menuitem " target="\_self"> "Menu Item 1" </a>
      Can you tell me if it´s possible to click this menu button? If yes, how? Cause I have no idea, I think i should use _IETagNameGetCollection
×
×
  • Create New...