简体   繁体   中英

Call SHGetStockIconInfo from Python

Background: I'm trying to add some UAC shield icons to a few menu options in my wxPython based Python application. Buttons I've had no problem, as I can just send the BCM_SETSHIELD message to the buttons and Windows handles the rest.

In the link MSDN article here , it describes calling SHGetStockIconInfo to get the Handle or location for the shield icon. I'm trying to call it via Python using this code:

from ctypes import *

class SHSTOCKICONINFO(Structure):
    _fields_ = [('cbSize',c_ulong),
                ('hIcon',c_void_p),
                ('iSysImageIndex',c_int),
                ('iIcon',c_int),
                ('szPath',c_wchar_p)]

_SHGetStockIconInfo = windll.shell32.SHGetStockIconInfo
_SHGetStockIconInfo.argtypes = [c_uint,c_uint,POINTER(SHSTOCKICONINFO)]
_SHGetStockIconInfo.restype = c_int

# Values copied from shellapi.h
SIID_SHIELD = 77

SHGSI_ICONLOCATION = 0
SHGSI_ICON = 0x100
SHGSI_SMALLICON = 0x1
SHGSI_LARGEICON = 0

def GetIconLocation(id,flags=SHGSI_LARGEICON):
    # Clear _ICON bit and set _ICONLOCATION bit
    flags = ~(~flags|SHGSI_ICON)|SHGSI_ICONLOCATION
    info = SHSTOCKICONINFO()
    info.cbSize = sizeof(SHSTOCKICONINFO)
    result = _SHGetStockIconInfo(id,flags,byref(info)):
    if result != 0:
        raise Exception(result)
    return (info.szPath,info.iIcon)

Now whenever I call it, I get a return result from SHGetStockIconInfo of 0x80070057 (E_INVALIDARG - One or more arguments are not valid).

Can anyone help figure out what's going wrong here? Or maybe point me to an easier way to get at this icon resource?

Edit: The problem was in my SHSTOCKICONINFO definition, see below. My example above now works correctly with the corrections from below.

The final field of the structure is declared incorrectly. Your code declared szPath to be a pointer to null-terminated array. But in fact it should be:

('szPath', c_wchar*MAX_PATH)

Take a look at the C++ declaration for that field:

WCHAR szPath[MAX_PATH];

That's an inline array of MAX_PATH wide characters. You can get hold of MAX_PATH like this:

from ctypes.wintypes import MAX_PATH

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM