Ontosy

ObjCreateInterface with custom object

13 posts in this topic

#1 ·  Posted (edited)

I have tryed to compile this "com object" and then use with AutoIt3 but not work: "err.number 0x80020006.

How to do?

#include-once

Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

Local Const $sCLSID_TaskbarList = "{7233b105-bc01-41ff-b72e-582c5954b76d}"
    Local Const $sIID_ITaskbarList = "{702d63b3-d7d1-4f17-ab11-2f2ed770fdc8}"
Local Const $sTagITaskbarList = 'SetString(wstr:cdecl);wstr:cdecl GetString();'


Local $oIExample = ObjCreateInterface($sCLSID_TaskbarList, $sIID_ITaskbarList, $sTagITaskbarList)
    
$a=$oIExample.SetString("Abc")
msgbox(0,@error,$a)
$a=$oIExample.GetString()
;.GetRootElement.CurrentClassName
exit
msgbox(0,0,$a)

Func _ErrFunc($oError)
    ; Do anything here.
    ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _
            @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _
            @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
            @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _
            @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _
            @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
            @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
            @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
            @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
            @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF)
EndFunc   ;==>_ErrFunc

 

Edited by Ontosy
1 person likes this

Share this post


Link to post
Share on other sites



Quote

Warning: This feature is experimental. It may not work, may contain bugs or may be changed or removed without notice.

DO NOT REPORT BUGS OR REQUEST NEW FEATURES FOR THIS FEATURE.

 

Share this post


Link to post
Share on other sites

I not have reported "BUGS OR REQUEST NEW FEATURES FOR THIS FEATURE".

I have asked for help in this regard.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

But you read it may not work and this happens in your script and i (and much others too) don't have the com.object. So i can only ask have you regsitered the object.

Edited by AutoBert

Share this post


Link to post
Share on other sites

It works! ty :)

Share this post


Link to post
Share on other sites

You are welcome. Great to see so much interest in this topic. There is a whole series of a total of 8 articles about COM objects. They are all named "Com in plain C, Part n", where n is 1 - 8. You can find the articles at codeproject.com. This guy Jeff Glatt seems to know what he is talking about, and he also knows how to explain it.

In "Com in plain C, Part 2" the IDispatch interface is added to the object which make it possible to create the object in a scripting language. In AutoIt you can create the object with the ObjCreate command.

Share this post


Link to post
Share on other sites

I also have tryed to use ObjCreate but it not work.

I thought maybe you need the ProgID

Share this post


Link to post
Share on other sites

Do "IExample8.object" include "IExample2.object" and all previuos?

Share this post


Link to post
Share on other sites

I don't know. I skimmed through the articles relatively quickly. I have not looked at the code. But I'm almost sure that it'll all work. Also in AutoIt. The articles seem pretty convincing.

Share this post


Link to post
Share on other sites

I have question and it may be simple as I am new to UIAutomation. How do you find the $sIID_ITaskbarList? I wanted to know which tool or method is used to find it?

ObjCreateInterface($sCLSID_TaskbarList, $sIID_ITaskbarList, $sTagITaskbarList)

Share this post


Link to post
Share on other sites

The interface description strings are specific for AutoIt. This means that AutoIt programmers have created all the existing description strings themselves.

There are created several hundred interface objects and there are created interface description strings for all these objects. If you're lucky a description string does already exists for the interface you need. Search the forums.

If a description string does not exists for your interface, you have to create it yourself. You create the description string from information you find in C/C++ header files. For ITaskbarList interface you find the information in ShObjIdl.h included in Windows SDK.

Before you start creating a description string you should compare existing description strings with information in header files. In that way you can figure out which AutoIt data types matches the C/C++ data types.

