win32gui.LoadImage 报 pywintypes.error: (0, ‘LoadImage‘, ‘No error message is available‘)

编程入门 行业动态 更新时间:2024-10-27 00:34:10

win32gui.<a href=https://www.elefans.com/category/jswz/34/1609446.html style=LoadImage 报 pywintypes.error: (0, ‘LoadImage‘, ‘No error message is available‘)"/>

win32gui.LoadImage 报 pywintypes.error: (0, ‘LoadImage‘, ‘No error message is available‘)

import contextlib
import tempfileimport win32api, win32con, win32gui_struct, win32gui
import os# 此方式报错
# hicon = win32gui.LoadImage(hinst, s.icon, win32con.IMAGE_ICON, 0, 0, icon_flags)#解决方式1
# with s.serialized_image(Image.open(s.icon), 'ICO') as icon_path:
# hicon = win32gui.LoadImage(None, icon_path, win32con.IMAGE_ICON, 0, 0, icon_flags)# 解决方式2with s.serialized_image(Image.open(s.icon), 'ICO') as icon_path:hicon = ctypes.LibraryLoader(ctypes.WinDLL).user32.LoadImageW(None, icon_path, win32con.IMAGE_ICON, 0, 0, icon_flags)class SysTrayIcon(object):'''SysTrayIcon类用于显示任务栏图标'''QUIT = 'QUIT'SPECIAL_ACTIONS = [QUIT]FIRST_ID = 5320def __init__(s, icon, hover_text, menu_options, on_quit, tk_window=None, default_menu_index=None,window_class_name=None):'''icon         需要显示的图标文件路径hover_text   鼠标停留在图标上方时显示的文字menu_options 右键菜单,格式: (('a', None, callback), ('b', None, (('b1', None, callback),)))on_quit      传递退出函数,在执行退出时一并运行tk_window    传递Tk窗口,s.root,用于单击图标显示窗口default_menu_index 不显示的右键菜单序号window_class_name  窗口类名'''s.icon = icons.hover_text = hover_texts.on_quit = on_quits.root = tk_window#  右键菜单添加退出menu_options = menu_options + (('退出', None, s.QUIT),)# 初始化托盘程序每个选项的ID,后面的依次+1s._next_action_id = s.FIRST_IDs.menu_actions_by_id = set()print(menu_options, type(menu_options),'menu_options')s.menu_options = s._add_ids_to_menu_options(list(menu_options))s.menu_actions_by_id = dict(s.menu_actions_by_id)print(s.menu_actions_by_id,'menu_actions_by_id')del s._next_action_ids.default_menu_index = (default_menu_index or 0)s.window_class_name = window_class_name or "SysTrayIconPy"message_map = {win32gui.RegisterWindowMessage("TaskbarCreated"): s.restart,win32con.WM_DESTROY: s.destroy,win32con.WM_COMMAND: smand,win32con.WM_USER + 20: s.notify, }# 注册窗口类。wc = win32gui.WNDCLASS()wc.hInstance = win32gui.GetModuleHandle(None)wc.lpszClassName = s.window_class_namewc.style = win32con.CS_VREDRAW | win32con.CS_HREDRAWwc.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW)wc.hbrBackground = win32con.COLOR_WINDOWwc.lpfnWndProc = message_map  # 也可以指定wndproc.s.classAtom = win32gui.RegisterClass(wc)def activation(s):'''激活任务栏图标,不用每次都重新创建新的托盘图标'''hinst = win32gui.GetModuleHandle(None)  # 创建窗口。style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENUs.hwnd = win32gui.CreateWindow(s.classAtom,s.window_class_name,style,0, 0,win32con.CW_USEDEFAULT,win32con.CW_USEDEFAULT,0, 0, hinst, None)win32gui.UpdateWindow(s.hwnd)s.notify_id = Nones.refresh(title='软件已后台!', msg='点击重新打开', time=500)win32gui.PumpMessages()def serialized_image(s, image, format, extension=None):"""Creates an image file from a :class:`PIL.Image.Image`.This function is a context manager that yields a temporary file name. Thefile is removed when the block is exited.:param PIL.Image.Image image: The in-memory image.:param str format: The format of the image. This format must be handled by*Pillow*.:param extension: The file extension. This defaults to ``format``lowercased.:type extensions: str or None"""fd, path = tempfile.mkstemp('.%s' % (extension or format.lower()))try:with os.fdopen(fd, 'wb') as f:image.save(f, format=format)yield pathfinally:try:os.unlink(path)except:raise@contextlib.contextmanagerdef serialized_image(s, image, format, extension=None):"""Creates an image file from a :class:`PIL.Image.Image`.This function is a context manager that yields a temporary file name. Thefile is removed when the block is exited.:param PIL.Image.Image image: The in-memory image.:param str format: The format of the image. This format must be handled by*Pillow*.:param extension: The file extension. This defaults to ``format``lowercased.:type extensions: str or None"""fd, path = tempfile.mkstemp('.%s' % (extension or format.lower()))try:with os.fdopen(fd, 'wb') as f:image.save(f, format=format)yield pathfinally:try:os.unlink(path)except:raisedef refresh(s, title='', msg='', time=500):'''刷新托盘图标title 标题msg   内容,为空的话就不显示提示time  提示显示时间'''# from pystray._util import serialized_image, win32from PIL import Imageimport ctypeshinst = win32gui.GetModuleHandle(None)if os.path.isfile(s.icon):icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE# 此方式报错# hicon = win32gui.LoadImage(hinst, s.icon, win32con.IMAGE_ICON, 0, 0, icon_flags)#解决方式1# with s.serialized_image(Image.open(s.icon), 'ICO') as icon_path:# hicon = win32gui.LoadImage(None, icon_path, win32con.IMAGE_ICON, 0, 0, icon_flags)# 解决方式2with s.serialized_image(Image.open(s.icon), 'ICO') as icon_path:hicon = ctypes.LibraryLoader(ctypes.WinDLL).user32.LoadImageW(None, icon_path, win32con.IMAGE_ICON, 0, 0, icon_flags)else:  # 找不到图标文件 - 使用默认值hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)if s.notify_id:message = win32gui.NIM_MODIFYelse:message = win32gui.NIM_ADDs.notify_id = (s.hwnd, 0,  # 句柄、托盘图标IDwin32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP | win32gui.NIF_INFO,# 托盘图标可以使用的功能的标识win32con.WM_USER + 20, hicon, s.hover_text,  # 回调消息ID、托盘图标句柄、图标字符串msg, time, title,  # 提示内容、提示显示时间、提示标题win32gui.NIIF_INFO  # 提示用到的图标)win32gui.Shell_NotifyIcon(message, s.notify_id)def show_menu(s):'''显示右键菜单'''menu = win32gui.CreatePopupMenu()s.create_menu(menu, s.menu_options)pos = win32gui.GetCursorPos()win32gui.SetForegroundWindow(s.hwnd)win32gui.TrackPopupMenu(menu,win32con.TPM_LEFTALIGN,pos[0],pos[1],0,s.hwnd,None)win32gui.PostMessage(s.hwnd, win32con.WM_NULL, 0, 0)# 整理菜单的选项,添加ID.递归添加,将二级菜单页添加进去def _add_ids_to_menu_options(s, menu_options):result = []for menu_option in menu_options:option_text, option_icon, option_action = menu_optionif callable(option_action) or option_action in s.SPECIAL_ACTIONS:s.menu_actions_by_id.add((s._next_action_id, option_action))result.append(menu_option + (s._next_action_id,))else:result.append((option_text,option_icon,s._add_ids_to_menu_options(option_action),s._next_action_id))s._next_action_id += 1print(result, 'result')return resultdef restart(s, hwnd, msg, wparam, lparam):s.refresh()def destroy(s, hwnd=None, msg=None, wparam=None, lparam=None, exit=1):nid = (s.hwnd, 0)win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)win32gui.PostQuitMessage(0)  # 终止应用程序。if exit and s.on_quit:s.on_quit()  # 需要传递自身过去时用 s.on_quit(s)else:s.root.deiconify()  # 显示tk窗口def notify(s, hwnd, msg, wparam, lparam):'''鼠标事件'''if lparam == win32con.WM_LBUTTONDBLCLK:  # 双击左键passelif lparam == win32con.WM_RBUTTONUP:  # 右键弹起s.show_menu()elif lparam == win32con.WM_LBUTTONUP:  # 左键弹起s.destroy(exit=0)return True"""可能的鼠标事件:WM_MOUSEMOVE      #光标经过图标WM_LBUTTONDOWN    #左键按下WM_LBUTTONUP      #左键弹起WM_LBUTTONDBLCLK  #双击左键WM_RBUTTONDOWN    #右键按下WM_RBUTTONUP      #右键弹起WM_RBUTTONDBLCLK  #双击右键WM_MBUTTONDOWN    #滚轮按下WM_MBUTTONUP      #滚轮弹起WM_MBUTTONDBLCLK  #双击滚轮"""def create_menu(s, menu, menu_options):for option_text, option_icon, option_action, option_id in menu_options[::-1]:if option_icon:option_icon = s.prep_menu_icon(option_icon)if option_id in s.menu_actions_by_id:item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text,hbmpItem=option_icon,wID=option_id)win32gui.InsertMenuItem(menu, 0, 1, item)else:submenu = win32gui.CreatePopupMenu()s.create_menu(submenu, option_action)item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text,hbmpItem=option_icon,hSubMenu=submenu)win32gui.InsertMenuItem(menu, 0, 1, item)def prep_menu_icon(s, icon):# 加载图标。ico_x = win32api.GetSystemMetrics(win32con.SM_CXSMICON)ico_y = win32api.GetSystemMetrics(win32con.SM_CYSMICON)hicon = win32gui.LoadImage(0, icon, win32con.IMAGE_ICON, ico_x, ico_y, win32con.LR_LOADFROMFILE)hdcBitmap = win32gui.CreateCompatibleDC(0)hdcScreen = win32gui.GetDC(0)hbm = win32gui.CreateCompatibleBitmap(hdcScreen, ico_x, ico_y)hbmOld = win32gui.SelectObject(hdcBitmap, hbm)brush = win32gui.GetSysColorBrush(win32con.COLOR_MENU)win32gui.FillRect(hdcBitmap, (0, 0, 16, 16), brush)win32gui.DrawIconEx(hdcBitmap, 0, 0, hicon, ico_x, ico_y, 0, 0, win32con.DI_NORMAL)win32gui.SelectObject(hdcBitmap, hbmOld)win32gui.DeleteDC(hdcBitmap)return hbmdef command(s, hwnd, msg, wparam, lparam):id = win32gui.LOWORD(wparam)s.execute_menu_option(id)def execute_menu_option(s, id):menu_action = s.menu_actions_by_id[id]if menu_action == s.QUIT:win32gui.DestroyWindow(s.hwnd)else:menu_action(s)
from tkinter import *
import tkinter.messagebox as messagebox
import time
# import HttpServer
import SysTrayIconwindow_width = 480
window_height = 500
LOG_LINE_NUM = 0
web_port = 9000
this_http_server = None
systrayIconObj = None
init_window = Noneicon = r'./favicon.ico'class main_gui():'''主界面类'''def __init__(self, this_window, toTrayIconFun):self.this_window = this_windowself.toTrayIconFun = toTrayIconFun'''界面类容  '''# 说明书self.init_desc_label = Label(self.this_window, fg="red", text="将此文件放到任意目录,①打开软件,②设置端口号,③点击启动 即可启动web服务。")self.init_desc_label.grid(row=0, column=0, rowspan=1, columnspan=6)# 端口文字self.init_port_label = Label(self.this_window, text="WEB端口:")self.init_port_label.grid(row=1, column=0)# 端口输入文本框self.init_port_Text = Entry(self.this_window, textvariable=StringVar(value=web_port))  # 原始数据录入框self.init_port_Text.grid(row=1, column=1, rowspan=1, columnspan=1)# 启动 按钮self.start_server_button = Button(self.this_window, text="启动WEB服务", bg="lightblue", width=10,command=self.start_server)  # 调用内部方法  加()为直接调用self.start_server_button.grid(row=1, column=2, rowspan=1, columnspan=1)# 隐藏到图标self.hide_server_button = Button(self.this_window, text="托盘隐藏", bg="lightblue", width=10,command=self.toTrayIconFun)  # 调用内部方法  加()为直接调用self.hide_server_button.grid(row=1, column=3)# 日志self.log_data_label = Label(self.this_window, text="日志类容:")self.log_data_label.grid(row=3, column=0, rowspan=1, columnspan=6)# 日志self.log_data_Text = Text(self.this_window, width=66, height=29)  # 日志框self.log_data_Text.grid(row=4, column=0, columnspan=6)# 清空日志self.start_server_button = Button(self.this_window, text="清空日志", bg="lightblue", width=10,command=self.clear_log)  # 调用内部方法  加()为直接调用self.start_server_button.grid(row=5, column=0, columnspan=6)# 隐藏到托盘def hide_to_stock(self):pass# 日志动态打印def write_log_to_Text(self, logmsg, err=None):print(f" 日志:{logmsg}", err)current_time = self.get_current_time()logmsg_in = str(current_time) + " " + str(logmsg) + "\n"  # 换行self.log_data_Text.insert("insert", logmsg_in)if err != None:self.log_data_Text.insert("insert", f"{err}" + "\n")self.log_data_Text.update()# 清空日志def clear_log(self):self.log_data_Text.delete(1.0, END)self.log_data_Text.update()def start_server(self):iport = self.init_port_Text.get().strip().replace("\n", "")if not iport.isdigit() or (int(iport) <= 0 or 65000 <= int(iport)):messagebox.showerror(title='端口错误', message='端口必须是数字,且只能填写1-65000之中的数字。')returnweb_port = int(iport)print(f" 新端口:{web_port}")global this_http_serverif this_http_server:this_http_server.close_server()# this_http_server = HttpServer.HttpServer(web_port, self.write_log_to_Text)# 获取当前时间def get_current_time(self):current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))return current_timedef exit(s=None, _sysTrayIcon=None):global init_windowinit_window.destroy()  # 退出界面loop,退出进程print('exit...')def Hidden_window(icon=icon, hover_text="静态文件服务器"):'''隐藏窗口至托盘区,调用SysTrayIcon的重要函数'''# 托盘图标右键菜单, 格式: ('name', None, callback),下面也是二级菜单的例子# 24行有自动添加‘退出’,不需要的可删除menu_options = ()init_window.withdraw()  # 隐藏tk窗口global systrayIconObjif not systrayIconObj:systrayIconObj = SysTrayIcon.SysTrayIcon(icon,  # 图标hover_text,  # 光标停留显示文字menu_options,  # 右键菜单on_quit=exit,  # 退出调用tk_window=init_window,  # Tk窗口)# 创建托盘图标systrayIconObj.activation()def gui_start():global init_windowinit_window = Tk()  # 实例化出一个父窗口init_window.resizable(False, False)  # 窗口不可调整大小# init_window.iconbitmap("icon.ico") #icod不方便打包,所以不单独设置icon了,init_window.title("静态文件服务器")  # 窗口名init_window["bg"] = "#F0F0F0"  # 窗口背景色,其他背景色见:blog.csdn/chl0000/article/details/7657887init_window.attributes("-alpha", 1)  # 虚化,值越小虚化程度越高main_gui(init_window, Hidden_window)# 设置窗口初始大小和位置 window_width window_height为窗口大小,+10 +10 定义窗口弹出时的默认展示位置init_window.geometry('%dx%d+%d+%d' % (window_width, window_height, 300, 300))# 绑定缩放托盘事件init_window.bind("<Unmap>", lambdaevent: Hidden_window() if init_window.state() == 'iconic' else False)  # 窗口最小化判断,可以说是调用最重要的一步init_window.protocol('WM_DELETE_WINDOW', exit)  # 点击Tk窗口关闭时直接调用s.exit,不使用默认关闭init_window.update()  # 刷新窗口显示init_window.mainloop()  # 父窗口进入事件循环,可以理解为保持窗口运行,否则界面不展示if __name__ == "__main__":gui_start()

更多推荐

win32gui.LoadImage 报 pywintypes.error: (0, ‘LoadImage‘, ‘No error message is ava

本文发布于:2024-03-08 12:48:37,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1720917.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:LoadImage   win32gui   pywintypes   message   error

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!