www.pudn.com > clking_src.rar > GuiOfficeBar.cpp
//-----------------------------------------------------------------------// // This is a part of the GuiLib MFC Extention. // // Autor : Francisco Campos // // (C) 2002 Francisco CamposAll rights reserved // // This code is provided "as is", with absolutely no warranty expressed // // or implied. Any use is at your own risk. // // You must obtain the author's consent before you can include this code // // in a software library. // // If the source code in this file is used in any application // // then acknowledgement must be made to the author of this program // // fcampos@tutopia.com // //-----------------------------------------------------------------------// #include "stdafx.h" #include "..\header\guiofficebar.h" #include "guidrawlayer.h" #include "resource.h" #define HORZF(dw) (dw & CBRS_ORIENT_HORZ) #define VERTF(dw) (dw & CBRS_ORIENT_VERT) #define CX_BORDER 1 #define CY_BORDER 1 enum btn{ HTBACK=520, HTFORWAR=521, THMENU=522, HTCLOS=523 }; int ArrBtn[4]={HTBACK,HTFORWAR,THMENU,HTCLOS}; void _AfxAdjustRectangle(CRect& rect, CPoint pt) { int nXOffset = (pt.x < rect.left) ? (pt.x - rect.left) : (pt.x > rect.right) ? (pt.x - rect.right) : 0; int nYOffset = (pt.y < rect.top) ? (pt.y - rect.top) : (pt.y > rect.bottom) ? (pt.y - rect.bottom) : 0; rect.OffsetRect(nXOffset, nYOffset); } BEGIN_MESSAGE_MAP(CGuiOfficeBar,CGuiControlBar) ON_WM_CREATE() ON_WM_NCLBUTTONDOWN() ON_WM_NCLBUTTONUP() ON_WM_TIMER() ON_WM_NCMOUSEMOVE() ON_WM_NCHITTEST() ON_COMMAND(HTBACK,OnBack) ON_COMMAND(HTFORWAR,OnForWard) ON_COMMAND(THMENU,OnMenu) END_MESSAGE_MAP() CGuiOfficeBar::CGuiOfficeBar(void) { m_stateBtnBack=NORMAL; m_stateBtnClose=NORMAL; m_stateBtnFor=NORMAL; m_stateBtnMenu=NORMAL; m_StateBtn=NORMAL; m_nHits=-1; } CGuiOfficeBar::~CGuiOfficeBar(void) { } void CGuiOfficeBar::OnBack() { } void CGuiOfficeBar::OnForWard() { } void CGuiOfficeBar::OnMenu() { } int CGuiOfficeBar::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CGuiControlBar::OnCreate(lpCreateStruct) == -1) return -1; m_ArrButtons[0].SetData(1,"Back"); m_ArrButtons[0].SetImageList(IDB_DOCKBAROFFICE,16,7,RGB(255,0,255)); m_ArrButtons[1].SetData(2,"Forwar"); m_ArrButtons[1].SetImageList(IDB_DOCKBAROFFICE,16,7,RGB(255,0,255)); m_ArrButtons[2].SetData(0,"Menu"); m_ArrButtons[2].SetImageList(IDB_DOCKBAROFFICE,16,7,RGB(255,0,255)); m_ArrButtons[3].SetData(6,"Close"); m_ArrButtons[3].SetImageList(IDB_DOCKBAROFFICE,16,7,RGB(255,0,255)); m_ArrButtons[0].SetTypeButton(CGuiControlBarButton::GUITOOLBUTTON); m_ArrButtons[1].SetTypeButton(CGuiControlBarButton::GUITOOLBUTTON); m_ArrButtons[2].SetTypeButton(CGuiControlBarButton::GUITOOLBUTTON); m_ArrButtons[3].SetTypeButton(CGuiControlBarButton::GUITOOLBUTTON); SetColorFondo(RGB(255,255,255)); return 0; } void CGuiOfficeBar::DrawGripper(CDC* pDC,CRect* rc) { CRect gripper = rc; gripper.top =3; gripper.left+=4; gripper.right-=IsVert()?5:4; gripper.bottom =gripper.top +nGapGripper-3; //si la ventana esta activa pintamos el caption o el area del titulo de color azul CPen cp(PS_SOLID,1,::GetSysColor(COLOR_BTNHIGHLIGHT)); CPen* cpold=pDC->SelectObject(&cp); //linea superior CBrush cb; cb.CreateSolidBrush(GuiDrawLayer::GetRGBColorFace());//GuiDrawLayer::GetRGBCaptionXP()); pDC->FillRect(gripper,&cb); pDC->SelectObject(cpold); gripper.DeflateRect(1, 1); CString m_caption; GetWindowText(m_caption); CFont m_cfont; m_cfont.CreateFont(-11,0,0,0,FW_SEMIBOLD,0,0,0,0,1,2,1,34,"Microsoft Sans Serif"); CFont* m_fontOld=pDC->SelectObject(&m_cfont); int nMode = pDC->SetBkMode(TRANSPARENT); CSize SizeCad=pDC->GetTextExtent(m_caption); CRect rCText=gripper; rCText.top=6; rCText.bottom =rCText.top+14; rCText.left=34; int cont=SizeCad.cx; while(cont > 1 && gripper.Width()-60 > 0) { CSize coor=pDC->GetTextExtent(m_caption,m_caption.GetLength()); if(coor.cx > gripper.Width()-60) { m_caption=m_caption.Left(m_caption.GetLength()-1); } else break; cont--; } //CRect gripper; //------------------------------------------------ GetWindowRect( gripper ); ScreenToClient( gripper ); gripper.OffsetRect( -gripper.left, -gripper.top ); //boton de Close m_ArrButtons[3].rcArea=gripper; m_ArrButtons[3].rcArea.left=m_ArrButtons[3].rcArea.right-20; m_ArrButtons[3].rcArea.right-=7; m_ArrButtons[3].rcArea.top+=4; m_ArrButtons[3].rcArea.bottom=m_ArrButtons[3].rcArea.top+13; //boton menu m_ArrButtons[2].rcArea=gripper; m_ArrButtons[2].rcArea.left=m_ArrButtons[3].rcArea.left-16; m_ArrButtons[2].rcArea.right=m_ArrButtons[2].rcArea.left+13; m_ArrButtons[2].rcArea.top+=4; m_ArrButtons[2].rcArea.bottom=m_ArrButtons[2].rcArea.top+13; //boton back m_ArrButtons[0].rcArea=gripper; m_ArrButtons[0].rcArea.left+=4; m_ArrButtons[0].rcArea.right=m_ArrButtons[0].rcArea.left+13; m_ArrButtons[0].rcArea.top+=4; m_ArrButtons[0].rcArea.bottom=m_ArrButtons[0].rcArea.top+13; //boton forward m_ArrButtons[1].rcArea=gripper; m_ArrButtons[1].rcArea.left+=m_ArrButtons[0].rcArea.right+2; m_ArrButtons[1].rcArea.right=m_ArrButtons[1].rcArea.left+13; m_ArrButtons[1].rcArea.top+=4; m_ArrButtons[1].rcArea.bottom=m_ArrButtons[1].rcArea.top+13; //m_rcCloseBtn.left-=4; //ClientToScreen(m_rcCloseBtn); m_ArrButtons[0].Paint(pDC,m_stateBtnBack,m_ArrButtons[0].rcArea,::GetSysColor(COLOR_BTNFACE)); m_ArrButtons[1].Paint(pDC,m_stateBtnFor,m_ArrButtons[1].rcArea,::GetSysColor(COLOR_BTNFACE)); m_ArrButtons[2].Paint(pDC,m_stateBtnMenu,m_ArrButtons[2].rcArea,::GetSysColor(COLOR_BTNFACE)); m_ArrButtons[3].Paint(pDC,m_stateBtnClose,m_ArrButtons[3].rcArea,::GetSysColor(COLOR_BTNFACE)); //------------------------------------------------ if (gripper.Width() > 0 ) pDC->TextOut(rCText.left+3,rCText.top,m_caption); //CRect gripper; //------------------------------------------------ pDC->SetBkMode(nMode); pDC->SelectObject(m_fontOld); } void CGuiOfficeBar::ShowTitle(CString m_Caption) { SetWindowText(m_Caption); SendMessage(WM_COMMAND,WM_SHOWTITLE); } void CGuiOfficeBar::OnNcLButtonDown(UINT nHitTest, CPoint point) { // TODO: Add your message handler code here and/or call default if( m_nHits == HTCLOS || m_nHits == HTBACK || m_nHits == HTFORWAR|| m_nHits == THMENU) { if (m_nHits == HTCLOS) m_stateBtnClose=PRESS; else if (m_nHits == HTBACK) m_stateBtnBack=PRESS; else if(m_nHits == HTFORWAR) m_stateBtnFor=PRESS; else if(m_nHits == THMENU) m_stateBtnMenu=PRESS; m_StateBtn=PRESS; SendMessage(WM_NCPAINT); SetTimer(1,100,0); return; } if (nHitTest == HTCAPTION) SetCursor(::LoadCursor(NULL,IDC_SIZEALL)); CGuiControlBar::OnNcLButtonDown(nHitTest, point); } void CGuiOfficeBar::OnNcLButtonUp(UINT nHitTest, CPoint point) { // TODO: Add your message handler code here and/or call default CRect rcT; point.y+=23; point.x+=5; if (m_stateBtnBack!=NORMAL) rcT=m_ArrButtons[0].rcArea; else if(m_stateBtnFor!=NORMAL) rcT=m_ArrButtons[1].rcArea; else if(m_stateBtnMenu!=NORMAL) rcT=m_ArrButtons[2].rcArea; else if(m_stateBtnClose!=NORMAL) rcT=m_ArrButtons[3].rcArea; ClientToScreen(rcT); if (rcT.PtInRect(point)) { if (m_StateBtn ==PRESS) { if(m_stateBtnClose!=NORMAL) GetDockingFrame()->ShowControlBar(this, FALSE, FALSE); else { SendMessage (WM_COMMAND,m_nHits); AfxGetMainWnd()->SendMessage(WM_COMMAND,m_nHits); } m_StateBtn=NORMAL; m_stateBtnBack=NORMAL; m_stateBtnClose=NORMAL; m_stateBtnFor=NORMAL; m_stateBtnMenu=NORMAL; m_nHits=-1; KillTimer(1); } //SendMessage(WM_NCPAINT); return; } CGuiControlBar::OnNcLButtonUp(nHitTest, point); } void CGuiOfficeBar::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if (m_StateBtn==NORMAL) return; CRect rc; CPoint pt(GetMessagePos()); CRect rcT=CRect(0,0,0,0); if (m_stateBtnBack!=NORMAL) rcT=m_ArrButtons[0].rcArea; else if(m_stateBtnFor!=NORMAL) rcT=m_ArrButtons[1].rcArea; else if(m_stateBtnMenu!=NORMAL) rcT=m_ArrButtons[2].rcArea; else if(m_stateBtnClose!=NORMAL) rcT=m_ArrButtons[3].rcArea; ClientToScreen(rcT); pt.y+=23; pt.x+=5; if (!rcT.PtInRect(pt)) { m_StateBtn=NORMAL; m_stateBtnBack=NORMAL; m_stateBtnClose=NORMAL; m_stateBtnFor=NORMAL; m_stateBtnMenu=NORMAL; m_nHits=-1; KillTimer(1); SendMessage(WM_NCPAINT); } CGuiControlBar::OnTimer(nIDEvent); } void CGuiOfficeBar::OnNcMouseMove(UINT nHitTest, CPoint point) { // TODO: Add your message handler code here and/or call default if (m_StateBtn != NORMAL) return; if (m_nHits == HTCLOS) { m_StateBtn=OVER; m_stateBtnClose=OVER; m_stateBtnBack=NORMAL; m_stateBtnFor=NORMAL; m_stateBtnMenu=NORMAL; SendMessage(WM_NCPAINT); SetTimer(1,100,0); return; } if (m_nHits == HTBACK) { m_stateBtnBack=OVER; m_stateBtnClose=NORMAL; m_stateBtnFor=NORMAL; m_stateBtnMenu=NORMAL; m_StateBtn=OVER; SendMessage(WM_NCPAINT); SetTimer(1,100,0); return; } if (m_nHits == HTFORWAR) { m_stateBtnBack=NORMAL; m_stateBtnClose=NORMAL; m_stateBtnFor=OVER; m_stateBtnMenu=NORMAL; m_StateBtn=OVER; SendMessage(WM_NCPAINT); SetTimer(1,100,0); return; } if (m_nHits == THMENU) { m_stateBtnBack=NORMAL; m_stateBtnClose=NORMAL; m_stateBtnFor=NORMAL; m_stateBtnMenu=OVER; m_StateBtn=OVER; SendMessage(WM_NCPAINT); SetTimer(1,100,0); return; } CGuiControlBar::OnNcMouseMove(nHitTest, point); } UINT CGuiOfficeBar::OnNcHitTest(CPoint point) { // TODO: Add your message handler code here and/or call default CRect rcWindow; //no se convierte las coordenadas de pantalla porque el punto //entregado por esta función esta dado en el mismo sentido. GetWindowRect(rcWindow); CPoint pt=point; pt.y+=23; pt.x+=5; for(int i=0; i < 4; i++) { CRect rcT=m_ArrButtons[i].rcArea; ClientToScreen(rcT); if (rcT.PtInRect(pt)) return m_nHits=ArrBtn[i]; } m_nHits=-1; return CGuiControlBar::OnNcHitTest(point); } CGuiDockContextOffice::~CGuiDockContextOffice() { } void CGuiDockContextOffice::StartDrag(CPoint pt) { ASSERT_VALID(m_pBar); m_bDragging = TRUE; InitLoop(); // GetWindowRect returns screen coordinates(not mirrored), // so if the desktop is mirrored then turn off mirroring // for the desktop dc so that we get correct focus rect drawn. // This layout change should be remembered, just in case ... if (m_pDC->GetLayout() & LAYOUT_RTL) m_pDC->SetLayout(LAYOUT_LTR); if (m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC) { // get true bar size (including borders) CRect rect; m_pBar->GetWindowRect(rect); m_ptLast = pt; AdjustWindowForFloat(rect); CSize sizeHorz = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK); CSize sizeVert = m_pBar->CalcDynamicLayout(0, LM_VERTDOCK); CSize sizeFloat = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH); m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz); m_rectDragVert = CRect(rect.TopLeft(), sizeVert); // calculate frame dragging rectangle m_rectFrameDragHorz = CRect(rect.TopLeft(), sizeFloat); m_rectFrameDragVert = CRect(rect.TopLeft(), sizeFloat); CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz); CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert); // m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); // m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); } else if (m_pBar->m_dwStyle & CBRS_SIZE_FIXED) { // get true bar size (including borders) CRect rect; m_pBar->GetWindowRect(rect); AdjustWindowForFloat(rect); m_ptLast = pt; CSize sizeHorz = m_pBar->CalcDynamicLayout(-1, LM_HORZ | LM_HORZDOCK); CSize sizeVert = m_pBar->CalcDynamicLayout(-1, LM_VERTDOCK); // calculate frame dragging rectangle m_rectFrameDragHorz = m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz); m_rectFrameDragVert = m_rectDragVert = CRect(rect.TopLeft(), sizeVert); CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz); CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert); // m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); // m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); } else { // get true bar size (including borders) CRect rect; m_pBar->GetWindowRect(rect); AdjustWindowForFloat(rect); m_ptLast = pt; BOOL bHorz = HORZF(m_dwStyle); DWORD dwMode = !bHorz ? (LM_HORZ | LM_HORZDOCK) : LM_VERTDOCK; CSize size = m_pBar->CalcDynamicLayout(-1, dwMode); // calculate inverted dragging rect if (bHorz) { m_rectDragHorz = rect; m_rectDragVert = CRect(CPoint(pt.x - rect.Height()/2, rect.top), size); } else // vertical orientation { m_rectDragVert = rect; m_rectDragHorz = CRect(CPoint(rect.left, pt.y - rect.Width()/2), size); } // calculate frame dragging rectangle m_rectFrameDragHorz = m_rectDragHorz; m_rectFrameDragVert = m_rectDragVert; CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz); CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert); // m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); // m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2); } // adjust rectangles so that point is inside _AfxAdjustRectangle(m_rectDragHorz, pt); _AfxAdjustRectangle(m_rectDragVert, pt); _AfxAdjustRectangle(m_rectFrameDragHorz, pt); _AfxAdjustRectangle(m_rectFrameDragVert, pt); // initialize tracking state and enter tracking loop m_dwOverDockStyle = CanDock(); Move(pt); // call it here to handle special keys Track(); } void CGuiDockContextOffice::AdjustWindowForFloat(CRect& rect) { if( m_pBar->IsFloating()) rect.top+=(GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYFRAME)); }