And you can always ask questions in this forum.

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

  • Similar Content

    • Danyfirex
      By Danyfirex
      well. Reading in msdn I found an interface to run a Gadget. So I wrote it. 
       
      #include <Array.au3> #include <File.au3> Global Const $sCLSID_DesktopGadget = "{924CCC1B-6562-4C85-8657-D177925222B6}" Global Const $sIID_IDesktopGadget = "{C1646BC4-F298-4F91-A204-EB2DD1709D1A}" Global Const $sTagIDesktopGadget = "RunGadget hresult(wstr);" Global Enum $eNoShared = 1, $eShared, $eAll Local $aGadGets = _GetGadget($eAll) If IsArray($aGadGets) Then For $i = 1 To $aGadGets[0] If StringInStr($aGadGets[$i], "CPU") Then ;Run CPU GadGet RunGadget($aGadGets[$i]) EndIf Next EndIf Func RunGadget($sGadGetPath) Local $oDesktopGadget = ObjCreateInterface($sCLSID_DesktopGadget, $sIID_IDesktopGadget, $sTagIDesktopGadget) if not IsObj($oDesktopGadget) then Return False return SUCCEEDED($oDesktopGadget.RunGadget($sGadGetPath)) EndFunc ;==>RunGadget Func _GetGadget($GadgetType = $eNoShared) Local $aNoSharedGadGets = 0 Local $aSharedGadGets = 0 Local $aGadGets = 0 Local $Size = 0 Local Const $sSharedGadget = @ProgramFilesDir & "\Windows Sidebar\Shared Gadgets" Local Const $sNoShared = @ProgramFilesDir & "\Windows Sidebar\Gadgets" If $GadgetType < $eNoShared Or $GadgetType > $eAll Then Return 0 If BitAND($GadgetType, $eNoShared) Then $aNoSharedGadGets = _FileListToArray($sNoShared, Default, Default, True) If BitAND($GadgetType, $eShared) Then $aSharedGadGets = _FileListToArray($sSharedGadget, Default, Default, True) If IsArray($aSharedGadGets) And IsArray($aNoSharedGadGets) Then $Size = UBound($aNoSharedGadGets) - 1 + (UBound($aSharedGadGets) - 1) _ArrayConcatenate($aNoSharedGadGets, $aSharedGadGets, 1) $aGadGets = $aNoSharedGadGets $aGadGets[0] = $Size Else If IsArray($aSharedGadGets) Then $aGadGets = $aSharedGadGets If IsArray($aNoSharedGadGets) Then $aGadGets = $aNoSharedGadGets EndIf $aSharedGadGets = 0;Free $aNoSharedGadGets = 0 ;Free Return $aGadGets EndFunc ;==>_GetGadget Func SUCCEEDED($hr) Return ($hr >= 0) EndFunc ;==>SUCCEEDED Saludos
       
       
       
    • Danyfirex
      By Danyfirex
      Well. I was needing to create a networks shortcut. so I did find anything into the forum. So I write this after reading about Nonfile Object.
       
      ;~ Danyfirex 26/07/2015 #include <WinAPIShellEx.au3> Opt("MustDeclareVars", 1) Global Const $SHCONTF_NONFOLDERS = 0x00040 Global Const $SHGDN_NORMAL = 0 Global Const $S_OK = 0 Global Const $sTagSTRRET = "UINT uType;ptr pOleStr;UINT uOffset;CHAR cStr[256]" Global Const $CLSID_ShellLink = "{00021401-0000-0000-C000-000000000046}" Global Const $sIID_IShellLinkW = "{000214F9-0000-0000-C000-000000000046}" Global Const $sTagIShellLink = "getpath hresult(long;long;long;long); " & _ "getidlist hresult(ptr); " & _ "setidlist hresult(ptr); " & _ "getdescription hresult(long;long); " & _ "setdescription hresult(wstr); " & _ "getworkingdirectory hresult(long;long); " & _ "setworkingdirectory hresult(long); " & _ "getarguments hresult(long;long); " & _ "setarguments hresult(ptr); " & _ "gethotkey hresult(long); " & _ "sethotkey hresult(word); " & _ "getshowcmd hresult(long); " & _ "setshowcmd hresult(int); " & _ "geticonlocation hresult(long;long;long); " & _ "seticonlocation hresult(wstr;int); " & _ "setrelativepath hresult(long;long); " & _ "resolve hresult(long;long); " & _ "setpath hresult(wstr)" Global Const $sIID_IPersistFile = "{0000010b-0000-0000-C000-000000000046}" Global Const $sTagIPersistFile = "GetClassID hresult(long); IsDirty hresult(); Load hresult(long;long); Save hresult(wstr;bool); SaveCompleted hresult(long); GetCurFile hresult(long)" Global Const $sIID_IEnumIDList = "{000214F2-0000-0000-C000-000000000046}" Global Const $sTagIEnumIDList = "Next hresult(ulong;ptr*;ulong*);" & _ "Reset hresult();" & _ "Skip hresult(ulong);" & _ "Clone hresult(ptr*);" Global Const $sIID_IShellFolder = "{000214E6-0000-0000-C000-000000000046}" Global Const $sTagIShellFolder = "ParseDisplayName hresult(hwnd;ptr;wstr;ulong*;ptr*;ulong*);" & _ "EnumObjects hresult(hwnd;dword;ptr*);" & _ "BindToObject hresult(ptr;ptr;clsid;ptr*);" & _ "BindToStorage hresult(ptr*;ptr;clsid;ptr*);" & _ "CompareIDs hresult(lparam;ptr*;ptr*);" & _ "CreateViewObject hresult(hwnd;clsid;ptr*);" & _ "GetAttributesOf hresult(uint:ptr*;ulong*);" & _ "GetUIObjectOf hresult(hwnd;uint;ptr*;clsid;uint*;ptr*);" & _ "GetDisplayNameOf hresult(ptr;dword;ptr);" & _ "SetNameOf hresult(hwnd;ptr*;wstr;dword;ptr*);" Local $MyNetWorkConnectionName="Conexión de red inalámbrica" CreateNetWorkConnectionShortCut($MyNetWorkConnectionName) ;~ Success: Return True ;~ Failure: Return False ;~ if $lnkPath = "" ShortCut will be Create on Desktop with the name of the Conections($sConnectionName) Func CreateNetWorkConnectionShortCut($sConnectionName, $lnkPath = "") Local $pConecctionsFolder = 0 Local $oConecctionsFolder = 0 Local $pEnumIDList = 0 Local $oEnumIDList = 0 Local $pPIDLItem = 0 Local $celtFetched = 0 Local $pPIDLConectionsFolder = 0 Local $bRet = False Local $tSTRRET = 0 Local $twstring = 0 Local $pShellFolder = SHGetDesktopFolder() Local $oShellFolder = ObjCreateInterface($pShellFolder, $sIID_IShellFolder, $sTagIShellFolder) If @error Then Return $bRet $pPIDLConectionsFolder = _WinAPI_ShellGetSpecialFolderLocation($CSIDL_CONNECTIONS) If SUCCEEDED($oShellFolder.BindToObject($pPIDLConectionsFolder, Null, $sIID_IShellFolder, $pConecctionsFolder)) Then $oConecctionsFolder = ObjCreateInterface($pConecctionsFolder, $sIID_IShellFolder, $sTagIShellFolder) If IsObj($oConecctionsFolder) Then If SUCCEEDED($oConecctionsFolder.EnumObjects(Null, $SHCONTF_NONFOLDERS, $pEnumIDList)) Then $oEnumIDList = ObjCreateInterface($pEnumIDList, $sIID_IEnumIDList, $sTagIEnumIDList) If IsObj($oEnumIDList) Then $tSTRRET = DllStructCreate($sTagSTRRET) While (SUCCEEDED($oEnumIDList.Next(1, $pPIDLItem, $celtFetched)) And $celtFetched > 0) If SUCCEEDED($oConecctionsFolder.GetDisplayNameOf($pPIDLItem, $SHGDN_NORMAL, DllStructGetPtr($tSTRRET))) Then $twstring = DllStructCreate("wchar Name[512]", $tSTRRET.pOleStr) If $twstring.Name = $sConnectionName Then If $lnkPath = "" Then $lnkPath = @DesktopDir & "\" & $twstring.Name & ".lnk" $bRet = CreateLnk($pPIDLConectionsFolder, $pPIDLItem, $lnkPath) ExitLoop EndIf $twstring = 0 EndIf WEnd EndIf EndIf EndIf EndIf If $pPIDLConectionsFolder Then _WinAPI_CoTaskMemFree($pPIDLConectionsFolder) Return $bRet EndFunc ;==>CreateNetWorkShortCut Func CreateLnk($PIDL1, $PIDL2, $lnkPath) Local $oShellLink = 0 Local $oIPersistFile = 0 Local $pIPersistFile = 0 Local $pAppendID = 0 Local $bRet = False $oShellLink = ObjCreateInterface($CLSID_ShellLink, $sIID_IShellLinkW, $sTagIShellLink) If @error Then Return $bRet $pAppendID = ILAppendID($PIDL1, $PIDL2) If IsObj($oShellLink) And $pAppendID Then If SUCCEEDED($oShellLink.SetIDList($pAppendID)) Then $oShellLink.QueryInterface($sIID_IPersistFile, $pIPersistFile) $oIPersistFile = ObjCreateInterface($pIPersistFile, $sIID_IPersistFile, $sTagIPersistFile) If IsObj($oIPersistFile) Then $bRet = SUCCEEDED($oIPersistFile.Save($lnkPath, True)) EndIf EndIf EndIf Return $bRet EndFunc ;==>CreateLnk Func ILAppendID($PIDLIST_RELATIVE, $LPSHITEMID, $fAppend = True) Local $aRet = DllCall("Shell32.dll", "ptr", "ILAppendID", "ptr", $PIDLIST_RELATIVE, "ptr", $LPSHITEMID, "bool", $fAppend) If @error Then Return SetError(@error, @extended, 0) If $aRet[0] = 0 Then Return SetError(10, $aRet[0], 0) Return $aRet[0] EndFunc ;==>ILAppendID Func SHGetDesktopFolder() Local $aRet = DllCall("Shell32.dll", "long", "SHGetDesktopFolder", "ptr*", Null) If @error Then Return SetError(@error, @extended, 0) If $aRet[0] Then Return SetError(10, $aRet[0], 0) Return $aRet[1] EndFunc ;==>SHGetDesktopFolder Func SUCCEEDED($hr) Return ($hr >= 0) EndFunc ;==>SUCCEEDED Saludos
    • Danyfirex
      By Danyfirex
      A simple example of listing installed applications using ObjCreateInterface.
      Update.  10/09/2014
      ;Danyfirex 06/09/2014 #include <Array.au3> Opt("MustDeclareVars", 1) Global Const $sTagAppInfoData = "UINT cbSize;UINT dwMask;ptr pszDisplayName;ptr pszVersion;ptr pszPublisher;ptr pszProductID;" & _ "ptr pszRegisteredOwner;ptr pszRegisteredCompany;ptr pszLanguage;ptr pszSupportUrl;ptr pszSupportTelephone;" & _ "ptr pszHelpLink;ptr pszInstallLocation;ptr pszInstallSource;ptr pszInstallDate;ptr pszContact;ptr pszComments;" & _ "ptr pszImage;ptr pszReadmeUrl;ptr pszUpdateInfoUrl" Global Const $sCLSID_EnumInstalledApps = "{0B124F8F-91F0-11D1-B8B5-006008059382}" Global Const $sIID_IEnumInstalledApps = "{1BC752E1-9046-11D1-B8B3-006008059382}" Global Const $sTagIEnumInstalledApps = "Next hresult(ptr*);Reset hresult();" Global Const $sIID_IShellApp = "{A3E14960-935F-11D1-B8B8-006008059382}" Global Const $sShellApp = "GetAppInfoData hresult(ptr);" Global Const $AIM_DISPLAYNAME = 0x00000001 Global Const $AIM_VERSION = 0x00000002 Global Const $AIM_PUBLISHER = 0x00000004 Global Const $AIM_PRODUCTID = 0x00000008 Global Const $AIM_REGISTEREDOWNER = 0x00000010 Global Const $AIM_REGISTEREDCOMPANY = 0x00000020 Global Const $AIM_LANGUAGE = 0x00000040 Global Const $AIM_SUPPORTURL = 0x00000080 Global Const $AIM_SUPPORTTELEPHONE = 0x00000100 Global Const $AIM_HELPLINK = 0x00000200 Global Const $AIM_INSTALLLOCATION = 0x00000400 Global Const $AIM_INSTALLSOURCE = 0x00000800 Global Const $AIM_INSTALLDATE = 0x00001000 Global Const $AIM_CONTACT = 0x00004000 Global Const $AIM_COMMENTS = 0x00008000 Global Const $AIM_IMAGE = 0x00020000 Global Const $AIM_READMEURL = 0x00040000 Global Const $AIM_UPDATEINFOURL = 0x00080000 Local $aArray = GetInstalledApps(BitOR($AIM_DISPLAYNAME, $AIM_INSTALLDATE)) _ArrayDisplay($aArray, "GetInstalledApps", Default, Default, Default, "NAME|INSTALLDATE") $aArray = GetInstalledApps(BitOR($AIM_DISPLAYNAME, $AIM_UPDATEINFOURL)) _ArrayDisplay($aArray, "GetInstalledApps", Default, Default, Default, "DISPLAYNAME|UPDATEINFOURL") $aArray = GetInstalledApps(BitOR($AIM_DISPLAYNAME, $AIM_INSTALLDATE, $AIM_INSTALLLOCATION)) _ArrayDisplay($aArray, "GetInstalledApps", Default, Default, Default, "DISPLAYNAME|INSTALLLOCATION|INSTALLDATE") Func GetInstalledApps($iMask = $AIM_DISPLAYNAME) Local $oEnumInstalledApps = ObjCreateInterface($sCLSID_EnumInstalledApps, $sIID_IEnumInstalledApps, $sTagIEnumInstalledApps) If @error Then Return 0 Local $pShellApp = 0 Local $oShellApp = 0 Local $AppInfoData = DllStructCreate($sTagAppInfoData) Local $pAppInfoData = DllStructGetPtr($AppInfoData) Local $i = 0 Local $aArray[0][0] Local $iF = 1 Local $tData = 0 Local $sData = "" Local $aMax = nCol($iMask) While $oEnumInstalledApps.Next($pShellApp) = 0 And $pShellApp <> 0 $oShellApp = ObjCreateInterface($pShellApp, $sIID_IShellApp, $sShellApp) If @error Then Return 0 DllStructSetData($AppInfoData, "cbSize", DllStructGetSize($AppInfoData)) DllStructSetData($AppInfoData, "dwMask", $iMask) $oShellApp.GetAppInfoData($pAppInfoData) ReDim $aArray[$iF][UBound($aMax)] For $i = 0 To UBound($aMax) - 1 $tData = DllStructCreate("wchar[260]", DllStructGetData($AppInfoData, $aMax[$i] + 2)) $sData = DllStructGetData($tData, 1) If $aMax[$i] = 13 Then $sData = StringMid($sData, 7, 2) & "/" & StringMid($sData, 5, 2) & "/" & StringMid($sData, 1, 4) $aArray[$iF - 1][$i] = ($sData = "0") ? "" : $sData DllStructSetData($tData, 1, "") Next $oShellApp = Null $iF += 1 WEnd $oEnumInstalledApps = Null Return $aArray EndFunc ;==>GetInstalledApps Func nCol($iMask) Local $aFlag[18] = [$AIM_DISPLAYNAME, $AIM_VERSION, $AIM_PUBLISHER, $AIM_PRODUCTID, $AIM_REGISTEREDOWNER, $AIM_REGISTEREDCOMPANY, _ $AIM_LANGUAGE, $AIM_SUPPORTURL, $AIM_SUPPORTTELEPHONE, $AIM_HELPLINK, $AIM_INSTALLLOCATION, $AIM_INSTALLSOURCE, _ $AIM_INSTALLDATE, $AIM_CONTACT, $AIM_COMMENTS, $AIM_IMAGE, $AIM_READMEURL, $AIM_UPDATEINFOURL] Local $iCol = 0 Local $x = 0 Local $aCol[18] For $i = 0 To UBound($aFlag) - 1 If BitAND($iMask, $aFlag[$i]) Then $aCol[$x] = $i + 1 $x += 1 EndIf Next ReDim $aCol[$x] Return $aCol EndFunc ;==>nCol  
      Saludos
    • Inververs
      By Inververs
      I try to create interface_description for ObjCreateInterface function
      Here the part of interface:
      [id(0x00000002), propput, helpstring("Default")] HRESULT Default([in] BSTR TokenId); [id(0x00000002), propget, helpstring("Default")] HRESULT Default([out, retval] BSTR* TokenId); you can see that there are two the same method Default.
      first is [in], second is - [out].

      how to write a description of this?

      Default hresult(bstr;);Default hresult(bstr*); - is it correct?

      or so?
      Default hresult(bstr;bstr*);
      please help.
    • LarsJ
      By LarsJ
      (The title of this example was originally "The Shell/Custom Favorites/Programs Menus".)



      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 procedureThe 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.