home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 February / maximum-cd-2011-02.iso / DiscContents / digsby_setup85.exe / lib / gui / native / win / windocking.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-11-24  |  22.9 KB  |  690 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. from gui.native.win.dockconstants import WM_EXITSIZEMOVE, WM_WINDOWPOSCHANGING, WM_SIZING, WM_NCHITTEST, WM_SYSCOMMAND, WM_USER, ABE_LEFT, ABE_RIGHT, ABM_REMOVE, SC_MAXIMIZE, SC_MINIMIZE, HTBOTTOMLEFT, HTLEFT, HTTOPLEFT, HTBOTTOMRIGHT, HTRIGHT, HTTOPRIGHT, SC_SIZE, ABM_SETPOS, WMSZ_LEFT, WMSZ_RIGHT, ABM_SETAUTOHIDEBAR, sideStrings, ABM_NEW, SWP_NOACTIVATE, SWP_NOMOVE, SWP_NOSIZE, ABM_GETSTATE, ABS_ALWAYSONTOP, HWND_BOTTOM, HWND_TOPMOST, ABE_TOP, ABE_BOTTOM, ABM_QUERYPOS, ABN_STATECHANGE, ABN_FULLSCREENAPP, ABN_POSCHANGED, ABN_WINDOWARRANGE, ABS_AUTOHIDE
  5. import ctypes
  6. import wx
  7. from wx import PyTimer
  8. from ctypes import c_uint, Structure, byref, c_int, POINTER, cast
  9. from logging import getLogger
  10. log = getLogger('dock')
  11. from gui.toolbox import Monitor
  12. from util.primitives.funcs import Delegate
  13. from util import default_timer
  14. from gui.native.win.winextensions import wxRectToRECT
  15. from ctypes.wintypes import DWORD, HANDLE, LPARAM, RECT
  16. user32 = ctypes.windll.user32
  17. SetWindowPos = user32.SetWindowPos
  18. MoveWindow = user32.MoveWindow
  19. shell32_SHAppBarMessage = ctypes.windll.shell32.SHAppBarMessage
  20. CallWindowProc = ctypes.windll.user32.CallWindowProcW
  21. DefWindowProc = ctypes.windll.user32.DefWindowProcW
  22.  
  23. def SHAppBarMessage(msg, abd):
  24.     return shell32_SHAppBarMessage(msg, byref(abd))
  25.  
  26. ANIMATE_SECS = 0.1
  27. AUTOHIDE_TIMER_MS = 130
  28. ANIMATE_DELTA = 6
  29. UNKNOWN_MAX_FLAG = 61490
  30.  
  31. sign = lambda v: if v > 0:
  32. 1if v < 0:
  33. -10
  34.  
  35. class Docker(object):
  36.     
  37.     def __init__(self, win, autohide = False, enabled = True):
  38.         self.win = win
  39.         self._side = None
  40.         self.DockMargin = 30
  41.         
  42.         self.ShouldShowInTaskbar = lambda : True
  43.         self.ShouldAlwaysStayOnTop = None
  44.         self.RevealDurationMs = 300
  45.         self.Animate = True
  46.         self.autohidden = self.docking = self.docked = False
  47.         self._enabled = enabled
  48.         self._autohide = autohide
  49.         self.bypassSizeEvents = False
  50.         self.bypassMoveEvents = False
  51.         self.reReserveTimer = None
  52.         Bind = win.Bind
  53.         BindWin32 = win.BindWin32
  54.         Bind(wx.EVT_MOVING, self.OnMoving)
  55.         Bind(wx.EVT_CLOSE, self.OnClose)
  56.         Bind(wx.EVT_ACTIVATE, self.OnActivate)
  57.         Bind(wx.EVT_DISPLAY_CHANGED, self.OnDisplayChanged)
  58.         Bind(wx.EVT_SHOW, self.OnShow)
  59.         BindWin32(WM_WINDOWPOSCHANGING, self.OnWindowPosChanging)
  60.         BindWin32(WM_EXITSIZEMOVE, self.OnExitSizeMove)
  61.         BindWin32(WM_SIZING, self.OnSizing)
  62.         BindWin32(WM_NCHITTEST, self.OnNCHitTest)
  63.         BindWin32(WM_SYSCOMMAND, self.OnSysCommand)
  64.         self.appbar_cb_id = WM_USER + 100
  65.         BindWin32(self.appbar_cb_id, self.AppBarCallback)
  66.         self.firstShow = True
  67.         self.wasDocked = False
  68.         self.oldSize = None
  69.         self.motiontrigger = False
  70.         self.timer = PyTimer(self.OnTimer)
  71.         self.OnDock = Delegate()
  72.         self.OnHide = Delegate()
  73.         self.LinkedWindows = []
  74.  
  75.     
  76.     def __repr__(self):
  77.         return '<Docker for %r>' % self.win
  78.  
  79.     
  80.     def GetSide(self):
  81.         if self._side == None:
  82.             pos = self.win.Rect
  83.             margin = self.DockMargin
  84.             screenRect = monitor_rect(self.win)
  85.             if pos.x < screenRect.X + margin and pos.Right > screenRect.X:
  86.                 self._side = ABE_LEFT
  87.             
  88.             if pos.Right > screenRect.Right - margin and pos.x < screenRect.Right:
  89.                 self._side = ABE_RIGHT
  90.             
  91.         
  92.         return self._side
  93.  
  94.     
  95.     def SetSide(self, side):
  96.         self._side = side
  97.  
  98.     side = property(GetSide, SetSide)
  99.     
  100.     def OnDisplayChanged(self, event):
  101.         log.debug('OnDisplayChanged')
  102.         if self.docked and not (self.AutoHide):
  103.             self.Undock(setFrameStyle = False)
  104.             self.win.FitInScreen(Monitor.GetFromDeviceId(self.monId))
  105.             self.Dock(setFrameStyle = False)
  106.             self.bypassMoveEvents = True
  107.             self.win.SetRect(self.dockedRect)
  108.             self.bypassMoveEvents = False
  109.             self.docking = True
  110.             self.docked = False
  111.             self.OnExitSizeMove()
  112.         elif self.docked and self.AutoHide:
  113.             onRight = self.side == ABE_RIGHT
  114.             mon = Monitor.GetFromDeviceId(self.monId)
  115.             monRect = mon.ClientArea
  116.             xPos = None if onRight else monRect.Left - 1
  117.             while onscreen(xPos, monRect.Y):
  118.                 mon = Monitor.GetFromPoint((xPos, monRect.Y))
  119.                 monRect = mon.ClientArea
  120.                 xPos = None if onRight else monRect.Left - 1
  121.             if onRight:
  122.                 self.dockedRect = wx.Rect((monRect.Right - self.win.Size.width) + 1, monRect.Top, self.win.Size.width, monRect.Bottom - monRect.Top)
  123.             else:
  124.                 self.dockedRect = wx.Rect(monRect.left - 1, monRect.Top, self.win.Size.width, monRect.Bottom - monRect.Top)
  125.             self.bypassMoveEvents = True
  126.             self.win.SetRect(self.dockedRect)
  127.             self.bypassMoveEvents = False
  128.             self.GoAway(monRect)
  129.         
  130.         event.Skip()
  131.  
  132.     
  133.     def OnShow(self, event):
  134.         event.Skip()
  135.         if not self.win.Shown:
  136.             return None
  137.         onRight = self.side == ABE_RIGHT
  138.         mon = Monitor.GetFromWindow(self.win)
  139.         monRect = mon.ClientArea
  140.         atEdge = not self.win.Shown(onscreen if onRight else monRect.Left - 1, monRect.Y)
  141.         if not self.wasDocked and self.firstShow and atEdge:
  142.             pass
  143.         shouldDock = not (self.AutoHide)
  144.         if self.Enabled and shouldDock and self.side is not None and not (self.docked):
  145.             self.Dock(setFrameStyle = self.firstShow)
  146.             self.firstShow = False
  147.             self.bypassMoveEvents = True
  148.             self.win.SetRect(self.dockedRect)
  149.             self.bypassMoveEvents = False
  150.             self.docking = True
  151.             self.docked = False
  152.             self.OnExitSizeMove()
  153.         elif self.firstShow:
  154.             self.firstShow = False
  155.         
  156.         self.wasDocked = False
  157.  
  158.     
  159.     def SetEnabled(self, val):
  160.         if not isinstance(val, bool):
  161.             raise TypeError('Enabled must be a boolean')
  162.         isinstance(val, bool)
  163.         self._enabled = val
  164.         if not val and self.docked:
  165.             self.Undock()
  166.             p = self.dockedRect[:2]
  167.             self.docking = self.docked = self.autohidden = False
  168.             wx.CallLater(50, self.SetRectSimple, wx.Rect(p[0], p[1], *wx.Size(*self.oldSize)))
  169.             self.UpdateTaskbar()
  170.         elif val and not (self.docked) and self.win.IsShownOnScreen():
  171.             self.docking = False
  172.             if self.OnMoving():
  173.                 self.OnExitSizeMove()
  174.                 if self.AutoHide:
  175.                     self.timer.Start(AUTOHIDE_TIMER_MS)
  176.                     self.motiontrigger = False
  177.                 
  178.                 self.win.SetRect(self.dockedRect)
  179.             
  180.         elif self.wasDocked:
  181.             SetToolStyle(self.win, val)
  182.             self.bypassMoveEvents = True
  183.             if val:
  184.                 self.win.Rect = self.dockedRect
  185.             else:
  186.                 self.win.Rect = wx.RectPS(self.dockedRect.Position, self.oldSize)
  187.             self.bypassMoveEvents = False
  188.             self.UpdateTaskbar()
  189.         
  190.         if not val:
  191.             self.oldSize = None
  192.         
  193.  
  194.     Enabled = property((lambda self: self._enabled), SetEnabled, None, 'Set this boolean property to enable or disable docking')
  195.     
  196.     def SetAutoHide(self, val):
  197.         log.debug('SetAutoHide')
  198.         if self.Enabled and self.docked:
  199.             self.Undock(setFrameStyle = False)
  200.             self._autohide = val
  201.             self.Dock(setFrameStyle = False)
  202.             self.docking = True
  203.             self.docked = False
  204.             self.OnExitSizeMove()
  205.             if not val:
  206.                 self.ComeBack()
  207.             
  208.             self.UpdateTaskbar()
  209.         else:
  210.             self._autohide = val
  211.  
  212.     AutoHide = property((lambda self: self._autohide), SetAutoHide, None, 'Set this boolean property to enable or disable autohiding.')
  213.     
  214.     def SetRectSimple(self, rect):
  215.         self.bypassMoveEvents = True
  216.         self.win.SetRect(rect)
  217.         self.bypassMoveEvents = False
  218.  
  219.     
  220.     def OnTimer(self, e = None):
  221.         if not self.Enabled and self.AutoHide and self.docked:
  222.             return None
  223.         w = self.win
  224.         mp = wx.GetMousePosition()
  225.         if w and not (self.motiontrigger) and not w.IsActive():
  226.             if not (any,)((lambda .0: for r in .0:
  227. r.Contains(mp))((lambda .0: for w in .0:
  228. w.ScreenRect)([
  229.                 w] + self.LinkedWindows))):
  230.                 self.GoAway()
  231.             
  232.         
  233.  
  234.     
  235.     def GoAway(self, rect = None):
  236.         log.debug('GoAway')
  237.         w = self.win
  238.         r = None if rect else monitor_rect(w)
  239.         margin = 1
  240.         if self.side == ABE_LEFT:
  241.             x = (r.X - w.Rect.width) + margin
  242.             y = r.Y
  243.         elif self.side == ABE_RIGHT:
  244.             x = r.Right - margin
  245.             y = r.Y
  246.         
  247.         self.motiontrigger = True
  248.         self.autohidden = True
  249.         self.timer.Stop()
  250.         self.OnHide()
  251.         self.AnimateWindowTo(wx.Rect(x, y, *w.Size))
  252.         self.SetWinAlwaysOnTop(True)
  253.  
  254.     
  255.     def ComeBack(self):
  256.         log.debug('ComeBack')
  257.         self.motiontrigger = False
  258.         self.AnimateWindowTo(self.dockedRect)
  259.         self.autohidden = False
  260.         self.timer.Start(AUTOHIDE_TIMER_MS)
  261.  
  262.     
  263.     def SetVelocity(self, v):
  264.         self._velocity = v
  265.  
  266.     velocity = property((lambda self: self._velocity), SetVelocity)
  267.     animateToTarget = None
  268.     lasttick = None
  269.     
  270.     def AnimateWindowTo(self, r = None):
  271.         now = default_timer()
  272.         if r is not None:
  273.             self.animateToTarget = r
  274.             self.lasttick = now
  275.         
  276.         (targetx, y) = self.animateToTarget[:2]
  277.         win = self.win
  278.         winx = win.Position.x
  279.         direction = sign(targetx - win.Position.x)
  280.         delta = int((now - self.lasttick) * self.velocity) * direction
  281.         self.bypassMoveEvents = True
  282.         if winx != targetx and self.Animate:
  283.             if delta:
  284.                 newx = winx + delta
  285.                 if (targetx >= winx) != (targetx >= newx):
  286.                     newx = targetx
  287.                 
  288.                 win.Move((newx, y))
  289.                 self.lasttick = now
  290.             
  291.             wx.CallLater(15, self.AnimateWindowTo)
  292.         elif winx != targetx:
  293.             win.SetRect(r)
  294.         
  295.         self.bypassMoveEvents = False
  296.  
  297.     
  298.     def OnClose(self, e):
  299.         log.info('OnClose: %r', e.EventObject)
  300.         if self.Enabled and self.docked:
  301.             if self.AutoHide:
  302.                 return self.GoAway()
  303.             SHAppBarMessage(ABM_REMOVE, self.newAppBarData)
  304.         
  305.         e.Skip(True)
  306.  
  307.     
  308.     def OnActivate(self, e):
  309.         if not (self.Enabled) and not (self.AutoHide) and not (self.docked) or not (self.autohidden):
  310.             return None
  311.         if e.GetActive():
  312.             if not onscreen(*self.win.Position):
  313.                 self.ComeBack()
  314.                 self.win.Raise()
  315.             
  316.         else:
  317.             self.timer.Start(AUTOHIDE_TIMER_MS)
  318.         e.Skip()
  319.  
  320.     
  321.     def OnSysCommand(self, hWnd, msg, wParam, lParam):
  322.         if self.Enabled and self.docked:
  323.             if msg == WM_SYSCOMMAND and wParam in (UNKNOWN_MAX_FLAG, SC_MINIMIZE, SC_MAXIMIZE):
  324.                 return False
  325.         
  326.  
  327.     
  328.     def autohidden_mouseover(self):
  329.         if self.Enabled and self.autohidden and self.motiontrigger and wx.FindWindowAtPointer() is self.win:
  330.             self.ComeBack()
  331.         
  332.  
  333.     
  334.     def OnNCHitTest(self, hWnd, msg, wParam, lParam):
  335.         if self.Enabled and self.motiontrigger:
  336.             ms = wx.GetMouseState()
  337.             if ms.LeftDown():
  338.                 self.bypassSizeEvents = True
  339.             elif self.bypassSizeEvents:
  340.                 self.bypassSizeEvents = False
  341.             
  342.             
  343.             try:
  344.                 t = self.autohidden_timer
  345.             except AttributeError:
  346.                 t = self.autohidden_timer = wx.PyTimer(self.autohidden_mouseover)
  347.  
  348.             if not t.IsRunning():
  349.                 t.StartOneShot(self.RevealDurationMs)
  350.             
  351.         elif self.Enabled and self.docked:
  352.             hit = DefWindowProc(hWnd, msg, wParam, lParam)
  353.             if (self.side == ABE_LEFT or hit in (HTLEFT, HTTOPLEFT, HTBOTTOMLEFT) or self.side == ABE_RIGHT) and hit in (HTRIGHT, HTTOPRIGHT, HTBOTTOMRIGHT):
  354.                 return False
  355.         
  356.  
  357.     
  358.     def OnExitSizeMove(self, hWnd = 0, msg = 0, wParam = 0, lParam = 0):
  359.         log.debug('SC_SIZE: %s', SC_SIZE)
  360.         log.debug('OnExitSizeMove %s %s %s', msg, wParam, lParam)
  361.         if not self.Enabled:
  362.             return None
  363.         if self.docking and not (self.docked):
  364.             self.docking = False
  365.             self.docked = True
  366.             self.AppBarQuerySetPos(set = True)
  367.         
  368.         if self.docked and not (self.AutoHide):
  369.             abd = self.GetNewAppBarData()
  370.             abd.rc = wxRectToRECT(self.dockedRect)
  371.             SHAppBarMessage(ABM_SETPOS, abd)
  372.         
  373.         if not self.docked:
  374.             self.oldSize = None
  375.         
  376.         self.UpdateTaskbar()
  377.  
  378.     
  379.     def UpdateTaskbar(self):
  380.         log.debug('UpdateTaskbar')
  381.         ontaskbar = self.win.OnTaskbar
  382.         if ontaskbar and self.docked:
  383.             log.debug('Hide Task')
  384.             self.win.OnTaskbar = False
  385.         else:
  386.             should = self.ShouldShowInTaskbar()
  387.             if should and not ontaskbar and not (self.docked):
  388.                 log.debug('Show Task')
  389.                 self.win.OnTaskbar = True
  390.             
  391.  
  392.     
  393.     def OnSizing(self, hWnd, msg, wParam, lParam):
  394.         if not self.Enabled and self.docked:
  395.             return None
  396.         
  397.         try:
  398.             if self._Docker__sizing:
  399.                 return None
  400.         except AttributeError:
  401.             self.docked
  402.             self.docked
  403.         except:
  404.             self.docked
  405.  
  406.         side = self.side
  407.         if not (self.bypassSizeEvents):
  408.             if (side == ABE_LEFT or wParam == WMSZ_RIGHT or side == ABE_RIGHT) and wParam == WMSZ_LEFT:
  409.                 log.debug('Docked sizing')
  410.                 r = wx.Rect.FromRECT(RECT.from_address(lParam))
  411.                 self._Docker__sizing = True
  412.                 self.dockedRect = r
  413.                 self.oldSize.width = r.width
  414.                 self._Docker__sizing = False
  415.             else:
  416.                 log.debug('Resize restricted')
  417.                 d = self.dockedRect
  418.                 r = RECT.from_address(lParam)
  419.                 r.x = d.x
  420.                 r.y = d.y
  421.                 r.right = d.x + d.width
  422.                 r.bottom = d.y + d.height
  423.                 return False
  424.             return self.docked
  425.  
  426.     
  427.     def OnWindowPosChanging(self, hWnd, msg, wParam, lParam):
  428.         if not self.Enabled:
  429.             return None
  430.         if not self.bypassMoveEvents:
  431.             mon = monitor_rect(self.win)
  432.             margin = self.DockMargin
  433.             pos = cast(lParam, POINTER(c_int))
  434.             (x, y, w, h) = pos[2:6]
  435.             if self.docked or self.docking:
  436.                 if not self.side == ABE_LEFT or x > mon.X + margin:
  437.                     pass
  438.                 awayFromLeft = x + w < mon.X
  439.                 if not self.side == ABE_RIGHT or x + w < mon.Right - margin:
  440.                     pass
  441.                 awayFromRight = x > mon.Right
  442.                 notResized = y + h != self.dockedRect.Bottom + 1
  443.                 if (awayFromLeft or awayFromRight) and notResized:
  444.                     return None
  445.                 for i, j in enumerate(xrange(2, 6)):
  446.                     pos[j] = self.dockedRect[i]
  447.                 
  448.             elif self.oldSize:
  449.                 pos[4] = self.oldSize.width
  450.                 pos[5] = self.oldSize.height
  451.             
  452.         
  453.  
  454.     
  455.     def OnMoving(self, e = None):
  456.         if e:
  457.             e.Skip(True)
  458.         
  459.         if not self.Enabled:
  460.             return None
  461.         pos = self.win.Rect
  462.         margin = self.DockMargin
  463.         rect = monitor_rect(self.win)
  464.         if not (self.docked) and not (self.docking):
  465.             if pos.Right > rect.Right - margin and pos.x < rect.Right:
  466.                 isOnScreen = isRectOnScreen(wx.Rect(rect.Right + 1, rect.Top, 1, rect.Height))
  467.                 if not (self.AutoHide) or not isOnScreen:
  468.                     return self.Dock(ABE_RIGHT)
  469.             elif pos.x < rect.X + margin and pos.Right > rect.X:
  470.                 isOnScreen = isRectOnScreen(wx.Rect(rect.X - 1, rect.Top, 1, rect.Height))
  471.                 if not (self.AutoHide) or not isOnScreen:
  472.                     return self.Dock(ABE_LEFT)
  473.             
  474.         elif self.side == ABE_LEFT or pos.x > rect.X + margin or pos.Right < rect.X:
  475.             self.Undock()
  476.         elif self.side == ABE_RIGHT or pos.Right < rect.Right - margin or pos.x > rect.Right:
  477.             self.Undock()
  478.         
  479.  
  480.     
  481.     def Dock(self, side = None, setFrameStyle = True):
  482.         log.debug('Dock')
  483.         self.monId = Monitor.GetFromWindow(self.win).DeviceId
  484.         if side is not None:
  485.             self.side = side
  486.         
  487.         if self.AutoHide:
  488.             if SHAppBarMessage(ABM_SETAUTOHIDEBAR, self.GetNewAppBarData(True)):
  489.                 log.info('registered autohide %s', sideStrings[self.side])
  490.                 if setFrameStyle:
  491.                     SetToolStyle(self.win, True)
  492.                 
  493.                 self.SetWinAlwaysOnTop(True)
  494.                 if self.oldSize is None:
  495.                     self.oldSize = self.win.Size
  496.                 
  497.                 self.SetAutoHidePos()
  498.                 self.timer.Start(AUTOHIDE_TIMER_MS)
  499.                 self.autohidden = False
  500.                 self.OnDock(True)
  501.                 return True
  502.             log.warning('obtaining autohide bar failed')
  503.         
  504.         if SHAppBarMessage(ABM_NEW, self.newAppBarData):
  505.             if not self.oldSize:
  506.                 pass
  507.             self.oldSize = self.win.Size
  508.             if setFrameStyle:
  509.                 SetToolStyle(self.win, True)
  510.             
  511.             self.AppBarQuerySetPos(set = False)
  512.             self.OnDock(True)
  513.             return True
  514.  
  515.     
  516.     def Undock(self, setFrameStyle = True):
  517.         log.debug('Undock')
  518.         if setFrameStyle:
  519.             SetToolStyle(self.win, False)
  520.         
  521.         if self.AutoHide:
  522.             SHAppBarMessage(ABM_SETAUTOHIDEBAR, self.newAppBarData)
  523.         
  524.         SHAppBarMessage(ABM_REMOVE, self.newAppBarData)
  525.         self.docking = self.docked = False
  526.         self.OnDock(False)
  527.         self.autohidden = False
  528.         self.SetWinAlwaysOnTop()
  529.  
  530.     winPosArgs = (0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE)
  531.     
  532.     def OnAppBarStateChange(self, wParam, lParam):
  533.         log.info('OnAppBarStateChange')
  534.         state = SHAppBarMessage(ABM_GETSTATE, self.newAppBarData)
  535.         None(SetWindowPos, self.Handle if ABS_ALWAYSONTOP & state else HWND_BOTTOM, *self.winPosArgs)
  536.  
  537.     
  538.     def OnAppBarFullscreenApp(self, wParam, lParam):
  539.         log.info('OnAppBarFullscreenApp')
  540.         state = SHAppBarMessage(ABM_GETSTATE, self.newAppBarData)
  541.         if lParam:
  542.             None(SetWindowPos, self.Handle if ABS_ALWAYSONTOP & state else HWND_BOTTOM, *self.winPosArgs)
  543.         elif state & ABS_ALWAYSONTOP:
  544.             SetWindowPos(self.Handle, HWND_TOPMOST, *self.winPosArgs)
  545.         
  546.  
  547.     
  548.     def OnAppBarPosChanged(self, wParam, lParam):
  549.         log.info('OnAppBarPosChanged')
  550.         rc = RECT()
  551.         mon = monitor_rect(self.win)
  552.         rc.top = mon.Top
  553.         rc.left = mon.Left
  554.         rc.right = mon.Right
  555.         rc.bottom = mon.Bototm
  556.         winrect = self.win.Rect
  557.         iHeight = winrect.Bottom - winrect.Top
  558.         iWidth = winrect.Right - winrect.Left
  559.         if self.side == ABE_TOP:
  560.             rc.bottom = rc.top + iHeight
  561.         elif self.side == ABE_BOTTOM:
  562.             rc.top = rc.bottom - iHeight
  563.         elif self.side == ABE_LEFT:
  564.             rc.right = rc.left + iWidth
  565.         elif self.side == ABE_RIGHT:
  566.             rc.left = rc.right - iWidth
  567.         
  568.  
  569.     
  570.     def GetDockRect(self, rect = None):
  571.         abd = self.newAppBarData
  572.         mon = monitor_rect(self.win)
  573.         if self.side in (ABE_LEFT, ABE_RIGHT):
  574.             r = None if rect is None else rect
  575.             winWidth = r.Width
  576.             abd.rc.left = None if self.side == ABE_LEFT else (mon.Right - r.Width) + 1
  577.             abd.rc.right = None if self.side == ABE_LEFT else mon.Right + 1
  578.         
  579.         abd.rc.top = mon.Top
  580.         abd.rc.bottom = mon.Bottom + 1
  581.         return (abd, winWidth)
  582.  
  583.     
  584.     def SetAutoHidePos(self):
  585.         (abd, unused_winWidth) = self.GetDockRect()
  586.         rc = abd.rc
  587.         self.dockedRect = wx.Rect(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top)
  588.         self.docking = True
  589.  
  590.     
  591.     def AppBarQuerySetPos(self, set = True):
  592.         side = self.side
  593.         (appBarData, winWidth) = self.GetDockRect()
  594.         if not set:
  595.             SHAppBarMessage(ABM_QUERYPOS, appBarData)
  596.         
  597.         if side == ABE_LEFT:
  598.             appBarData.rc.right = appBarData.rc.left + winWidth
  599.         elif side == ABE_RIGHT:
  600.             appBarData.rc.left = appBarData.rc.right - winWidth
  601.         
  602.         if set:
  603.             SHAppBarMessage(ABM_SETPOS, appBarData)
  604.         
  605.         rc = appBarData.rc
  606.         self.dockedRect = wx.Rect(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top)
  607.         self.docking = True
  608.  
  609.     
  610.     def OnAppBarWindowArrange(self, wParam, lParam):
  611.         log.info('OnAppBarWindowArrange')
  612.  
  613.     appBarCallbackMap = {
  614.         ABN_STATECHANGE: OnAppBarStateChange,
  615.         ABN_FULLSCREENAPP: OnAppBarFullscreenApp,
  616.         ABN_POSCHANGED: OnAppBarPosChanged,
  617.         ABN_WINDOWARRANGE: OnAppBarWindowArrange }
  618.     
  619.     def AppBarCallback(self, *params):
  620.         log.info('AppBarCallback %r', params)
  621.         (wParam, lParam) = params[2:4]
  622.         self.appBarCallbackMap[wParam](wParam, lParam)
  623.  
  624.     
  625.     def GetNewAppBarData(self, lParam = False):
  626.         abd = APPBARDATA()
  627.         abd.hWnd = self.Handle
  628.         abd.uEdge = self.side
  629.         abd.rc = self.win.RECT
  630.         abd.lParam = lParam
  631.         return abd
  632.  
  633.     newAppBarData = property(GetNewAppBarData)
  634.     
  635.     def Handle(self):
  636.         return self.win.Handle
  637.  
  638.     Handle = property(Handle)
  639.     
  640.     def SetWinAlwaysOnTop(self, val = None):
  641.         if self.ShouldAlwaysStayOnTop:
  642.             self.ShouldAlwaysStayOnTop(val)
  643.         
  644.  
  645.  
  646.  
  647. def SetToolStyle(win, val):
  648.     if val:
  649.         win.SetWindowStyle(wx.FRAME_TOOL_WINDOW | win.GetWindowStyle())
  650.     else:
  651.         win.SetWindowStyle(~(wx.FRAME_TOOL_WINDOW) & win.GetWindowStyle())
  652.  
  653.  
  654. def monitor_rect(win):
  655.     return Monitor.GetFromWindow(win).ClientArea
  656.  
  657.  
  658. def onscreen(x, y):
  659.     return Monitor.GetFromPoint((x, y), find_near = False) is not None
  660.  
  661.  
  662. def isRectOnScreen(rect):
  663.     return Monitor.GetFromRect(rect, find_near = False) is not None
  664.  
  665.  
  666. class APPBARDATA(Structure):
  667.     _fields_ = [
  668.         ('cbSize', DWORD),
  669.         ('hWnd', HANDLE),
  670.         ('uCallbackMessage', c_uint),
  671.         ('uEdge', c_uint),
  672.         ('rc', RECT),
  673.         ('lParam', LPARAM)]
  674.  
  675. taskbar_abd = APPBARDATA()
  676. from ctypes import sizeof
  677. taskbar_abd.cbSize = sizeof(APPBARDATA)
  678.  
  679. def taskbar_info():
  680.     uState = SHAppBarMessage(ABM_GETSTATE, taskbar_abd)
  681.     return dict(always_on_top = uState & ABS_ALWAYSONTOP, autohide = uState & ABS_AUTOHIDE)
  682.  
  683.  
  684. try:
  685.     import psyco
  686. except Exception:
  687.     e = None
  688.  
  689. psyco.bind(Docker)
  690.