Как загрузить встроенный значок из исполняемого файла с PyWin32? - PullRequest
7 голосов
/ 18 сентября 2008

У меня есть exe-файл, созданный с помощью py2exe. В файле setup.py я указываю значок для встраивания в исполняемый файл:

windows=[{'script': 'my_script.py','icon_resources': [(0, 'my_icon.ico')], ...

Я попытался загрузить значок, используя:

hinst = win32api.GetModuleHandle(None)
hicon = win32gui.LoadImage(hinst, 0, win32con.IMAGE_ICON, 0, 0, win32con.LR_DEFAULTSIZE)

Но это приводит к (очень неопределенной) ошибке:
pywintypes.error: (0, «LoadImage», «Сообщение об ошибке недоступно»)

Если я попытаюсь указать 0 в виде строки

hicon = win32gui.LoadImage(hinst, '0', win32con.IMAGE_ICON, 0, 0, win32con.LR_DEFAULTSIZE)

тогда я получаю ошибку:
pywintypes.error: (1813, 'LoadImage', 'Указанный тип ресурса не найден в файле изображения.')

Итак, каков правильный метод / синтаксис для загрузки иконки?
Также обратите внимание, что я не использую какой-либо инструментарий GUI - только Windows API через PyWin32.

Ответы [ 4 ]

5 голосов
/ 21 сентября 2008

@ efotinis: Ты прав.

Вот обходной путь, пока py2exe не будет исправлен, и вы не захотите включать один и тот же значок дважды:

hicon = win32gui.CreateIconFromResource(win32api.LoadResource(None, win32con.RT_ICON, 1), True)

Имейте в виду, что 1 - это не идентификатор, который вы дали значку в setup.py (который является идентификатором группы значков), а идентификатор ресурса , автоматически назначенный py2exe каждому значок в каждой группе значков. По крайней мере, я так понимаю.

Если вы хотите создать значок с указанным размером (так как CreateIconFromResource использует системный размер значка по умолчанию), вам нужно использовать CreateIconFromResourceEx, который недоступен через PyWin32:

icon_res = win32api.LoadResource(None, win32con.RT_ICON, 1)
hicon = ctypes.windll.user32.CreateIconFromResourceEx(icon_res, len(icon_res), True,
    0x00030000, 16, 16, win32con.LR_DEFAULTCOLOR)
1 голос
/ 18 сентября 2008

Если вы используете wxPython, вы можете использовать следующий простой код:

wx.Icon(sys.argv[0], wx.BITMAP_TYPE_ICO)

У меня обычно есть код, который проверяет, работает ли он из EXE или нет, и действует соответственно:

def get_app_icon():
    if hasattr(sys, "frozen") and getattr(sys, "frozen") == "windows_exe":
        return wx.Icon(sys.argv[0], wx.BITMAP_TYPE_ICO)
    else:
        return wx.Icon("gfx/myapp.ico", wx.BITMAP_TYPE_ICO)
1 голос
/ 18 сентября 2008

Ну, хорошо ... Я установил py2exe, и я думаю, что это ошибка. В py2exe_util.c они должны начинать rt_icon_id с 1 вместо 0. В настоящее время невозможно загрузить первый формат первого значка с помощью LoadIcon / LoadImage.

Я сообщу разработчикам об этом, если это еще не известная проблема.

В то же время, временным решением может быть включение одного и того же значка в ваш файл setup.py:

дважды.
'icon_resources': [(1, 'my_icon.ico'), (2, 'my_icon.ico')]

Вы можете загрузить второй, в то время как Windows будет использовать первый как значок оболочки. Не забудьте использовать ненулевые идентификаторы, хотя. :)

0 голосов
/ 18 сентября 2008

Вы должны установить идентификатор значка, отличный от 0:

'icon_resources': [(42, 'my_icon.ico')]

Идентификаторы ресурса Windows должны быть от 1 до 32767.

...