1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4# Copyright (c) 2009-2014, Mario Vilas
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions are met:
9#
10#     * Redistributions of source code must retain the above copyright notice,
11#       this list of conditions and the following disclaimer.
12#     * Redistributions in binary form must reproduce the above copyright
13#       notice,this list of conditions and the following disclaimer in the
14#       documentation and/or other materials provided with the distribution.
15#     * Neither the name of the copyright holder nor the names of its
16#       contributors may be used to endorse or promote products derived from
17#       this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29# POSSIBILITY OF SUCH DAMAGE.
30
31"""
32Wrapper for user32.dll in ctypes.
33"""
34
35__revision__ = "$Id$"
36
37from winappdbg.win32.defines import *
38from winappdbg.win32.version import bits
39from winappdbg.win32.kernel32 import GetLastError, SetLastError
40from winappdbg.win32.gdi32 import POINT, PPOINT, LPPOINT, RECT, PRECT, LPRECT
41
42#==============================================================================
43# This is used later on to calculate the list of exported symbols.
44_all = None
45_all = set(vars().keys())
46#==============================================================================
47
48#--- Helpers ------------------------------------------------------------------
49
50def MAKE_WPARAM(wParam):
51    """
52    Convert arguments to the WPARAM type.
53    Used automatically by SendMessage, PostMessage, etc.
54    You shouldn't need to call this function.
55    """
56    wParam = ctypes.cast(wParam, LPVOID).value
57    if wParam is None:
58        wParam = 0
59    return wParam
60
61def MAKE_LPARAM(lParam):
62    """
63    Convert arguments to the LPARAM type.
64    Used automatically by SendMessage, PostMessage, etc.
65    You shouldn't need to call this function.
66    """
67    return ctypes.cast(lParam, LPARAM)
68
69class __WindowEnumerator (object):
70    """
71    Window enumerator class. Used internally by the window enumeration APIs.
72    """
73    def __init__(self):
74        self.hwnd = list()
75    def __call__(self, hwnd, lParam):
76##        print hwnd  # XXX DEBUG
77        self.hwnd.append(hwnd)
78        return TRUE
79
80#--- Types --------------------------------------------------------------------
81
82WNDENUMPROC = WINFUNCTYPE(BOOL, HWND, PVOID)
83
84#--- Constants ----------------------------------------------------------------
85
86HWND_DESKTOP    = 0
87HWND_TOP        = 1
88HWND_BOTTOM     = 1
89HWND_TOPMOST    = -1
90HWND_NOTOPMOST  = -2
91HWND_MESSAGE    = -3
92
93# GetWindowLong / SetWindowLong
94GWL_WNDPROC                          = -4
95GWL_HINSTANCE                        = -6
96GWL_HWNDPARENT                       = -8
97GWL_ID                               = -12
98GWL_STYLE                            = -16
99GWL_EXSTYLE                          = -20
100GWL_USERDATA                         = -21
101
102# GetWindowLongPtr / SetWindowLongPtr
103GWLP_WNDPROC                         = GWL_WNDPROC
104GWLP_HINSTANCE                       = GWL_HINSTANCE
105GWLP_HWNDPARENT                      = GWL_HWNDPARENT
106GWLP_STYLE                           = GWL_STYLE
107GWLP_EXSTYLE                         = GWL_EXSTYLE
108GWLP_USERDATA                        = GWL_USERDATA
109GWLP_ID                              = GWL_ID
110
111# ShowWindow
112SW_HIDE                             = 0
113SW_SHOWNORMAL                       = 1
114SW_NORMAL                           = 1
115SW_SHOWMINIMIZED                    = 2
116SW_SHOWMAXIMIZED                    = 3
117SW_MAXIMIZE                         = 3
118SW_SHOWNOACTIVATE                   = 4
119SW_SHOW                             = 5
120SW_MINIMIZE                         = 6
121SW_SHOWMINNOACTIVE                  = 7
122SW_SHOWNA                           = 8
123SW_RESTORE                          = 9
124SW_SHOWDEFAULT                      = 10
125SW_FORCEMINIMIZE                    = 11
126
127# SendMessageTimeout flags
128SMTO_NORMAL                         = 0
129SMTO_BLOCK                          = 1
130SMTO_ABORTIFHUNG                    = 2
131SMTO_NOTIMEOUTIFNOTHUNG 			= 8
132SMTO_ERRORONEXIT                    = 0x20
133
134# WINDOWPLACEMENT flags
135WPF_SETMINPOSITION                  = 1
136WPF_RESTORETOMAXIMIZED              = 2
137WPF_ASYNCWINDOWPLACEMENT            = 4
138
139# GetAncestor flags
140GA_PARENT                           = 1
141GA_ROOT                             = 2
142GA_ROOTOWNER                        = 3
143
144# GetWindow flags
145GW_HWNDFIRST                        = 0
146GW_HWNDLAST                         = 1
147GW_HWNDNEXT                         = 2
148GW_HWNDPREV                         = 3
149GW_OWNER                            = 4
150GW_CHILD                            = 5
151GW_ENABLEDPOPUP                     = 6
152
153#--- Window messages ----------------------------------------------------------
154
155WM_USER                              = 0x400
156WM_APP                               = 0x800
157
158WM_NULL                              = 0
159WM_CREATE                            = 1
160WM_DESTROY                           = 2
161WM_MOVE                              = 3
162WM_SIZE                              = 5
163WM_ACTIVATE                          = 6
164WA_INACTIVE                          = 0
165WA_ACTIVE                            = 1
166WA_CLICKACTIVE                       = 2
167WM_SETFOCUS                          = 7
168WM_KILLFOCUS                         = 8
169WM_ENABLE                            = 0x0A
170WM_SETREDRAW                         = 0x0B
171WM_SETTEXT                           = 0x0C
172WM_GETTEXT                           = 0x0D
173WM_GETTEXTLENGTH                     = 0x0E
174WM_PAINT                             = 0x0F
175WM_CLOSE                             = 0x10
176WM_QUERYENDSESSION                   = 0x11
177WM_QUIT                              = 0x12
178WM_QUERYOPEN                         = 0x13
179WM_ERASEBKGND                        = 0x14
180WM_SYSCOLORCHANGE                    = 0x15
181WM_ENDSESSION                        = 0x16
182WM_SHOWWINDOW                        = 0x18
183WM_WININICHANGE                      = 0x1A
184WM_SETTINGCHANGE                	 = WM_WININICHANGE
185WM_DEVMODECHANGE                     = 0x1B
186WM_ACTIVATEAPP                       = 0x1C
187WM_FONTCHANGE                        = 0x1D
188WM_TIMECHANGE                        = 0x1E
189WM_CANCELMODE                        = 0x1F
190WM_SETCURSOR                         = 0x20
191WM_MOUSEACTIVATE                     = 0x21
192WM_CHILDACTIVATE                     = 0x22
193WM_QUEUESYNC                         = 0x23
194WM_GETMINMAXINFO                     = 0x24
195WM_PAINTICON                         = 0x26
196WM_ICONERASEBKGND                    = 0x27
197WM_NEXTDLGCTL                        = 0x28
198WM_SPOOLERSTATUS                     = 0x2A
199WM_DRAWITEM                          = 0x2B
200WM_MEASUREITEM                       = 0x2C
201WM_DELETEITEM                        = 0x2D
202WM_VKEYTOITEM                        = 0x2E
203WM_CHARTOITEM                        = 0x2F
204WM_SETFONT                           = 0x30
205WM_GETFONT                           = 0x31
206WM_SETHOTKEY                         = 0x32
207WM_GETHOTKEY                         = 0x33
208WM_QUERYDRAGICON                     = 0x37
209WM_COMPAREITEM                       = 0x39
210WM_GETOBJECT                    	 = 0x3D
211WM_COMPACTING                        = 0x41
212WM_OTHERWINDOWCREATED                = 0x42
213WM_OTHERWINDOWDESTROYED              = 0x43
214WM_COMMNOTIFY                        = 0x44
215
216CN_RECEIVE                           = 0x1
217CN_TRANSMIT                          = 0x2
218CN_EVENT                             = 0x4
219
220WM_WINDOWPOSCHANGING                 = 0x46
221WM_WINDOWPOSCHANGED                  = 0x47
222WM_POWER                             = 0x48
223
224PWR_OK                               = 1
225PWR_FAIL                             = -1
226PWR_SUSPENDREQUEST                   = 1
227PWR_SUSPENDRESUME                    = 2
228PWR_CRITICALRESUME                   = 3
229
230WM_COPYDATA                          = 0x4A
231WM_CANCELJOURNAL                     = 0x4B
232WM_NOTIFY                            = 0x4E
233WM_INPUTLANGCHANGEREQUEST            = 0x50
234WM_INPUTLANGCHANGE                   = 0x51
235WM_TCARD                             = 0x52
236WM_HELP                              = 0x53
237WM_USERCHANGED                       = 0x54
238WM_NOTIFYFORMAT                      = 0x55
239WM_CONTEXTMENU                       = 0x7B
240WM_STYLECHANGING                     = 0x7C
241WM_STYLECHANGED                      = 0x7D
242WM_DISPLAYCHANGE                     = 0x7E
243WM_GETICON                           = 0x7F
244WM_SETICON                           = 0x80
245WM_NCCREATE                          = 0x81
246WM_NCDESTROY                         = 0x82
247WM_NCCALCSIZE                        = 0x83
248WM_NCHITTEST                         = 0x84
249WM_NCPAINT                           = 0x85
250WM_NCACTIVATE                        = 0x86
251WM_GETDLGCODE                        = 0x87
252WM_SYNCPAINT                    	 = 0x88
253WM_NCMOUSEMOVE                       = 0x0A0
254WM_NCLBUTTONDOWN                     = 0x0A1
255WM_NCLBUTTONUP                       = 0x0A2
256WM_NCLBUTTONDBLCLK                   = 0x0A3
257WM_NCRBUTTONDOWN                     = 0x0A4
258WM_NCRBUTTONUP                       = 0x0A5
259WM_NCRBUTTONDBLCLK                   = 0x0A6
260WM_NCMBUTTONDOWN                     = 0x0A7
261WM_NCMBUTTONUP                       = 0x0A8
262WM_NCMBUTTONDBLCLK                   = 0x0A9
263WM_KEYFIRST                          = 0x100
264WM_KEYDOWN                           = 0x100
265WM_KEYUP                             = 0x101
266WM_CHAR                              = 0x102
267WM_DEADCHAR                          = 0x103
268WM_SYSKEYDOWN                        = 0x104
269WM_SYSKEYUP                          = 0x105
270WM_SYSCHAR                           = 0x106
271WM_SYSDEADCHAR                       = 0x107
272WM_KEYLAST                           = 0x108
273WM_INITDIALOG                        = 0x110
274WM_COMMAND                           = 0x111
275WM_SYSCOMMAND                        = 0x112
276WM_TIMER                             = 0x113
277WM_HSCROLL                           = 0x114
278WM_VSCROLL                           = 0x115
279WM_INITMENU                          = 0x116
280WM_INITMENUPOPUP                     = 0x117
281WM_MENUSELECT                        = 0x11F
282WM_MENUCHAR                          = 0x120
283WM_ENTERIDLE                         = 0x121
284WM_CTLCOLORMSGBOX                    = 0x132
285WM_CTLCOLOREDIT                      = 0x133
286WM_CTLCOLORLISTBOX                   = 0x134
287WM_CTLCOLORBTN                       = 0x135
288WM_CTLCOLORDLG                       = 0x136
289WM_CTLCOLORSCROLLBAR                 = 0x137
290WM_CTLCOLORSTATIC                    = 0x138
291WM_MOUSEFIRST                        = 0x200
292WM_MOUSEMOVE                         = 0x200
293WM_LBUTTONDOWN                       = 0x201
294WM_LBUTTONUP                         = 0x202
295WM_LBUTTONDBLCLK                     = 0x203
296WM_RBUTTONDOWN                       = 0x204
297WM_RBUTTONUP                         = 0x205
298WM_RBUTTONDBLCLK                     = 0x206
299WM_MBUTTONDOWN                       = 0x207
300WM_MBUTTONUP                         = 0x208
301WM_MBUTTONDBLCLK                     = 0x209
302WM_MOUSELAST                         = 0x209
303WM_PARENTNOTIFY                      = 0x210
304WM_ENTERMENULOOP                     = 0x211
305WM_EXITMENULOOP                      = 0x212
306WM_MDICREATE                         = 0x220
307WM_MDIDESTROY                        = 0x221
308WM_MDIACTIVATE                       = 0x222
309WM_MDIRESTORE                        = 0x223
310WM_MDINEXT                           = 0x224
311WM_MDIMAXIMIZE                       = 0x225
312WM_MDITILE                           = 0x226
313WM_MDICASCADE                        = 0x227
314WM_MDIICONARRANGE                    = 0x228
315WM_MDIGETACTIVE                      = 0x229
316WM_MDISETMENU                        = 0x230
317WM_DROPFILES                         = 0x233
318WM_MDIREFRESHMENU                    = 0x234
319WM_CUT                               = 0x300
320WM_COPY                              = 0x301
321WM_PASTE                             = 0x302
322WM_CLEAR                             = 0x303
323WM_UNDO                              = 0x304
324WM_RENDERFORMAT                      = 0x305
325WM_RENDERALLFORMATS                  = 0x306
326WM_DESTROYCLIPBOARD                  = 0x307
327WM_DRAWCLIPBOARD                     = 0x308
328WM_PAINTCLIPBOARD                    = 0x309
329WM_VSCROLLCLIPBOARD                  = 0x30A
330WM_SIZECLIPBOARD                     = 0x30B
331WM_ASKCBFORMATNAME                   = 0x30C
332WM_CHANGECBCHAIN                     = 0x30D
333WM_HSCROLLCLIPBOARD                  = 0x30E
334WM_QUERYNEWPALETTE                   = 0x30F
335WM_PALETTEISCHANGING                 = 0x310
336WM_PALETTECHANGED                    = 0x311
337WM_HOTKEY                            = 0x312
338WM_PRINT                        	 = 0x317
339WM_PRINTCLIENT                       = 0x318
340WM_PENWINFIRST                       = 0x380
341WM_PENWINLAST                        = 0x38F
342
343#--- Structures ---------------------------------------------------------------
344
345# typedef struct _WINDOWPLACEMENT {
346#     UINT length;
347#     UINT flags;
348#     UINT showCmd;
349#     POINT ptMinPosition;
350#     POINT ptMaxPosition;
351#     RECT rcNormalPosition;
352# } WINDOWPLACEMENT;
353class WINDOWPLACEMENT(Structure):
354    _fields_ = [
355        ('length',              UINT),
356        ('flags',               UINT),
357        ('showCmd',             UINT),
358        ('ptMinPosition',       POINT),
359        ('ptMaxPosition',       POINT),
360        ('rcNormalPosition',    RECT),
361    ]
362PWINDOWPLACEMENT  = POINTER(WINDOWPLACEMENT)
363LPWINDOWPLACEMENT = PWINDOWPLACEMENT
364
365# typedef struct tagGUITHREADINFO {
366#     DWORD cbSize;
367#     DWORD flags;
368#     HWND hwndActive;
369#     HWND hwndFocus;
370#     HWND hwndCapture;
371#     HWND hwndMenuOwner;
372#     HWND hwndMoveSize;
373#     HWND hwndCaret;
374#     RECT rcCaret;
375# } GUITHREADINFO, *PGUITHREADINFO;
376class GUITHREADINFO(Structure):
377    _fields_ = [
378        ('cbSize',          DWORD),
379        ('flags',           DWORD),
380        ('hwndActive',      HWND),
381        ('hwndFocus',       HWND),
382        ('hwndCapture',     HWND),
383        ('hwndMenuOwner',   HWND),
384        ('hwndMoveSize',    HWND),
385        ('hwndCaret',       HWND),
386        ('rcCaret',         RECT),
387    ]
388PGUITHREADINFO  = POINTER(GUITHREADINFO)
389LPGUITHREADINFO = PGUITHREADINFO
390
391#--- High level classes -------------------------------------------------------
392
393# Point() and Rect() are here instead of gdi32.py because they were mainly
394# created to handle window coordinates rather than drawing on the screen.
395
396# XXX not sure if these classes should be psyco-optimized,
397# it may not work if the user wants to serialize them for some reason
398
399class Point(object):
400    """
401    Python wrapper over the L{POINT} class.
402
403    @type x: int
404    @ivar x: Horizontal coordinate
405    @type y: int
406    @ivar y: Vertical coordinate
407    """
408
409    def __init__(self, x = 0, y = 0):
410        """
411        @see: L{POINT}
412        @type  x: int
413        @param x: Horizontal coordinate
414        @type  y: int
415        @param y: Vertical coordinate
416        """
417        self.x = x
418        self.y = y
419
420    def __iter__(self):
421        return (self.x, self.y).__iter__()
422
423    def __len__(self):
424        return 2
425
426    def __getitem__(self, index):
427        return (self.x, self.y) [index]
428
429    def __setitem__(self, index, value):
430        if   index == 0:
431            self.x = value
432        elif index == 1:
433            self.y = value
434        else:
435            raise IndexError("index out of range")
436
437    @property
438    def _as_parameter_(self):
439        """
440        Compatibility with ctypes.
441        Allows passing transparently a Point object to an API call.
442        """
443        return POINT(self.x, self.y)
444
445    def screen_to_client(self, hWnd):
446        """
447        Translates window screen coordinates to client coordinates.
448
449        @see: L{client_to_screen}, L{translate}
450
451        @type  hWnd: int or L{HWND} or L{system.Window}
452        @param hWnd: Window handle.
453
454        @rtype:  L{Point}
455        @return: New object containing the translated coordinates.
456        """
457        return ScreenToClient(hWnd, self)
458
459    def client_to_screen(self, hWnd):
460        """
461        Translates window client coordinates to screen coordinates.
462
463        @see: L{screen_to_client}, L{translate}
464
465        @type  hWnd: int or L{HWND} or L{system.Window}
466        @param hWnd: Window handle.
467
468        @rtype:  L{Point}
469        @return: New object containing the translated coordinates.
470        """
471        return ClientToScreen(hWnd, self)
472
473    def translate(self, hWndFrom = HWND_DESKTOP, hWndTo = HWND_DESKTOP):
474        """
475        Translate coordinates from one window to another.
476
477        @note: To translate multiple points it's more efficient to use the
478            L{MapWindowPoints} function instead.
479
480        @see: L{client_to_screen}, L{screen_to_client}
481
482        @type  hWndFrom: int or L{HWND} or L{system.Window}
483        @param hWndFrom: Window handle to translate from.
484            Use C{HWND_DESKTOP} for screen coordinates.
485
486        @type  hWndTo: int or L{HWND} or L{system.Window}
487        @param hWndTo: Window handle to translate to.
488            Use C{HWND_DESKTOP} for screen coordinates.
489
490        @rtype:  L{Point}
491        @return: New object containing the translated coordinates.
492        """
493        return MapWindowPoints(hWndFrom, hWndTo, [self])
494
495class Rect(object):
496    """
497    Python wrapper over the L{RECT} class.
498
499    @type   left: int
500    @ivar   left: Horizontal coordinate for the top left corner.
501    @type    top: int
502    @ivar    top: Vertical coordinate for the top left corner.
503    @type  right: int
504    @ivar  right: Horizontal coordinate for the bottom right corner.
505    @type bottom: int
506    @ivar bottom: Vertical coordinate for the bottom right corner.
507
508    @type  width: int
509    @ivar  width: Width in pixels. Same as C{right - left}.
510    @type height: int
511    @ivar height: Height in pixels. Same as C{bottom - top}.
512    """
513
514    def __init__(self, left = 0, top = 0, right = 0, bottom = 0):
515        """
516        @see: L{RECT}
517        @type    left: int
518        @param   left: Horizontal coordinate for the top left corner.
519        @type     top: int
520        @param    top: Vertical coordinate for the top left corner.
521        @type   right: int
522        @param  right: Horizontal coordinate for the bottom right corner.
523        @type  bottom: int
524        @param bottom: Vertical coordinate for the bottom right corner.
525        """
526        self.left   = left
527        self.top    = top
528        self.right  = right
529        self.bottom = bottom
530
531    def __iter__(self):
532        return (self.left, self.top, self.right, self.bottom).__iter__()
533
534    def __len__(self):
535        return 2
536
537    def __getitem__(self, index):
538        return (self.left, self.top, self.right, self.bottom) [index]
539
540    def __setitem__(self, index, value):
541        if   index == 0:
542            self.left   = value
543        elif index == 1:
544            self.top    = value
545        elif index == 2:
546            self.right  = value
547        elif index == 3:
548            self.bottom = value
549        else:
550            raise IndexError("index out of range")
551
552    @property
553    def _as_parameter_(self):
554        """
555        Compatibility with ctypes.
556        Allows passing transparently a Point object to an API call.
557        """
558        return RECT(self.left, self.top, self.right, self.bottom)
559
560    def __get_width(self):
561        return self.right - self.left
562
563    def __get_height(self):
564        return self.bottom - self.top
565
566    def __set_width(self, value):
567        self.right = value - self.left
568
569    def __set_height(self, value):
570        self.bottom = value - self.top
571
572    width  = property(__get_width, __set_width)
573    height = property(__get_height, __set_height)
574
575    def screen_to_client(self, hWnd):
576        """
577        Translates window screen coordinates to client coordinates.
578
579        @see: L{client_to_screen}, L{translate}
580
581        @type  hWnd: int or L{HWND} or L{system.Window}
582        @param hWnd: Window handle.
583
584        @rtype:  L{Rect}
585        @return: New object containing the translated coordinates.
586        """
587        topleft     = ScreenToClient(hWnd, (self.left,   self.top))
588        bottomright = ScreenToClient(hWnd, (self.bottom, self.right))
589        return Rect( topleft.x, topleft.y, bottomright.x, bottomright.y )
590
591    def client_to_screen(self, hWnd):
592        """
593        Translates window client coordinates to screen coordinates.
594
595        @see: L{screen_to_client}, L{translate}
596
597        @type  hWnd: int or L{HWND} or L{system.Window}
598        @param hWnd: Window handle.
599
600        @rtype:  L{Rect}
601        @return: New object containing the translated coordinates.
602        """
603        topleft     = ClientToScreen(hWnd, (self.left,   self.top))
604        bottomright = ClientToScreen(hWnd, (self.bottom, self.right))
605        return Rect( topleft.x, topleft.y, bottomright.x, bottomright.y )
606
607    def translate(self, hWndFrom = HWND_DESKTOP, hWndTo = HWND_DESKTOP):
608        """
609        Translate coordinates from one window to another.
610
611        @see: L{client_to_screen}, L{screen_to_client}
612
613        @type  hWndFrom: int or L{HWND} or L{system.Window}
614        @param hWndFrom: Window handle to translate from.
615            Use C{HWND_DESKTOP} for screen coordinates.
616
617        @type  hWndTo: int or L{HWND} or L{system.Window}
618        @param hWndTo: Window handle to translate to.
619            Use C{HWND_DESKTOP} for screen coordinates.
620
621        @rtype:  L{Rect}
622        @return: New object containing the translated coordinates.
623        """
624        points = [ (self.left, self.top), (self.right, self.bottom) ]
625        return MapWindowPoints(hWndFrom, hWndTo, points)
626
627class WindowPlacement(object):
628    """
629    Python wrapper over the L{WINDOWPLACEMENT} class.
630    """
631
632    def __init__(self, wp = None):
633        """
634        @type  wp: L{WindowPlacement} or L{WINDOWPLACEMENT}
635        @param wp: Another window placement object.
636        """
637
638        # Initialize all properties with empty values.
639        self.flags            = 0
640        self.showCmd          = 0
641        self.ptMinPosition    = Point()
642        self.ptMaxPosition    = Point()
643        self.rcNormalPosition = Rect()
644
645        # If a window placement was given copy it's properties.
646        if wp:
647            self.flags            = wp.flags
648            self.showCmd          = wp.showCmd
649            self.ptMinPosition    = Point( wp.ptMinPosition.x, wp.ptMinPosition.y )
650            self.ptMaxPosition    = Point( wp.ptMaxPosition.x, wp.ptMaxPosition.y )
651            self.rcNormalPosition = Rect(
652                                        wp.rcNormalPosition.left,
653                                        wp.rcNormalPosition.top,
654                                        wp.rcNormalPosition.right,
655                                        wp.rcNormalPosition.bottom,
656                                        )
657
658    @property
659    def _as_parameter_(self):
660        """
661        Compatibility with ctypes.
662        Allows passing transparently a Point object to an API call.
663        """
664        wp                          = WINDOWPLACEMENT()
665        wp.length                   = sizeof(wp)
666        wp.flags                    = self.flags
667        wp.showCmd                  = self.showCmd
668        wp.ptMinPosition.x          = self.ptMinPosition.x
669        wp.ptMinPosition.y          = self.ptMinPosition.y
670        wp.ptMaxPosition.x          = self.ptMaxPosition.x
671        wp.ptMaxPosition.y          = self.ptMaxPosition.y
672        wp.rcNormalPosition.left    = self.rcNormalPosition.left
673        wp.rcNormalPosition.top     = self.rcNormalPosition.top
674        wp.rcNormalPosition.right   = self.rcNormalPosition.right
675        wp.rcNormalPosition.bottom  = self.rcNormalPosition.bottom
676        return wp
677
678#--- user32.dll ---------------------------------------------------------------
679
680# void WINAPI SetLastErrorEx(
681#   __in  DWORD dwErrCode,
682#   __in  DWORD dwType
683# );
684def SetLastErrorEx(dwErrCode, dwType = 0):
685    _SetLastErrorEx = windll.user32.SetLastErrorEx
686    _SetLastErrorEx.argtypes = [DWORD, DWORD]
687    _SetLastErrorEx.restype  = None
688    _SetLastErrorEx(dwErrCode, dwType)
689
690# HWND FindWindow(
691#     LPCTSTR lpClassName,
692#     LPCTSTR lpWindowName
693# );
694def FindWindowA(lpClassName = None, lpWindowName = None):
695    _FindWindowA = windll.user32.FindWindowA
696    _FindWindowA.argtypes = [LPSTR, LPSTR]
697    _FindWindowA.restype  = HWND
698
699    hWnd = _FindWindowA(lpClassName, lpWindowName)
700    if not hWnd:
701        errcode = GetLastError()
702        if errcode != ERROR_SUCCESS:
703            raise ctypes.WinError(errcode)
704    return hWnd
705
706def FindWindowW(lpClassName = None, lpWindowName = None):
707    _FindWindowW = windll.user32.FindWindowW
708    _FindWindowW.argtypes = [LPWSTR, LPWSTR]
709    _FindWindowW.restype  = HWND
710
711    hWnd = _FindWindowW(lpClassName, lpWindowName)
712    if not hWnd:
713        errcode = GetLastError()
714        if errcode != ERROR_SUCCESS:
715            raise ctypes.WinError(errcode)
716    return hWnd
717
718FindWindow = GuessStringType(FindWindowA, FindWindowW)
719
720# HWND WINAPI FindWindowEx(
721#   __in_opt  HWND hwndParent,
722#   __in_opt  HWND hwndChildAfter,
723#   __in_opt  LPCTSTR lpszClass,
724#   __in_opt  LPCTSTR lpszWindow
725# );
726def FindWindowExA(hwndParent = None, hwndChildAfter = None, lpClassName = None, lpWindowName = None):
727    _FindWindowExA = windll.user32.FindWindowExA
728    _FindWindowExA.argtypes = [HWND, HWND, LPSTR, LPSTR]
729    _FindWindowExA.restype  = HWND
730
731    hWnd = _FindWindowExA(hwndParent, hwndChildAfter, lpClassName, lpWindowName)
732    if not hWnd:
733        errcode = GetLastError()
734        if errcode != ERROR_SUCCESS:
735            raise ctypes.WinError(errcode)
736    return hWnd
737
738def FindWindowExW(hwndParent = None, hwndChildAfter = None, lpClassName = None, lpWindowName = None):
739    _FindWindowExW = windll.user32.FindWindowExW
740    _FindWindowExW.argtypes = [HWND, HWND, LPWSTR, LPWSTR]
741    _FindWindowExW.restype  = HWND
742
743    hWnd = _FindWindowExW(hwndParent, hwndChildAfter, lpClassName, lpWindowName)
744    if not hWnd:
745        errcode = GetLastError()
746        if errcode != ERROR_SUCCESS:
747            raise ctypes.WinError(errcode)
748    return hWnd
749
750FindWindowEx = GuessStringType(FindWindowExA, FindWindowExW)
751
752# int GetClassName(
753#     HWND hWnd,
754#     LPTSTR lpClassName,
755#     int nMaxCount
756# );
757def GetClassNameA(hWnd):
758    _GetClassNameA = windll.user32.GetClassNameA
759    _GetClassNameA.argtypes = [HWND, LPSTR, ctypes.c_int]
760    _GetClassNameA.restype = ctypes.c_int
761
762    nMaxCount = 0x1000
763    dwCharSize = sizeof(CHAR)
764    while 1:
765        lpClassName = ctypes.create_string_buffer("", nMaxCount)
766        nCount = _GetClassNameA(hWnd, lpClassName, nMaxCount)
767        if nCount == 0:
768            raise ctypes.WinError()
769        if nCount < nMaxCount - dwCharSize:
770            break
771        nMaxCount += 0x1000
772    return lpClassName.value
773
774def GetClassNameW(hWnd):
775    _GetClassNameW = windll.user32.GetClassNameW
776    _GetClassNameW.argtypes = [HWND, LPWSTR, ctypes.c_int]
777    _GetClassNameW.restype = ctypes.c_int
778
779    nMaxCount = 0x1000
780    dwCharSize = sizeof(WCHAR)
781    while 1:
782        lpClassName = ctypes.create_unicode_buffer(u"", nMaxCount)
783        nCount = _GetClassNameW(hWnd, lpClassName, nMaxCount)
784        if nCount == 0:
785            raise ctypes.WinError()
786        if nCount < nMaxCount - dwCharSize:
787            break
788        nMaxCount += 0x1000
789    return lpClassName.value
790
791GetClassName = GuessStringType(GetClassNameA, GetClassNameW)
792
793# int WINAPI GetWindowText(
794#   __in   HWND hWnd,
795#   __out  LPTSTR lpString,
796#   __in   int nMaxCount
797# );
798def GetWindowTextA(hWnd):
799    _GetWindowTextA = windll.user32.GetWindowTextA
800    _GetWindowTextA.argtypes = [HWND, LPSTR, ctypes.c_int]
801    _GetWindowTextA.restype = ctypes.c_int
802
803    nMaxCount = 0x1000
804    dwCharSize = sizeof(CHAR)
805    while 1:
806        lpString = ctypes.create_string_buffer("", nMaxCount)
807        nCount = _GetWindowTextA(hWnd, lpString, nMaxCount)
808        if nCount == 0:
809            raise ctypes.WinError()
810        if nCount < nMaxCount - dwCharSize:
811            break
812        nMaxCount += 0x1000
813    return lpString.value
814
815def GetWindowTextW(hWnd):
816    _GetWindowTextW = windll.user32.GetWindowTextW
817    _GetWindowTextW.argtypes = [HWND, LPWSTR, ctypes.c_int]
818    _GetWindowTextW.restype = ctypes.c_int
819
820    nMaxCount = 0x1000
821    dwCharSize = sizeof(CHAR)
822    while 1:
823        lpString = ctypes.create_string_buffer("", nMaxCount)
824        nCount = _GetWindowTextW(hWnd, lpString, nMaxCount)
825        if nCount == 0:
826            raise ctypes.WinError()
827        if nCount < nMaxCount - dwCharSize:
828            break
829        nMaxCount += 0x1000
830    return lpString.value
831
832GetWindowText = GuessStringType(GetWindowTextA, GetWindowTextW)
833
834# BOOL WINAPI SetWindowText(
835#   __in      HWND hWnd,
836#   __in_opt  LPCTSTR lpString
837# );
838def SetWindowTextA(hWnd, lpString = None):
839    _SetWindowTextA = windll.user32.SetWindowTextA
840    _SetWindowTextA.argtypes = [HWND, LPSTR]
841    _SetWindowTextA.restype  = bool
842    _SetWindowTextA.errcheck = RaiseIfZero
843    _SetWindowTextA(hWnd, lpString)
844
845def SetWindowTextW(hWnd, lpString = None):
846    _SetWindowTextW = windll.user32.SetWindowTextW
847    _SetWindowTextW.argtypes = [HWND, LPWSTR]
848    _SetWindowTextW.restype  = bool
849    _SetWindowTextW.errcheck = RaiseIfZero
850    _SetWindowTextW(hWnd, lpString)
851
852SetWindowText = GuessStringType(SetWindowTextA, SetWindowTextW)
853
854# LONG GetWindowLong(
855#     HWND hWnd,
856#     int nIndex
857# );
858def GetWindowLongA(hWnd, nIndex = 0):
859    _GetWindowLongA = windll.user32.GetWindowLongA
860    _GetWindowLongA.argtypes = [HWND, ctypes.c_int]
861    _GetWindowLongA.restype  = DWORD
862
863    SetLastError(ERROR_SUCCESS)
864    retval = _GetWindowLongA(hWnd, nIndex)
865    if retval == 0:
866        errcode = GetLastError()
867        if errcode != ERROR_SUCCESS:
868            raise ctypes.WinError(errcode)
869    return retval
870
871def GetWindowLongW(hWnd, nIndex = 0):
872    _GetWindowLongW = windll.user32.GetWindowLongW
873    _GetWindowLongW.argtypes = [HWND, ctypes.c_int]
874    _GetWindowLongW.restype  = DWORD
875
876    SetLastError(ERROR_SUCCESS)
877    retval = _GetWindowLongW(hWnd, nIndex)
878    if retval == 0:
879        errcode = GetLastError()
880        if errcode != ERROR_SUCCESS:
881            raise ctypes.WinError(errcode)
882    return retval
883
884GetWindowLong = DefaultStringType(GetWindowLongA, GetWindowLongW)
885
886# LONG_PTR WINAPI GetWindowLongPtr(
887#   _In_  HWND hWnd,
888#   _In_  int nIndex
889# );
890
891if bits == 32:
892
893    GetWindowLongPtrA = GetWindowLongA
894    GetWindowLongPtrW = GetWindowLongW
895    GetWindowLongPtr  = GetWindowLong
896
897else:
898
899    def GetWindowLongPtrA(hWnd, nIndex = 0):
900        _GetWindowLongPtrA = windll.user32.GetWindowLongPtrA
901        _GetWindowLongPtrA.argtypes = [HWND, ctypes.c_int]
902        _GetWindowLongPtrA.restype  = SIZE_T
903
904        SetLastError(ERROR_SUCCESS)
905        retval = _GetWindowLongPtrA(hWnd, nIndex)
906        if retval == 0:
907            errcode = GetLastError()
908            if errcode != ERROR_SUCCESS:
909                raise ctypes.WinError(errcode)
910        return retval
911
912    def GetWindowLongPtrW(hWnd, nIndex = 0):
913        _GetWindowLongPtrW = windll.user32.GetWindowLongPtrW
914        _GetWindowLongPtrW.argtypes = [HWND, ctypes.c_int]
915        _GetWindowLongPtrW.restype  = DWORD
916
917        SetLastError(ERROR_SUCCESS)
918        retval = _GetWindowLongPtrW(hWnd, nIndex)
919        if retval == 0:
920            errcode = GetLastError()
921            if errcode != ERROR_SUCCESS:
922                raise ctypes.WinError(errcode)
923        return retval
924
925    GetWindowLongPtr = DefaultStringType(GetWindowLongPtrA, GetWindowLongPtrW)
926
927# LONG WINAPI SetWindowLong(
928#   _In_  HWND hWnd,
929#   _In_  int nIndex,
930#   _In_  LONG dwNewLong
931# );
932
933def SetWindowLongA(hWnd, nIndex, dwNewLong):
934    _SetWindowLongA = windll.user32.SetWindowLongA
935    _SetWindowLongA.argtypes = [HWND, ctypes.c_int, DWORD]
936    _SetWindowLongA.restype  = DWORD
937
938    SetLastError(ERROR_SUCCESS)
939    retval = _SetWindowLongA(hWnd, nIndex, dwNewLong)
940    if retval == 0:
941        errcode = GetLastError()
942        if errcode != ERROR_SUCCESS:
943            raise ctypes.WinError(errcode)
944    return retval
945
946def SetWindowLongW(hWnd, nIndex, dwNewLong):
947    _SetWindowLongW = windll.user32.SetWindowLongW
948    _SetWindowLongW.argtypes = [HWND, ctypes.c_int, DWORD]
949    _SetWindowLongW.restype  = DWORD
950
951    SetLastError(ERROR_SUCCESS)
952    retval = _SetWindowLongW(hWnd, nIndex, dwNewLong)
953    if retval == 0:
954        errcode = GetLastError()
955        if errcode != ERROR_SUCCESS:
956            raise ctypes.WinError(errcode)
957    return retval
958
959SetWindowLong = DefaultStringType(SetWindowLongA, SetWindowLongW)
960
961# LONG_PTR WINAPI SetWindowLongPtr(
962#   _In_  HWND hWnd,
963#   _In_  int nIndex,
964#   _In_  LONG_PTR dwNewLong
965# );
966
967if bits == 32:
968
969    SetWindowLongPtrA = SetWindowLongA
970    SetWindowLongPtrW = SetWindowLongW
971    SetWindowLongPtr  = SetWindowLong
972
973else:
974
975    def SetWindowLongPtrA(hWnd, nIndex, dwNewLong):
976        _SetWindowLongPtrA = windll.user32.SetWindowLongPtrA
977        _SetWindowLongPtrA.argtypes = [HWND, ctypes.c_int, SIZE_T]
978        _SetWindowLongPtrA.restype  = SIZE_T
979
980        SetLastError(ERROR_SUCCESS)
981        retval = _SetWindowLongPtrA(hWnd, nIndex, dwNewLong)
982        if retval == 0:
983            errcode = GetLastError()
984            if errcode != ERROR_SUCCESS:
985                raise ctypes.WinError(errcode)
986        return retval
987
988    def SetWindowLongPtrW(hWnd, nIndex, dwNewLong):
989        _SetWindowLongPtrW = windll.user32.SetWindowLongPtrW
990        _SetWindowLongPtrW.argtypes = [HWND, ctypes.c_int, SIZE_T]
991        _SetWindowLongPtrW.restype  = SIZE_T
992
993        SetLastError(ERROR_SUCCESS)
994        retval = _SetWindowLongPtrW(hWnd, nIndex, dwNewLong)
995        if retval == 0:
996            errcode = GetLastError()
997            if errcode != ERROR_SUCCESS:
998                raise ctypes.WinError(errcode)
999        return retval
1000
1001    SetWindowLongPtr = DefaultStringType(SetWindowLongPtrA, SetWindowLongPtrW)
1002
1003# HWND GetShellWindow(VOID);
1004def GetShellWindow():
1005    _GetShellWindow = windll.user32.GetShellWindow
1006    _GetShellWindow.argtypes = []
1007    _GetShellWindow.restype  = HWND
1008    _GetShellWindow.errcheck = RaiseIfZero
1009    return _GetShellWindow()
1010
1011# DWORD GetWindowThreadProcessId(
1012#     HWND hWnd,
1013#     LPDWORD lpdwProcessId
1014# );
1015def GetWindowThreadProcessId(hWnd):
1016    _GetWindowThreadProcessId = windll.user32.GetWindowThreadProcessId
1017    _GetWindowThreadProcessId.argtypes = [HWND, LPDWORD]
1018    _GetWindowThreadProcessId.restype  = DWORD
1019    _GetWindowThreadProcessId.errcheck = RaiseIfZero
1020
1021    dwProcessId = DWORD(0)
1022    dwThreadId = _GetWindowThreadProcessId(hWnd, byref(dwProcessId))
1023    return (dwThreadId, dwProcessId.value)
1024
1025# HWND WINAPI GetWindow(
1026#   __in  HWND hwnd,
1027#   __in  UINT uCmd
1028# );
1029def GetWindow(hWnd, uCmd):
1030    _GetWindow = windll.user32.GetWindow
1031    _GetWindow.argtypes = [HWND, UINT]
1032    _GetWindow.restype  = HWND
1033
1034    SetLastError(ERROR_SUCCESS)
1035    hWndTarget = _GetWindow(hWnd, uCmd)
1036    if not hWndTarget:
1037        winerr = GetLastError()
1038        if winerr != ERROR_SUCCESS:
1039            raise ctypes.WinError(winerr)
1040    return hWndTarget
1041
1042# HWND GetParent(
1043#       HWND hWnd
1044# );
1045def GetParent(hWnd):
1046    _GetParent = windll.user32.GetParent
1047    _GetParent.argtypes = [HWND]
1048    _GetParent.restype  = HWND
1049
1050    SetLastError(ERROR_SUCCESS)
1051    hWndParent = _GetParent(hWnd)
1052    if not hWndParent:
1053        winerr = GetLastError()
1054        if winerr != ERROR_SUCCESS:
1055            raise ctypes.WinError(winerr)
1056    return hWndParent
1057
1058# HWND WINAPI GetAncestor(
1059#   __in  HWND hwnd,
1060#   __in  UINT gaFlags
1061# );
1062def GetAncestor(hWnd, gaFlags = GA_PARENT):
1063    _GetAncestor = windll.user32.GetAncestor
1064    _GetAncestor.argtypes = [HWND, UINT]
1065    _GetAncestor.restype  = HWND
1066
1067    SetLastError(ERROR_SUCCESS)
1068    hWndParent = _GetAncestor(hWnd, gaFlags)
1069    if not hWndParent:
1070        winerr = GetLastError()
1071        if winerr != ERROR_SUCCESS:
1072            raise ctypes.WinError(winerr)
1073    return hWndParent
1074
1075# BOOL EnableWindow(
1076#     HWND hWnd,
1077#     BOOL bEnable
1078# );
1079def EnableWindow(hWnd, bEnable = True):
1080    _EnableWindow = windll.user32.EnableWindow
1081    _EnableWindow.argtypes = [HWND, BOOL]
1082    _EnableWindow.restype  = bool
1083    return _EnableWindow(hWnd, bool(bEnable))
1084
1085# BOOL ShowWindow(
1086#     HWND hWnd,
1087#     int nCmdShow
1088# );
1089def ShowWindow(hWnd, nCmdShow = SW_SHOW):
1090    _ShowWindow = windll.user32.ShowWindow
1091    _ShowWindow.argtypes = [HWND, ctypes.c_int]
1092    _ShowWindow.restype  = bool
1093    return _ShowWindow(hWnd, nCmdShow)
1094
1095# BOOL ShowWindowAsync(
1096#     HWND hWnd,
1097#     int nCmdShow
1098# );
1099def ShowWindowAsync(hWnd, nCmdShow = SW_SHOW):
1100    _ShowWindowAsync = windll.user32.ShowWindowAsync
1101    _ShowWindowAsync.argtypes = [HWND, ctypes.c_int]
1102    _ShowWindowAsync.restype  = bool
1103    return _ShowWindowAsync(hWnd, nCmdShow)
1104
1105# HWND GetDesktopWindow(VOID);
1106def GetDesktopWindow():
1107    _GetDesktopWindow = windll.user32.GetDesktopWindow
1108    _GetDesktopWindow.argtypes = []
1109    _GetDesktopWindow.restype  = HWND
1110    _GetDesktopWindow.errcheck = RaiseIfZero
1111    return _GetDesktopWindow()
1112
1113# HWND GetForegroundWindow(VOID);
1114def GetForegroundWindow():
1115    _GetForegroundWindow = windll.user32.GetForegroundWindow
1116    _GetForegroundWindow.argtypes = []
1117    _GetForegroundWindow.restype  = HWND
1118    _GetForegroundWindow.errcheck = RaiseIfZero
1119    return _GetForegroundWindow()
1120
1121# BOOL IsWindow(
1122#     HWND hWnd
1123# );
1124def IsWindow(hWnd):
1125    _IsWindow = windll.user32.IsWindow
1126    _IsWindow.argtypes = [HWND]
1127    _IsWindow.restype  = bool
1128    return _IsWindow(hWnd)
1129
1130# BOOL IsWindowVisible(
1131#     HWND hWnd
1132# );
1133def IsWindowVisible(hWnd):
1134    _IsWindowVisible = windll.user32.IsWindowVisible
1135    _IsWindowVisible.argtypes = [HWND]
1136    _IsWindowVisible.restype  = bool
1137    return _IsWindowVisible(hWnd)
1138
1139# BOOL IsWindowEnabled(
1140#     HWND hWnd
1141# );
1142def IsWindowEnabled(hWnd):
1143    _IsWindowEnabled = windll.user32.IsWindowEnabled
1144    _IsWindowEnabled.argtypes = [HWND]
1145    _IsWindowEnabled.restype  = bool
1146    return _IsWindowEnabled(hWnd)
1147
1148# BOOL IsZoomed(
1149#     HWND hWnd
1150# );
1151def IsZoomed(hWnd):
1152    _IsZoomed = windll.user32.IsZoomed
1153    _IsZoomed.argtypes = [HWND]
1154    _IsZoomed.restype  = bool
1155    return _IsZoomed(hWnd)
1156
1157# BOOL IsIconic(
1158#     HWND hWnd
1159# );
1160def IsIconic(hWnd):
1161    _IsIconic = windll.user32.IsIconic
1162    _IsIconic.argtypes = [HWND]
1163    _IsIconic.restype  = bool
1164    return _IsIconic(hWnd)
1165
1166# BOOL IsChild(
1167#     HWND hWnd
1168# );
1169def IsChild(hWnd):
1170    _IsChild = windll.user32.IsChild
1171    _IsChild.argtypes = [HWND]
1172    _IsChild.restype  = bool
1173    return _IsChild(hWnd)
1174
1175# HWND WindowFromPoint(
1176#     POINT Point
1177# );
1178def WindowFromPoint(point):
1179    _WindowFromPoint = windll.user32.WindowFromPoint
1180    _WindowFromPoint.argtypes = [POINT]
1181    _WindowFromPoint.restype  = HWND
1182    _WindowFromPoint.errcheck = RaiseIfZero
1183    if isinstance(point, tuple):
1184        point = POINT(*point)
1185    return _WindowFromPoint(point)
1186
1187# HWND ChildWindowFromPoint(
1188#     HWND hWndParent,
1189#     POINT Point
1190# );
1191def ChildWindowFromPoint(hWndParent, point):
1192    _ChildWindowFromPoint = windll.user32.ChildWindowFromPoint
1193    _ChildWindowFromPoint.argtypes = [HWND, POINT]
1194    _ChildWindowFromPoint.restype  = HWND
1195    _ChildWindowFromPoint.errcheck = RaiseIfZero
1196    if isinstance(point, tuple):
1197        point = POINT(*point)
1198    return _ChildWindowFromPoint(hWndParent, point)
1199
1200#HWND RealChildWindowFromPoint(
1201#    HWND hwndParent,
1202#    POINT ptParentClientCoords
1203#);
1204def RealChildWindowFromPoint(hWndParent, ptParentClientCoords):
1205    _RealChildWindowFromPoint = windll.user32.RealChildWindowFromPoint
1206    _RealChildWindowFromPoint.argtypes = [HWND, POINT]
1207    _RealChildWindowFromPoint.restype  = HWND
1208    _RealChildWindowFromPoint.errcheck = RaiseIfZero
1209    if isinstance(ptParentClientCoords, tuple):
1210        ptParentClientCoords = POINT(*ptParentClientCoords)
1211    return _RealChildWindowFromPoint(hWndParent, ptParentClientCoords)
1212
1213# BOOL ScreenToClient(
1214#   __in  HWND hWnd,
1215#         LPPOINT lpPoint
1216# );
1217def ScreenToClient(hWnd, lpPoint):
1218    _ScreenToClient = windll.user32.ScreenToClient
1219    _ScreenToClient.argtypes = [HWND, LPPOINT]
1220    _ScreenToClient.restype  = bool
1221    _ScreenToClient.errcheck = RaiseIfZero
1222
1223    if isinstance(lpPoint, tuple):
1224        lpPoint = POINT(*lpPoint)
1225    else:
1226        lpPoint = POINT(lpPoint.x, lpPoint.y)
1227    _ScreenToClient(hWnd, byref(lpPoint))
1228    return Point(lpPoint.x, lpPoint.y)
1229
1230# BOOL ClientToScreen(
1231#   HWND hWnd,
1232#   LPPOINT lpPoint
1233# );
1234def ClientToScreen(hWnd, lpPoint):
1235    _ClientToScreen = windll.user32.ClientToScreen
1236    _ClientToScreen.argtypes = [HWND, LPPOINT]
1237    _ClientToScreen.restype  = bool
1238    _ClientToScreen.errcheck = RaiseIfZero
1239
1240    if isinstance(lpPoint, tuple):
1241        lpPoint = POINT(*lpPoint)
1242    else:
1243        lpPoint = POINT(lpPoint.x, lpPoint.y)
1244    _ClientToScreen(hWnd, byref(lpPoint))
1245    return Point(lpPoint.x, lpPoint.y)
1246
1247# int MapWindowPoints(
1248#   __in     HWND hWndFrom,
1249#   __in     HWND hWndTo,
1250#   __inout  LPPOINT lpPoints,
1251#   __in     UINT cPoints
1252# );
1253def MapWindowPoints(hWndFrom, hWndTo, lpPoints):
1254    _MapWindowPoints = windll.user32.MapWindowPoints
1255    _MapWindowPoints.argtypes = [HWND, HWND, LPPOINT, UINT]
1256    _MapWindowPoints.restype  = ctypes.c_int
1257
1258    cPoints  = len(lpPoints)
1259    lpPoints = (POINT * cPoints)(* lpPoints)
1260    SetLastError(ERROR_SUCCESS)
1261    number   = _MapWindowPoints(hWndFrom, hWndTo, byref(lpPoints), cPoints)
1262    if number == 0:
1263        errcode = GetLastError()
1264        if errcode != ERROR_SUCCESS:
1265            raise ctypes.WinError(errcode)
1266    x_delta = number & 0xFFFF
1267    y_delta = (number >> 16) & 0xFFFF
1268    return x_delta, y_delta, [ (Point.x, Point.y) for Point in lpPoints ]
1269
1270#BOOL SetForegroundWindow(
1271#    HWND hWnd
1272#);
1273def SetForegroundWindow(hWnd):
1274    _SetForegroundWindow = windll.user32.SetForegroundWindow
1275    _SetForegroundWindow.argtypes = [HWND]
1276    _SetForegroundWindow.restype  = bool
1277    _SetForegroundWindow.errcheck = RaiseIfZero
1278    return _SetForegroundWindow(hWnd)
1279
1280# BOOL GetWindowPlacement(
1281#     HWND hWnd,
1282#     WINDOWPLACEMENT *lpwndpl
1283# );
1284def GetWindowPlacement(hWnd):
1285    _GetWindowPlacement = windll.user32.GetWindowPlacement
1286    _GetWindowPlacement.argtypes = [HWND, PWINDOWPLACEMENT]
1287    _GetWindowPlacement.restype  = bool
1288    _GetWindowPlacement.errcheck = RaiseIfZero
1289
1290    lpwndpl = WINDOWPLACEMENT()
1291    lpwndpl.length = sizeof(lpwndpl)
1292    _GetWindowPlacement(hWnd, byref(lpwndpl))
1293    return WindowPlacement(lpwndpl)
1294
1295# BOOL SetWindowPlacement(
1296#     HWND hWnd,
1297#     WINDOWPLACEMENT *lpwndpl
1298# );
1299def SetWindowPlacement(hWnd, lpwndpl):
1300    _SetWindowPlacement = windll.user32.SetWindowPlacement
1301    _SetWindowPlacement.argtypes = [HWND, PWINDOWPLACEMENT]
1302    _SetWindowPlacement.restype  = bool
1303    _SetWindowPlacement.errcheck = RaiseIfZero
1304
1305    if isinstance(lpwndpl, WINDOWPLACEMENT):
1306        lpwndpl.length = sizeof(lpwndpl)
1307    _SetWindowPlacement(hWnd, byref(lpwndpl))
1308
1309# BOOL WINAPI GetWindowRect(
1310#   __in   HWND hWnd,
1311#   __out  LPRECT lpRect
1312# );
1313def GetWindowRect(hWnd):
1314    _GetWindowRect = windll.user32.GetWindowRect
1315    _GetWindowRect.argtypes = [HWND, LPRECT]
1316    _GetWindowRect.restype  = bool
1317    _GetWindowRect.errcheck = RaiseIfZero
1318
1319    lpRect = RECT()
1320    _GetWindowRect(hWnd, byref(lpRect))
1321    return Rect(lpRect.left, lpRect.top, lpRect.right, lpRect.bottom)
1322
1323# BOOL WINAPI GetClientRect(
1324#   __in   HWND hWnd,
1325#   __out  LPRECT lpRect
1326# );
1327def GetClientRect(hWnd):
1328    _GetClientRect = windll.user32.GetClientRect
1329    _GetClientRect.argtypes = [HWND, LPRECT]
1330    _GetClientRect.restype  = bool
1331    _GetClientRect.errcheck = RaiseIfZero
1332
1333    lpRect = RECT()
1334    _GetClientRect(hWnd, byref(lpRect))
1335    return Rect(lpRect.left, lpRect.top, lpRect.right, lpRect.bottom)
1336
1337#BOOL MoveWindow(
1338#    HWND hWnd,
1339#    int X,
1340#    int Y,
1341#    int nWidth,
1342#    int nHeight,
1343#    BOOL bRepaint
1344#);
1345def MoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint = True):
1346    _MoveWindow = windll.user32.MoveWindow
1347    _MoveWindow.argtypes = [HWND, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, BOOL]
1348    _MoveWindow.restype  = bool
1349    _MoveWindow.errcheck = RaiseIfZero
1350    _MoveWindow(hWnd, X, Y, nWidth, nHeight, bool(bRepaint))
1351
1352# BOOL GetGUIThreadInfo(
1353#     DWORD idThread,
1354#     LPGUITHREADINFO lpgui
1355# );
1356def GetGUIThreadInfo(idThread):
1357    _GetGUIThreadInfo = windll.user32.GetGUIThreadInfo
1358    _GetGUIThreadInfo.argtypes = [DWORD, LPGUITHREADINFO]
1359    _GetGUIThreadInfo.restype  = bool
1360    _GetGUIThreadInfo.errcheck = RaiseIfZero
1361
1362    gui = GUITHREADINFO()
1363    _GetGUIThreadInfo(idThread, byref(gui))
1364    return gui
1365
1366# BOOL CALLBACK EnumWndProc(
1367#     HWND hwnd,
1368#     LPARAM lParam
1369# );
1370class __EnumWndProc (__WindowEnumerator):
1371    pass
1372
1373# BOOL EnumWindows(
1374#     WNDENUMPROC lpEnumFunc,
1375#     LPARAM lParam
1376# );
1377def EnumWindows():
1378    _EnumWindows = windll.user32.EnumWindows
1379    _EnumWindows.argtypes = [WNDENUMPROC, LPARAM]
1380    _EnumWindows.restype  = bool
1381
1382    EnumFunc = __EnumWndProc()
1383    lpEnumFunc = WNDENUMPROC(EnumFunc)
1384    if not _EnumWindows(lpEnumFunc, NULL):
1385        errcode = GetLastError()
1386        if errcode not in (ERROR_NO_MORE_FILES, ERROR_SUCCESS):
1387            raise ctypes.WinError(errcode)
1388    return EnumFunc.hwnd
1389
1390# BOOL CALLBACK EnumThreadWndProc(
1391#     HWND hwnd,
1392#     LPARAM lParam
1393# );
1394class __EnumThreadWndProc (__WindowEnumerator):
1395    pass
1396
1397# BOOL EnumThreadWindows(
1398#     DWORD dwThreadId,
1399#     WNDENUMPROC lpfn,
1400#     LPARAM lParam
1401# );
1402def EnumThreadWindows(dwThreadId):
1403    _EnumThreadWindows = windll.user32.EnumThreadWindows
1404    _EnumThreadWindows.argtypes = [DWORD, WNDENUMPROC, LPARAM]
1405    _EnumThreadWindows.restype  = bool
1406
1407    fn = __EnumThreadWndProc()
1408    lpfn = WNDENUMPROC(fn)
1409    if not _EnumThreadWindows(dwThreadId, lpfn, NULL):
1410        errcode = GetLastError()
1411        if errcode not in (ERROR_NO_MORE_FILES, ERROR_SUCCESS):
1412            raise ctypes.WinError(errcode)
1413    return fn.hwnd
1414
1415# BOOL CALLBACK EnumChildProc(
1416#     HWND hwnd,
1417#     LPARAM lParam
1418# );
1419class __EnumChildProc (__WindowEnumerator):
1420    pass
1421
1422# BOOL EnumChildWindows(
1423#     HWND hWndParent,
1424#     WNDENUMPROC lpEnumFunc,
1425#     LPARAM lParam
1426# );
1427def EnumChildWindows(hWndParent = NULL):
1428    _EnumChildWindows = windll.user32.EnumChildWindows
1429    _EnumChildWindows.argtypes = [HWND, WNDENUMPROC, LPARAM]
1430    _EnumChildWindows.restype  = bool
1431
1432    EnumFunc = __EnumChildProc()
1433    lpEnumFunc = WNDENUMPROC(EnumFunc)
1434    SetLastError(ERROR_SUCCESS)
1435    _EnumChildWindows(hWndParent, lpEnumFunc, NULL)
1436    errcode = GetLastError()
1437    if errcode != ERROR_SUCCESS and errcode not in (ERROR_NO_MORE_FILES, ERROR_SUCCESS):
1438        raise ctypes.WinError(errcode)
1439    return EnumFunc.hwnd
1440
1441# LRESULT SendMessage(
1442#     HWND hWnd,
1443#     UINT Msg,
1444#     WPARAM wParam,
1445#     LPARAM lParam
1446# );
1447def SendMessageA(hWnd, Msg, wParam = 0, lParam = 0):
1448    _SendMessageA = windll.user32.SendMessageA
1449    _SendMessageA.argtypes = [HWND, UINT, WPARAM, LPARAM]
1450    _SendMessageA.restype  = LRESULT
1451
1452    wParam = MAKE_WPARAM(wParam)
1453    lParam = MAKE_LPARAM(lParam)
1454    return _SendMessageA(hWnd, Msg, wParam, lParam)
1455
1456def SendMessageW(hWnd, Msg, wParam = 0, lParam = 0):
1457    _SendMessageW = windll.user32.SendMessageW
1458    _SendMessageW.argtypes = [HWND, UINT, WPARAM, LPARAM]
1459    _SendMessageW.restype  = LRESULT
1460
1461    wParam = MAKE_WPARAM(wParam)
1462    lParam = MAKE_LPARAM(lParam)
1463    return _SendMessageW(hWnd, Msg, wParam, lParam)
1464
1465SendMessage = GuessStringType(SendMessageA, SendMessageW)
1466
1467# BOOL PostMessage(
1468#     HWND hWnd,
1469#     UINT Msg,
1470#     WPARAM wParam,
1471#     LPARAM lParam
1472# );
1473def PostMessageA(hWnd, Msg, wParam = 0, lParam = 0):
1474    _PostMessageA = windll.user32.PostMessageA
1475    _PostMessageA.argtypes = [HWND, UINT, WPARAM, LPARAM]
1476    _PostMessageA.restype  = bool
1477    _PostMessageA.errcheck = RaiseIfZero
1478
1479    wParam = MAKE_WPARAM(wParam)
1480    lParam = MAKE_LPARAM(lParam)
1481    _PostMessageA(hWnd, Msg, wParam, lParam)
1482
1483def PostMessageW(hWnd, Msg, wParam = 0, lParam = 0):
1484    _PostMessageW = windll.user32.PostMessageW
1485    _PostMessageW.argtypes = [HWND, UINT, WPARAM, LPARAM]
1486    _PostMessageW.restype  = bool
1487    _PostMessageW.errcheck = RaiseIfZero
1488
1489    wParam = MAKE_WPARAM(wParam)
1490    lParam = MAKE_LPARAM(lParam)
1491    _PostMessageW(hWnd, Msg, wParam, lParam)
1492
1493PostMessage = GuessStringType(PostMessageA, PostMessageW)
1494
1495# BOOL PostThreadMessage(
1496#     DWORD idThread,
1497#     UINT Msg,
1498#     WPARAM wParam,
1499#     LPARAM lParam
1500# );
1501def PostThreadMessageA(idThread, Msg, wParam = 0, lParam = 0):
1502    _PostThreadMessageA = windll.user32.PostThreadMessageA
1503    _PostThreadMessageA.argtypes = [DWORD, UINT, WPARAM, LPARAM]
1504    _PostThreadMessageA.restype  = bool
1505    _PostThreadMessageA.errcheck = RaiseIfZero
1506
1507    wParam = MAKE_WPARAM(wParam)
1508    lParam = MAKE_LPARAM(lParam)
1509    _PostThreadMessageA(idThread, Msg, wParam, lParam)
1510
1511def PostThreadMessageW(idThread, Msg, wParam = 0, lParam = 0):
1512    _PostThreadMessageW = windll.user32.PostThreadMessageW
1513    _PostThreadMessageW.argtypes = [DWORD, UINT, WPARAM, LPARAM]
1514    _PostThreadMessageW.restype  = bool
1515    _PostThreadMessageW.errcheck = RaiseIfZero
1516
1517    wParam = MAKE_WPARAM(wParam)
1518    lParam = MAKE_LPARAM(lParam)
1519    _PostThreadMessageW(idThread, Msg, wParam, lParam)
1520
1521PostThreadMessage = GuessStringType(PostThreadMessageA, PostThreadMessageW)
1522
1523# LRESULT c(
1524#     HWND hWnd,
1525#     UINT Msg,
1526#     WPARAM wParam,
1527#     LPARAM lParam,
1528#     UINT fuFlags,
1529#     UINT uTimeout,
1530#     PDWORD_PTR lpdwResult
1531# );
1532def SendMessageTimeoutA(hWnd, Msg, wParam = 0, lParam = 0, fuFlags = 0, uTimeout = 0):
1533    _SendMessageTimeoutA = windll.user32.SendMessageTimeoutA
1534    _SendMessageTimeoutA.argtypes = [HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR]
1535    _SendMessageTimeoutA.restype  = LRESULT
1536    _SendMessageTimeoutA.errcheck = RaiseIfZero
1537
1538    wParam = MAKE_WPARAM(wParam)
1539    lParam = MAKE_LPARAM(lParam)
1540    dwResult = DWORD(0)
1541    _SendMessageTimeoutA(hWnd, Msg, wParam, lParam, fuFlags, uTimeout, byref(dwResult))
1542    return dwResult.value
1543
1544def SendMessageTimeoutW(hWnd, Msg, wParam = 0, lParam = 0):
1545    _SendMessageTimeoutW = windll.user32.SendMessageTimeoutW
1546    _SendMessageTimeoutW.argtypes = [HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR]
1547    _SendMessageTimeoutW.restype  = LRESULT
1548    _SendMessageTimeoutW.errcheck = RaiseIfZero
1549
1550    wParam = MAKE_WPARAM(wParam)
1551    lParam = MAKE_LPARAM(lParam)
1552    dwResult = DWORD(0)
1553    _SendMessageTimeoutW(hWnd, Msg, wParam, lParam, fuFlags, uTimeout, byref(dwResult))
1554    return dwResult.value
1555
1556SendMessageTimeout = GuessStringType(SendMessageTimeoutA, SendMessageTimeoutW)
1557
1558# BOOL SendNotifyMessage(
1559#     HWND hWnd,
1560#     UINT Msg,
1561#     WPARAM wParam,
1562#     LPARAM lParam
1563# );
1564def SendNotifyMessageA(hWnd, Msg, wParam = 0, lParam = 0):
1565    _SendNotifyMessageA = windll.user32.SendNotifyMessageA
1566    _SendNotifyMessageA.argtypes = [HWND, UINT, WPARAM, LPARAM]
1567    _SendNotifyMessageA.restype  = bool
1568    _SendNotifyMessageA.errcheck = RaiseIfZero
1569
1570    wParam = MAKE_WPARAM(wParam)
1571    lParam = MAKE_LPARAM(lParam)
1572    _SendNotifyMessageA(hWnd, Msg, wParam, lParam)
1573
1574def SendNotifyMessageW(hWnd, Msg, wParam = 0, lParam = 0):
1575    _SendNotifyMessageW = windll.user32.SendNotifyMessageW
1576    _SendNotifyMessageW.argtypes = [HWND, UINT, WPARAM, LPARAM]
1577    _SendNotifyMessageW.restype  = bool
1578    _SendNotifyMessageW.errcheck = RaiseIfZero
1579
1580    wParam = MAKE_WPARAM(wParam)
1581    lParam = MAKE_LPARAM(lParam)
1582    _SendNotifyMessageW(hWnd, Msg, wParam, lParam)
1583
1584SendNotifyMessage = GuessStringType(SendNotifyMessageA, SendNotifyMessageW)
1585
1586# LRESULT SendDlgItemMessage(
1587#     HWND hDlg,
1588#     int nIDDlgItem,
1589#     UINT Msg,
1590#     WPARAM wParam,
1591#     LPARAM lParam
1592# );
1593def SendDlgItemMessageA(hDlg, nIDDlgItem, Msg, wParam = 0, lParam = 0):
1594    _SendDlgItemMessageA = windll.user32.SendDlgItemMessageA
1595    _SendDlgItemMessageA.argtypes = [HWND, ctypes.c_int, UINT, WPARAM, LPARAM]
1596    _SendDlgItemMessageA.restype  = LRESULT
1597
1598    wParam = MAKE_WPARAM(wParam)
1599    lParam = MAKE_LPARAM(lParam)
1600    return _SendDlgItemMessageA(hDlg, nIDDlgItem, Msg, wParam, lParam)
1601
1602def SendDlgItemMessageW(hDlg, nIDDlgItem, Msg, wParam = 0, lParam = 0):
1603    _SendDlgItemMessageW = windll.user32.SendDlgItemMessageW
1604    _SendDlgItemMessageW.argtypes = [HWND, ctypes.c_int, UINT, WPARAM, LPARAM]
1605    _SendDlgItemMessageW.restype  = LRESULT
1606
1607    wParam = MAKE_WPARAM(wParam)
1608    lParam = MAKE_LPARAM(lParam)
1609    return _SendDlgItemMessageW(hDlg, nIDDlgItem, Msg, wParam, lParam)
1610
1611SendDlgItemMessage = GuessStringType(SendDlgItemMessageA, SendDlgItemMessageW)
1612
1613# DWORD WINAPI WaitForInputIdle(
1614#   _In_  HANDLE hProcess,
1615#   _In_  DWORD dwMilliseconds
1616# );
1617def WaitForInputIdle(hProcess, dwMilliseconds = INFINITE):
1618    _WaitForInputIdle = windll.user32.WaitForInputIdle
1619    _WaitForInputIdle.argtypes = [HANDLE, DWORD]
1620    _WaitForInputIdle.restype  = DWORD
1621
1622    r = _WaitForInputIdle(hProcess, dwMilliseconds)
1623    if r == WAIT_FAILED:
1624        raise ctypes.WinError()
1625    return r
1626
1627# UINT RegisterWindowMessage(
1628#     LPCTSTR lpString
1629# );
1630def RegisterWindowMessageA(lpString):
1631    _RegisterWindowMessageA = windll.user32.RegisterWindowMessageA
1632    _RegisterWindowMessageA.argtypes = [LPSTR]
1633    _RegisterWindowMessageA.restype  = UINT
1634    _RegisterWindowMessageA.errcheck = RaiseIfZero
1635    return _RegisterWindowMessageA(lpString)
1636
1637def RegisterWindowMessageW(lpString):
1638    _RegisterWindowMessageW = windll.user32.RegisterWindowMessageW
1639    _RegisterWindowMessageW.argtypes = [LPWSTR]
1640    _RegisterWindowMessageW.restype  = UINT
1641    _RegisterWindowMessageW.errcheck = RaiseIfZero
1642    return _RegisterWindowMessageW(lpString)
1643
1644RegisterWindowMessage = GuessStringType(RegisterWindowMessageA, RegisterWindowMessageW)
1645
1646# UINT RegisterClipboardFormat(
1647#     LPCTSTR lpString
1648# );
1649def RegisterClipboardFormatA(lpString):
1650    _RegisterClipboardFormatA = windll.user32.RegisterClipboardFormatA
1651    _RegisterClipboardFormatA.argtypes = [LPSTR]
1652    _RegisterClipboardFormatA.restype  = UINT
1653    _RegisterClipboardFormatA.errcheck = RaiseIfZero
1654    return _RegisterClipboardFormatA(lpString)
1655
1656def RegisterClipboardFormatW(lpString):
1657    _RegisterClipboardFormatW = windll.user32.RegisterClipboardFormatW
1658    _RegisterClipboardFormatW.argtypes = [LPWSTR]
1659    _RegisterClipboardFormatW.restype  = UINT
1660    _RegisterClipboardFormatW.errcheck = RaiseIfZero
1661    return _RegisterClipboardFormatW(lpString)
1662
1663RegisterClipboardFormat = GuessStringType(RegisterClipboardFormatA, RegisterClipboardFormatW)
1664
1665# HANDLE WINAPI GetProp(
1666#   __in  HWND hWnd,
1667#   __in  LPCTSTR lpString
1668# );
1669def GetPropA(hWnd, lpString):
1670    _GetPropA = windll.user32.GetPropA
1671    _GetPropA.argtypes = [HWND, LPSTR]
1672    _GetPropA.restype  = HANDLE
1673    return _GetPropA(hWnd, lpString)
1674
1675def GetPropW(hWnd, lpString):
1676    _GetPropW = windll.user32.GetPropW
1677    _GetPropW.argtypes = [HWND, LPWSTR]
1678    _GetPropW.restype  = HANDLE
1679    return _GetPropW(hWnd, lpString)
1680
1681GetProp = GuessStringType(GetPropA, GetPropW)
1682
1683# BOOL WINAPI SetProp(
1684#   __in      HWND hWnd,
1685#   __in      LPCTSTR lpString,
1686#   __in_opt  HANDLE hData
1687# );
1688def SetPropA(hWnd, lpString, hData):
1689    _SetPropA = windll.user32.SetPropA
1690    _SetPropA.argtypes = [HWND, LPSTR, HANDLE]
1691    _SetPropA.restype  = BOOL
1692    _SetPropA.errcheck = RaiseIfZero
1693    _SetPropA(hWnd, lpString, hData)
1694
1695def SetPropW(hWnd, lpString, hData):
1696    _SetPropW = windll.user32.SetPropW
1697    _SetPropW.argtypes = [HWND, LPWSTR, HANDLE]
1698    _SetPropW.restype  = BOOL
1699    _SetPropW.errcheck = RaiseIfZero
1700    _SetPropW(hWnd, lpString, hData)
1701
1702SetProp = GuessStringType(SetPropA, SetPropW)
1703
1704# HANDLE WINAPI RemoveProp(
1705#   __in  HWND hWnd,
1706#   __in  LPCTSTR lpString
1707# );
1708def RemovePropA(hWnd, lpString):
1709    _RemovePropA = windll.user32.RemovePropA
1710    _RemovePropA.argtypes = [HWND, LPSTR]
1711    _RemovePropA.restype  = HANDLE
1712    return _RemovePropA(hWnd, lpString)
1713
1714def RemovePropW(hWnd, lpString):
1715    _RemovePropW = windll.user32.RemovePropW
1716    _RemovePropW.argtypes = [HWND, LPWSTR]
1717    _RemovePropW.restype  = HANDLE
1718    return _RemovePropW(hWnd, lpString)
1719
1720RemoveProp = GuessStringType(RemovePropA, RemovePropW)
1721
1722#==============================================================================
1723# This calculates the list of exported symbols.
1724_all = set(vars().keys()).difference(_all)
1725__all__ = [_x for _x in _all if not _x.startswith('_')]
1726__all__.sort()
1727#==============================================================================
1728