gil*_*red 6 python windows winapi ctypes
使用下面的代码,在请求其成员获取图标后,我得到一个指向SysListView32桌面的指针:
import ctypes
def GetDesktopListViewHandle():
import ctypes
FindWindow = ctypes.windll.user32.FindWindowW
GetWindow = ctypes.windll.user32.GetWindow
def GetClassName(hwnd):
buff = ctypes.create_unicode_buffer(100)
ctypes.windll.user32.GetClassNameW(hwnd, buff, 99)
return buff.value
from win32con import GW_CHILD
hwnd = FindWindow('Progman', None)
hwnd = GetWindow(hwnd, GW_CHILD) # SHELLDLL_DefView
hwnd = GetWindow(hwnd, GW_CHILD) # SysListView32
if GetClassName(hwnd) != 'SysListView32':
return 0
return hwnd
def ListView_GetItemCount(hwnd):
import commctrl
import ctypes
SendMessage = ctypes.windll.user32.SendMessageW
return SendMessage(hwnd, commctrl.LVM_GETITEMCOUNT, 0, 0)
class LVITEMW(ctypes.Structure):
_fields_ = [
('mask', ctypes.c_uint32),
('iItem', ctypes.c_int32),
('iSubItem', ctypes.c_int32),
('state', ctypes.c_uint32),
('stateMask', ctypes.c_uint32),
('pszText', ctypes.c_uint64),
('cchTextMax', ctypes.c_int32),
('iImage', ctypes.c_int32),
('lParam', ctypes.c_uint64), # On 32 bit should be c_long
('iIndent', ctypes.c_int32),
('iGroupId', ctypes.c_int32),
('cColumns', ctypes.c_uint32),
('puColumns', ctypes.c_uint64),
('piColFmt', ctypes.c_int64),
('iGroup', ctypes.c_int32),
]
def get_desktop_image_icon(index):
import struct
import ctypes
from commctrl import LVIF_IMAGE, LVM_GETITEMW
from win32con import PROCESS_ALL_ACCESS, MEM_RESERVE, MEM_COMMIT, PAGE_READWRITE, MEM_RELEASE
GetWindowThreadProcessId = ctypes.windll.user32.GetWindowThreadProcessId
SendMessage = ctypes.windll.user32.SendMessageW
OpenProcess = ctypes.windll.kernel32.OpenProcess
VirtualAllocEx = ctypes.windll.kernel32.VirtualAllocEx
WriteProcessMemory = ctypes.windll.kernel32.WriteProcessMemory
ReadProcessMemory = ctypes.windll.kernel32.ReadProcessMemory
VirtualFreeEx = ctypes.windll.kernel32.VirtualFreeEx
CloseHandle = ctypes.windll.kernel32.CloseHandle
MAX_LEN = 4096
try:
hwnd = GetDesktopListViewHandle()
pid = ctypes.create_string_buffer(4)
p_pid = ctypes.addressof(pid)
GetWindowThreadProcessId(hwnd, p_pid)
h_process = OpenProcess(PROCESS_ALL_ACCESS, False, struct.unpack("i", pid)[0])
copied = ctypes.create_string_buffer(4)
p_copied = ctypes.addressof(copied)
lvitem = LVITEMW()
lvitem.mask = ctypes.c_uint32(LVIF_IMAGE)
lvitem.iItem = ctypes.c_int32(index)
lvitem.iSubItem = ctypes.c_int32(0)
p_buffer_lvi = VirtualAllocEx(h_process, 0, MAX_LEN, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)
WriteProcessMemory(h_process, p_buffer_lvi, ctypes.addressof(lvitem), ctypes.sizeof(LVITEMW), p_copied)
SendMessage(hwnd, LVM_GETITEMW, 0, p_buffer_lvi)
ReadProcessMemory(h_process, p_buffer_lvi, ctypes.addressof(lvitem), ctypes.sizeof(LVITEMW), p_copied)
return lvitem.iImage
finally:
try:
VirtualFreeEx(h_process, p_buffer_lvi, 0, MEM_RELEASE)
except:
pass
try:
CloseHandle(h_process)
except:
pass
Run Code Online (Sandbox Code Playgroud)
当你运行代码时,进行一些操作,我不知道可以做什么:
print(get_desktop_image_icon(0)) # 11
print(get_desktop_image_icon(1)) # 12
print(get_desktop_image_icon(2)) # 13
Run Code Online (Sandbox Code Playgroud)
更新:
假设get_desktop_image_icon函数返回索引ImageList,我使用下面的代码来获取ImageList ListView桌面的句柄,并ImageList在索引中请求图标,但它们不会返回.提示,可能是什么问题以及如何解决?
print(get_desktop_image_icon(0)) # 11
print(get_desktop_image_icon(1)) # 12
print(get_desktop_image_icon(2)) # 13
hwnd = GetDesktopListViewHandle()
print(hwnd) # 65784
from commctrl import LVSIL_NORMAL, ILD_IMAGE
h_il = ListView_GetImageList(hwnd, LVSIL_NORMAL)
print(h_il) # 860139888
from win32gui import ImageList_GetIcon
print(ImageList_GetIcon(h_il, 0, ILD_IMAGE)) # 0
print(ImageList_GetIcon(h_il, 11, ILD_IMAGE)) # 0
# typedef struct _IMAGEINFO {
# HBITMAP hbmImage;
# HBITMAP hbmMask;
# int Unused1;
# int Unused2;
# RECT rcImage;
# } IMAGEINFO, *LPIMAGEINFO;
import ctypes.wintypes
class IMAGEINFO(ctypes.Structure):
_fields_ = [
('hbmImage', ctypes.wintypes.HBITMAP),
('hbmMask', ctypes.wintypes.HBITMAP),
('Unused1', ctypes.c_int),
('Unused2', ctypes.c_int),
('rcImage', ctypes.wintypes.RECT),
]
ImageList_GetImageInfo = ctypes.windll.comctl32.ImageList_GetImageInfo
# BOOL ImageList_GetImageInfo(
# HIMAGELIST himl,
# int i,
# IMAGEINFO *pImageInfo
# );
pImageInfo = IMAGEINFO()
print(ImageList_GetImageInfo(h_il, 0, ctypes.byref(pImageInfo))) # 0
print(ImageList_GetImageInfo(h_il, 11, ctypes.byref(pImageInfo))) # 0
Run Code Online (Sandbox Code Playgroud)
我怎样才能获得图标并保存它们?