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
python类CreateCompatibleDC()的实例源码
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 OnPaint(self, hwnd, msg, wp, lp):
dc, ps=win32gui.BeginPaint(hwnd)
wndrect = win32gui.GetClientRect(hwnd)
wndwidth = wndrect[2]-wndrect[0]
wndheight = wndrect[3]-wndrect[1]
win32clipboard.OpenClipboard()
try:
try:
hbitmap = win32clipboard.GetClipboardData(win32clipboard.CF_BITMAP)
except TypeError:
font=win32gui.LOGFONT()
font.lfHeight=15 #int(wndheight/20)
font.lfWidth=15 #font.lfHeight
# font.lfWeight=150
hf=win32gui.CreateFontIndirect(font)
win32gui.SelectObject(dc,hf)
win32gui.SetBkMode(dc, win32con.TRANSPARENT)
win32gui.SetTextColor(dc,win32api.RGB(0,0,0))
win32gui.DrawText(dc,'No bitmaps are in the clipboard\n(try pressing the PrtScn button)', -1,
(0,0, wndwidth, wndheight),
win32con.DT_CENTER)
else:
bminfo = win32gui.GetObject(hbitmap)
dcDC = win32gui.CreateCompatibleDC(None)
win32gui.SelectObject(dcDC, hbitmap)
win32gui.StretchBlt(dc, 0, 0, wndwidth, wndheight, dcDC, 0, 0, bminfo.bmWidth, bminfo.bmHeight, win32con.SRCCOPY)
win32gui.DeleteDC(dcDC)
win32gui.EndPaint(hwnd, ps)
finally:
win32clipboard.CloseClipboard()
return 0
def __init_screen_handles(self):
# opengl windows cannot get from it's hwnd, so we use the screen
hwnd = win32gui.GetDesktopWindow()
# get screen size and offset
left, top, right, bottom = self.rect
width, height = right-left, bottom-top
# the device context of the window
hdcwin = win32gui.GetWindowDC(hwnd)
# make a temporary dc
hdcmem = win32gui.CreateCompatibleDC(hdcwin)
# make a temporary bitmap in memory, this is a PyHANDLE object
hbmp = win32gui.CreateCompatibleBitmap(hdcwin, width, height)
# select bitmap for temporary dc
win32gui.SelectObject(hdcmem, hbmp)
# check the bitmap object infomation
bmp = win32gui.GetObject(hbmp)
bi = BITMAPINFOHEADER()
bi.biSize = ctypes.sizeof(BITMAPINFOHEADER)
bi.biWidth = bmp.bmWidth
bi.biHeight = bmp.bmHeight
bi.biPlanes = bmp.bmPlanes
bi.biBitCount = bmp.bmBitsPixel
bi.biCompression = 0 # BI_RGB
bi.biSizeImage = 0
bi.biXPelsPerMeter = 0
bi.biYPelsPerMeter = 0
bi.biClrUsed = 0
bi.biClrImportant = 0
# calculate total size for bits
pixel = bmp.bmBitsPixel
size = ((bmp.bmWidth * pixel + pixel - 1)/pixel) * 4 * bmp.bmHeight
buf = (ctypes.c_char * size)()
self._hdcwin = hdcwin
self._hdcmem = hdcmem
self._bi = bi
self._hbmp = hbmp
self._buf = buf
def __init_screen_handles(self):
# opengl windows cannot get from it's hwnd, so we use the screen
hwnd = win32gui.GetDesktopWindow()
# get screen size and offset
left, top, right, bottom = self.rect
width, height = right-left, bottom-top
# the device context of the window
hdcwin = win32gui.GetWindowDC(hwnd)
# make a temporary dc
hdcmem = win32gui.CreateCompatibleDC(hdcwin)
# make a temporary bitmap in memory, this is a PyHANDLE object
hbmp = win32gui.CreateCompatibleBitmap(hdcwin, width, height)
# select bitmap for temporary dc
win32gui.SelectObject(hdcmem, hbmp)
# check the bitmap object infomation
bmp = win32gui.GetObject(hbmp)
bi = BITMAPINFOHEADER()
bi.biSize = ctypes.sizeof(BITMAPINFOHEADER)
bi.biWidth = bmp.bmWidth
bi.biHeight = bmp.bmHeight
bi.biPlanes = bmp.bmPlanes
bi.biBitCount = bmp.bmBitsPixel
bi.biCompression = 0 # BI_RGB
bi.biSizeImage = 0
bi.biXPelsPerMeter = 0
bi.biYPelsPerMeter = 0
bi.biClrUsed = 0
bi.biClrImportant = 0
# calculate total size for bits
pixel = bmp.bmBitsPixel
size = ((bmp.bmWidth * pixel + pixel - 1)/pixel) * 4 * bmp.bmHeight
buf = (ctypes.c_char * size)()
self._hdcwin = hdcwin
self._hdcmem = hdcmem
self._bi = bi
self._hbmp = hbmp
self._buf = buf
def OnPaint(self, hwnd, msg, wp, lp):
dc, ps=win32gui.BeginPaint(hwnd)
wndrect = win32gui.GetClientRect(hwnd)
wndwidth = wndrect[2]-wndrect[0]
wndheight = wndrect[3]-wndrect[1]
win32clipboard.OpenClipboard()
try:
try:
hbitmap = win32clipboard.GetClipboardData(win32clipboard.CF_BITMAP)
except TypeError:
font=win32gui.LOGFONT()
font.lfHeight=15 #int(wndheight/20)
font.lfWidth=15 #font.lfHeight
# font.lfWeight=150
hf=win32gui.CreateFontIndirect(font)
win32gui.SelectObject(dc,hf)
win32gui.SetBkMode(dc, win32con.TRANSPARENT)
win32gui.SetTextColor(dc,win32api.RGB(0,0,0))
win32gui.DrawText(dc,'No bitmaps are in the clipboard\n(try pressing the PrtScn button)', -1,
(0,0, wndwidth, wndheight),
win32con.DT_CENTER)
else:
bminfo = win32gui.GetObject(hbitmap)
dcDC = win32gui.CreateCompatibleDC(None)
win32gui.SelectObject(dcDC, hbitmap)
win32gui.StretchBlt(dc, 0, 0, wndwidth, wndheight, dcDC, 0, 0, bminfo.bmWidth, bminfo.bmHeight, win32con.SRCCOPY)
win32gui.DeleteDC(dcDC)
win32gui.EndPaint(hwnd, ps)
finally:
win32clipboard.CloseClipboard()
return 0
def screen(self):
"""PIL Image of current window screen. (the window must be on the top)
reference: https://msdn.microsoft.com/en-us/library/dd183402(v=vs.85).aspx"""
# opengl windows cannot get from it's hwnd, so we use the screen
hwnd = win32gui.GetDesktopWindow()
# get window size and offset
left, top, right, bottom = self.rect
width, height = right-left, bottom-top
# the device context of the window
hdcwin = win32gui.GetWindowDC(hwnd)
# make a temporary dc
hdcmem = win32gui.CreateCompatibleDC(hdcwin)
# make a temporary bitmap in memory, this is a PyHANDLE object
hbmp = win32gui.CreateCompatibleBitmap(hdcwin, width, height)
# select bitmap for temporary dc
win32gui.SelectObject(hdcmem, hbmp)
# copy bits to temporary dc
win32gui.BitBlt(hdcmem, 0, 0, width, height,
hdcwin, left, top, win32con.SRCCOPY)
# check the bitmap object infomation
bmp = win32gui.GetObject(hbmp)
bi = BITMAPINFOHEADER()
bi.biSize = ctypes.sizeof(BITMAPINFOHEADER)
bi.biWidth = bmp.bmWidth
bi.biHeight = bmp.bmHeight
bi.biPlanes = bmp.bmPlanes
bi.biBitCount = bmp.bmBitsPixel
bi.biCompression = 0 # BI_RGB
bi.biSizeImage = 0
bi.biXPelsPerMeter = 0
bi.biYPelsPerMeter = 0
bi.biClrUsed = 0
bi.biClrImportant = 0
# calculate total size for bits
pixel = bmp.bmBitsPixel
size = ((bmp.bmWidth * pixel + pixel - 1)/pixel) * 4 * bmp.bmHeight
buf = (ctypes.c_char * size)()
# read bits into buffer
windll.gdi32.GetDIBits(hdcmem, hbmp.handle, 0, bmp.bmHeight, buf, ctypes.byref(bi), win32con.DIB_RGB_COLORS)
# make a PIL Image
img = Image.frombuffer('RGB', (bmp.bmWidth, bmp.bmHeight), buf, 'raw', 'BGRX', 0, 1)
img = img.transpose(Image.FLIP_TOP_BOTTOM)
# cleanup
win32gui.DeleteObject(hbmp)
win32gui.DeleteObject(hdcmem)
win32gui.ReleaseDC(hwnd, hdcwin)
return img
def screen(self):
"""PIL Image of current window screen. (the window must be on the top)
reference: https://msdn.microsoft.com/en-us/library/dd183402(v=vs.85).aspx"""
# opengl windows cannot get from it's hwnd, so we use the screen
hwnd = win32gui.GetDesktopWindow()
# get window size and offset
left, top, right, bottom = self.rect
width, height = right-left, bottom-top
# the device context of the window
hdcwin = win32gui.GetWindowDC(hwnd)
# make a temporary dc
hdcmem = win32gui.CreateCompatibleDC(hdcwin)
# make a temporary bitmap in memory, this is a PyHANDLE object
hbmp = win32gui.CreateCompatibleBitmap(hdcwin, width, height)
# select bitmap for temporary dc
win32gui.SelectObject(hdcmem, hbmp)
# copy bits to temporary dc
win32gui.BitBlt(hdcmem, 0, 0, width, height,
hdcwin, left, top, win32con.SRCCOPY)
# check the bitmap object infomation
bmp = win32gui.GetObject(hbmp)
bi = BITMAPINFOHEADER()
bi.biSize = ctypes.sizeof(BITMAPINFOHEADER)
bi.biWidth = bmp.bmWidth
bi.biHeight = bmp.bmHeight
bi.biPlanes = bmp.bmPlanes
bi.biBitCount = bmp.bmBitsPixel
bi.biCompression = 0 # BI_RGB
bi.biSizeImage = 0
bi.biXPelsPerMeter = 0
bi.biYPelsPerMeter = 0
bi.biClrUsed = 0
bi.biClrImportant = 0
# calculate total size for bits
pixel = bmp.bmBitsPixel
size = ((bmp.bmWidth * pixel + pixel - 1)/pixel) * 4 * bmp.bmHeight
buf = (ctypes.c_char * size)()
# read bits into buffer
windll.gdi32.GetDIBits(hdcmem, hbmp.handle, 0, bmp.bmHeight, buf, ctypes.byref(bi), win32con.DIB_RGB_COLORS)
# make a PIL Image
img = Image.frombuffer('RGB', (bmp.bmWidth, bmp.bmHeight), buf, 'raw', 'BGRX', 0, 1)
img = img.transpose(Image.FLIP_TOP_BOTTOM)
# cleanup
win32gui.DeleteObject(hbmp)
win32gui.DeleteObject(hdcmem)
win32gui.ReleaseDC(hwnd, hdcwin)
return img