sách gpt4 ai đã đi

windows - 如何使用 python 2.7 移动 Windows 桌面图标?

In lại 作者:可可西里 更新时间:2023-11-01 14:23:59 26 4
mua khóa gpt4 Nike

我正在尝试编写一个 python 例程来保存和恢复桌面图标位置。我在 Windows 7 x64 上使用 32 位 python 2.7。使用此处的信息(堆栈交换),我能够从 Windows 用于存储此信息的外部进程 ListView 中读取图标名称和位置,但是在使用 LVM_SETITEMPOSITION 设置新位置(或恢复位置)时我失败了。所有图标最终都位于桌面上的同一位置。 “自动排列”和“对齐网格”已关闭。相关代码在底部。警告:如果你运行这段代码,你所有的图标都会堆成一堆 :(

import ctypes

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),
]

class POINT(ctypes.Structure):
_fields_ = [('x', ctypes.c_int), ('y', ctypes.c_int)]

def icon_save_restore(savedicons=None, restore=False):
import struct, commctrl, win32gui, win32con, win32api
dthwnd = win32gui.FindWindow(None, 'Program Manager')
ukhwnd = win32gui.GetWindow(dthwnd, win32con.GW_CHILD)
slvhwnd = win32gui.GetWindow(ukhwnd, win32con.GW_CHILD)
pid = ctypes.create_string_buffer(4)
p_pid = ctypes.addressof(pid)
ctypes.windll.user32.GetWindowThreadProcessId(slvhwnd, p_pid)
hProcHnd = ctypes.windll.kernel32.OpenProcess(win32con.PROCESS_ALL_ACCESS, False, struct.unpack("i",pid)[0])
pBuffertxt = ctypes.windll.kernel32.VirtualAllocEx(hProcHnd, 0, 4096, win32con.MEM_RESERVE|win32con.MEM_COMMIT, win32con.PAGE_READWRITE)
copied = ctypes.create_string_buffer(4)
p_copied = ctypes.addressof(copied)
lvitem = LVITEMW()
lvitem.mask = ctypes.c_uint32(commctrl.LVIF_TEXT)
lvitem.pszText = ctypes.c_uint64(pBuffertxt)
lvitem.cchTextMax = ctypes.c_int32(4096)
lvitem.iSubItem = ctypes.c_int32(0)
pLVI = ctypes.windll.kernel32.VirtualAllocEx(hProcHnd, 0, 4096, win32con.MEM_RESERVE| win32con.MEM_COMMIT, win32con.PAGE_READWRITE)
win32api.SetLastError(0)
ctypes.windll.kernel32.WriteProcessMemory(hProcHnd, pLVI, ctypes.addressof(lvitem), ctypes.sizeof(lvitem), p_copied)
num_items = win32gui.SendMessage(slvhwnd, commctrl.LVM_GETITEMCOUNT)
if restore is False:
p = POINT()
pBufferpnt = ctypes.windll.kernel32.VirtualAllocEx(hProcHnd, 0, ctypes.sizeof(p), win32con.MEM_RESERVE|win32con.MEM_COMMIT, win32con.PAGE_READWRITE)
icons = {}
for i in xrange(num_items):
# Get icon text
win32gui.SendMessage(slvhwnd, commctrl.LVM_GETITEMTEXT, i, pLVI)
target_bufftxt = ctypes.create_string_buffer(4096)
ctypes.windll.kernel32.ReadProcessMemory(hProcHnd, pBuffertxt, ctypes.addressof(target_bufftxt), 4096, p_copied)
key = target_bufftxt.value
# Get icon position
win32api.SendMessage(slvhwnd, commctrl.LVM_GETITEMPOSITION, i, pBufferpnt)
p = POINT()
ctypes.windll.kernel32.ReadProcessMemory(hProcHnd, pBufferpnt, ctypes.addressof(p), ctypes.sizeof(p), p_copied)
icons[key] = (i,p)
ctypes.windll.kernel32.VirtualFreeEx(hProcHnd, pLVI, 0, win32con.MEM_RELEASE)
ctypes.windll.kernel32.VirtualFreeEx(hProcHnd, pBuffertxt, 0, win32con.MEM_RELEASE)
ctypes.windll.kernel32.VirtualFreeEx(hProcHnd, pBufferpnt, 0, win32con.MEM_RELEASE)
win32api.CloseHandle(hProcHnd)
return icons
else: # RESTORE ICON POSITIONS PROBLEM IS HERE SOMEWHERE!!!
win32gui.SendMessage(slvhwnd, win32con.WM_SETREDRAW, 0, 0)
for i in xrange(num_items):
# Get icon text
win32gui.SendMessage(slvhwnd, commctrl.LVM_GETITEMTEXT, i, pLVI)
target_bufftxt = ctypes.create_string_buffer(4096)
ctypes.windll.kernel32.ReadProcessMemory(hProcHnd, pBuffertxt, ctypes.addressof(target_bufftxt), 4096, p_copied)
key = target_bufftxt.value
if key in savedicons.keys():
# Set icon position
p = savedicons[key][1] # p is ctypes POINT
p_lng = point_to_long(p) # explicitly convert to HIWORD/LOWORD and c_long
# Reserve space for input variable in foreign process and get pointer to it the that memory space
pBufferpnt = ctypes.windll.kernel32.VirtualAllocEx(hProcHnd, 0, ctypes.sizeof(p_lng), win32con.MEM_RESERVE|win32con.MEM_COMMIT, win32con.PAGE_READWRITE)
# Write the desired coordinates in to the space just created
ret = ctypes.windll.kernel32.WriteProcessMemory(hProcHnd, pBufferpnt, ctypes.addressof(p_lng), ctypes.sizeof(p_lng), p_copied)
if ret == 0:
raise WindowsError
# Send the message to change the position for that item's index and the pointer to the new position
ret = win32gui.SendMessage(slvhwnd, commctrl.LVM_SETITEMPOSITION, i, pBufferpnt)
if ret == 0:
raise WindowsError
# Release the reserved memory for the variable (I recognize that I probably don't need to aLloc/free this within the loop)
ctypes.windll.kernel32.VirtualFreeEx(hProcHnd, pBufferpnt, 0, win32con.MEM_RELEASE)
win32gui.SendMessage(slvhwnd, win32con.WM_SETREDRAW, 1, 0)
ctypes.windll.kernel32.VirtualFreeEx(hProcHnd, pLVI, 0, win32con.MEM_RELEASE)
ctypes.windll.kernel32.VirtualFreeEx(hProcHnd, pBuffertxt, 0, win32con.MEM_RELEASE)
win32api.CloseHandle(hProcHnd)
return None


def point_to_long(p):
ret = (p.y * 0x10000) + (p.x & 0xFFFF)
return ctypes.c_long(ret)

nếu __name__ == '__main__':
mysavedicons = icon_save_restore(restore=False)
icon_save_restore(mysavedicons, restore=True)

我认为可能有问题 1) 与 32 位和 64 位内存地址空间有关,但我编写 LVITEM 结构或读取图标文本的其他组件工作正常或 2) 有一些我转换坐标信息或为 GETITEMPOSITION 调用 SendMessage 的方式存在问题。任何见解或帮助将不胜感激。

1 Câu trả lời

事实证明,有一个版本使用 32 位地址 (LVM_SETITEMPOSITION32),我希望 MSDN 在其文档中交叉引用:https://msdn.microsoft.com/en-us/library/windows/desktop/bb761194(v=vs.85).aspx

这直接接受 POINT 结构,因此无需尝试转换为 HIWORD/LOWORD。在发布之前,我确实尝试过使用 32 位移位和 longlong(long 的 64 位版本),但对 LVM_SETITEMPOSITION 都不起作用。无论如何,随着更改,一切都按预期进行。

关于windows - 如何使用 python 2.7 移动 Windows 桌面图标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28505766/

26 4 0
可可西里
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com