使用下面的代码,在请求其成员获取图标后,我得到一个指向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
当你运行代码时,要进行一些操作,我不知道可以做些什么:
print(get_desktop_image_icon(0)) # 11
print(get_desktop_image_icon(1)) # 12
print(get_desktop_image_icon(2)) # 13
更新
假设get_desktop_image_icon
函数返回ImageList
索引,我使用下面的代码来获取ImageList
ListView
桌面的句柄,{{1}请求索引中的图标,但它们不会回来。提示,可能是什么问题以及如何解决它?
ImageList
如何获取图标并保存?