def _OnActivate(self, activate_state): if self.activate_state == activate_state: return self._OnDeactivate() # restore menu's first, if necessary. if activate_state != shellcon.SVUIA_DEACTIVATE: assert self.hmenu is None, "Should have destroyed it!" self.hmenu = win32gui.CreateMenu() widths = 0, 0, 0, 0, 0, 0 # Ask explorer to add its standard items. self.browser.InsertMenusSB(self.hmenu, widths) # Merge with these standard items self._MergeMenus(activate_state) self.browser.SetMenuSB(self.hmenu, 0, self.hwnd) self.activate_state = activate_state
def InitMenu(hwnd): try: #初始化菜单 f = open(GetParentPath("\\menu\\menus_map.json"), "r") s = f.read() j = json.loads(s) if (getAppCfg("is_show_menu") == "0"): return global menuData menuData = j["menus"] menus = win32gui.CreateMenu() for d in menuData: #print d["id"] #print d["title"] win32gui.AppendMenu(menus, win32con.MF_STRING | win32con.MF_ENABLED, int(d["id"]), d["title"]) win32gui.SetMenu(hwnd, menus) except: win32gui.MessageBox(None, u"初始化菜单失败", u"错误", 0)
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)