Это толстый, толстый материал win32. Я начал писать это, используя pywin32, но переключился на ctypes, чтобы лучше разобраться со структурами. Обратите внимание, я написал это в 32 Win XP. Вы получите изменение TBBUTTON def для 64 бит. Я не уверен, что UAC сделает с этим (можете ли вы выделить память в другом процессе?).
import commctrl, win32con
from ctypes import *
# represent the TBBUTTON structure
# note this is 32 bit, 64 bit padds 4 more reserved bytes
class TBBUTTON(Structure):
_pack_ = 1
_fields_ = [
('iBitmap', c_int),
('idCommand', c_int),
('fsState', c_ubyte),
('fsStyle', c_ubyte),
('bReserved', c_ubyte * 2),
('dwData', c_ulong),
('iString', c_int),
]
# get the handle to the sytem tray
hWnd = windll.user32.FindWindowA("Shell_TrayWnd", None)
hWnd = windll.user32.FindWindowExA(hWnd, None, "TrayNotifyWnd", None)
hWnd = windll.user32.FindWindowExA(hWnd, None, "SysPager", None)
hWnd = windll.user32.FindWindowExA(hWnd, None, "ToolbarWindow32", None)
# get the count of icons in the tray
numIcons = windll.user32.SendMessageA(hWnd, commctrl.TB_BUTTONCOUNT, 0, 0)
# allocate memory within the system tray
pid = c_ulong();
windll.user32.GetWindowThreadProcessId(hWnd, byref(pid))
hProcess = windll.kernel32.OpenProcess(win32con.PROCESS_ALL_ACCESS, 0, pid)
lpPointer = windll.kernel32.VirtualAllocEx(hProcess, 0, sizeof(TBBUTTON), win32con.MEM_COMMIT, win32con.PAGE_READWRITE)
# init our tool bar button and a handle to it
tbButton = TBBUTTON()
butHandle = c_int()
for i in range(numIcons):
# query the button into the memory we allocated
windll.user32.SendMessageA(hWnd, commctrl.TB_GETBUTTON, i, lpPointer)
# read the memory into our button struct
windll.kernel32.ReadProcessMemory(hProcess, lpPointer, addressof(tbButton), 20, None)
# read the 1st 4 bytes from the dwData into the butHandle var
# these first 4 bytes contain the handle to the button
windll.kernel32.ReadProcessMemory(hProcess, tbButton.dwData, addressof(butHandle), 4, None)
# get the pid that created the button
butPid = c_ulong()
windll.user32.GetWindowThreadProcessId(butHandle, byref(butPid))
# i leave it to you to get the process from the pid
# that should be trivial...
print butPid