您的位置:首页 > 其它

MFC技术系列(四)--Frame窗口之Control Bar(2)

2007-08-04 23:36 363 查看

1.3 CDockContext类

在前面的CControlBar类中,提到了当拖动荡Bar时,将借助CDockContext类的方法来完成。CDockContext类主要就是用来完成对Bar的行为,包括:拖动,在浮动和停靠间Toggle、改变尺寸。下面分别做一个说明:
1. Drag(拖动)



标准的行为,即从鼠标左键按下Bar的空白区域(非子窗口区域),然后拖动,绘制焦点矩型,直到鼠标左键抬起,拖动结束。涉及的方法包括:
StartDrag:分三种情况分别计算拖动矩形的初始值(由于有水平和垂直两个方向,所以矩形都是成对的):CBRS_SIZE_DYNAMIC风格、CBRS_SIZE_FIXED风格和其它风格。对于第二种固定尺寸风格来说,只需要一对矩形;而对第一种风格,因为浮动状态还可以改变尺寸,所以还需要计算一个浮动矩形,用m_rectFrameDragHorz和m_rectFrameDragVert两个成员保存。该矩形的计算经过三个步骤:第一,先调用Bar的CalcDynamicLayout计算Bar的Rect(相当于Frame的客户区);第二,计算Frame的Rect,此时,调用了CMiniFrameWnd的CalcBorders方法,它调用AdjustWindowRectEx API,该方法用来依据客户区域计算整个窗口Rect;第三,减去窗口边缘的尺寸
Move:响应鼠标移动消息,移动上述矩形。另外,还判断是否能够Dock,依据的信息包括:Ctrl键按下(m_bForceFrame)、Shift键按下(m_bFlip)、Dock位置风格(CBRS_ORIENT_VERT和CBRS_ORIENT_HORZ),主要逻辑封装在其CanDock方法中,该方法最终的判断会交给Frame窗口(由m_pDockSite记录)的CanDock方法。
Track:Capture鼠标,从消息队列获取消息,实际处理的消息包括:
a. WM_LBUTTONUP:如果是Drag状态,那么调用EndDrag,结束拖动;否则为Resize状态,那么调用EndResize结束该行为。
b. WM_MOUSEMOVE:Drag状态,调用Move移动焦点矩形;否则,调用Stretch方法,改变焦点矩形的尺寸,然后绘制它
c. WM_KEYUP:调用其OnKey方法,主要处理Ctrl和Shift键
d. WM_KEYDOWN:调用其OnKey方法,主要处理Ctrl和Shift键。此时,如果Esc键被按下,那么CancelLoop将被调用,从而结束上述行为(Drag,或Resize)
e. WM_RBUTTONDOWN:调用CancelLoop
可见,在Drag过程中,可以使用Esc,或者鼠标右键结束Drag。(后面的Resize也同样适用)
EndDrag:下面两个步骤
a. 调用CancelLoop
b. 根据Dock的状态,调用Frame窗口的DockControlBar,或者FloatControlBar完成相应的Dock
另外两个方法:
InitLoop:下面三个步骤:
a. 处理消息队列中的WM_PAINT消息
b. 初始化一些状态和中间尺寸
c. 获得桌面窗口(CWnd的GetDesktopWindow)
d. 调用桌面窗口的LockWindowUpdate,任何绘画都不会生效,当然窗口也不可能被移动,直到调用UnlockWindowUpdate
e. 获取桌面窗口的DC(通过CWnd的GetDCEx)
CancelLoop:下面四个步骤:
a. 调用DrawFocusRect,消除Drag矩形
b. 然后释放鼠标的Capture
c. 调用UnlockWindowUpdate,让绘画生效
d. 释放DC
2. Stretch(Resize)



这个过程很类似上面的Drag。基本可以对应起来,它们共用Track方法,从开始到结束,基本是StartResize, InitLoop, Track (Stretch), EndLoop, EndResize。
3. Toggle Docking
在浮动和停靠两种状态间切换,由该类的ToggleDocking方法完成。该方法比较简单。
4. 绘制焦点矩形
无论是Drag,还是Resize,都有这个步骤。它由该类的DrawFocusRect方法完成,绘制部分调用了CDC的DrawDragRect方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: