SourceForge: pywin32/pywin32: changeset 4262:acf52e97b876
Don't leave an exception hanging if EnumWindows callback fails
authorrupole@users.sourceforge.net
Wed Aug 22 07:35:18 2012 -0400 (2012-08-22)
changeset 4262acf52e97b876
parent 4261 cb8d7cb7982e
child 4263 4f51918ce379
Don't leave an exception hanging if EnumWindows callback fails
win32/src/win32gui.i
     1.1 --- a/win32/src/win32gui.i	Tue Aug 21 21:32:33 2012 -0400
     1.2 +++ b/win32/src/win32gui.i	Wed Aug 22 07:35:18 2012 -0400
     1.3 @@ -2066,20 +2066,27 @@
     1.4  	PyEnumWindowsCallback *cb = (PyEnumWindowsCallback *)lParam;
     1.5  	CEnterLeavePython _celp;
     1.6  	PyObject *args = Py_BuildValue("(NO)", PyWinLong_FromHANDLE(hwnd), cb->extra);
     1.7 +	if (args == NULL)
     1.8 +		return FALSE;
     1.9  	PyObject *ret = PyEval_CallObject(cb->func, args);
    1.10 -	Py_XDECREF(args);
    1.11 -	if (ret && PyInt_Check(ret))
    1.12 +	Py_DECREF(args);
    1.13 +	if (ret == NULL)		
    1.14 +		return FALSE;
    1.15 +	if (ret != Py_None){
    1.16  		result = PyInt_AsLong(ret);
    1.17 -	Py_XDECREF(ret);
    1.18 +		if (result == -1 && PyErr_Occurred())
    1.19 +			result = FALSE;
    1.20 +		}
    1.21 +	Py_DECREF(ret);
    1.22  	return result;
    1.23  }
    1.24  
    1.25 -// @pyswig |EnumWindows|Enumerates all top-level windows on the screen by passing the handle to each window, in turn, to an application-defined callback function. EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE
    1.26 +// @pyswig |EnumWindows|Enumerates all top-level windows on the screen by passing the handle to each window, in turn, to an application-defined callback function.
    1.27  static PyObject *PyEnumWindows(PyObject *self, PyObject *args)
    1.28  {
    1.29  	BOOL rc;
    1.30  	PyObject *obFunc, *obOther;
    1.31 -	// @pyparm object|callback||A Python function to be used as the callback.
    1.32 +	// @pyparm function|callback||A Python function to be used as the callback.  Function can return False to stop enumeration, or raise an exception.
    1.33  	// @pyparm object|extra||Any python object - this is passed to the callback function as the second param (first is the hwnd).
    1.34  	if (!PyArg_ParseTuple(args, "OO", &obFunc, &obOther))
    1.35  		return NULL;
    1.36 @@ -2093,8 +2100,12 @@
    1.37      Py_BEGIN_ALLOW_THREADS
    1.38  	rc = EnumWindows(PyEnumWindowsProc, (LPARAM)&cb);
    1.39      Py_END_ALLOW_THREADS
    1.40 -	if (!rc)
    1.41 +	if (!rc){
    1.42 +		// Callback may have raised an exception already
    1.43 +		if (PyErr_Occurred())
    1.44 +			return NULL;
    1.45  		return PyWin_SetAPIError("EnumWindows");
    1.46 +		}
    1.47  	Py_INCREF(Py_None);
    1.48  	return Py_None;
    1.49  }