def OnDrawItem(self, hwnd, msg, wparam, lparam): fmt = "5i2P4iP" data = struct.unpack( fmt, win32gui.PyGetString(lparam, struct.calcsize(fmt))) ctlType, ctlID, itemID, itemAction, itemState, hwndItem, \ hDC, left, top, right, bot, itemData = data rect = left, top, right, bot hicon, text = self.menu_item_map[itemData] if text is None: # This means the menu-item had HBMMENU_CALLBACK - so all we # draw is the icon. rect is the entire area we should use. win32gui.DrawIconEx(hDC, left, top, hicon, right - left, bot - top, 0, 0, win32con.DI_NORMAL) else: # If the user has selected the item, use the selected # text and background colors to display the item. selected = itemState & win32con.ODS_SELECTED if selected: crText = win32gui.SetTextColor( hDC, win32gui.GetSysColor(win32con.COLOR_HIGHLIGHTTEXT)) crBkgnd = win32gui.SetBkColor( hDC, win32gui.GetSysColor(win32con.COLOR_HIGHLIGHT)) each_pad = self.icon_x_pad // 2 x_icon = left + each_pad x_text = x_icon + self.menu_icon_width + each_pad # Draw text first, specifying a complete rect to fill - this sets # up the background (but overwrites anything else already there!) # Select the font, draw it, and restore the previous font. hfontOld = win32gui.SelectObject(hDC, self.font_menu) win32gui.ExtTextOut(hDC, x_text, top + 2, win32con.ETO_OPAQUE, rect, text) win32gui.SelectObject(hDC, hfontOld) # Icon image next. Icons are transparent - no need to handle # selection specially. win32gui.DrawIconEx(hDC, x_icon, top + 2, hicon, self.menu_icon_width, self.menu_icon_height, 0, 0, win32con.DI_NORMAL) # Return the text and background colors to their # normal state (not selected). if selected: win32gui.SetTextColor(hDC, crText) win32gui.SetBkColor(hDC, crBkgnd)
def prep_menu_icon(self, icon): # First load the 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) # Fill the background. brush = win32gui.GetSysColorBrush(win32con.COLOR_MENU) win32gui.FillRect(hdcBitmap, (0, 0, 16, 16), brush) # unclear if brush needs to be feed. Best clue I can find is: # "GetSysColorBrush returns a cached brush instead of allocating a new # one." - implies no DeleteObject # draw the icon win32gui.DrawIconEx( hdcBitmap, 0, 0, hicon, ico_x, ico_y, 0, 0, win32con.DI_NORMAL ) win32gui.SelectObject(hdcBitmap, hbmOld) win32gui.DeleteDC(hdcBitmap) return hbm
def prep_menu_icon(self, icon): # Version of prep_menu_icon using win32ui package # Source: https://stackoverflow.com/questions/45716730/add-image-in-window-tray-menu/45890829 # First load the 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) hwndDC = win32gui.GetWindowDC(self.hwnd) dc = win32ui.CreateDCFromHandle(hwndDC) memDC = dc.CreateCompatibleDC() iconBitmap = win32ui.CreateBitmap() iconBitmap.CreateCompatibleBitmap(dc, ico_x, ico_y) oldBmp = memDC.SelectObject(iconBitmap) brush = win32gui.GetSysColorBrush(win32con.COLOR_MENU) win32gui.FillRect(memDC.GetSafeHdc(), (0, 0, ico_x, ico_y), brush) win32gui.DrawIconEx(memDC.GetSafeHdc(), 0, 0, hicon, ico_x, ico_y, 0, 0, win32con.DI_NORMAL) memDC.SelectObject(oldBmp) memDC.DeleteDC() win32gui.ReleaseDC(self.hwnd, hwndDC) return iconBitmap.GetHandle()
def prep_menu_icon(self, icon): """ Ref: https://stackoverflow.com/a/45890829/973425 :param icon: :return: """ # First load the 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) hwndDC = win32gui.GetWindowDC(self.hwnd) dc = win32ui.CreateDCFromHandle(hwndDC) memDC = dc.CreateCompatibleDC() iconBitmap = win32ui.CreateBitmap() iconBitmap.CreateCompatibleBitmap(dc, ico_x, ico_y) oldBmp = memDC.SelectObject(iconBitmap) brush = win32gui.GetSysColorBrush(win32con.COLOR_MENU) win32gui.FillRect(memDC.GetSafeHdc(), (0, 0, ico_x, ico_y), brush) win32gui.DrawIconEx(memDC.GetSafeHdc(), 0, 0, hIcon, ico_x, ico_y, 0, 0, win32con.DI_NORMAL) memDC.SelectObject(oldBmp) memDC.DeleteDC() win32gui.ReleaseDC(self.hwnd, hwndDC) return iconBitmap.GetHandle()
def prep_menu_icon(self, 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 hbm