diff --git a/CHANGES.txt b/CHANGES.txt index de04e6eb6..0e11d0643 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -15,6 +15,7 @@ Coming in build 307, as yet unreleased -------------------------------------- ### pywin32 +* Add RealGetWindowClass (#2299, @CristiFati) * Make it compile on Python 3.13 (#2260, @clin1234) * Fixed accidentally trying to raise a `str` instead of an `Exception` in (#2270, @Avasam) * `Pythonwin/pywin/debugger/debugger.py` diff --git a/win32/src/win32gui.i b/win32/src/win32gui.i index c579241cd..518e84cf9 100644 --- a/win32/src/win32gui.i +++ b/win32/src/win32gui.i @@ -5998,26 +5998,49 @@ PyGetScrollInfo (PyObject *self, PyObject *args) %native (GetScrollInfo) PyGetScrollInfo; %{ +#define MAX_CHARS 0x100 + // @pyswig string|GetClassName|Retrieves the name of the class to which the specified window belongs. static PyObject * PyGetClassName(PyObject *self, PyObject *args) { - HWND hwnd; - PyObject *obhwnd; - TCHAR buf[256]; - // @pyparm |hwnd||The handle to the window - if (!PyArg_ParseTuple(args, "O:GetClassName", &obhwnd)) - return NULL; - if (!PyWinObject_AsHANDLE(obhwnd, (HANDLE *)&hwnd)) - return NULL; - // don't bother with lock - no callback possible. - int nchars = GetClassName(hwnd, buf, sizeof buf/sizeof buf[0]); - if (nchars==0) - return PyWin_SetAPIError("GetClassName"); - return PyWinObject_FromTCHAR(buf, nchars); + HWND hwnd; + PyObject *obhwnd; + TCHAR buf[MAX_CHARS]; + // @pyparm |hwnd||The handle to the window + if (!PyArg_ParseTuple(args, "O:GetClassName", &obhwnd)) + return NULL; + if (!PyWinObject_AsHANDLE(obhwnd, (HANDLE*)&hwnd)) + return NULL; + // don't bother with lock - no callback possible. + int nchars = GetClassName(hwnd, buf, MAX_CHARS); + if (nchars == 0) + return PyWin_SetAPIErrorOrReturnNone("GetClassName"); + return PyWinObject_FromTCHAR(buf, nchars); } + +// @pyswig string|RealGetWindowClass|Retrieves the name of the class to which the specified window belongs. +static PyObject * +PyRealGetWindowClass(PyObject *self, PyObject *args) +{ + HWND hwnd; + PyObject *obhwnd; + TCHAR buf[MAX_CHARS]; + // @pyparm |hwnd||The handle to the window + if (!PyArg_ParseTuple(args, "O:RealGetWindowClass", &obhwnd)) + return NULL; + if (!PyWinObject_AsHANDLE(obhwnd, (HANDLE*)&hwnd)) + return NULL; + // don't bother with lock - no callback possible. + UINT nchars = RealGetWindowClass(hwnd, buf, MAX_CHARS); + if (nchars == 0) + return PyWin_SetAPIErrorOrReturnNone("RealGetWindowClass"); + return PyWinObject_FromTCHAR(buf, nchars); +} + %} %native (GetClassName) PyGetClassName; +%native (RealGetWindowClass) PyRealGetWindowClass; // @pyswig int|WindowFromPoint|Retrieves a handle to the window that contains the specified point. // @pyparm (int, int)|point||The point. diff --git a/win32/test/test_win32gui.py b/win32/test/test_win32gui.py index c5754722c..e61bae1b8 100644 --- a/win32/test/test_win32gui.py +++ b/win32/test/test_win32gui.py @@ -209,5 +209,20 @@ def test_enumdesktopwindows(self): ) +class TestWindowProperties(unittest.TestCase): + def setUp(self): + self.class_functions = ( + win32gui.GetClassName, + win32gui.RealGetWindowClass, + ) + + def test_classname(self): + for func in self.class_functions: + self.assertRaises(pywintypes.error, func, 0) + wnd = win32gui.GetDesktopWindow() + for func in self.class_functions: + self.assertTrue(func(wnd)) + + if __name__ == "__main__": unittest.main()