DockPageBar.cpp 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907
  1. /////////////////////////////////////////////////////////////////////////
  2. //
  3. // CDockPageBar Version 1.2
  4. //
  5. // Created: Mar 16, 2004
  6. //
  7. /////////////////////////////////////////////////////////////////////////
  8. // Copyright (C) 2004 by Cuick. All rights reserved.
  9. //
  10. // This code is free for personal and commercial use, providing this
  11. // notice remains intact in the source files and all eventual changes are
  12. // clearly marked with comments.
  13. //
  14. // Send bug reports, bug fixes, enhancements, requests, flames, etc. to
  15. // Cuick@163.net
  16. //
  17. // Hint: These classes are intended to be used as base classes. Do not
  18. // simply add your code to these file - instead create a new class
  19. // derived from CDockPageBar classes and put there what you need. See
  20. // CTestBar classes in the demo projects for examples.
  21. // Modify this file only to fix bugs, and don't forget to send me a copy.
  22. /////////////////////////////////////////////////////////////////////////
  23. // Acknowledgements:
  24. // o 感谢Cristi Posea的CSizingControlBar
  25. // o 借鉴了王骏的《轻松实现类VC界面》中的部分代码,在这里表示感谢。
  26. // o 感谢hengai帮助修改了部分内存泄漏问题
  27. // o 开发过程中遇到的问题得到了VC知识库论坛中很多人的帮助,这里一并感谢。
  28. //
  29. //////////////////////////////////////////////////////////////////////////
  30. //Updates
  31. //////////////////////////////////////////////////////////////////////////
  32. // Author | Date | Description
  33. //========================================================================
  34. // Tony |2006-09-04 | Bugfixs:
  35. //=======================| 1.add Timer TID_AUTO_HIDE_DELAY to prevent two
  36. //tony__cb@hotmail.com | AHFloatWnds being displayed at the same time.
  37. // | 2.focus switch problems(especially between AHFloatwnd and
  38. // | DockPageBar).
  39. // | 3.frequence screen flash on sizing the DockPageBar.
  40. // | 4.resize the AHFloatWnds with the wider than the mainframe.
  41. // | 5.link problems related with static MFC lib
  42. // | by setting a new compile flag STATIC_MFC_LINK
  43. // | 6.Verify the pWnd's style in CDockPageBar::AddPage function,
  44. // | to make sure pWnd to have the WS_CHILD style, and to avoid
  45. // | the window management disorder in clean up.
  46. // | ------------------------------------------------
  47. // | Improvements and new features:
  48. // | 1.add the slide in/out animation display for AHFloatWnds
  49. // | (the API ::AnimateWindow doesnt work for the self-draw window)
  50. // | 2.make a lot of detail display changes(border,caption bar,...)
  51. // | to have nicer windows
  52. // | 3.add the new docking detection algorithm(accurate docking)
  53. // | just as MS VC2003, but with the limitation that
  54. // | the horizontal docking always has the higher priority.
  55. // | 4.add the support for MDI style Frame
  56. // | 5.rewrite the NcPaint,NcCalClient,OnNcLButtonXXXX,OnNcHitTest part
  57. // | for CDockPageBar to draw the caption(griper),and item tab button
  58. // | in the NcPaint.
  59. // | 6.disable the DragShowContent mode in CSizingControlBar and
  60. // | the OnNcPaint in CDockPageBar when sizing the bar to avoid
  61. // | the dirty & flashy display
  62. // DockPageBar.cpp : implementation file
  63. //
  64. #include "stdafx.h"
  65. #include "DockPageBar.h"
  66. #include ".\dockpagebar.h"
  67. #ifdef _DEBUG
  68. #define new DEBUG_NEW
  69. #undef THIS_FILE
  70. static char THIS_FILE[] = __FILE__;
  71. #endif
  72. /////////////////////////////////////////////////////////////////////////
  73. // delete the line between menu bar and tool bar
  74. // From <afximpl.h>
  75. struct AUX_DATA
  76. {
  77. int _unused1, _unused2;
  78. int _unused3, _unused4;
  79. int cxBorder2, cyBorder2;
  80. };
  81. extern __declspec(dllimport) AUX_DATA afxData;
  82. class INIT_afxData
  83. {
  84. public:
  85. INIT_afxData ()
  86. {
  87. afxData.cxBorder2 = afxData.cyBorder2 = 0;
  88. }
  89. } g_afxData2;
  90. /////////////////////////////////////////////////////////////////////////
  91. // CMyButton
  92. CMyButton::CMyButton()
  93. {
  94. bRaised = FALSE;
  95. bPushed = FALSE;
  96. }
  97. void CMyButton::Paint(CDC* pDC, BOOL isActive)
  98. {
  99. CRect rc = GetRect();
  100. if (bPushed)
  101. pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNSHADOW),
  102. ::GetSysColor(COLOR_BTNHIGHLIGHT));
  103. else
  104. if (bRaised)
  105. pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNHIGHLIGHT),
  106. ::GetSysColor(COLOR_BTNSHADOW));
  107. }
  108. // draw close button
  109. void CCloseButton::Paint(CDC* pDC, BOOL isActive)
  110. {
  111. CMyButton::Paint(pDC, isActive);
  112. COLORREF clrOldTextColor = pDC->GetTextColor();
  113. //if(TRUE == isActive)
  114. pDC->SetTextColor(RGB(255,255,255));
  115. //else
  116. // pDC->SetTextColor(RGB(0,0,0));
  117. int nPrevBkMode = pDC->SetBkMode(TRANSPARENT);
  118. CFont font;
  119. int ppi = pDC->GetDeviceCaps(LOGPIXELSX);
  120. int pointsize = MulDiv(75, 96, ppi); // 6 points at 96 ppi
  121. font.CreatePointFont(pointsize, _T("Marlett"));
  122. CFont* oldfont = pDC->SelectObject(&font);
  123. pDC->TextOut(ptOrg.x + 2, ptOrg.y + 2, CString(_T("r"))); // x-like
  124. pDC->SelectObject(oldfont);
  125. pDC->SetBkMode(nPrevBkMode);
  126. pDC->SetTextColor(clrOldTextColor);
  127. }
  128. CStudButton::CStudButton()
  129. {
  130. }
  131. // draw stud
  132. void CStudButton::Paint(CDC* pDC, BOOL isActive)
  133. {
  134. CMyButton::Paint(pDC, isActive);
  135. HPEN oldPen;
  136. CPen pen;
  137. //if(TRUE == isActive)
  138. pen.CreatePen (PS_SOLID, 1, RGB(255,255,255));
  139. //else
  140. // pen.CreatePen (PS_SOLID, 1, RGB(0,0,0));
  141. oldPen = (HPEN)pDC->SelectObject (pen);
  142. if(FALSE == bFloat)
  143. {
  144. pDC->MoveTo (ptOrg.x + 4, ptOrg.y + 8);
  145. pDC->LineTo (ptOrg.x + 4, ptOrg.y + 3);
  146. pDC->LineTo (ptOrg.x + 8, ptOrg.y + 3);
  147. pDC->LineTo (ptOrg.x + 8, ptOrg.y + 8);
  148. pDC->MoveTo (ptOrg.x + 7, ptOrg.y + 3);
  149. pDC->LineTo (ptOrg.x + 7, ptOrg.y + 8);
  150. pDC->MoveTo (ptOrg.x + 2, ptOrg.y + 8);
  151. pDC->LineTo (ptOrg.x + 11, ptOrg.y + 8);
  152. pDC->MoveTo (ptOrg.x + 6, ptOrg.y + 8);
  153. pDC->LineTo (ptOrg.x + 6, ptOrg.y + 12);
  154. }
  155. else
  156. {
  157. pDC->MoveTo (ptOrg.x + 5, ptOrg.y + 4);
  158. pDC->LineTo (ptOrg.x + 10, ptOrg.y + 4);
  159. pDC->LineTo (ptOrg.x + 10, ptOrg.y + 8);
  160. pDC->LineTo (ptOrg.x + 5, ptOrg.y + 8);
  161. pDC->MoveTo (ptOrg.x + 5, ptOrg.y + 7);
  162. pDC->LineTo (ptOrg.x + 10, ptOrg.y + 7);
  163. pDC->MoveTo (ptOrg.x + 5, ptOrg.y + 2);
  164. pDC->LineTo (ptOrg.x + 5, ptOrg.y + 11);
  165. pDC->MoveTo (ptOrg.x + 1, ptOrg.y + 6);
  166. pDC->LineTo (ptOrg.x + 5, ptOrg.y + 6);
  167. }
  168. pDC->SelectObject(oldPen);
  169. }
  170. /////////////////////////////////////////////////////////////////////////////
  171. // CPageItem
  172. void CPageItem::Draw(CDC *pDC, BOOL bActive)
  173. {
  174. CRect rect = m_rect;
  175. COLORREF crOldText;
  176. rect.top +=2;
  177. if(bActive)
  178. {
  179. rect.bottom -= 2;
  180. CRect rcButton=rect;
  181. rcButton.DeflateRect(-1,0,0,-2);
  182. CBrush brush(GetSysColor(COLOR_3DFACE));
  183. pDC->FillRect(rcButton,&brush);
  184. CPen pen(PS_SOLID,1,GetSysColor(COLOR_3DDKSHADOW));
  185. HPEN oldPen = (HPEN)pDC->SelectObject (&pen);
  186. pDC->MoveTo (rect.left-1 , rect.bottom+2 );
  187. pDC->LineTo (rect.right ,rect.bottom+2);
  188. pDC->MoveTo (rect.right-1, rect.top);
  189. pDC->LineTo (rect.right-1,rect.bottom+3 );
  190. pDC->SelectObject (oldPen);
  191. crOldText = pDC->SetTextColor(RGB(0,0,0));
  192. m_pWnd->ShowWindow(SW_SHOW);
  193. }
  194. else
  195. {
  196. CPen pen(PS_SOLID, 1, RGB(128,128,128));
  197. HPEN oldPen = (HPEN)pDC->SelectObject (&pen);
  198. pDC->MoveTo (rect.right, rect.top + 5);
  199. pDC->LineTo (rect.right, rect.bottom -1);
  200. pDC->SelectObject (oldPen);
  201. crOldText = pDC->SetTextColor(RGB(128,128,128));
  202. m_pWnd->ShowWindow(SW_HIDE);
  203. }
  204. rect.left += 3;
  205. rect.right -= 2;
  206. // draw Icon
  207. if(rect.Width() > 16 && m_hIcon != NULL)
  208. {
  209. ::DrawIconEx(pDC->m_hDC,rect.left,rect.top + 3,m_hIcon,16,16,0,NULL,DI_NORMAL);
  210. rect.left += 22;
  211. }
  212. if (!m_sText.IsEmpty())
  213. {
  214. // draw text
  215. rect.top += 2;
  216. CString sText = m_sText;
  217. int l = sText.GetLength();
  218. int i;
  219. for(i=0;i<10 && pDC->GetTextExtent(sText).cx > rect.Width();i++,l-=2)
  220. sText = sText.Left(l-2);
  221. if(i > 0)
  222. {
  223. sText = sText.Left(l-2);
  224. sText += "...";
  225. }
  226. int nPrevBkMode = pDC->SetBkMode(TRANSPARENT);
  227. pDC->DrawText(sText, &rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
  228. pDC->SetBkMode(nPrevBkMode);
  229. }
  230. pDC->SetTextColor (crOldText);
  231. }
  232. /////////////////////////////////////////////////////////////////////////////
  233. // CDockPageBar
  234. IMPLEMENT_DYNAMIC(CDockPageBar, baseCDockPageBar);
  235. CDockPageBar::CDockPageBar()
  236. {
  237. m_szMinHorz = CSize(50, 50);
  238. m_szMinVert = CSize(60, 60);
  239. m_szMinFloat = CSize(150, 150);
  240. m_cyGripper = CAPTION_HEIGHT+4;
  241. m_isActive = FALSE;
  242. m_Title = "";
  243. m_nActivePage = -1;
  244. m_stud.bFloat = FALSE;
  245. }
  246. CDockPageBar::~CDockPageBar()
  247. {
  248. for(POSITION pos = m_PageList.GetHeadPosition(); pos;)
  249. {
  250. CPageItem* pItem=(CPageItem*)m_PageList.GetNext(pos);
  251. delete pItem; pItem=NULL;
  252. }
  253. m_PageList.RemoveAll();
  254. for(pos = m_pDPBContext.GetHeadPosition(); pos;)
  255. {
  256. CDockPageBarContext* pDPBContext = (CDockPageBarContext*)m_pDPBContext.GetNext(pos);
  257. if(pDPBContext)
  258. {
  259. pDPBContext->FreeAll();
  260. }
  261. }
  262. m_pDPBContext.RemoveAll();
  263. }
  264. BEGIN_MESSAGE_MAP(CDockPageBar, baseCDockPageBar)
  265. //{{AFX_MSG_MAP(CDockPageBar)
  266. ON_WM_CREATE()
  267. ON_WM_NCPAINT()
  268. ON_WM_SIZE()
  269. //ON_WM_PAINT()
  270. ON_WM_NCHITTEST()
  271. ON_WM_NCLBUTTONUP()
  272. ON_WM_NCLBUTTONDOWN()
  273. ON_WM_NCLBUTTONDBLCLK()
  274. ON_WM_DESTROY()
  275. //}}AFX_MSG_MAP
  276. ON_WM_ERASEBKGND()
  277. END_MESSAGE_MAP()
  278. /////////////////////////////////////////////////////////////////////////////
  279. // CDockPageBar message handlers
  280. int CDockPageBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
  281. {
  282. if (baseCDockPageBar::OnCreate(lpCreateStruct) == -1)
  283. return -1;
  284. if (m_font.CreatePointFont(85, "Tahoma"))
  285. SetFont(&m_font);
  286. m_isActive = FALSE;
  287. //SetBkColor( this->GetDC()->GetSafeHdc(),RGB( 0,0,0 ) );
  288. return 0;
  289. }
  290. void CDockPageBar::OnDestroy()
  291. {
  292. }
  293. void CDockPageBar::OnUpdateCmdUI(CFrameWnd *pTarget, BOOL bDisableIfNoHndler)
  294. {
  295. if (!HasGripper())
  296. return;
  297. BOOL bNeedPaint = FALSE;
  298. CWnd* pFocus = GetFocus();
  299. BOOL bActiveOld = m_isActive;
  300. m_isActive = (pFocus->GetSafeHwnd() && IsChild(pFocus));
  301. m_isActive = m_isActive || (pFocus == this);
  302. if (m_isActive != bActiveOld)
  303. bNeedPaint = TRUE;
  304. CPoint pt;
  305. ::GetCursorPos(&pt);
  306. ///////////////////////////////////////////////////////////
  307. // hit close
  308. BOOL bHit = (OnNcHitTest(pt) == HTCLOSE);
  309. BOOL bLButtonDown = (::GetKeyState(VK_LBUTTON) < 0);
  310. BOOL bWasPushed = m_biHide.bPushed;
  311. m_biHide.bPushed = bHit && bLButtonDown;
  312. BOOL bWasRaised = m_biHide.bRaised;
  313. m_biHide.bRaised = bHit && !bLButtonDown;
  314. bNeedPaint |= (m_biHide.bPushed ^ bWasPushed) ||
  315. (m_biHide.bRaised ^ bWasRaised);
  316. ////////////////////////////////////////////////////////////
  317. // hit stud
  318. bHit = (OnNcHitTest(pt) == HTSTUD);
  319. bWasPushed = m_stud.bPushed;
  320. m_stud.bPushed = bHit && bLButtonDown;
  321. bWasRaised = m_stud.bRaised;
  322. m_stud.bRaised = bHit && !bLButtonDown;
  323. bNeedPaint |= (m_stud.bPushed ^ bWasPushed) ||
  324. (m_stud.bRaised ^ bWasRaised);
  325. if (bNeedPaint)
  326. SendMessage(WM_NCPAINT);
  327. }
  328. // draw title bar
  329. void CDockPageBar::NcPaintGripper(CDC *pDC, CRect rcClient)
  330. {
  331. //Note: Here the rcClient' coordinate is for NonClient painting,
  332. // so it is referenced to the current window's topleft.
  333. if (!HasGripper())
  334. return;
  335. CRect clientBorderRc,gripper;
  336. clientBorderRc=gripper=rcClient;
  337. CRect rcbtn = m_biHide.GetRect();
  338. gripper.DeflateRect(-1,-1,0,0);
  339. gripper.top -= m_cyGripper;
  340. gripper.bottom = gripper.top + CAPTION_HEIGHT;
  341. HFONT oldFont = (HFONT)pDC->SelectObject (m_font);
  342. int nPrevBkMode = pDC->SetBkMode(TRANSPARENT);
  343. COLORREF crOldText;
  344. if(TRUE == m_isActive) // active state
  345. {
  346. //CBrush brush(RGB(10,36,106)); //原色;
  347. CBrush brush(RGB(220,155,0)); //Zero.t改色;
  348. pDC->FillRect(&gripper, &brush);
  349. crOldText = pDC->SetTextColor(RGB(255,255,255));
  350. }
  351. else
  352. {
  353. CPen pen(PS_SOLID, 1, RGB(128,128,128));
  354. HPEN poldPen = (HPEN)pDC->SelectObject (&pen);
  355. // Draw better rect
  356. // ------------------------------
  357. //| |
  358. //| |
  359. // ------------------------------
  360. CPoint pt=gripper.TopLeft();
  361. pt.Offset(1,0);
  362. pDC->MoveTo (pt);
  363. pDC->LineTo (gripper.right ,gripper.top );
  364. pt=gripper.TopLeft();
  365. pt.Offset(1,gripper.Height());
  366. pDC->MoveTo (pt);
  367. pDC->LineTo (gripper.right ,gripper.bottom );
  368. pt=gripper.BottomRight();
  369. pt.Offset(0,-1);
  370. pDC->MoveTo (pt);
  371. pDC->LineTo (gripper.right ,gripper.top);
  372. pt=gripper.BottomRight();
  373. pt.Offset(-gripper.Width(),-1);
  374. pDC->MoveTo(pt);
  375. pDC->LineTo (gripper.left ,gripper.top);
  376. pDC->SelectObject (poldPen);
  377. //crOldText = pDC->SetTextColor(RGB(0,0,0));
  378. //CBrush brush(RGB(10,36,106)); //原色;
  379. CBrush brush(RGB(12,0,213)); //Zero.t改色;
  380. pDC->FillRect(&gripper, &brush);
  381. crOldText = pDC->SetTextColor(RGB(255,255,255));
  382. }
  383. gripper.left += 4;
  384. gripper.top += 2;
  385. // draw caption
  386. if (!m_Title.IsEmpty())
  387. {
  388. CString sText = m_Title;
  389. int l = sText.GetLength();
  390. int i;
  391. for(i=0;i<10 && pDC->GetTextExtent(sText).cx > (gripper.Width() - 30);i++,l-=2)
  392. sText = sText.Left(l-2);
  393. if(i > 0)
  394. {
  395. sText = sText.Left(l-2);
  396. sText += "...";
  397. }
  398. pDC->TextOut (gripper.left, gripper.top, sText);
  399. }
  400. pDC->SetTextColor (crOldText);
  401. pDC->SetBkMode(nPrevBkMode);
  402. pDC->SelectObject(oldFont);
  403. CPoint ptOrgBtn;
  404. ptOrgBtn = CPoint(gripper.right - 15, gripper.top);
  405. m_biHide.Move(ptOrgBtn);
  406. m_biHide.Paint(pDC, m_isActive);
  407. ptOrgBtn.x -= 17;
  408. m_stud.Move (ptOrgBtn);
  409. m_stud.Paint(pDC, m_isActive);
  410. }
  411. void CDockPageBar::NcCalcClient(LPRECT pRc, UINT nDockBarID)
  412. {
  413. CRect rcBar(pRc); // save the bar rect
  414. // subtract edges
  415. baseCDockPageBar::NcCalcClient(pRc, nDockBarID);
  416. if (!HasGripper()&&!m_PageList.GetCount())
  417. return;
  418. CRect rc(pRc); // the client rect as calculated by the base class
  419. rc.DeflateRect(1,0,1,0);
  420. BOOL bHorz = (nDockBarID == AFX_IDW_DOCKBAR_TOP) ||
  421. (nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);
  422. if(!IsFloating()){
  423. bHorz ? rc.DeflateRect(0, m_cyGripper-1, 2,0):
  424. rc.DeflateRect(0, m_cyGripper-1, 0,0);
  425. }
  426. if(m_PageList.GetCount()>1)
  427. rc.DeflateRect(0,0,0,ITEMBUTTON_HEIGHT);
  428. DEFLECT_RECT_FOR_STATIC_LINK(rc);
  429. *pRc = rc;
  430. }
  431. void CDockPageBar::OnStudClick()
  432. {
  433. //GetParentFrame()->PostMessage(WM_AUTOHIDE_ON, m_nDockBarID, (LPARAM)this);
  434. //CDockPageBar * pWnd = (CDockPageBar *)lParam;
  435. CAutoHideBar * pAutoHideBar;
  436. switch(m_nDockBarID)
  437. {
  438. case AFX_IDW_DOCKBAR_TOP:
  439. pAutoHideBar = (CAutoHideBar *)((CFrameWnd*)AfxGetMainWnd())->GetControlBar(AHBRS_TOP);
  440. break;
  441. case AFX_IDW_DOCKBAR_BOTTOM:
  442. pAutoHideBar = (CAutoHideBar *)((CFrameWnd*)AfxGetMainWnd())->GetControlBar(AHBRS_BOTTOM);
  443. break;
  444. case AFX_IDW_DOCKBAR_LEFT:
  445. pAutoHideBar = (CAutoHideBar *)((CFrameWnd*)AfxGetMainWnd())->GetControlBar(AHBRS_LEFT);
  446. break;
  447. case AFX_IDW_DOCKBAR_RIGHT:
  448. pAutoHideBar = (CAutoHideBar *)((CFrameWnd*)AfxGetMainWnd())->GetControlBar(AHBRS_RIGHT);
  449. break;
  450. }
  451. pAutoHideBar->HidePageBar(this);
  452. ((CFrameWnd*)AfxGetMainWnd())->RecalcLayout();
  453. }
  454. BOOL CDockPageBar::HasGripper() const
  455. {
  456. if (IsFloating())
  457. return FALSE;
  458. return TRUE;
  459. }
  460. UINT CDockPageBar::OnNcHitTest(CPoint point)
  461. {
  462. CRect rcBar;
  463. GetWindowRect(rcBar);
  464. UINT nRet = baseCDockPageBar::OnNcHitTest(point);
  465. if (nRet != HTCLIENT)
  466. return nRet;
  467. CRect rc = m_biHide.GetRect();
  468. rc.OffsetRect(rcBar.TopLeft());
  469. if (rc.PtInRect(point))
  470. return HTCLOSE;
  471. rc = m_stud.GetRect();
  472. rc.OffsetRect(rcBar.TopLeft());
  473. if (rc.PtInRect(point))
  474. return HTSTUD;
  475. GetItemGroupRect(&rc);
  476. if(rc.PtInRect(point))
  477. return HTITEMBUTTON;
  478. GetCaptionRect(&rc);
  479. if(rc.PtInRect(point))
  480. return HTGRIPPER;
  481. return HTCLIENT;
  482. }
  483. LRESULT CDockPageBar::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  484. {
  485. // TODO: 在此添加专用代码和/或调用基类
  486. switch( message )
  487. {
  488. case WM_MY_INVALIDATE:
  489. {
  490. m_pDockSite->ShowControlBar(this, TRUE, FALSE);
  491. if(::IsWindow(m_hWnd))
  492. SendMessage(WM_NCPAINT);
  493. }
  494. break;
  495. }
  496. return CSizingControlBar::WindowProc(message, wParam, lParam);
  497. }
  498. /////////////////////////////////////////////////////////////////////////////
  499. // about PageIte
  500. CPageItem* CDockPageBar::GetPageItem(int nIndex)
  501. {
  502. CPageItem *pItem = NULL;
  503. POSITION pos = m_PageList.FindIndex(nIndex);
  504. if(pos)
  505. pItem = (CPageItem*)m_PageList.GetAt(pos);
  506. return pItem;
  507. }
  508. void CDockPageBar::SetActivePage(int nIndex)
  509. {
  510. if(nIndex == m_nActivePage)
  511. return;
  512. CPageItem *pItem;
  513. pItem = (CPageItem*)GetPageItem(nIndex);
  514. if(!pItem) return;
  515. m_nActivePage = nIndex;
  516. m_Title = pItem->m_sText;
  517. SetWindowText(m_Title);
  518. SendMessage(WM_NCPAINT);
  519. Invalidate();
  520. }
  521. void CDockPageBar::OnSize(UINT nType, int cx, int cy)
  522. {
  523. UpdateSize();
  524. Invalidate();
  525. SendMessage(WM_NCPAINT);
  526. }
  527. void CDockPageBar::UpdateSize()
  528. {
  529. UINT PageCount = m_PageList.GetCount();
  530. if(PageCount < 1) return;
  531. CPageItem *pItem;
  532. CRect ClientRect;
  533. if(PageCount == 1)
  534. {
  535. GetClientRect(ClientRect);
  536. pItem = (CPageItem*)GetPageItem(0);;
  537. if(pItem->m_pWnd)
  538. {
  539. pItem->m_pWnd->MoveWindow(ClientRect);
  540. pItem->m_pWnd->ShowWindow(SW_SHOW);
  541. }
  542. return;
  543. }
  544. POSITION pos;
  545. CRect rect,ItemRect,wndRect;
  546. GetWindowRect(&wndRect);
  547. GetClientRect(ClientRect);
  548. //Note: Here the rect/ItemRect' coordinate is for NonClient painting,
  549. // so it is referenced to the current window's topleft.
  550. GetItemGroupRect(&rect);
  551. rect.OffsetRect(-wndRect.TopLeft());
  552. rect.DeflateRect(4,-3,4,3);
  553. DEFLECT_RECT_FOR_STATIC_LINK(rect);
  554. //rect.right-=10;
  555. ItemRect = rect;
  556. int AreaWidth = 0,ItemWidth,ItemIndex=0;
  557. for(pos=m_PageList.GetHeadPosition();pos!=NULL;ItemIndex++)
  558. {
  559. pItem=(CPageItem*)m_PageList.GetNext(pos);
  560. if(pItem)
  561. {
  562. ItemWidth = pItem->m_TabWidth;
  563. AreaWidth += ItemWidth;
  564. ItemRect.right = ItemRect.left+ItemWidth-1;
  565. pItem->m_rect = ItemRect;
  566. ItemRect.left = ItemRect.right + 1;
  567. if(pItem->m_pWnd)
  568. pItem->m_pWnd->MoveWindow(ClientRect);
  569. }
  570. }
  571. if(AreaWidth > rect.Width())
  572. {
  573. ItemRect = rect;
  574. int AreaWidth,MaxWidth = rect.Width()/PageCount;
  575. for(pos=m_PageList.GetHeadPosition();pos!=NULL;)
  576. {
  577. pItem=(CPageItem*)m_PageList.GetNext(pos);
  578. if(pItem)
  579. {
  580. AreaWidth = pItem->m_TabWidth;
  581. ItemWidth = (MaxWidth < AreaWidth)?MaxWidth:AreaWidth;
  582. ItemRect.right = ItemRect.left+ItemWidth;
  583. pItem->m_rect = ItemRect;
  584. ItemRect.left = ItemRect.right + 1;
  585. }
  586. }
  587. }
  588. }
  589. void CDockPageBar::GetItemGroupRect(LPRECT lpRect)
  590. {
  591. CRect rcBar,cr;
  592. GetWindowRect(rcBar);
  593. rcBar.left+=1;
  594. rcBar.right-=3;
  595. rcBar.bottom-=1;
  596. #ifdef STATIC_MFC_LINK
  597. rcBar.top=rcBar.bottom-ITEMBUTTON_HEIGHT;//+2;
  598. #else
  599. rcBar.top=rcBar.bottom-ITEMBUTTON_HEIGHT+2;
  600. #endif
  601. //Note: Here we return the rect, which referenced to the screen
  602. *lpRect=rcBar;
  603. }
  604. void CDockPageBar::GetCaptionRect(LPRECT lpRect)
  605. {
  606. CRect rcBar,cr;
  607. GetWindowRect(rcBar);
  608. rcBar.left+=1;
  609. rcBar.right-=3;
  610. rcBar.top-=1;
  611. rcBar.bottom=rcBar.top+CAPTION_HEIGHT;
  612. *lpRect=rcBar;
  613. }
  614. BOOL CDockPageBar::AddPage(CWnd *pWnd, LPCTSTR sText, UINT IconID)
  615. {
  616. ASSERT(IsWindow(pWnd->m_hWnd));
  617. DWORD dwStyle=pWnd->GetStyle();
  618. if(!(dwStyle&WS_CHILD)){
  619. TRACE0("Force the dock page bar content to be WS_CHILD style!");
  620. pWnd->ModifyStyle(WS_POPUP|WS_OVERLAPPED,WS_CHILD);
  621. }
  622. CPageItem *pItem;
  623. pItem = new CPageItem();
  624. pItem->m_pWnd = pWnd;
  625. pItem->m_pWnd->SetParent (this);
  626. pItem->m_sText = sText;
  627. CClientDC dc(this);
  628. pItem->m_TabWidth = dc.GetTextExtent (sText).cx;
  629. if(IconID)
  630. {
  631. pItem->m_hIcon = AfxGetApp()->LoadIcon(IconID);
  632. pItem->m_TabWidth += 18;
  633. }
  634. else
  635. pItem->m_hIcon = NULL;
  636. pItem->m_TabWidth += 9;
  637. if(pWnd)
  638. {
  639. CRect rect;
  640. GetClientRect(rect);
  641. pWnd->MoveWindow(rect);
  642. pWnd->ShowWindow(SW_HIDE);
  643. }
  644. m_PageList.AddTail(pItem);
  645. UpdateWindow();
  646. return TRUE;
  647. }
  648. BOOL CDockPageBar::AddPage(CPageItem *pPageItem)
  649. {
  650. pPageItem->m_pWnd->SetParent (this);
  651. m_PageList.AddTail(pPageItem);
  652. SetFocus();
  653. //Fore the system to send WM_NCCALCSIZE to update the client rect
  654. SetWindowPos(NULL,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE);
  655. //Use the new size to update the window
  656. UpdateWindow();
  657. return TRUE;
  658. }
  659. BOOL CDockPageBar::AddPage(CDockPageBar *dockPageBar)
  660. {
  661. POSITION pos;
  662. CPageItem* pItem;
  663. for(pos = dockPageBar->m_PageList.GetHeadPosition();pos!=NULL;)
  664. {
  665. pItem=(CPageItem*)dockPageBar->m_PageList.GetNext(pos);
  666. if(pItem)
  667. {
  668. AddPage(pItem);
  669. SetActivePage(m_PageList.GetCount()-1);
  670. }
  671. }
  672. dockPageBar->m_pDockContext->m_pDockSite->FloatControlBar(dockPageBar,CSize(0,0),0);
  673. dockPageBar->m_PageList.RemoveAll();
  674. dockPageBar->m_pDockContext->m_pDockSite->RemoveControlBar(dockPageBar);
  675. UpdateWindow();
  676. return dockPageBar->DestroyWindow ();
  677. }
  678. CPageItem* CDockPageBar::DeletePage()
  679. {
  680. CPageItem *pItem = NULL;
  681. POSITION pos = m_PageList.FindIndex(m_nActivePage);
  682. if(!pos)
  683. {
  684. return NULL;
  685. }
  686. pItem = (CPageItem*)m_PageList.GetAt(pos);
  687. pItem->m_pWnd->ShowWindow(SW_HIDE);
  688. m_PageList.RemoveAt (pos);
  689. m_nActivePage = -1;
  690. //Fore the system to send WM_NCCALCSIZE to update the client rect
  691. if(m_PageList.GetCount()==1)
  692. SetWindowPos(NULL,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE);
  693. UpdateWindow();
  694. return pItem;
  695. }
  696. void CDockPageBar::UpdateWindow()
  697. {
  698. if(m_nActivePage < 0)
  699. SetActivePage(0);
  700. UpdateSize();
  701. Invalidate();
  702. SendMessage(WM_NCPAINT);;
  703. }
  704. void CDockPageBar::DEFLECT_RECT_FOR_STATIC_LINK(CRect & rect)
  705. {
  706. #ifdef STATIC_MFC_LINK
  707. switch(m_dwStyle&CBRS_ALIGN_ANY)
  708. {
  709. case CBRS_ALIGN_LEFT:
  710. rect.DeflateRect(1,1,1,1);
  711. break;
  712. case CBRS_ALIGN_RIGHT:
  713. rect.DeflateRect(1,1,0,1);
  714. break;
  715. case CBRS_ALIGN_TOP:
  716. rect.DeflateRect(1,1,0,1);
  717. break;
  718. case CBRS_ALIGN_BOTTOM:
  719. rect.DeflateRect(1,1,0,1);
  720. break;
  721. default:
  722. ASSERT(FALSE);
  723. }
  724. #endif
  725. }
  726. void CDockPageBar::OnNcPaint()
  727. {
  728. //If you are drawing the plastic line to change the dock page bar'size,
  729. //No painting will be done to avoid the dirty result
  730. if(m_bTracking)
  731. return;
  732. // get window DC that is clipped to the non-client area
  733. CWindowDC dc(this);
  734. CRect rcClient, rcBar;
  735. GetClientRect(rcClient);
  736. ClientToScreen(rcClient);
  737. rcClient.DeflateRect(-1,0,-1,0);
  738. GetWindowRect(rcBar);
  739. rcClient.OffsetRect(-rcBar.TopLeft());
  740. rcBar.OffsetRect(-rcBar.TopLeft());
  741. CDC mdc;
  742. mdc.CreateCompatibleDC(&dc);
  743. CBitmap bm;
  744. bm.CreateCompatibleBitmap(&dc, rcBar.Width(), rcBar.Height());
  745. CBitmap* pOldBm = mdc.SelectObject(&bm);
  746. // draw borders in non-client area
  747. CRect rcDraw = rcBar;
  748. DrawBorders(&mdc, rcDraw);
  749. // erase the NC background
  750. mdc.FillRect(rcDraw, CBrush::FromHandle(
  751. (HBRUSH) GetClassLong(m_hWnd, GCL_HBRBACKGROUND)));
  752. //Draw border edges
  753. if (m_dwSCBStyle & SCBS_SHOWEDGES)
  754. {
  755. CRect rcEdge; // paint the sizing edges
  756. for (int i = 0; i < 4; i++)
  757. if (GetEdgeRect(rcBar, GetEdgeHTCode(i), rcEdge))
  758. mdc.Draw3dRect(rcEdge, ::GetSysColor(COLOR_BTNHIGHLIGHT),
  759. ::GetSysColor(COLOR_BTNSHADOW));
  760. }
  761. //Draw Gripper(the caption bar)
  762. CRect rc=rcClient;
  763. DEFLECT_RECT_FOR_STATIC_LINK(rcClient);
  764. NcPaintGripper(&mdc, rcClient);
  765. rcClient=rc; //restore
  766. //Draw Client Boarder
  767. CRect clientBorderRc=rcBar;
  768. clientBorderRc.left=rcClient.left-1;
  769. clientBorderRc.right=rcClient.right;
  770. DEFLECT_RECT_FOR_STATIC_LINK(clientBorderRc);
  771. //if (IsHorzDocked())
  772. // clientBorderRc.DeflateRect(1,m_cyGripper,5,3);
  773. //else
  774. // clientBorderRc.DeflateRect(1,m_cyGripper,3,3);
  775. if (IsHorzDocked())
  776. clientBorderRc.DeflateRect(0,m_cyGripper,0,3);
  777. else
  778. clientBorderRc.DeflateRect(0,m_cyGripper,0,3);
  779. if(m_PageList.GetCount()>1)
  780. clientBorderRc.DeflateRect(0,0,0,ITEMBUTTON_HEIGHT);
  781. CPen penRect(PS_SOLID, 1, RGB(128,128,128));
  782. HPEN oldPen = (HPEN)mdc.SelectObject (&penRect);
  783. mdc.MoveTo(clientBorderRc.TopLeft());
  784. mdc.LineTo(clientBorderRc.right,clientBorderRc.top);
  785. mdc.LineTo(clientBorderRc.right,clientBorderRc.bottom);
  786. mdc.LineTo(clientBorderRc.left,clientBorderRc.bottom);
  787. mdc.LineTo(clientBorderRc.left,clientBorderRc.top);
  788. mdc.SelectObject (oldPen);
  789. //Draw item tab button
  790. if(m_PageList.GetCount()>1)
  791. {
  792. CPageItem *pItem;
  793. POSITION pos;
  794. int nItemIndex = 0;
  795. CRect rect,wndRect;
  796. GetItemGroupRect(&rect);
  797. GetWindowRect(&wndRect);
  798. rect.OffsetRect(-wndRect.TopLeft());
  799. rect.OffsetRect(0,-1);
  800. DEFLECT_RECT_FOR_STATIC_LINK(rect);
  801. //rect.DeflateRect(0,-2,0,0);
  802. CBrush brush(RGB(247,243,233));
  803. mdc.FillRect(rect,&brush);
  804. CPen penButton(PS_SOLID,1,GetSysColor(COLOR_3DDKSHADOW));
  805. HPEN oldPen = (HPEN)mdc.SelectObject (&penButton);
  806. mdc.MoveTo (rect.TopLeft() );
  807. mdc.LineTo (rect.right, rect.top);
  808. mdc.SelectObject (oldPen);
  809. HFONT oldFont = (HFONT)mdc.SelectObject (m_font);
  810. // draw PageItem
  811. for(pos=m_PageList.GetHeadPosition();pos!=NULL;nItemIndex++)
  812. {
  813. pItem=(CPageItem*)m_PageList.GetNext(pos);
  814. if(pItem)
  815. {
  816. pItem->Draw(&mdc,(m_nActivePage==nItemIndex)?TRUE:FALSE);
  817. }
  818. }
  819. mdc.SelectObject (oldFont);
  820. }
  821. // client area is not our bussiness :)
  822. dc.IntersectClipRect(rcBar);
  823. rcClient.DeflateRect(1,0,1,0);
  824. dc.ExcludeClipRect(rcClient);
  825. dc.BitBlt(0, 0, rcBar.Width(), rcBar.Height(), &mdc, 0, 0, SRCCOPY);
  826. ReleaseDC(&dc);
  827. mdc.SelectObject(pOldBm);
  828. bm.DeleteObject();
  829. mdc.DeleteDC();
  830. }
  831. /////////////////////////////////////////////////////////////////////////////
  832. //
  833. void CDockPageBar::OnNcLButtonUp(UINT nHitTest, CPoint point)
  834. {
  835. if (nHitTest == HTCLOSE)
  836. {
  837. m_pDockSite->ShowControlBar(this, FALSE, FALSE); // hide
  838. }
  839. if (nHitTest == HTSTUD)
  840. OnStudClick();
  841. baseCDockPageBar::OnNcLButtonUp(nHitTest, point);
  842. if(::IsWindow(m_hWnd))
  843. SendMessage(WM_NCPAINT);
  844. }
  845. void CDockPageBar::OnNcLButtonDown(UINT nFlags, CPoint point)
  846. {
  847. #if 1
  848. if (nFlags == HTCLOSE)
  849. {
  850. m_pDockSite->ShowControlBar(this, FALSE, FALSE); // hide
  851. }
  852. if (nFlags == HTSTUD)
  853. OnStudClick();
  854. baseCDockPageBar::OnNcLButtonDown(nFlags, point);
  855. if(::IsWindow(m_hWnd))
  856. SendMessage(WM_NCPAINT);
  857. #else
  858. UINT nItemIndex=0;
  859. POSITION pos;
  860. CPageItem *pItem;
  861. CRect rect;
  862. //Note: Here the rect coordinate is for NonClient painting,
  863. // so it is referenced to the current window's topleft.
  864. GetWindowRect(&rect);
  865. point.Offset(-rect.TopLeft());
  866. if (HTITEMBUTTON==nFlags){
  867. for(pos=m_PageList.GetHeadPosition();pos!=NULL;nItemIndex++)
  868. {
  869. pItem=(CPageItem*)m_PageList.GetNext(pos);
  870. if(pItem)
  871. {
  872. if(pItem->m_rect.PtInRect(point))
  873. {
  874. SetFocus();
  875. SetActivePage(nItemIndex);
  876. CanDrag(point); // drag PageItem
  877. return;
  878. }
  879. }
  880. }
  881. }
  882. //Note: Here the rect coordinate is referenced to the screen
  883. point.Offset(rect.TopLeft());
  884. if ((nFlags >= HTSIZEFIRST) && (nFlags <= HTSIZELAST))
  885. {
  886. baseCDockPageBar::OnNcLButtonDown(nFlags, point);
  887. return;
  888. }
  889. ((CDockPageBarContext*)m_pDockContext)->m_isPage = FALSE;
  890. if (m_pDockBar != NULL&&HTGRIPPER==nFlags)
  891. {
  892. // start the drag
  893. SetFocus();
  894. ASSERT(m_pDockContext != NULL);
  895. m_pDockContext->StartDrag(point);
  896. }
  897. else
  898. CWnd::OnNcLButtonDown(nFlags, point);
  899. #endif
  900. }
  901. void CDockPageBar::OnNcLButtonDblClk(UINT nFlags, CPoint point)
  902. {
  903. if (HTGRIPPER==nFlags&&m_pDockBar != NULL)
  904. {
  905. // start the drag
  906. ASSERT(m_pDockContext != NULL);
  907. m_pDockContext->ToggleDocking();
  908. }
  909. else
  910. CWnd::OnNcLButtonDblClk(nFlags, point);
  911. }
  912. void CDockPageBar::EnableDocking(DWORD dwDockStyle)
  913. {
  914. // must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only
  915. ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);
  916. // cannot have the CBRS_FLOAT_MULTI style
  917. ASSERT((dwDockStyle & CBRS_FLOAT_MULTI) == 0);
  918. // the bar must have CBRS_SIZE_DYNAMIC style
  919. ASSERT((m_dwStyle & CBRS_SIZE_DYNAMIC) != 0);
  920. m_dwDockStyle = dwDockStyle;
  921. if (m_pDockContext == NULL)
  922. {
  923. m_pDockContext = new CDockPageBarContext(this);
  924. m_pDPBContext.AddTail(m_pDockContext); //hengai
  925. }
  926. // permanently wire the bar's owner to its current parent
  927. if (m_hWndOwner == NULL)
  928. m_hWndOwner = ::GetParent(m_hWnd);
  929. }
  930. void CDockPageBar::CanDrag(CPoint pt)
  931. {
  932. SetCapture();
  933. // get messages until capture lost or cancelled/accepted
  934. while (CWnd::GetCapture() == this)
  935. {
  936. MSG msg;
  937. if (!::GetMessage(&msg, NULL, 0, 0))
  938. {
  939. AfxPostQuitMessage(msg.wParam);
  940. break;
  941. }
  942. switch (msg.message)
  943. {
  944. case WM_LBUTTONUP:
  945. ReleaseCapture();
  946. break;
  947. case WM_MOUSEMOVE:
  948. Move(msg.pt);
  949. break;
  950. default:
  951. DispatchMessage(&msg);
  952. break;
  953. }
  954. }
  955. }
  956. void CDockPageBar::Move(CPoint pt)
  957. {
  958. CRect rect,wndRect;
  959. //Note: Here the rect coordinate is for NonClient painting,
  960. // so it is referenced to the current window's topleft.
  961. GetWindowRect(&wndRect);
  962. GetItemGroupRect(&rect);
  963. rect.OffsetRect(-wndRect.TopLeft());
  964. pt.Offset(-wndRect.TopLeft());
  965. if(rect.PtInRect(pt))
  966. {
  967. int nItemIndex=0;
  968. POSITION pos;
  969. CPageItem *pItem;
  970. for(pos=m_PageList.GetHeadPosition();pos!=NULL;nItemIndex++)
  971. {
  972. pItem=(CPageItem*)m_PageList.GetNext(pos);
  973. if(pItem)
  974. {
  975. if(pItem->m_rect.PtInRect(pt))
  976. {
  977. if(nItemIndex != m_nActivePage)
  978. {
  979. POSITION oldPos = m_PageList.FindIndex(m_nActivePage);
  980. POSITION curPos = m_PageList.FindIndex(nItemIndex);
  981. CPageItem *pOldItem = (CPageItem*)m_PageList.GetAt(oldPos);
  982. // exchange PageItem
  983. m_PageList.SetAt(oldPos, pItem);
  984. m_PageList.SetAt(curPos, pOldItem);
  985. m_nActivePage = nItemIndex;
  986. UpdateWindow();
  987. break;
  988. }
  989. }
  990. }
  991. }
  992. }
  993. else
  994. {
  995. ReleaseCapture();
  996. StartDrag(pt);
  997. }
  998. }
  999. void CDockPageBar::StartDrag(CPoint pt)
  1000. {
  1001. ClientToScreen(&pt);
  1002. ((CDockPageBarContext*)m_pDockContext)->m_isPage = TRUE;
  1003. m_pDockContext->StartDrag(pt);
  1004. ((CDockPageBarContext*)m_pDockContext)->m_isPage = FALSE;
  1005. }
  1006. /////////////////////////////////////////////////////////////////////////////
  1007. // CDockPageBarContext
  1008. #define _AfxGetDlgCtrlID(hWnd) ((UINT)(WORD)::GetDlgCtrlID(hWnd))
  1009. #define CX_BORDER 1
  1010. #define CY_BORDER 1
  1011. #define CBRS_ALIGN_INSERT_PAGE 0x0001L // drag to another CDockPageBar
  1012. #define HORZF(dw) (dw & CBRS_ORIENT_HORZ)
  1013. #define VERTF(dw) (dw & CBRS_ORIENT_VERT)
  1014. static void AFXAPI _AfxAdjustRectangle(CRect& rect, CPoint pt)
  1015. {
  1016. int nXOffset = (pt.x < rect.left) ? (pt.x - rect.left) :
  1017. (pt.x > rect.right) ? (pt.x - rect.right) : 0;
  1018. int nYOffset = (pt.y < rect.top) ? (pt.y - rect.top) :
  1019. (pt.y > rect.bottom) ? (pt.y - rect.bottom) : 0;
  1020. rect.OffsetRect(nXOffset, nYOffset);
  1021. }
  1022. void CDockPageBarContext::StartDrag(CPoint pt)
  1023. {
  1024. ASSERT_VALID(m_pBar);
  1025. m_bDragging = TRUE;
  1026. InitLoop();
  1027. // GetWindowRect returns screen coordinates(not mirrored),
  1028. // so if the desktop is mirrored then turn off mirroring
  1029. // for the desktop dc so that we get correct focus rect drawn.
  1030. // This layout change should be remembered, just in case ...
  1031. if (m_pDC->GetLayout() & LAYOUT_RTL)
  1032. m_pDC->SetLayout(LAYOUT_LTR);
  1033. if (m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC)
  1034. {
  1035. // get true bar size (including borders)
  1036. CRect rect;
  1037. m_pBar->GetWindowRect(rect);
  1038. m_ptLast = pt;
  1039. CSize sizeHorz = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK);
  1040. CSize sizeVert = m_pBar->CalcDynamicLayout(0, LM_VERTDOCK);
  1041. CSize sizeFloat = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH);
  1042. m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
  1043. m_rectDragVert = CRect(rect.TopLeft(), sizeVert);
  1044. // calculate frame dragging rectangle
  1045. m_rectFrameDragHorz = CRect(rect.TopLeft(), sizeFloat);
  1046. m_rectFrameDragVert = CRect(rect.TopLeft(), sizeFloat);
  1047. CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
  1048. CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
  1049. m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  1050. m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  1051. }
  1052. else if (m_pBar->m_dwStyle & CBRS_SIZE_FIXED)
  1053. {
  1054. // get true bar size (including borders)
  1055. CRect rect;
  1056. m_pBar->GetWindowRect(rect);
  1057. m_ptLast = pt;
  1058. CSize sizeHorz = m_pBar->CalcDynamicLayout(-1, LM_HORZ | LM_HORZDOCK);
  1059. CSize sizeVert = m_pBar->CalcDynamicLayout(-1, LM_VERTDOCK);
  1060. // calculate frame dragging rectangle
  1061. m_rectFrameDragHorz = m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
  1062. m_rectFrameDragVert = m_rectDragVert = CRect(rect.TopLeft(), sizeVert);
  1063. CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
  1064. CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
  1065. m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  1066. m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  1067. }
  1068. else
  1069. {
  1070. // get true bar size (including borders)
  1071. CRect rect;
  1072. m_pBar->GetWindowRect(rect);
  1073. m_ptLast = pt;
  1074. BOOL bHorz = HORZF(m_dwStyle);
  1075. DWORD dwMode = !bHorz ? (LM_HORZ | LM_HORZDOCK) : LM_VERTDOCK;
  1076. CSize size = m_pBar->CalcDynamicLayout(-1, dwMode);
  1077. // calculate inverted dragging rect
  1078. if (bHorz)
  1079. {
  1080. m_rectDragHorz = rect;
  1081. m_rectDragVert = CRect(CPoint(pt.x - rect.Height()/2, rect.top), size);
  1082. }
  1083. else // vertical orientation
  1084. {
  1085. m_rectDragVert = rect;
  1086. m_rectDragHorz = CRect(CPoint(rect.left, pt.y - rect.Width()/2), size);
  1087. }
  1088. // calculate frame dragging rectangle
  1089. m_rectFrameDragHorz = m_rectDragHorz;
  1090. m_rectFrameDragVert = m_rectDragVert;
  1091. CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
  1092. CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
  1093. m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  1094. m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  1095. }
  1096. // adjust rectangles so that point is inside
  1097. _AfxAdjustRectangle(m_rectDragHorz, pt);
  1098. _AfxAdjustRectangle(m_rectDragVert, pt);
  1099. _AfxAdjustRectangle(m_rectFrameDragHorz, pt);
  1100. _AfxAdjustRectangle(m_rectFrameDragVert, pt);
  1101. // initialize tracking state and enter tracking loop
  1102. m_dwOverDockStyle = CanDock();
  1103. Move(pt); // call it here to handle special keys
  1104. Track();
  1105. }
  1106. CDockPageBarContext::~CDockPageBarContext(void)
  1107. {
  1108. }
  1109. //hengai
  1110. void CDockPageBarContext::FreeAll()
  1111. {
  1112. for(POSITION pos = m_pDPBar.GetHeadPosition(); pos;)
  1113. {
  1114. CDockPageBar* pBar = (CDockPageBar*)m_pDPBar.GetNext(pos);
  1115. ASSERT(pBar != NULL);
  1116. delete pBar->m_pDockBar; pBar->m_pDockBar = NULL;
  1117. delete pBar; pBar = NULL;
  1118. }
  1119. m_pDPBar.RemoveAll (); // cuick 2004/04/08
  1120. }
  1121. BOOL CDockPageBarContext::Track()
  1122. {
  1123. // don't handle if capture already set
  1124. if (::GetCapture() != NULL)
  1125. return FALSE;
  1126. // set capture to the window which received this message
  1127. m_pBar->SetCapture();
  1128. ASSERT(m_pBar == CWnd::GetCapture());
  1129. // get messages until capture lost or cancelled/accepted
  1130. while (CWnd::GetCapture() == m_pBar)
  1131. {
  1132. MSG msg;
  1133. if (!::GetMessage(&msg, NULL, 0, 0))
  1134. {
  1135. AfxPostQuitMessage(msg.wParam);
  1136. break;
  1137. }
  1138. switch (msg.message)
  1139. {
  1140. case WM_LBUTTONUP:
  1141. if (m_bDragging)
  1142. EndDrag();
  1143. else
  1144. EndResize();
  1145. return TRUE;
  1146. case WM_MOUSEMOVE:
  1147. if (m_bDragging)
  1148. Move(msg.pt);
  1149. else
  1150. Stretch(msg.pt);
  1151. break;
  1152. case WM_KEYUP:
  1153. if (m_bDragging)
  1154. OnKey((int)msg.wParam, FALSE);
  1155. break;
  1156. case WM_KEYDOWN:
  1157. if (m_bDragging)
  1158. OnKey((int)msg.wParam, TRUE);
  1159. if (msg.wParam == VK_ESCAPE)
  1160. {
  1161. CancelLoop();
  1162. return FALSE;
  1163. }
  1164. break;
  1165. case WM_RBUTTONDOWN:
  1166. CancelLoop();
  1167. return FALSE;
  1168. // just dispatch rest of the messages
  1169. default:
  1170. DispatchMessage(&msg);
  1171. break;
  1172. }
  1173. }
  1174. CancelLoop();
  1175. return FALSE;
  1176. }
  1177. CDockPageBar * CDockPageBarContext::TryToGetDockPageBar(POINT pt)
  1178. {
  1179. CFrameWnd * pFrameWnd=(CFrameWnd *)AfxGetMainWnd();
  1180. POSITION pos = pFrameWnd->m_listControlBars.GetHeadPosition();
  1181. while (pos != NULL)
  1182. {
  1183. CControlBar* pBar = (CControlBar*)pFrameWnd->m_listControlBars.GetNext(pos);
  1184. ASSERT(pBar != NULL);
  1185. if (pBar->IsKindOf(RUNTIME_CLASS(CDockPageBar)))
  1186. {
  1187. CRect rect;
  1188. pBar->GetWindowRect(&rect);
  1189. if(rect.PtInRect(pt)&&!pBar->IsFloating())
  1190. return (CDockPageBar*)pBar;
  1191. }
  1192. }
  1193. return NULL;
  1194. }
  1195. //////////////////////////////////////////////////////////////////////
  1196. // drag and draw focus rect
  1197. void CDockPageBarContext::Move(CPoint pt)
  1198. {
  1199. CPoint ptOffset = pt - m_ptLast;
  1200. if(TRUE == isDockPage(pt))
  1201. {
  1202. m_dwOverDockStyle = CBRS_ALIGN_INSERT_PAGE;
  1203. }
  1204. else
  1205. {
  1206. //MACRO Definition for the adavnced docking
  1207. //#define CBRS_ALIGN_INSERT_PAGE 0x0001L
  1208. #define DOCK_ALIGN_INSERT_PAGE CBRS_ALIGN_INSERT_PAGE
  1209. #define DOCK_IN_FRAME_CLIENT 0x02
  1210. #define DOCK_IN_FRAME_BORDER 0x04
  1211. #define DOCK_IN_DOCK_PAGE_BAR 0x08
  1212. #define HOR_BORDER_DETECT_PIXELS max(CAPTION_HEIGHT+8,ITEMBUTTON_HEIGHT+8)
  1213. #define VER_BORDER_DETECT_PIXELS 16
  1214. #define BORDER_DETECT_LEFT 0x0100
  1215. #define BORDER_DETECT_RIGHT 0x0200
  1216. #define BORDER_DETECT_TOP 0x0400
  1217. #define BORDER_DETECT_BOTTOM 0x0800
  1218. //POINT pt;
  1219. //GetCursorPos(&pt);
  1220. CWnd *pCurWnd= CWnd::FromHandle(::WindowFromPoint(pt));
  1221. CDockPageBar *pDockPageBarWnd;
  1222. DWORD borderDetect=0;
  1223. CRect mainFrameRect,mainFrameClientRect;
  1224. DWORD dwDockStyle=0;
  1225. m_bAdvancedDock=FALSE;
  1226. m_endDragDockStruct.dwDockStyle=0;
  1227. CWnd *pMainFrameWnd=AfxGetMainWnd();
  1228. pMainFrameWnd->GetWindowRect(&mainFrameRect);
  1229. //Try to find a docking position
  1230. if(mainFrameRect.PtInRect(pt))
  1231. {
  1232. //Get the pure client rect of the frame wnd
  1233. GET_MAIN_FRAME_PURE_CLIENT(pMainFrameWnd,mainFrameClientRect);
  1234. if((pDockPageBarWnd=TryToGetDockPageBar(pt))!=NULL){
  1235. pDockPageBarWnd->GetWindowRect(&m_curRect);
  1236. m_endDragDockStruct.dwDockStyle=dwDockStyle=DOCK_IN_DOCK_PAGE_BAR;
  1237. m_bAdvancedDock=TRUE;
  1238. }else if(mainFrameClientRect.PtInRect(pt)){
  1239. m_curRect=mainFrameClientRect;
  1240. m_endDragDockStruct.dwDockStyle=dwDockStyle=DOCK_IN_FRAME_CLIENT;
  1241. m_bAdvancedDock=TRUE;
  1242. }else{ //the bar is move to the non client area (tool bar for example)
  1243. CRect rc=mainFrameClientRect;
  1244. rc.DeflateRect(-VER_BORDER_DETECT_PIXELS,-HOR_BORDER_DETECT_PIXELS);
  1245. if(rc.PtInRect(pt)){
  1246. m_curRect=rc;
  1247. m_endDragDockStruct.dwDockStyle=dwDockStyle=DOCK_IN_FRAME_BORDER;
  1248. m_bAdvancedDock=TRUE;
  1249. }else{
  1250. const CRuntimeClass * pRunTimeClass=pCurWnd->GetRuntimeClass();
  1251. TRACE0("Unprocessed window type:");
  1252. TRACE0(pRunTimeClass->m_lpszClassName);
  1253. TRACE0("\r\n");
  1254. m_bAdvancedDock=FALSE;
  1255. }
  1256. }
  1257. }else{
  1258. CRect rc=mainFrameRect;
  1259. rc.DeflateRect(-VER_BORDER_DETECT_PIXELS,-HOR_BORDER_DETECT_PIXELS);
  1260. if(rc.PtInRect(pt)){
  1261. m_curRect=rc;
  1262. m_endDragDockStruct.dwDockStyle=dwDockStyle=DOCK_IN_FRAME_BORDER;
  1263. m_bAdvancedDock=TRUE;
  1264. }else{
  1265. const CRuntimeClass * pRunTimeClass=pCurWnd->GetRuntimeClass();
  1266. TRACE0("Unprocessed window type:");
  1267. TRACE0(pRunTimeClass->m_lpszClassName);
  1268. TRACE0("\r\n");
  1269. m_bAdvancedDock=FALSE;
  1270. }
  1271. }
  1272. //Check whether the current position can be used for the advanced docking :-)
  1273. if(m_bAdvancedDock&&
  1274. m_curRect.Width()>VER_BORDER_DETECT_PIXELS*2+1&&
  1275. m_curRect.Height()>HOR_BORDER_DETECT_PIXELS*2+1)
  1276. {
  1277. //Init the current detection border rect
  1278. CRect rectLeft(m_curRect.TopLeft(),CSize(VER_BORDER_DETECT_PIXELS,m_curRect.Height())),
  1279. rectTop(m_curRect.TopLeft(),CSize(m_curRect.Width(),HOR_BORDER_DETECT_PIXELS));
  1280. CRect rectRight=rectLeft,rectBottom=rectTop;
  1281. rectRight.OffsetRect(m_curRect.Width()-VER_BORDER_DETECT_PIXELS,0);
  1282. rectBottom.OffsetRect(0,m_curRect.Height()-HOR_BORDER_DETECT_PIXELS);
  1283. borderDetect|=rectLeft.PtInRect(pt) ? BORDER_DETECT_LEFT:0;
  1284. borderDetect|=rectRight.PtInRect(pt) ? BORDER_DETECT_RIGHT:0;
  1285. borderDetect|=rectTop.PtInRect(pt) ? BORDER_DETECT_TOP:0;
  1286. borderDetect|=rectBottom.PtInRect(pt) ? BORDER_DETECT_BOTTOM:0;
  1287. ASSERT(!((borderDetect&BORDER_DETECT_LEFT)&&(borderDetect&BORDER_DETECT_RIGHT)));
  1288. ASSERT(!((borderDetect&BORDER_DETECT_TOP)&&(borderDetect&BORDER_DETECT_BOTTOM)));
  1289. if(borderDetect&BORDER_DETECT_LEFT)
  1290. {
  1291. borderDetect=BORDER_DETECT_LEFT;
  1292. if(DOCK_IN_FRAME_CLIENT==dwDockStyle||DOCK_IN_FRAME_BORDER==dwDockStyle)
  1293. dwDockStyle=CBRS_ALIGN_LEFT;
  1294. else
  1295. dwDockStyle=pDockPageBarWnd->m_dwStyle;
  1296. }else if(borderDetect&BORDER_DETECT_RIGHT){
  1297. borderDetect=BORDER_DETECT_RIGHT;
  1298. if(DOCK_IN_FRAME_CLIENT==dwDockStyle||DOCK_IN_FRAME_BORDER==dwDockStyle)
  1299. dwDockStyle=CBRS_ALIGN_RIGHT;
  1300. else
  1301. dwDockStyle=pDockPageBarWnd->m_dwStyle;
  1302. }else if(borderDetect&BORDER_DETECT_TOP){
  1303. borderDetect=BORDER_DETECT_TOP;
  1304. if(DOCK_IN_FRAME_CLIENT==dwDockStyle||DOCK_IN_FRAME_BORDER==dwDockStyle)
  1305. dwDockStyle=CBRS_ALIGN_TOP;
  1306. else
  1307. dwDockStyle=pDockPageBarWnd->m_dwStyle;
  1308. }else if(borderDetect&BORDER_DETECT_BOTTOM){
  1309. borderDetect=BORDER_DETECT_BOTTOM;
  1310. if(DOCK_IN_FRAME_CLIENT==dwDockStyle||DOCK_IN_FRAME_BORDER==dwDockStyle)
  1311. dwDockStyle=CBRS_ALIGN_BOTTOM;
  1312. else
  1313. dwDockStyle=pDockPageBarWnd->m_dwStyle;
  1314. }
  1315. CRect rc;
  1316. m_pBar->GetWindowRect(&rc);
  1317. INT hightWidth;
  1318. if(DOCK_IN_FRAME_BORDER==m_endDragDockStruct.dwDockStyle)
  1319. {
  1320. m_curRect.DeflateRect(VER_BORDER_DETECT_PIXELS,HOR_BORDER_DETECT_PIXELS);
  1321. if(borderDetect&(BORDER_DETECT_LEFT|BORDER_DETECT_RIGHT)){
  1322. if(m_curRect==mainFrameClientRect)
  1323. (borderDetect&BORDER_DETECT_LEFT ? m_curRect.left:m_curRect.right)=
  1324. (borderDetect&BORDER_DETECT_LEFT ? mainFrameClientRect.left:mainFrameClientRect.right);
  1325. else
  1326. (borderDetect&BORDER_DETECT_LEFT ? m_curRect.left:m_curRect.right)=
  1327. (borderDetect&BORDER_DETECT_LEFT ? mainFrameRect.left:mainFrameRect.right);
  1328. m_curRect.top=mainFrameRect.top;
  1329. m_curRect.bottom=mainFrameRect.bottom;
  1330. }else{
  1331. if(m_curRect==mainFrameClientRect)
  1332. (borderDetect&BORDER_DETECT_TOP ? m_curRect.top:m_curRect.bottom)=
  1333. (borderDetect&BORDER_DETECT_TOP ? mainFrameClientRect.top:mainFrameClientRect.bottom);
  1334. else
  1335. (borderDetect&BORDER_DETECT_TOP ? m_curRect.top:m_curRect.bottom)=
  1336. (borderDetect&BORDER_DETECT_TOP ? mainFrameRect.top:mainFrameRect.bottom);
  1337. m_curRect.left=mainFrameRect.left;
  1338. m_curRect.right=mainFrameRect.right;
  1339. }
  1340. hightWidth=borderDetect&(BORDER_DETECT_LEFT|BORDER_DETECT_RIGHT) ? mainFrameRect.Width():mainFrameRect.Height();
  1341. }else
  1342. hightWidth=borderDetect&(BORDER_DETECT_LEFT|BORDER_DETECT_RIGHT) ? rc.Width():rc.Height();
  1343. switch(borderDetect)
  1344. {
  1345. case BORDER_DETECT_LEFT:
  1346. m_curRect.right=m_curRect.left+min(hightWidth,m_curRect.Width()/2);
  1347. break;
  1348. case BORDER_DETECT_RIGHT:
  1349. m_curRect.left=m_curRect.right-min(hightWidth,m_curRect.Width()/2);
  1350. break;
  1351. case BORDER_DETECT_TOP:
  1352. m_curRect.bottom=m_curRect.top+min(hightWidth,m_curRect.Height()/2);
  1353. break;
  1354. case BORDER_DETECT_BOTTOM:
  1355. m_curRect.top=m_curRect.bottom-min(hightWidth,m_curRect.Height()/2);
  1356. break;
  1357. default:
  1358. m_bAdvancedDock=FALSE;
  1359. }
  1360. }else
  1361. m_bAdvancedDock=FALSE;
  1362. if(m_bAdvancedDock){
  1363. ASSERT(VERTF(dwDockStyle)||HORZF(dwDockStyle));
  1364. m_dwOverDockStyle=dwDockStyle;
  1365. if(DOCK_IN_DOCK_PAGE_BAR==m_endDragDockStruct.dwDockStyle){
  1366. m_endDragDockStruct.pDockPageBar=pDockPageBarWnd;
  1367. m_endDragDockStruct.dwDockStyle|=borderDetect;
  1368. }
  1369. else
  1370. m_endDragDockStruct.pDockPageBar=NULL;;
  1371. m_rectDragVert.OffsetRect(ptOffset);
  1372. m_rectDragHorz.OffsetRect(ptOffset);
  1373. m_rectFrameDragHorz.OffsetRect(ptOffset);
  1374. m_rectFrameDragVert.OffsetRect(ptOffset);
  1375. }else{
  1376. // offset all drag rects to new position
  1377. m_rectDragHorz.OffsetRect(ptOffset);
  1378. m_rectFrameDragHorz.OffsetRect(ptOffset);
  1379. m_rectDragVert.OffsetRect(ptOffset);
  1380. m_rectFrameDragVert.OffsetRect(ptOffset);
  1381. m_dwOverDockStyle = 0;/*m_bForceFrame ? 0 : CanDock();*/
  1382. }
  1383. }
  1384. m_ptLast = pt;
  1385. // update feedback
  1386. if(FALSE == m_isMe)
  1387. DrawFocusRect();
  1388. else
  1389. DrawFocusRect(TRUE);
  1390. }
  1391. // get the target CDockPageBar on mouse move
  1392. BOOL CDockPageBarContext::isDockPage(CPoint pt)
  1393. {
  1394. m_isMe = FALSE;
  1395. HWND hWnd = WindowFromPoint(pt);
  1396. CWnd * pWnd=CWnd::FromHandle (hWnd);
  1397. if(pWnd->IsKindOf (RUNTIME_CLASS(CDockPageBar)))
  1398. {
  1399. CDockPageBar* pBar = (CDockPageBar*)pWnd;
  1400. if(pBar != m_pBar)
  1401. {
  1402. CRect rectCaption,rectItem;
  1403. pBar->GetWindowRect (&rectCaption);
  1404. rectItem=rectCaption;
  1405. rectCaption.bottom = rectCaption.top + pBar->m_cyGripper;
  1406. rectItem.top=rectItem.bottom-ITEMBUTTON_HEIGHT;
  1407. if(rectCaption.PtInRect (pt)||
  1408. (pBar->m_PageList.GetCount()>1)&&(rectItem.PtInRect(pt)))
  1409. {
  1410. m_pTgDockPage = pBar;
  1411. pBar->GetWindowRect (&m_addRect);
  1412. return TRUE;
  1413. }
  1414. }
  1415. else
  1416. {
  1417. m_isMe = TRUE;
  1418. }
  1419. }else if(pWnd->IsKindOf(RUNTIME_CLASS(CMiniDockFrameWnd))){ //Docking in the float window
  1420. CMiniDockFrameWnd * pFrameWnd=(CMiniDockFrameWnd *)pWnd;
  1421. //Get the DockPageBar on the Floating MiniDockFrameWnd
  1422. CDockPageBar* pBar = (CDockPageBar* )CWnd::FromHandle(pWnd->m_hWndOwner);
  1423. ASSERT(pBar->IsKindOf(RUNTIME_CLASS(CDockPageBar)));
  1424. if(pBar != m_pBar)
  1425. {
  1426. CRect rectCaption,rectItem;
  1427. pFrameWnd->GetWindowRect (&rectCaption);
  1428. pBar->GetWindowRect(&rectItem);
  1429. rectCaption.bottom = rectCaption.top + pBar->m_cyGripper;
  1430. rectItem.top=rectItem.bottom-ITEMBUTTON_HEIGHT;
  1431. if(rectCaption.PtInRect (pt)||
  1432. (pBar->m_PageList.GetCount()>1)&&(rectItem.PtInRect(pt)))
  1433. {
  1434. m_pTgDockPage = pBar;
  1435. pBar->GetWindowRect (&m_addRect);
  1436. return TRUE;
  1437. }
  1438. }
  1439. else
  1440. {
  1441. m_isMe = TRUE;
  1442. }
  1443. }
  1444. m_pTgDockPage = NULL;
  1445. return FALSE;
  1446. }
  1447. void CDockPageBarContext::EndDrag()
  1448. {
  1449. CancelLoop();
  1450. if(TRUE == m_isMe)
  1451. return;
  1452. // drag to another CDockPageBar
  1453. if((NULL != m_pTgDockPage) && (m_dwOverDockStyle == CBRS_ALIGN_INSERT_PAGE))
  1454. {
  1455. if(TRUE == m_isPage) // drag PageItem
  1456. {
  1457. CPageItem * pItem = (CPageItem *)((CDockPageBar*)m_pBar)->DeletePage ();
  1458. m_pTgDockPage->AddPage(pItem);
  1459. }
  1460. else // drag a CDockPageBar object to another CDockPageBar
  1461. {
  1462. m_pTgDockPage->AddPage((CDockPageBar*)m_pBar);
  1463. }
  1464. return;
  1465. }
  1466. // if drag a PageItem, create a new bar which contains the PageItem
  1467. CControlBar* pBar;
  1468. if(TRUE == m_isPage) // drag PageItem (dock or float)
  1469. pBar = CreateNewBar();
  1470. else
  1471. pBar = m_pBar; // drag CDockPageBar
  1472. if(NULL == pBar)
  1473. return;
  1474. if (m_dwOverDockStyle != 0)
  1475. {
  1476. CDockBar* pDockBar;
  1477. CFrameWnd * pFrameWnd=(CFrameWnd *)AfxGetMainWnd();
  1478. //Find the specific docking bar
  1479. POSITION pos = pFrameWnd->m_listControlBars.GetHeadPosition();
  1480. while (pos != NULL)
  1481. {
  1482. pDockBar = (CDockBar*)pFrameWnd->m_listControlBars.GetNext(pos);
  1483. if (pDockBar->IsDockBar() && pDockBar->IsWindowVisible() &&
  1484. (pDockBar->m_dwStyle & m_dwOverDockStyle & CBRS_ALIGN_ANY) &&
  1485. (!pDockBar->m_bFloating ||
  1486. (m_dwOverDockStyle & pDockBar->m_dwStyle & CBRS_FLOAT_MULTI)))
  1487. {
  1488. break;
  1489. }
  1490. }
  1491. ASSERT(pDockBar != NULL);
  1492. CRect rect;
  1493. if(m_bAdvancedDock){
  1494. rect=m_curRect;
  1495. if(m_endDragDockStruct.dwDockStyle&DOCK_IN_DOCK_PAGE_BAR)
  1496. {
  1497. ASSERT(m_endDragDockStruct.pDockPageBar);
  1498. ASSERT(m_endDragDockStruct.pDockPageBar->IsKindOf(RUNTIME_CLASS(CDockPageBar)));
  1499. CRect rc;
  1500. m_endDragDockStruct.pDockPageBar->GetWindowRect(&rc);
  1501. if(VERTF(m_endDragDockStruct.pDockPageBar->m_dwStyle))
  1502. {
  1503. if(m_endDragDockStruct.dwDockStyle&BORDER_DETECT_RIGHT)
  1504. rect.OffsetRect(rc.Width()/2,0);
  1505. else if(m_endDragDockStruct.dwDockStyle&BORDER_DETECT_LEFT)
  1506. rect.OffsetRect(-rc.Width()/2,0);
  1507. }else if(HORZF(m_endDragDockStruct.pDockPageBar->m_dwStyle))
  1508. {
  1509. if(m_endDragDockStruct.dwDockStyle&BORDER_DETECT_TOP)
  1510. rect.OffsetRect(0,-rc.Width()/2);
  1511. else if(m_endDragDockStruct.dwDockStyle&BORDER_DETECT_BOTTOM)
  1512. rect.OffsetRect(0,rc.Width()/2);
  1513. }else
  1514. ASSERT(FALSE);
  1515. }
  1516. //Advanced docking :)
  1517. if(VERTF(m_dwOverDockStyle))
  1518. {
  1519. ((CDockPageBar*)pBar)->GetVerSize().cx=rect.Width();
  1520. ((CDockPageBar*)pBar)->GetVerSize().cy=rect.Height();
  1521. }else if(HORZF(m_dwOverDockStyle))
  1522. {
  1523. ((CDockPageBar*)pBar)->GetHorSize().cx=rect.Width();
  1524. ((CDockPageBar*)pBar)->GetHorSize().cy=rect.Height();
  1525. }else
  1526. ASSERT(FALSE);
  1527. }else
  1528. rect= (m_dwOverDockStyle & CBRS_ORIENT_VERT) ? m_rectDragVert : m_rectDragHorz;
  1529. UINT uID = _AfxGetDlgCtrlID(pDockBar->m_hWnd);
  1530. if (uID >= AFX_IDW_DOCKBAR_TOP &&
  1531. uID <= AFX_IDW_DOCKBAR_BOTTOM)
  1532. {
  1533. m_uMRUDockID = uID;
  1534. m_rectMRUDockPos = rect;
  1535. pDockBar->ScreenToClient(&m_rectMRUDockPos);
  1536. }
  1537. // dock it at the specified position, RecalcLayout will snap
  1538. m_pDockSite->DockControlBar(pBar, pDockBar, &rect);
  1539. m_pDockSite->RecalcLayout();
  1540. if(DOCK_IN_DOCK_PAGE_BAR==m_endDragDockStruct.dwDockStyle)
  1541. m_endDragDockStruct.pDockPageBar->SetFocus();
  1542. }
  1543. else if ((m_dwStyle & CBRS_SIZE_DYNAMIC) || (HORZF(m_dwStyle) && !m_bFlip) ||
  1544. (VERTF(m_dwStyle) && m_bFlip))
  1545. {
  1546. m_dwMRUFloatStyle = CBRS_ALIGN_TOP | (m_dwDockStyle & CBRS_FLOAT_MULTI);
  1547. m_ptMRUFloatPos = m_rectFrameDragHorz.TopLeft();
  1548. m_pDockSite->FloatControlBar(pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle);
  1549. }
  1550. else // vertical float
  1551. {
  1552. m_dwMRUFloatStyle = CBRS_ALIGN_LEFT | (m_dwDockStyle & CBRS_FLOAT_MULTI);
  1553. m_ptMRUFloatPos = m_rectFrameDragVert.TopLeft();
  1554. m_pDockSite->FloatControlBar(pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle);
  1555. }
  1556. }
  1557. CDockPageBar* CDockPageBarContext::CreateNewBar()
  1558. {
  1559. CPageItem * pItem = (CPageItem *)((CDockPageBar*)m_pBar)->DeletePage ();
  1560. CDockPageBar* pBar = new CDockPageBar();
  1561. if (!(pBar->Create(_T("New Bar"), m_pDockSite, 12345)))
  1562. {
  1563. TRACE0("Failed to create mybar\n");
  1564. return NULL; // fail to create
  1565. }
  1566. pBar->SetBarStyle(m_pBar->GetBarStyle() |
  1567. CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
  1568. pBar->EnableDocking(CBRS_ALIGN_ANY);
  1569. pBar->AddPage (pItem);
  1570. m_pDPBar.AddTail(pBar);
  1571. return pBar;
  1572. }
  1573. void CDockPageBarContext::DrawFocusRect(BOOL bRemoveRect)
  1574. {
  1575. ASSERT(m_pDC != NULL);
  1576. // default to thin frame
  1577. CSize size(3,3);
  1578. // determine new rect and size
  1579. CRect rect;
  1580. CBrush* pWhiteBrush = CBrush::FromHandle((HBRUSH)::GetStockObject(WHITE_BRUSH));
  1581. CBrush* pDitherBrush = CDC::GetHalftoneBrush();
  1582. CBrush* pBrush = pDitherBrush;
  1583. if(m_bAdvancedDock)
  1584. {
  1585. rect=m_curRect;;
  1586. }else{
  1587. if (HORZF(m_dwOverDockStyle))
  1588. rect = m_rectDragHorz;
  1589. else if (VERTF(m_dwOverDockStyle))
  1590. rect = m_rectDragVert;
  1591. else
  1592. {
  1593. // use thick frame instead
  1594. size.cx = GetSystemMetrics(SM_CXFRAME) - CX_BORDER;
  1595. size.cy = GetSystemMetrics(SM_CYFRAME) - CY_BORDER;
  1596. if ((HORZF(m_dwStyle) && !m_bFlip) || (VERTF(m_dwStyle) && m_bFlip))
  1597. rect = m_rectFrameDragHorz;
  1598. else
  1599. rect = m_rectFrameDragVert;
  1600. pBrush = pDitherBrush;
  1601. }
  1602. }
  1603. if (bRemoveRect)
  1604. size.cx = size.cy = 0;
  1605. if(m_dwOverDockStyle == CBRS_ALIGN_INSERT_PAGE)
  1606. rect = m_addRect; // rect of target CDockPageBar
  1607. // draw it and remember last size
  1608. m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast,
  1609. pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush);
  1610. m_rectLast = rect;
  1611. m_sizeLast = size;
  1612. m_bDitherLast = (pBrush == pDitherBrush);
  1613. }