14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Windows specific tests
24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
34adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom ctypes import *
44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom ctypes.test import is_resource_enabled
54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport unittest, sys
64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom test import test_support as support
74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport _ctypes_test
94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif sys.platform == "win32" and sizeof(c_void_p) == sizeof(c_int):
114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # Only windows 32-bit has different calling conventions.
124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    class WindowsTestCase(unittest.TestCase):
144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def test_callconv_1(self):
154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # Testing stdcall function
164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            IsWindow = windll.user32.IsWindow
184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # ValueError: Procedure probably called with not enough arguments (4 bytes missing)
194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertRaises(ValueError, IsWindow)
204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # This one should succeed...
224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(0, IsWindow(0))
234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # ValueError: Procedure probably called with too many arguments (8 bytes in excess)
254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertRaises(ValueError, IsWindow, 0, 0, 0)
264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def test_callconv_2(self):
284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # Calling stdcall function as cdecl
294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            IsWindow = cdll.user32.IsWindow
314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # ValueError: Procedure called with not enough arguments (4 bytes missing)
334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # or wrong calling convention
344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertRaises(ValueError, IsWindow, None)
354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif sys.platform == "win32":
374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    class FunctionCallTestCase(unittest.TestCase):
384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if is_resource_enabled("SEH"):
404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            def test_SEH(self):
414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                # Call functions with invalid arguments, and make sure
424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                # that access violations are trapped and raise an
434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                # exception.
444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.assertRaises(WindowsError, windll.kernel32.GetModuleHandleA, 32)
454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def test_noargs(self):
474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # This is a special case on win32 x64
484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            windll.user32.GetDesktopWindow()
494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    class TestWintypes(unittest.TestCase):
514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def test_HWND(self):
524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            from ctypes import wintypes
534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(sizeof(wintypes.HWND), sizeof(c_void_p))
544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def test_PARAM(self):
564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            from ctypes import wintypes
574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(sizeof(wintypes.WPARAM),
584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                 sizeof(c_void_p))
594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(sizeof(wintypes.LPARAM),
604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                 sizeof(c_void_p))
614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def test_COMError(self):
634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            from _ctypes import COMError
644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if support.HAVE_DOCSTRINGS:
654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.assertEqual(COMError.__doc__,
664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                 "Raised when a COM method call failed.")
674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            ex = COMError(-1, "text", ("details",))
694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(ex.hresult, -1)
704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(ex.text, "text")
714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(ex.details, ("details",))
724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass Structures(unittest.TestCase):
744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_struct_by_value(self):
764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        class POINT(Structure):
774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            _fields_ = [("x", c_long),
784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        ("y", c_long)]
794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        class RECT(Structure):
814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            _fields_ = [("left", c_long),
824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        ("top", c_long),
834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        ("right", c_long),
844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        ("bottom", c_long)]
854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        dll = CDLL(_ctypes_test.__file__)
874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        pt = POINT(10, 10)
894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        rect = RECT(0, 0, 20, 20)
904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(1, dll.PointInRect(byref(rect), pt))
914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif __name__ == '__main__':
934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    unittest.main()
94