def _OnDeactivate(self): if self.browser is not None and self.hmenu is not None: self.browser.SetMenuSB(0, 0, 0) self.browser.RemoveMenusSB(self.hmenu) win32gui.DestroyMenu(self.hmenu) self.hmenu = None self.hsubmenus = None self.activate_state = shellcon.SVUIA_DEACTIVATE
def Destroy(self): for menuitem in self.MenuItems: menuitem.Destroy() if not self.Parent: if debug or verbose > 1: safe_print('DestroyMenu HMENU', self.hmenu) win32gui.DestroyMenu(self.hmenu) if debug or verbose > 1: safe_print('Destroy', self.__class__.__name__, self) self._destroyed = True wx.EvtHandler.Destroy(self)
def destroy(self): for i in range(len(self._handlelist)): # DestroyMenu は親を渡せば再帰的に解放してくれるが, # 親子関係が構築されている保証はないので, # 念のため全部解放してまわる. # 既に解放されているとエラーになるため無視する. try: win32gui.DestroyMenu(self._handlelist[i]) except: pass self._handlelist = []
def icon_wndproc(hwnd, msg, wp, lp): """Window proc for the tray icons""" if lp == win32con.WM_LBUTTONDOWN: ## popup menu won't disappear if you don't do this win32gui.SetForegroundWindow(hwnd) curr_desktop = win32service.OpenInputDesktop(0, True, win32con.MAXIMUM_ALLOWED) curr_desktop_name = win32service.GetUserObjectInformation( curr_desktop, win32con.UOI_NAME ) winsta = win32service.GetProcessWindowStation() desktops = winsta.EnumDesktops() m = win32gui.CreatePopupMenu() desktop_cnt = len(desktops) ## *don't* create an item 0 for d in range(1, desktop_cnt + 1): mf_flags = win32con.MF_STRING ## if you switch to winlogon yourself, there's nothing there and you're stuck if desktops[d - 1].lower() in ("winlogon", "disconnect"): mf_flags = mf_flags | win32con.MF_GRAYED | win32con.MF_DISABLED if desktops[d - 1] == curr_desktop_name: mf_flags = mf_flags | win32con.MF_CHECKED win32gui.AppendMenu(m, mf_flags, d, desktops[d - 1]) win32gui.AppendMenu(m, win32con.MF_STRING, desktop_cnt + 1, "Create new ...") win32gui.AppendMenu(m, win32con.MF_STRING, desktop_cnt + 2, "Exit") x, y = win32gui.GetCursorPos() d = win32gui.TrackPopupMenu( m, win32con.TPM_LEFTBUTTON | win32con.TPM_RETURNCMD | win32con.TPM_NONOTIFY, x, y, 0, hwnd, None, ) win32gui.PumpWaitingMessages() win32gui.DestroyMenu(m) if d == desktop_cnt + 1: ## Create new get_new_desktop_name(hwnd) elif d == desktop_cnt + 2: ## Exit win32gui.PostQuitMessage(0) win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, window_info[hwnd]) del window_info[hwnd] origin_desktop.SwitchDesktop() elif d > 0: hdesk = win32service.OpenDesktop( desktops[d - 1], 0, 0, win32con.MAXIMUM_ALLOWED ) hdesk.SwitchDesktop() return 0 else: return win32gui.DefWindowProc(hwnd, msg, wp, lp)
def OnContextMenu(self, hwnd, msg, wparam, lparam): # Get the selected items. pidls = [] n = -1 while True: n = win32gui.SendMessage(self.hwnd_child, commctrl.LVM_GETNEXTITEM, n, commctrl.LVNI_SELECTED) if n == -1: break pidls.append(self.children[n][-1:]) spt = win32api.GetCursorPos() if not pidls: print("Ignoring background click") return # Get the IContextMenu for the items. inout, cm = self.folder.GetUIObjectOf( self.hwnd_parent, pidls, shell.IID_IContextMenu, 0) hmenu = win32gui.CreatePopupMenu() sel = None # As per 'Q179911', we need to determine if the default operation # should be 'open' or 'explore' try: flags = 0 try: self.browser.GetControlWindow(shellcon.FCW_TREE) flags |= shellcon.CMF_EXPLORE except pythoncom.com_error: pass id_cmd_first = 1 # TrackPopupMenu makes it hard to use 0 cm.QueryContextMenu(hmenu, 0, id_cmd_first, -1, flags) tpm_flags = win32con.TPM_LEFTALIGN | win32con.TPM_RETURNCMD | \ win32con.TPM_RIGHTBUTTON sel = win32gui.TrackPopupMenu(hmenu, tpm_flags, spt[0], spt[1], 0, self.hwnd, None) print("TrackPopupMenu returned", sel) finally: win32gui.DestroyMenu(hmenu) if sel: ci = 0, self.hwnd_parent, sel - id_cmd_first, None, None, 0, 0, 0 cm.InvokeCommand(ci)
def OnNotify(self, hwnd, msg, wparam, lparam): hwndFrom, idFrom, code = win32gui_struct.UnpackWMNOTIFY(lparam) # print "OnNotify code=0x%x (0x%x, 0x%x)" % (code, wparam, lparam) if code == commctrl.NM_SETFOCUS: # Control got focus - Explorer may not know - tell it if self.browser is not None: self.browser.OnViewWindowActive(None) # And do our menu thang self._OnActivate(shellcon.SVUIA_ACTIVATE_FOCUS) elif code == commctrl.NM_KILLFOCUS: self._OnDeactivate() elif code == commctrl.NM_DBLCLK: # This DblClick implementation leaves a little to be desired :) # It demonstrates some useful concepts, such as asking the # folder for its context-menu and invoking a command from it. # However, as our folder delegates IContextMenu to the shell # itself, the end result is that the folder is opened in # its "normal" place in Windows explorer rather than inside # our shell-extension. # Determine the selected items. sel = [] n = -1 while 1: n = win32gui.SendMessage(self.hwnd_child, commctrl.LVM_GETNEXTITEM, n, commctrl.LVNI_SELECTED) if n == -1: break sel.append(self.children[n][-1:]) print("Selection is", sel) hmenu = win32gui.CreateMenu() try: # Get the IContextMenu for the items. inout, cm = self.folder.GetUIObjectOf(self.hwnd_parent, sel, shell.IID_IContextMenu, 0) # As per 'Q179911', we need to determine if the default operation # should be 'open' or 'explore' flags = shellcon.CMF_DEFAULTONLY try: self.browser.GetControlWindow(shellcon.FCW_TREE) flags |= shellcon.CMF_EXPLORE except pythoncom.com_error: pass # *sob* - delegating to the shell does work - but lands us # in the original location. Q179911 also shows that # ShellExecuteEx should work - but I can't make it work as # described (XP: function call succeeds, but another thread # shows a dialog with text of E_INVALID_PARAM, and new # Explorer window opens with desktop view. Vista: function # call succeeds, but no window created at all. # On Vista, I'd love to get an IExplorerBrowser interface # from the shell, but a QI fails, and although the # IShellBrowser does appear to support IServiceProvider, I # still can't get it if 0: id_cmd_first = 1 # TrackPopupMenu makes it hard to use 0 cm.QueryContextMenu(hmenu, 0, id_cmd_first, -1, flags) # Find the default item in the returned menu. cmd = win32gui.GetMenuDefaultItem(hmenu, False, 0) if cmd == -1: print( "Oops: _doDefaultActionFor found no default menu") else: ci = 0, self.hwnd_parent, cmd - id_cmd_first, None, None, 0, 0, 0 cm.InvokeCommand(ci) else: rv = shell.ShellExecuteEx(hwnd=self.hwnd_parent, nShow=win32con.SW_NORMAL, lpClass="folder", lpVerb="explore", lpIDList=sel[0]) print("ShellExecuteEx returned", rv) finally: win32gui.DestroyMenu(hmenu)