From: Mark H. <mha...@us...> - 2008-05-04 10:45:52
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28146/win32/src Modified Files: win32gui.i Log Message: Support for RegisterDeviceNotification and related structures, including a new demo and updates to serviceEvents demo. Index: win32gui.i =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/win32gui.i,v retrieving revision 1.116 retrieving revision 1.117 diff -C2 -d -r1.116 -r1.117 *** win32gui.i 12 Feb 2008 17:39:43 -0000 1.116 --- win32gui.i 4 May 2008 10:45:54 -0000 1.117 *************** *** 32,35 **** --- 32,36 ---- #include "commctrl.h" #include "windowsx.h" // For edit control hacks. + #include "Dbt.h" // device notification #include "malloc.h" *************** *** 173,178 **** { PyObject *ret=new PyGdiHANDLE(h); ! if (ret==NULL) ! PyErr_NoMemory(); return ret; } --- 174,181 ---- { PyObject *ret=new PyGdiHANDLE(h); ! if (ret==NULL) { ! DeleteObject(h); ! PyErr_NoMemory(); ! } return ret; } *************** *** 216,219 **** --- 219,255 ---- } + %{ + // @object PyHDEVNOTIFY|A handle returned by RegisterDeviceNotifications which + // automatically calls UnregisterDeviceNotification on destruction. + // Inherits the methods and properties of <o PyHANDLE>. + class PyHDEVNOTIFY: public PyHANDLE + { + public: + PyHDEVNOTIFY(HANDLE hInit) : PyHANDLE(hInit) {} + virtual BOOL Close(void){ + BOOL ret=UnregisterDeviceNotification(m_handle); + if (!ret) + PyWin_SetAPIError("UnregisterDeviceNotification"); + m_handle = 0; + return ret; + } + virtual const char *GetTypeName(){ + return "PyHDEVNOTIFY"; + } + }; + + PyObject *PyWinObject_FromHDEVNOTIFY(HGDIOBJ h) + { + PyObject *ret=new PyHDEVNOTIFY(h); + if (ret==NULL) { + UnregisterDeviceNotification(h); + PyErr_NoMemory(); + } + return ret; + } + %} + // TODO: SWIG support for PyHDEVNOTIFY - but SWIG currently doesn't use it. + + // Written to the module init function. %init %{ *************** *** 1447,1451 **** #endif // @pyparm int|len||length of the buffer object ! // @pyparm int|addr||Address of the memory to reference if (!PyArg_ParseTuple(args, input_fmt, &len,&addr)) return NULL; --- 1483,1491 ---- #endif // @pyparm int|len||length of the buffer object ! // @pyparm int|addr||Address of the memory to reference. If zero or not ! // specified, a new buffer object is created with the specified size. ! // @todo We should consider deprecating and dropping the behaviour when ! // the address is zero - it leads to unexpected bugs, as passing NULL ! // appears to return a reference to what was valid memory. if (!PyArg_ParseTuple(args, input_fmt, &len,&addr)) return NULL; *************** *** 1453,1458 **** if(NULL == addr) return PyBuffer_New(len); ! else return PyBuffer_FromMemory(addr, len); } %} --- 1493,1504 ---- if(NULL == addr) return PyBuffer_New(len); ! else { ! if (IsBadReadPtr(addr, len)) { ! PyErr_SetString(PyExc_ValueError, ! "The value is not a valid address for reading"); ! return NULL; ! } return PyBuffer_FromMemory(addr, len); + } } %} *************** *** 1477,1483 **** if (len==-1) ! len = _tcslen(addr); ! if (len == 0) return PyUnicodeObject_FromString(""); if (IsBadReadPtr(addr, len)) { PyErr_SetString(PyExc_ValueError, --- 1523,1529 ---- if (len==-1) ! len = strlen(addr); ! if (len == 0) return PyString_FromString(""); if (IsBadReadPtr(addr, len)) { PyErr_SetString(PyExc_ValueError, *************** *** 1485,1489 **** return NULL; } ! return PyWinObject_FromTCHAR(addr, len); } %} --- 1531,1535 ---- return NULL; } ! return PyString_FromStringAndSize(addr, len); } %} *************** *** 7332,7333 **** --- 7378,7418 ---- HWND GetConsoleWindow(); #endif + + %{ + // @pyswig <o PyHDEVNOTIFY>|RegisterDeviceNotification|Registers the device or type of device for which a window will receive notifications. + PyObject *PyRegisterDeviceNotification(PyObject *self, PyObject *args) + { + unsigned int flags; + PyObject *obh, *obFilter; + if (!PyArg_ParseTuple(args, "OOk:RegisterDeviceNotification", + &obh, // @pyparm <o PyHANDLE>|handle||The handle to a window or a service + &obFilter, // @pyparm buffer|filter||A buffer laid out like one of the DEV_BROADCAST_* structures, generally built by one of the win32gui_struct helpers. + &flags)) // @pyparm int|flags|| + return NULL; + HANDLE handle; + if (!PyWinObject_AsHANDLE(obh, &handle)) + return NULL; + const void *filter; + Py_ssize_t nbytes; + if (PyObject_AsReadBuffer(obFilter, &filter, &nbytes)==-1) + return NULL; + // basic sanity check. + Py_ssize_t struct_bytes = ((DEV_BROADCAST_HDR *)filter)->dbch_size; + if (nbytes != struct_bytes) + return PyErr_Format(PyExc_ValueError, + "buffer isn't a DEV_BROADCAST_* structure: " + "structure says it has %d bytes, but %d was provided", + (int)struct_bytes, (int)nbytes); + // @pyseeapi RegisterDeviceNotification + HDEVNOTIFY not = RegisterDeviceNotification(handle, (void *)filter, flags); + if (not == NULL) + return PyWin_SetAPIError("RegisterDeviceNotification"); + return PyWinObject_FromHDEVNOTIFY(not); + } + %} + %native(RegisterDeviceNotification) PyRegisterDeviceNotification; + + // @pyswig |UnregisterDeviceNotification|Unregisters a Device Notification handle. + // It is generally not necessary to call this function manually, but in some cases, + // handle values may be extracted via the struct module and need to be closed explicitly. + BOOLAPI UnregisterDeviceNotification(HANDLE); |