import wx
import win32gui
import win32con
import win32api
import time
from winxpgui import *
class SparkTaskBarIcon(wx.TaskBarIcon):
TBMENU_RESTORE = wx.NewId()
TBMENU_CLOSE = wx.NewId()
TBMENU_CHANGE = wx.NewId()
TBMENU_REMOVE = wx.NewId()
def __init__(self, frame,picon,icon):
wx.TaskBarIcon.__init__(self)
self.frame = frame
#self.SetIcon(picon, "Spark")
self.imgidx = 1
# bind some events
self.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.OnTaskBarActivate)
self.Bind(wx.EVT_MENU, self.OnTaskBarActivate, id=self.TBMENU_RESTORE)
self.Bind(wx.EVT_MENU, self.OnTaskBarClose, id=self.TBMENU_CLOSE)
#self.Bind(wx.EVT_MENU, self.OnTaskBarChange, id=self.TBMENU_CHANGE)
self.Bind(wx.EVT_MENU, self.OnTaskBarRemove, id=self.TBMENU_REMOVE)
self.ReigstWinClass(icon)
self.CreatWin()
#气泡提示注册win的窗口消息
def ReigstWinClass(self,icon):
wc = win32gui.WNDCLASS()
hinst = wc.hInstance = win32gui.GetModuleHandle(None)
#msg_TaskbarRestart = win32gui.RegisterWindowMessage("TaskbarCreated");
self.message_map={
#msg_TaskbarRestart:self.OnWinRestart,
win32con.WM_DESTROY:self.OnWinDestory,
win32con.WM_COMMAND:self.OnWinCommand,
win32con.WM_USER+20:self.OnTaskbarNotify,
}
wc.lpszClassName = "Spark"
wc.lpfnWndProc = self.message_map
try:
classAtom = win32gui.RegisterClass(wc)
except win32gui.error, err_info:
if err_info.winerror!=winerror.ERROR_CLASS_ALREADY_EXISTS:
raise
#classAtom = win32gui.RegisterClass(wc)
icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE
self.hicon =win32gui.LoadImage(hinst, icon, win32con.IMAGE_ICON, 0, 0, icon_flags)
#return classAtom
def CreatWin(self):
style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
hinst = win32gui.GetModuleHandle(None)
self.hwnd = win32gui.CreateWindow( "Spark", "Spark", style,
0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT,
0, 0, hinst, None)
flags = win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP
#nid = (self.hwnd, 0, flags, win32con.WM_USER+20, hicon, "Python Demo")
nid = (self.hwnd, 0, flags, win32con.WM_USER+20,self.hicon, "Spark")
win32gui.Shell_NotifyIcon(win32gui.NIM_ADD, nid)
win32gui.UpdateWindow(self.hwnd)
def OnWinRestart(self, hwnd, msg, wparam, lparam):
pass
#self._DoCreateIcons()
def OnWinDestory(self, hwnd, msg, wparam, lparam):
nid = (self.hwnd, 0)
win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)
win32gui.PostQuitMessage(0)
def OnTaskbarNotify(self, hwnd, msg, wparam, lparam):
print 'OnWinTaskbarNotify'
if lparam==win32con.WM_LBUTTONUP:
print "You clicked me."
elif lparam==win32con.WM_LBUTTONDBLCLK:
print "You double-clicked me - goodbye"
win32gui.DestroyWindow(self.hwnd)
elif lparam==win32con.WM_RBUTTONUP:
print "You right clicked me."
menu = win32gui.CreatePopupMenu()
win32gui.AppendMenu( menu, win32con.MF_STRING, 1023, "Restore Spark")
win32gui.AppendMenu( menu, win32con.MF_STRING, 1024, "Exit Spark")
win32gui.AppendMenu( menu, win32con.MF_STRING, 1025, "Remove Spark" )
pos = win32gui.GetCursorPos()
win32gui.SetForegroundWindow(self.hwnd)
win32gui.TrackPopupMenu(menu, win32con.TPM_LEFTALIGN, pos[0], pos[1], 0, self.hwnd, None)
win32gui.PostMessage(self.hwnd, win32con.WM_NULL, 0, 0)
return 1
def OnDestroy(self, hwnd, msg, wparam, lparam):
nid = (self.hwnd, 0)
win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)
win32gui.PostQuitMessage(0) # Terminate the app.
def showMsg(self, title, msg):
# 原作者使用Shell_NotifyIconA方法代替包装后的Shell_NotifyIcon方法
# 据称是不能win32gui structure, 我稀里糊涂搞出来了.
# 具体对比原代码.
nid = (self.hwnd, # 句柄
0, # 托盘图标ID
win32gui.NIF_INFO, # 标识
0, # 回调消息ID
0, # 托盘图标句柄
"Spark Message", # 图标字符串
msg, # 气球提示字符串
5, # 提示的显示时间
title, # 提示标题
win32gui.NIIF_INFO # 提示用到的图标
)
win32gui.Shell_NotifyIcon(win32gui.NIM_MODIFY, nid)
#win32gui.DestroyWindow(self.hwnd)
#win32gui.PumpMessages()
def CreatePopupMenu(self):
"""
This method is called by the base class when it needs to popup
the menu for the default EVT_RIGHT_DOWN event. Just create
the menu how you want it and return it from this function,
the base class takes care of the rest.
"""
menu = wx.Menu()
menu.Append(self.TBMENU_RESTORE, "Restore spark")
menu.Append(self.TBMENU_CLOSE, "Close spark")
menu.AppendSeparator()
#menu.Append(self.TBMENU_CHANGE, "Change the TB Icon")
menu.Append(self.TBMENU_REMOVE, "Remove Spark")
return menu
#def MakeIcon(self, img):
#"""
#The various platforms have different requirements for the
#icon size...
#"""
#if "wxMSW" in wx.PlatformInfo:
#img = img.Scale(16, 16)
#elif "wxGTK" in wx.PlatformInfo:
#img = img.Scale(22, 22)
## wxMac can be any size upto 128x128, so leave the source img alone....
#icon = wx.IconFromBitmap(img.ConvertToBitmap() )
#return icon
def OnTaskBarActivate(self, evt):
if self.frame.IsIconized():
self.frame.Iconize(False)
if not self.frame.IsShown():
self.frame.Show(True)
self.frame.Raise()
def OnTaskBarClose(self, evt):
wx.CallAfter(self.frame.OnClose)
#def OnTaskBarChange(self, evt):
#names = [ "WXPdemo", "Mondrian", "Pencil", "Carrot" ]
#name = names[self.imgidx]
#eImg = getattr(images, name)
#self.imgidx += 1
#if self.imgidx >= len(names):
#self.imgidx = 0
#icon = self.MakeIcon(eImg.Image)
#self.SetIcon(icon, "This is a new icon: " + name)
def OnTaskBarRemove(self, evt):
self.RemoveIcon()
def OnWinCommand(self, hwnd, msg, wparam, lparam):
print 'OnWinCommand'
id = win32api.LOWORD(wparam)
if id == 1023:
if self.frame.IsIconized():
self.frame.Iconize(False)
if not self.frame.IsShown():
self.frame.Show(True)
self.frame.Raise()
elif id == 1024:
nid = (self.hwnd, 0)
win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)
wx.CallAfter(self.frame.OnClose)
win32gui.PostQuitMessage(0)
#self.OnWinDestory()
elif id == 1025:
self.RemoveIcon()
else:
print "Unknown command -", id