From: Mark H. <mha...@us...> - 2008-05-04 10:45:50
|
Update of /cvsroot/pywin32/pywin32/win32/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28146/win32/Lib Modified Files: win32gui_struct.py Log Message: Support for RegisterDeviceNotification and related structures, including a new demo and updates to serviceEvents demo. Index: win32gui_struct.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/Lib/win32gui_struct.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** win32gui_struct.py 6 Sep 2007 06:44:05 -0000 1.10 --- win32gui_struct.py 4 May 2008 10:45:54 -0000 1.11 *************** *** 24,27 **** --- 24,30 ---- # mechanism - I think it makes more sense to support ctype structures # at the win32gui level, then there will be no need for this module at all. + # XXX - the above makes sense in terms of what is built and passed to + # win32gui (ie, the Pack* functions) - but doesn't make as much sense for + # the Unpack* functions, where the aim is user convenience. import win32gui *************** *** 30,33 **** --- 33,37 ---- import array import commctrl + import pywintypes # Generic WM_NOTIFY unpacking *************** *** 556,557 **** --- 560,625 ---- fmt, param, image, order, 0, 0) return array.array("c", buf), extra + + # Device notification stuff + + # Generic function for packing a DEV_BROADCAST_* structure - generally used + # by the other PackDEV_BROADCAST_* functions in this module. + def PackDEV_BROADCAST(devicetype, rest_fmt, rest_data, extra_data=''): + # It seems a requirement is 4 byte alignment, even for the 'BYTE data[1]' + # field (eg, that would make DEV_BROADCAST_HANDLE 41 bytes, but we must + # be 44. + extra_data += '\0' * (4-len(extra_data)%4) + format = "iii" + rest_fmt + full_size = struct.calcsize(format) + len(extra_data) + data = (full_size, devicetype, 0) + rest_data + return struct.pack(format, *data) + extra_data + + def PackDEV_BROADCAST_HANDLE(handle, hdevnotify=0, guid="\0"*16, name_offset=0, data="\0"): + return PackDEV_BROADCAST(win32con.DBT_DEVTYP_HANDLE, "PP16sl", + (long(handle), long(hdevnotify), str(buffer(guid)), name_offset), + data) + + def PackDEV_BROADCAST_DEVICEINTERFACE(classguid, name=""): + rest_fmt = "16s%ds" % len(name) + # str(buffer(iid)) hoops necessary to get the raw IID bytes. + rest_data = (str(buffer(pywintypes.IID(classguid))), name) + return PackDEV_BROADCAST(win32con.DBT_DEVTYP_DEVICEINTERFACE, rest_fmt, rest_data) + + # An object returned by UnpackDEV_BROADCAST. + class DEV_BROADCAST_INFO: + def __init__(self, devicetype, **kw): + self.devicetype = devicetype + self.__dict__.update(kw) + def __str__(self): + return "DEV_BROADCAST_INFO:" + str(self.__dict__) + + # Support for unpacking the 'lparam' + def UnpackDEV_BROADCAST(lparam): + # guard for 0 here, otherwise PyMakeBuffer will create a new buffer. + if lparam == 0: + return None + hdr_size = struct.calcsize("iii") + hdr_buf = win32gui.PyMakeBuffer(hdr_size, lparam) + size, devtype, reserved = struct.unpack("iii", hdr_buf) + rest = win32gui.PyMakeBuffer(size-hdr_size, lparam+hdr_size) + + extra = x = {} + if devtype == win32con.DBT_DEVTYP_HANDLE: + # 2 handles, a GUID, a LONG and possibly an array following... + fmt = "PP16sl" + x['handle'], x['hdevnotify'], guid_bytes, x['nameoffset'] = \ + struct.unpack(fmt, rest[:struct.calcsize(fmt)]) + x['eventguid'] = pywintypes.IID(guid_bytes, True) + elif devtype == win32con.DBT_DEVTYP_DEVICEINTERFACE: + # guid, null-terminated name + x['classguid'] = pywintypes.IID(rest[:16], 1) + name = rest[16:] + if '\0' in name: + name = name.split('\0', 1)[0] + x['name'] = name + elif devtype == win32con.DBT_DEVTYP_VOLUME: + # int mask and flags + x['unitmask'], x['flags'] = struct.unpack("II", rest[:struct.calcsize("II")]) + else: + raise NotImplementedError("unknown device type %d" % (devtype,)) + return DEV_BROADCAST_INFO(devtype, **extra) |