Shell_NotifyIcon 修改托盘图标失败的问题

本文介绍了如何解决托盘图标闪烁的问题,通过正确使用NOTIFYICONDATA结构,并展示了如何实现托盘图标的状态改变,避免了Shell_NotifyIcon返回1460错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近需要完成托盘图标闪烁的功能,但是一直没有达到效果,使用Shell_NotifyIcon 一直返回1460的错误。

后面找了很多资料发现问题;NOTIFYICONDATA结构只能在NIM_ADD里面定义一次,多次定义会导致修改托盘图标失败。

NOTIFYICONDATA m_nc;//定义在全局,只定义一次

void CFrameWnd::AddToTray()
{
	m_nc.cbSize = sizeof(NOTIFYICONDATA);
	m_nc.hWnd = m_hWnd;
	m_nc.uID = IDI_TORY;   
	m_nc.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
	m_nc.uCallbackMessage = MSG_SHOW_TORY;   
	m_nc.hIcon = LoadIcon(m_PaintManager.GetInstance(), MAKEINTRESOURCE(IDI_TORY));

#ifndef _UNICODE
	strcpy(m_nc.szTip, _T("托盘测试"));
#else
	wcscpy(m_nc.szTip, _T("托盘测试")); //托盘图标鼠标悬浮提示文字
#endif
	Shell_NotifyIcon(NIM_ADD, &m_nc);
}

void CFrameWnd::ModifyToryIcon()//修改托盘是不能再重新定义NOTIFYICONDATA,而是应该和NIM_ADD里面使用相同的结构
{
	if (m_bIsIcon)
	{
		m_nc.hIcon = LoadIcon(CPaintManagerUI::GetInstance(), MAKEINTRESOURCE(NULL));
		m_nc.uFlags = NIF_ICON;
		int m = Shell_NotifyIcon(NIM_MODIFY, &m_nc);
		DWORD dw = GetLastError();
		m_bIsIcon = false;
	}
	else
	{
		m_nc.hIcon = LoadIcon(CPaintManagerUI::GetInstance(), MAKEINTRESOURCE(IDI_NEWUSER));
		m_nc.uFlags = NIF_ICON;
		int m = Shell_NotifyIcon(NIM_MODIFY, &m_nc);
		DWORD dw = GetLastError();
		m_bIsIcon = true;
	}
}


import tkinter as tk from tkinter import Menu import threading import win32api import pythoncom from win32gui import NIF_TIP, NIF_MESSAGE, NIF_ICON, LoadImage, Shell_NotifyIcon, NIM_ADD, NIM_DELETE,GetCursorPos from win32con import LR_LOADFROMFILE, WM_USER, IMAGE_ICON, WM_LBUTTONUP, LR_DEFAULTSIZE,WM_RBUTTONUP import os WM_TRAYICON = WM_USER + 1 class SysTrayIcon: def __init__(self, hwnd, icon_path: str = 'app.ico', title="Tkinter App"): self.hwnd =hwnd # 主窗口引用 self.icon_path = os.path.abspath(icon_path) self.title = title self.message_map = {WM_LBUTTONUP: self.on_left_click} # 左键单击事件 self.message_map.update({WM_RBUTTONUP: self.show_menu}) self.create_tray_icon() def create_tray_icon(self): # 创建托盘图标 self.icon_flags = NIF_ICON | NIF_MESSAGE | NIF_TIP self.hIcon = LoadImage(None, self.icon_path, IMAGE_ICON, 0, 0, LR_LOADFROMFILE) self.nid = ( self.hwnd, 0, self.icon_flags, WM_TRAYICON, self.hIcon, "双击显示窗口" ) # print(self.nid) Shell_NotifyIcon(NIM_ADD, self.nid) def on_left_click(self, hwnd, msg, wparam, lparam): self.hwnd.deiconify() # 恢复窗口显示 self.remove_icon() # 移除托盘图标 # 添加托盘菜单功能(扩展SysTrayIcon类) def show_menu(self, hwnd, msg, wparam, lparam): if msg == WM_RBUTTONUP: # 右键单击 pos = GetCursorPos() self.tray_menu.tk_popup(pos[0], pos[1]) # 在鼠标位置弹出菜单 def remove_icon(self): Shell_NotifyIcon(NIM_DELETE, self.nid) class MainWindow(tk.Tk): def __init__(self): super().__init__() self.title("系统托盘示例") self.geometry("300x200") self.protocol("WM_DELETE_WINDOW", self.on_close) # 覆盖关闭按钮行为 self.bind("<Unmap>", self.minimize_to_tray) # 绑定最小化事件 # 创建托盘菜单 self.tray_menu = Menu(self, tearoff=0) self.tray_menu.add_command(label="恢复窗口", command=self.restore_window) self.tray_menu.add_command(label="退出", command=self.destroy) def minimize_to_tray(self, event): if event.widget == self: # 确保是主窗口最小化 self.withdraw() # 隐藏窗口 SysTrayIcon(self.winfo_id(), "app.ico") # 创建托盘图标 def on_close(self): self.destroy() # 实际关闭程序 def restore_window(self): self.deiconify() # 恢复窗口显示 if __name__ == "__main__": app = MainWindow() app.mainloop()
最新发布
06-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值