codekingpro/portable-devtools
114k
1# DockingBar.py2 3# Ported directly (comments and all) from the samples at www.codeguru.com4 5# WARNING: Use at your own risk, as this interface is highly likely to change.6# Currently we support only one child per DockingBar. Later we need to add7# support for multiple children.8 9import struct10 11import win32api12import win32con13import win32ui14from pywin.mfc import afxres, window15 16clrBtnHilight = win32api.GetSysColor(win32con.COLOR_BTNHILIGHT)17clrBtnShadow = win32api.GetSysColor(win32con.COLOR_BTNSHADOW)18 19 20def CenterPoint(rect):21 width = rect[2] - rect[0]22 height = rect[3] - rect[1]23 return rect[0] + width // 2, rect[1] + height // 224 25 26def OffsetRect(rect, point):27 (x, y) = point28 return rect[0] + x, rect[1] + y, rect[2] + x, rect[3] + y29 30 31def DeflateRect(rect, point):32 (x, y) = point33 return rect[0] + x, rect[1] + y, rect[2] - x, rect[3] - y34 35 36def PtInRect(rect, pt):37 return rect[0] <= pt[0] < rect[2] and rect[1] <= pt[1] < rect[3]38 39 40class DockingBar(window.Wnd):41 def __init__(self, obj=None):42 if obj is None:43 obj = win32ui.CreateControlBar()44 window.Wnd.__init__(self, obj)45 self.dialog = None46 self.nDockBarID = 047 self.sizeMin = 32, 3248 self.sizeHorz = 200, 20049 self.sizeVert = 200, 20050 self.sizeFloat = 200, 20051 self.bTracking = 052 self.bInRecalcNC = 053 self.cxEdge = 654 self.cxBorder = 355 self.cxGripper = 2056 self.brushBkgd = win32ui.CreateBrush()57 self.brushBkgd.CreateSolidBrush(win32api.GetSysColor(win32con.COLOR_BTNFACE))58 59 # Support for diagonal resizing60 self.cyBorder = 361 self.cCaptionSize = win32api.GetSystemMetrics(win32con.SM_CYSMCAPTION)62 self.cMinWidth = win32api.GetSystemMetrics(win32con.SM_CXMIN)63 self.cMinHeight = win32api.GetSystemMetrics(win32con.SM_CYMIN)64 self.rectUndock = (0, 0, 0, 0)65 66 def OnUpdateCmdUI(self, target, bDisableIfNoHndler):67 return self.UpdateDialogControls(target, bDisableIfNoHndler)68 69 def CreateWindow(70 self,71 parent,72 childCreator,73 title,74 id,75 style=win32con.WS_CHILD | win32con.WS_VISIBLE | afxres.CBRS_LEFT,76 childCreatorArgs=(),77 ):78 assert not (79 (style & afxres.CBRS_SIZE_FIXED) and (style & afxres.CBRS_SIZE_DYNAMIC)80 ), "Invalid style"81 self.rectClose = self.rectBorder = self.rectGripper = self.rectTracker = (82 0,83 0,84 0,85 0,86 )87 88 # save the style89 self._obj_.dwStyle = style & afxres.CBRS_ALL90 91 cursor = win32api.LoadCursor(0, win32con.IDC_ARROW)92 wndClass = win32ui.RegisterWndClass(93 win32con.CS_DBLCLKS, cursor, self.brushBkgd.GetSafeHandle(), 094 )95 96 self._obj_.CreateWindow(wndClass, title, style, (0, 0, 0, 0), parent, id)97 98 # Create the child dialog99 self.dialog = childCreator(*(self,) + childCreatorArgs)100 101 # use the dialog dimensions as default base dimensions102 assert self.dialog.IsWindow(), (103 "The childCreator function %s did not create a window!" % childCreator104 )105 rect = self.dialog.GetWindowRect()106 self.sizeHorz = self.sizeVert = self.sizeFloat = (107 rect[2] - rect[0],108 rect[3] - rect[1],109 )110 111 self.sizeHorz = self.sizeHorz[0], self.sizeHorz[1] + self.cxEdge + self.cxBorder112 self.sizeVert = self.sizeVert[0] + self.cxEdge + self.cxBorder, self.sizeVert[1]113 self.HookMessages()114 115 def CalcFixedLayout(self, bStretch, bHorz):116 rectTop = self.dockSite.GetControlBar(117 afxres.AFX_IDW_DOCKBAR_TOP118 ).GetWindowRect()119 rectLeft = self.dockSite.GetControlBar(120 afxres.AFX_IDW_DOCKBAR_LEFT121 ).GetWindowRect()122 if bStretch:123 nHorzDockBarWidth = 32767124 nVertDockBarHeight = 32767125 else:126 nHorzDockBarWidth = rectTop[2] - rectTop[0] + 4127 nVertDockBarHeight = rectLeft[3] - rectLeft[1] + 4128 129 if self.IsFloating():130 return self.sizeFloat131 if bHorz:132 return nHorzDockBarWidth, self.sizeHorz[1]133 return self.sizeVert[0], nVertDockBarHeight134 135 def CalcDynamicLayout(self, length, mode):136 # Support for diagonal sizing.137 if self.IsFloating():138 self.GetParent().GetParent().ModifyStyle(win32ui.MFS_4THICKFRAME, 0)139 if mode & (win32ui.LM_HORZDOCK | win32ui.LM_VERTDOCK):140 flags = (141 win32con.SWP_NOSIZE142 | win32con.SWP_NOMOVE143 | win32con.SWP_NOZORDER144 | win32con.SWP_NOACTIVATE145 | win32con.SWP_FRAMECHANGED146 )147 self.SetWindowPos(148 0,149 (150 0,151 0,152 0,153 0,154 ),155 flags,156 )157 self.dockSite.RecalcLayout()158 return self._obj_.CalcDynamicLayout(length, mode)159 160 if mode & win32ui.LM_MRUWIDTH:161 return self.sizeFloat162 if mode & win32ui.LM_COMMIT:163 self.sizeFloat = length, self.sizeFloat[1]164 return self.sizeFloat165 # More diagonal sizing.166 if self.IsFloating():167 dc = self.dockContext168 pt = win32api.GetCursorPos()169 windowRect = self.GetParent().GetParent().GetWindowRect()170 171 hittest = dc.nHitTest172 if hittest == win32con.HTTOPLEFT:173 cx = max(windowRect[2] - pt[0], self.cMinWidth) - self.cxBorder174 cy = max(windowRect[3] - self.cCaptionSize - pt[1], self.cMinHeight) - 1175 self.sizeFloat = cx, cy176 177 top = (178 min(pt[1], windowRect[3] - self.cCaptionSize - self.cMinHeight)179 - self.cyBorder180 )181 left = min(pt[0], windowRect[2] - self.cMinWidth) - 1182 dc.rectFrameDragHorz = (183 left,184 top,185 dc.rectFrameDragHorz[2],186 dc.rectFrameDragHorz[3],187 )188 return self.sizeFloat189 if hittest == win32con.HTTOPRIGHT:190 cx = max(pt[0] - windowRect[0], self.cMinWidth)191 cy = max(windowRect[3] - self.cCaptionSize - pt[1], self.cMinHeight) - 1192 self.sizeFloat = cx, cy193 194 top = (195 min(pt[1], windowRect[3] - self.cCaptionSize - self.cMinHeight)196 - self.cyBorder197 )198 dc.rectFrameDragHorz = (199 dc.rectFrameDragHorz[0],200 top,201 dc.rectFrameDragHorz[2],202 dc.rectFrameDragHorz[3],203 )204 return self.sizeFloat205 206 if hittest == win32con.HTBOTTOMLEFT:207 cx = max(windowRect[2] - pt[0], self.cMinWidth) - self.cxBorder208 cy = max(pt[1] - windowRect[1] - self.cCaptionSize, self.cMinHeight)209 self.sizeFloat = cx, cy210 211 left = min(pt[0], windowRect[2] - self.cMinWidth) - 1212 dc.rectFrameDragHorz = (213 left,214 dc.rectFrameDragHorz[1],215 dc.rectFrameDragHorz[2],216 dc.rectFrameDragHorz[3],217 )218 return self.sizeFloat219 220 if hittest == win32con.HTBOTTOMRIGHT:221 cx = max(pt[0] - windowRect[0], self.cMinWidth)222 cy = max(pt[1] - windowRect[1] - self.cCaptionSize, self.cMinHeight)223 self.sizeFloat = cx, cy224 return self.sizeFloat225 226 if mode & win32ui.LM_LENGTHY:227 self.sizeFloat = self.sizeFloat[0], max(self.sizeMin[1], length)228 return self.sizeFloat229 else:230 return max(self.sizeMin[0], length), self.sizeFloat[1]231 232 def OnWindowPosChanged(self, msg):233 if self.GetSafeHwnd() == 0 or self.dialog is None:234 return 0235 lparam = msg[3]236 """ LPARAM used with WM_WINDOWPOSCHANGED:237 typedef struct {238 HWND hwnd;239 HWND hwndInsertAfter;240 int x;241 int y;242 int cx;243 int cy;244 UINT flags;} WINDOWPOS;245 """246 format = "PPiiiii"247 bytes = win32ui.GetBytes(lparam, struct.calcsize(format))248 hwnd, hwndAfter, x, y, cx, cy, flags = struct.unpack(format, bytes)249 250 if self.bInRecalcNC:251 rc = self.GetClientRect()252 self.dialog.MoveWindow(rc)253 return 0254 # Find on which side are we docked255 nDockBarID = self.GetParent().GetDlgCtrlID()256 # Return if dropped at same location257 # no docking side change and no size change258 if (259 (nDockBarID == self.nDockBarID)260 and (flags & win32con.SWP_NOSIZE)261 and (262 (self._obj_.dwStyle & afxres.CBRS_BORDER_ANY) != afxres.CBRS_BORDER_ANY263 )264 ):265 return266 self.nDockBarID = nDockBarID267 268 # Force recalc the non-client area269 self.bInRecalcNC = 1270 try:271 swpflags = (272 win32con.SWP_NOSIZE273 | win32con.SWP_NOMOVE274 | win32con.SWP_NOZORDER275 | win32con.SWP_FRAMECHANGED276 )277 self.SetWindowPos(0, (0, 0, 0, 0), swpflags)278 finally:279 self.bInRecalcNC = 0280 return 0281 282 # This is a virtual and not a message hook.283 def OnSetCursor(self, window, nHitTest, wMouseMsg):284 if nHitTest != win32con.HTSIZE or self.bTracking:285 return self._obj_.OnSetCursor(window, nHitTest, wMouseMsg)286 287 if self.IsHorz():288 win32api.SetCursor(win32api.LoadCursor(0, win32con.IDC_SIZENS))289 else:290 win32api.SetCursor(win32api.LoadCursor(0, win32con.IDC_SIZEWE))291 return 1292 293 # Mouse Handling294 def OnLButtonUp(self, msg):295 if not self.bTracking:296 return 1 # pass it on.297 self.StopTracking(1)298 return 0 # Dont pass on299 300 def OnLButtonDown(self, msg):301 # UINT nFlags, CPoint point)302 # only start dragging if clicked in "void" space303 if self.dockBar is not None:304 # start the drag305 pt = msg[5]306 pt = self.ClientToScreen(pt)307 self.dockContext.StartDrag(pt)308 return 0309 return 1310 311 def OnNcLButtonDown(self, msg):312 if self.bTracking:313 return 0314 nHitTest = wparam = msg[2]315 pt = msg[5]316 317 if nHitTest == win32con.HTSYSMENU and not self.IsFloating():318 self.GetDockingFrame().ShowControlBar(self, 0, 0)319 elif nHitTest == win32con.HTMINBUTTON and not self.IsFloating():320 self.dockContext.ToggleDocking()321 elif (322 nHitTest == win32con.HTCAPTION323 and not self.IsFloating()324 and self.dockBar is not None325 ):326 self.dockContext.StartDrag(pt)327 elif nHitTest == win32con.HTSIZE and not self.IsFloating():328 self.StartTracking()329 else:330 return 1331 return 0332 333 def OnLButtonDblClk(self, msg):334 # only toggle docking if clicked in "void" space335 if self.dockBar is not None:336 # toggle docking337 self.dockContext.ToggleDocking()338 return 0339 return 1340 341 def OnNcLButtonDblClk(self, msg):342 nHitTest = wparam = msg[2]343 # UINT nHitTest, CPoint point)344 if self.dockBar is not None and nHitTest == win32con.HTCAPTION:345 # toggle docking346 self.dockContext.ToggleDocking()347 return 0348 return 1349 350 def OnMouseMove(self, msg):351 flags = wparam = msg[2]352 lparam = msg[3]353 if self.IsFloating() or not self.bTracking:354 return 1355 356 # Convert unsigned 16 bit to signed 32 bit.357 x = win32api.LOWORD(lparam)358 if x & 32768:359 x = x | -65536360 y = win32api.HIWORD(lparam)361 if y & 32768:362 y = y | -65536363 pt = x, y364 cpt = CenterPoint(self.rectTracker)365 pt = self.ClientToWnd(pt)366 if self.IsHorz():367 if cpt[1] != pt[1]:368 self.OnInvertTracker(self.rectTracker)369 self.rectTracker = OffsetRect(self.rectTracker, (0, pt[1] - cpt[1]))370 self.OnInvertTracker(self.rectTracker)371 else:372 if cpt[0] != pt[0]:373 self.OnInvertTracker(self.rectTracker)374 self.rectTracker = OffsetRect(self.rectTracker, (pt[0] - cpt[0], 0))375 self.OnInvertTracker(self.rectTracker)376 377 return 0 # Dont pass it on.378 379 # def OnBarStyleChange(self, old, new):380 381 def OnNcCalcSize(self, bCalcValid, size_info):382 (rc0, rc1, rc2, pos) = size_info383 self.rectBorder = self.GetWindowRect()384 self.rectBorder = OffsetRect(385 self.rectBorder, (-self.rectBorder[0], -self.rectBorder[1])386 )387 388 dwBorderStyle = self._obj_.dwStyle | afxres.CBRS_BORDER_ANY389 390 if self.nDockBarID == afxres.AFX_IDW_DOCKBAR_TOP:391 dwBorderStyle = dwBorderStyle & ~afxres.CBRS_BORDER_BOTTOM392 rc0.left = rc0.left + self.cxGripper393 rc0.bottom = rc0.bottom - self.cxEdge394 rc0.top = rc0.top + self.cxBorder395 rc0.right = rc0.right - self.cxBorder396 self.rectBorder = (397 self.rectBorder[0],398 self.rectBorder[3] - self.cxEdge,399 self.rectBorder[2],400 self.rectBorder[3],401 )402 elif self.nDockBarID == afxres.AFX_IDW_DOCKBAR_BOTTOM:403 dwBorderStyle = dwBorderStyle & ~afxres.CBRS_BORDER_TOP404 rc0.left = rc0.left + self.cxGripper405 rc0.top = rc0.top + self.cxEdge406 rc0.bottom = rc0.bottom - self.cxBorder407 rc0.right = rc0.right - self.cxBorder408 self.rectBorder = (409 self.rectBorder[0],410 self.rectBorder[1],411 self.rectBorder[2],412 self.rectBorder[1] + self.cxEdge,413 )414 elif self.nDockBarID == afxres.AFX_IDW_DOCKBAR_LEFT:415 dwBorderStyle = dwBorderStyle & ~afxres.CBRS_BORDER_RIGHT416 rc0.right = rc0.right - self.cxEdge417 rc0.left = rc0.left + self.cxBorder418 rc0.bottom = rc0.bottom - self.cxBorder419 rc0.top = rc0.top + self.cxGripper420 self.rectBorder = (421 self.rectBorder[2] - self.cxEdge,422 self.rectBorder[1],423 self.rectBorder[2],424 self.rectBorder[3],425 )426 elif self.nDockBarID == afxres.AFX_IDW_DOCKBAR_RIGHT:427 dwBorderStyle = dwBorderStyle & ~afxres.CBRS_BORDER_LEFT428 rc0.left = rc0.left + self.cxEdge429 rc0.right = rc0.right - self.cxBorder430 rc0.bottom = rc0.bottom - self.cxBorder431 rc0.top = rc0.top + self.cxGripper432 self.rectBorder = (433 self.rectBorder[0],434 self.rectBorder[1],435 self.rectBorder[0] + self.cxEdge,436 self.rectBorder[3],437 )438 else:439 self.rectBorder = 0, 0, 0, 0440 441 self.SetBarStyle(dwBorderStyle)442 return 0443 444 def OnNcPaint(self, msg):445 self.EraseNonClient()446 dc = self.GetWindowDC()447 ctl = win32api.GetSysColor(win32con.COLOR_BTNHIGHLIGHT)448 cbr = win32api.GetSysColor(win32con.COLOR_BTNSHADOW)449 dc.Draw3dRect(self.rectBorder, ctl, cbr)450 451 self.DrawGripper(dc)452 453 rect = self.GetClientRect()454 self.InvalidateRect(rect, 1)455 return 0456 457 def OnNcHitTest(self, pt): # A virtual, not a hooked message.458 if self.IsFloating():459 return 1460 461 ptOrig = pt462 rect = self.GetWindowRect()463 pt = pt[0] - rect[0], pt[1] - rect[1]464 465 if PtInRect(self.rectClose, pt):466 return win32con.HTSYSMENU467 elif PtInRect(self.rectUndock, pt):468 return win32con.HTMINBUTTON469 elif PtInRect(self.rectGripper, pt):470 return win32con.HTCAPTION471 elif PtInRect(self.rectBorder, pt):472 return win32con.HTSIZE473 else:474 return self._obj_.OnNcHitTest(ptOrig)475 476 def StartTracking(self):477 self.SetCapture()478 479 # make sure no updates are pending480 self.RedrawWindow(None, None, win32con.RDW_ALLCHILDREN | win32con.RDW_UPDATENOW)481 self.dockSite.LockWindowUpdate()482 483 self.ptOld = CenterPoint(self.rectBorder)484 self.bTracking = 1485 486 self.rectTracker = self.rectBorder487 if not self.IsHorz():488 l, t, r, b = self.rectTracker489 b = b - 4490 self.rectTracker = l, t, r, b491 492 self.OnInvertTracker(self.rectTracker)493 494 def OnCaptureChanged(self, msg):495 hwnd = lparam = msg[3]496 if self.bTracking and hwnd != self.GetSafeHwnd():497 self.StopTracking(0) # cancel tracking498 return 1499 500 def StopTracking(self, bAccept):501 self.OnInvertTracker(self.rectTracker)502 self.dockSite.UnlockWindowUpdate()503 self.bTracking = 0504 self.ReleaseCapture()505 if not bAccept:506 return507 508 rcc = self.dockSite.GetWindowRect()509 if self.IsHorz():510 newsize = self.sizeHorz[1]511 maxsize = newsize + (rcc[3] - rcc[1])512 minsize = self.sizeMin[1]513 else:514 newsize = self.sizeVert[0]515 maxsize = newsize + (rcc[2] - rcc[0])516 minsize = self.sizeMin[0]517 518 pt = CenterPoint(self.rectTracker)519 if self.nDockBarID == afxres.AFX_IDW_DOCKBAR_TOP:520 newsize = newsize + (pt[1] - self.ptOld[1])521 elif self.nDockBarID == afxres.AFX_IDW_DOCKBAR_BOTTOM:522 newsize = newsize + (-pt[1] + self.ptOld[1])523 elif self.nDockBarID == afxres.AFX_IDW_DOCKBAR_LEFT:524 newsize = newsize + (pt[0] - self.ptOld[0])525 elif self.nDockBarID == afxres.AFX_IDW_DOCKBAR_RIGHT:526 newsize = newsize + (-pt[0] + self.ptOld[0])527 newsize = max(minsize, min(maxsize, newsize))528 if self.IsHorz():529 self.sizeHorz = self.sizeHorz[0], newsize530 else:531 self.sizeVert = newsize, self.sizeVert[1]532 self.dockSite.RecalcLayout()533 return 0534 535 def OnInvertTracker(self, rect):536 assert rect[2] - rect[0] > 0 and rect[3] - rect[1] > 0, "rect is empty"537 assert self.bTracking538 rcc = self.GetWindowRect()539 rcf = self.dockSite.GetWindowRect()540 541 rect = OffsetRect(rect, (rcc[0] - rcf[0], rcc[1] - rcf[1]))542 rect = DeflateRect(rect, (1, 1))543 544 flags = win32con.DCX_WINDOW | win32con.DCX_CACHE | win32con.DCX_LOCKWINDOWUPDATE545 dc = self.dockSite.GetDCEx(None, flags)546 try:547 brush = win32ui.GetHalftoneBrush()548 oldBrush = dc.SelectObject(brush)549 550 dc.PatBlt(551 (rect[0], rect[1]),552 (rect[2] - rect[0], rect[3] - rect[1]),553 win32con.PATINVERT,554 )555 dc.SelectObject(oldBrush)556 finally:557 self.dockSite.ReleaseDC(dc)558 559 def IsHorz(self):560 return (561 self.nDockBarID == afxres.AFX_IDW_DOCKBAR_TOP562 or self.nDockBarID == afxres.AFX_IDW_DOCKBAR_BOTTOM563 )564 565 def ClientToWnd(self, pt):566 x, y = pt567 if self.nDockBarID == afxres.AFX_IDW_DOCKBAR_BOTTOM:568 y = y + self.cxEdge569 elif self.nDockBarID == afxres.AFX_IDW_DOCKBAR_RIGHT:570 x = x + self.cxEdge571 return x, y572 573 def DrawGripper(self, dc):574 # no gripper if floating575 if self._obj_.dwStyle & afxres.CBRS_FLOATING:576 return577 578 # -==HACK==-579 # in order to calculate the client area properly after docking,580 # the client area must be recalculated twice (I have no idea why)581 self.dockSite.RecalcLayout()582 # -==END HACK==-583 584 gripper = self.GetWindowRect()585 gripper = self.ScreenToClient(gripper)586 gripper = OffsetRect(gripper, (-gripper[0], -gripper[1]))587 gl, gt, gr, gb = gripper588 589 if self._obj_.dwStyle & afxres.CBRS_ORIENT_HORZ:590 # gripper at left591 self.rectGripper = gl, gt + 40, gl + 20, gb592 # draw close box593 self.rectClose = gl + 7, gt + 10, gl + 19, gt + 22594 dc.DrawFrameControl(595 self.rectClose, win32con.DFC_CAPTION, win32con.DFCS_CAPTIONCLOSE596 )597 # draw docking toggle box598 self.rectUndock = OffsetRect(self.rectClose, (0, 13))599 dc.DrawFrameControl(600 self.rectUndock, win32con.DFC_CAPTION, win32con.DFCS_CAPTIONMAX601 )602 603 gt = gt + 38604 gb = gb - 10605 gl = gl + 10606 gr = gl + 3607 gripper = gl, gt, gr, gb608 dc.Draw3dRect(gripper, clrBtnHilight, clrBtnShadow)609 dc.Draw3dRect(OffsetRect(gripper, (4, 0)), clrBtnHilight, clrBtnShadow)610 else:611 # gripper at top612 self.rectGripper = gl, gt, gr - 40, gt + 20613 # draw close box614 self.rectClose = gr - 21, gt + 7, gr - 10, gt + 18615 dc.DrawFrameControl(616 self.rectClose, win32con.DFC_CAPTION, win32con.DFCS_CAPTIONCLOSE617 )618 # draw docking toggle box619 self.rectUndock = OffsetRect(self.rectClose, (-13, 0))620 dc.DrawFrameControl(621 self.rectUndock, win32con.DFC_CAPTION, win32con.DFCS_CAPTIONMAX622 )623 gr = gr - 38624 gl = gl + 10625 gt = gt + 10626 gb = gt + 3627 628 gripper = gl, gt, gr, gb629 dc.Draw3dRect(gripper, clrBtnHilight, clrBtnShadow)630 dc.Draw3dRect(OffsetRect(gripper, (0, 4)), clrBtnHilight, clrBtnShadow)631 632 def HookMessages(self):633 self.HookMessage(self.OnLButtonUp, win32con.WM_LBUTTONUP)634 self.HookMessage(self.OnLButtonDown, win32con.WM_LBUTTONDOWN)635 self.HookMessage(self.OnLButtonDblClk, win32con.WM_LBUTTONDBLCLK)636 self.HookMessage(self.OnNcLButtonDown, win32con.WM_NCLBUTTONDOWN)637 self.HookMessage(self.OnNcLButtonDblClk, win32con.WM_NCLBUTTONDBLCLK)638 self.HookMessage(self.OnMouseMove, win32con.WM_MOUSEMOVE)639 self.HookMessage(self.OnNcPaint, win32con.WM_NCPAINT)640 self.HookMessage(self.OnCaptureChanged, win32con.WM_CAPTURECHANGED)641 self.HookMessage(self.OnWindowPosChanged, win32con.WM_WINDOWPOSCHANGED)642 643 644# self.HookMessage(self.OnSize, win32con.WM_SIZE)645 646 647def EditCreator(parent):648 d = win32ui.CreateEdit()649 es = (650 win32con.WS_CHILD651 | win32con.WS_VISIBLE652 | win32con.WS_BORDER653 | win32con.ES_MULTILINE654 | win32con.ES_WANTRETURN655 )656 d.CreateWindow(es, (0, 0, 150, 150), parent, 1000)657 return d658 659 660def test():661 import pywin.mfc.dialog662 663 global bar664 bar = DockingBar()665 creator = EditCreator666 bar.CreateWindow(win32ui.GetMainFrame(), creator, "Coolbar Demo", 0xFFFFF)667 # win32ui.GetMainFrame().ShowControlBar(bar, 1, 0)668 bar.SetBarStyle(669 bar.GetBarStyle()670 | afxres.CBRS_TOOLTIPS671 | afxres.CBRS_FLYBY672 | afxres.CBRS_SIZE_DYNAMIC673 )674 bar.EnableDocking(afxres.CBRS_ALIGN_ANY)675 win32ui.GetMainFrame().DockControlBar(bar, afxres.AFX_IDW_DOCKBAR_BOTTOM)676 677 678if __name__ == "__main__":679 test()680 