|
4 | 4 | importlogging
|
5 | 5 | importwin32ui
|
6 | 6 | importwin32con
|
| 7 | +importwin32api |
7 | 8 | importctypes
|
8 | 9 | importctypes.wintypes
|
9 | 10 | fromcore.utils.win32.app_uwpimportget_package
|
|
19 | 20 |
|
20 | 21 | TARGETSIZE_REGEX=re.compile(r'targetsize-([0-9]+)')
|
21 | 22 |
|
22 |
| -defget_window_icon(hwnd,smooth_level=0): |
23 |
| -"""Fetch the icon of the window at higher quality if possible.""" |
| 23 | +defget_window_icon(hwnd,smooth_level=0): |
| 24 | +"""Fetch the icon of the window.""" |
24 | 25 | try:
|
25 | 26 | hicon=win32gui.SendMessage(hwnd,win32con.WM_GETICON,win32con.ICON_BIG,0)
|
26 | 27 | ifhicon==0:
|
| 28 | +# If big icon is not available, try to get the small icon |
27 | 29 | hicon=win32gui.SendMessage(hwnd,win32con.WM_GETICON,win32con.ICON_SMALL,0)
|
28 | 30 | ifhicon==0:
|
| 31 | +# If both small and big icons are not available, get the class icon |
29 | 32 | ifhasattr(win32gui,'GetClassLongPtr'):
|
30 | 33 | hicon=win32gui.GetClassLongPtr(hwnd,win32con.GCLP_HICON)
|
31 | 34 | else:
|
32 | 35 | hicon=win32gui.GetClassLong(hwnd,win32con.GCL_HICON)
|
33 |
| -
|
| 36 | + |
34 | 37 | ifhicon:
|
35 |
| -desired_size=48# Most of UWPs also return 48x48 icons |
36 | 38 | hdc_handle=win32gui.GetDC(0)
|
37 | 39 | ifnothdc_handle:
|
38 | 40 | raiseException("Failed to get DC handle")
|
39 | 41 | try:
|
40 | 42 | hdc=win32ui.CreateDCFromHandle(hdc_handle)
|
41 | 43 | hbmp=win32ui.CreateBitmap()
|
42 |
| -hbmp.CreateCompatibleBitmap(hdc,desired_size,desired_size) |
| 44 | +system_icon_size=win32api.GetSystemMetrics(win32con.SM_CXICON) |
| 45 | +bitmap_size=int(system_icon_size) |
| 46 | +hbmp.CreateCompatibleBitmap(hdc,bitmap_size,bitmap_size) |
43 | 47 | memdc=hdc.CreateCompatibleDC()
|
44 |
| -memdc.SelectObject(hbmp) |
45 |
| - |
46 |
| -# Call DrawIconEx via ctypes |
47 |
| -DrawIconEx=ctypes.windll.user32.DrawIconEx |
48 |
| -DrawIconEx.argtypes= [ |
49 |
| -ctypes.wintypes.HDC,ctypes.c_int,ctypes.c_int, |
50 |
| -ctypes.wintypes.HICON,ctypes.c_int,ctypes.c_int, |
51 |
| -ctypes.c_uint,ctypes.wintypes.HBRUSH,ctypes.c_uint |
52 |
| - ] |
53 |
| -DI_NORMAL=0x0003 |
54 |
| -result=DrawIconEx(memdc.GetSafeHdc(),0,0,hicon, |
55 |
| -desired_size,desired_size,0,0,DI_NORMAL) |
56 |
| -ifresult==0: |
| 48 | +# Select the bitmap into the memory device context |
| 49 | +memdc.SelectObject(hbmp) |
| 50 | +try: |
| 51 | +memdc.DrawIcon((0,0),hicon) |
| 52 | +exceptException: |
57 | 53 | returnNone
|
58 |
| -
|
| 54 | + |
59 | 55 | bmpinfo=hbmp.GetInfo()
|
60 | 56 | bmpstr=hbmp.GetBitmapBits(True)
|
| 57 | + |
61 | 58 | raw_data=bytes(bmpstr)
|
62 | 59 | img=Image.frombuffer(
|
63 | 60 | 'RGBA',
|
64 | 61 | (bmpinfo['bmWidth'],bmpinfo['bmHeight']),
|
65 | 62 | raw_data,'raw','BGRA',0,1
|
66 | 63 | ).convert('RGBA')
|
| 64 | +#target_size = 48 # target size (48x48) wihout DPI, most of uwps are also 48x48 |
| 65 | +#img = img.resize((target_size, target_size), Image.LANCZOS) |
67 | 66 | ifsmooth_level==1:
|
68 | 67 | img=img.filter(ImageFilter.SMOOTH)
|
69 | 68 | elifsmooth_level==2:
|
70 | 69 | img=img.filter(ImageFilter.SMOOTH_MORE)
|
71 | 70 | returnimg
|
72 | 71 | finally:
|
| 72 | +# Cleaning up resources |
| 73 | +#logging.debug("Cleaning up") |
73 | 74 | try:
|
74 | 75 | win32gui.DestroyIcon(hicon)
|
75 |
| -exceptException: |
| 76 | +#logging.debug("Destroyed hicon") |
| 77 | +exceptExceptionase: |
| 78 | +#logging.debug(f"Error destroying hicon: {e}") |
76 | 79 | pass
|
77 | 80 | try:
|
78 | 81 | memdc.DeleteDC()
|
79 |
| -exceptException: |
| 82 | +#logging.debug("Deleted memory device context.") |
| 83 | +exceptExceptionase: |
| 84 | +#logging.debug(f"Error deleting memory device context: {e}") |
80 | 85 | pass
|
81 | 86 | try:
|
82 | 87 | hdc.DeleteDC()
|
83 |
| -exceptException: |
| 88 | +#logging.debug("Deleted device context.") |
| 89 | +exceptExceptionase: |
| 90 | +#logging.debug(f"Error deleting device context: {e}") |
84 | 91 | pass
|
85 | 92 | try:
|
86 | 93 | win32gui.DeleteObject(hbmp.GetHandle())
|
87 |
| -exceptException: |
| 94 | +#logging.debug("Deleted bitmap object.") |
| 95 | +exceptExceptionase: |
| 96 | +#logging.debug(f"Error deleting bitmap object: {e}") |
88 | 97 | pass
|
89 | 98 | try:
|
90 | 99 | win32gui.ReleaseDC(0,hdc_handle)
|
91 |
| -exceptException: |
| 100 | +#logging.debug("Released device context handle.") |
| 101 | +exceptExceptionase: |
| 102 | +#logging.debug(f"Error releasing device context handle: {e}") |
92 | 103 | pass
|
93 | 104 | else:
|
94 | 105 | try:
|
|