home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 June / maximum-cd-2009-06.iso / DiscContents / digsby_setup.exe / lib / gui / native / win / windocking.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-02-26  |  23.1 KB  |  714 lines

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