⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 guicontrolbar.cpp

📁 这是一个串口监视程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------//
// This is a part of the GuiLib MFC Extention.							 //	
// Autor  :  Francisco Campos											 //
// (C) 2002 Francisco Campos <www.beyondata.com> All 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		 //	
// fco_campos@tutopia.com													 //
// Version :1.1															 //
// Modified by : Francisco Campos										 //	 
//-----------------------------------------------------------------------//


// GuiControlBar.cpp : implementation file


#include "stdafx.h"
#include "..\header\GuiControlBar.h"
#include "..\header\GuiDockContext.h"
#include "..\header\guicontrolbar.h"
#include "..\header\GuiDrawLayer.h"
#include "..\header\guicontrolbar.h"
// CGuiControlBar

IMPLEMENT_DYNAMIC(CGuiControlBar, CControlBar)
CGuiControlBar::CGuiControlBar()
{
	nGapGripper=20;
	m_bActive=FALSE;
	m_bOldActive=FALSE;
	m_sizeMinFloating=m_sizeVert=m_sizeHorz=CSize(200,100);
	m_sizeHorzt=CSize(200,100);
	m_sizeVertt=CSize(200,100);
	m_pos=0;
	m_Last=0;
	m_bTracking=FALSE;
	m_rcBorder=CRect(0,0,0,0);
	m_rcOldBorder=CRect(0,0,0,0);
	m_ptOld=CPoint(0,0);
	m_sizeMinV=CSize(28,28);
	m_sizeMinH=CSize(28,28);
	m_Initialize=FALSE;
	m_First=-1;
	m_bForcepaint=FALSE;
	m_stateBtn=NORMAL;
	m_clrFondo=GuiDrawLayer::GetRGBColorFace();
	m_bSupportMultiView=FALSE;
	m_MenuContext=NULL;
	
}

CGuiControlBar::~CGuiControlBar()
{
	
}


BEGIN_MESSAGE_MAP(CGuiControlBar, CControlBar)
	ON_WM_CREATE()
	ON_WM_LBUTTONDOWN()
	ON_WM_RBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_NCLBUTTONDOWN()
	ON_WM_NCRBUTTONDOWN()
	ON_WM_NCLBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_NCPAINT()
	ON_WM_NCCALCSIZE()
	ON_WM_WINDOWPOSCHANGED()
	ON_WM_PAINT()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_NCLBUTTONDBLCLK()
	ON_WM_NCHITTEST()
	ON_WM_SETCURSOR()
	ON_WM_SIZE()
	ON_WM_NCMOUSEMOVE()
	ON_WM_TIMER()
	ON_COMMAND(WM_SHOWTITLE, OnShowTitle)
	ON_WM_SYSCOLORCHANGE()
	
END_MESSAGE_MAP()



// CGuiControlBar message handlers

void CGuiControlBar::OnUpdateCmdUI(CFrameWnd* /*pTarget*/, BOOL /*bDisableIfNoHndler*/)
{
	
	CWnd* pFocus = GetFocus();
	m_bOldActive=(pFocus->GetSafeHwnd() && IsChild(pFocus));
	m_bForcepaint=TRUE;
	if (!m_bActive && m_bOldActive)
		OnActiveWindow();
	m_bForcepaint=FALSE;
	

}

void CGuiControlBar::OnSysColorChange( )
{
	m_clrFondo=GuiDrawLayer::GetRGBColorFace();
	CControlBar::OnSysColorChange( );
	
}

BOOL CGuiControlBar::Create(LPCTSTR lpszWindowName, DWORD dwStyle,CWnd* pParentWnd, UINT nID)
{
	// TODO: Add your specialized code here and/or call the base class
	//gran parte del codigo se tomo como guia de clases MFC
	ASSERT_VALID(pParentWnd);   // must have a parent
	//en esta linea se verifica que la ventana debe disponer de un estilo fijo o dinamico
	//pero no los dos.el estilo Dynamic permite cambiar el tama駉 dela ventana mientras flota
	//pero no cuando esta docking, el estilo fijo determina las columnas en que se disponen los
	//componentes y permance asi.
	ASSERT(!((dwStyle & CBRS_SIZE_FIXED) && (dwStyle & CBRS_SIZE_DYNAMIC)));
	// save the style
	//en dwStyle debe asignarse un tipo de alineaci髇 por ejemplo CBRS_TOP,etc de lo contrario
	//se generase un ASSERT al acambiar el Style
	dwStyle|=CBRS_TOP;
	m_dwStyle = (dwStyle & CBRS_ALL);//save the original style
	dwStyle &= ~CBRS_ALL;
	//en la siguiente instruccion el proposito que se busca es evitar el parpadeo 
	//cuando se refresca la ventana.
	//WS_CLIPCHILDREN : recorta el area de las ventanas hijas cuando se dibuja sobre 
	//				 la ventana que la contiene.
	//WS_CLIPSIBLING : cuando se recibe el mensaje paint se recorta el area de las otras ventanas
	//				   hijas superpuestas, que estan fuera de la region.	
	dwStyle |= WS_CLIPSIBLINGS|WS_CLIPCHILDREN;
	//con el estilo CS_DBLCLKS, lo que se busca es que al recibir un doble clic
	//la ventana reaccione,ojo el problema es que esto lo hace solo con el area cliente. 
	LPCTSTR lpszClassName=::AfxRegisterWndClass(CS_DBLCLKS,
												::LoadCursor(NULL,IDC_ARROW),
												::GetSysColorBrush(COLOR_BTNFACE),
												NULL);
	//poque no se llama a CControlBar::Create, bueno, da igual llamar a cualquiera, CWnd o CControlBar
	//esto debido a que CControlbar se deriva de CWnd y porque ademas CControlBar no sobrecarga el 
	//metodo Create, nosotros si porque tenemos que particularizar, cosas.
	BOOL bResp= CWnd::Create(lpszClassName, lpszWindowName, dwStyle, CRect(0,0,0,0), pParentWnd, nID);
	if (!bResp) return FALSE;
	
	return TRUE;
}

int CGuiControlBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CControlBar::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO:  Add your specialized creation code here
	//aqui es cuando llamamos a nuestra clase CGuiDockContext, de esta manera
	//sobrecargamos el clase original que para nuestros propositos no nos sirve.
	//porque ?, bueno porque me interesa que no se pegen las toolbar en el interior
	//de las ventanas.
	if (m_pDockContext==NULL)
		m_pDockContext=new CGuiDockContext(this);
	ASSERT(m_pDockContext);
	m_CloseBtn.SetData(6,"Close");
	m_CloseBtn.SetImageList(IDB_DOCKBAR,9,10,RGB(255,0,255));
	return 0;
}


void CGuiControlBar::OnShowTitle()
{
	ActiveCaption();
	SendMessage(WM_NCPAINT);
}


//esta funcion calcula el tama駉 horizontal de la ventana,no importa si esta 
//docking a izquierda o derecha o arriba o abajo.Debemos disponer de un espacio equitativo entre todas
//ventanas que se encuentren docking ya sea en una fila o columna.
CSize CGuiControlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
{
	//la funcion original toma el ancho o alto dependiendo del sentido que nos 
	//indica bHorz.
	ASSERT_VALID(this);
	
	if (IsFloating())
		return m_sizeMinFloating;
	else
	{
		//si bStrerch es TRUE significa que esta ventana no se puede hacer
		//Docking
		if (bStretch) 
		{
			if (bHorz)
				return CSize(32767, m_sizeHorz.cy);
			else
				return CSize(m_sizeVert.cx, 32767);
		}
	}
	
	int Len=GetHiWid();

	int nWidth = GetWidthMax();
	int nMinSpace=0;//minimo espacio requerido con lo tama駉s normales
	int nMinimo=0;  //minimo espacio de los tama駉s minimos
	int nRealBars=0;
	int m_First=GetFirstPos();
	
	for (int nPos = m_First; nPos <= m_Last; nPos++)
	{
		CGuiControlBar* pBar = GetGuiControlBar(nPos,TRUE);
		if (pBar== NULL) continue;
		if (!pBar->IsVisible()) continue;
		if (!pBar->IsKindOf(RUNTIME_CLASS(CGuiControlBar)))
		{
			CPoint pt(GetMessagePos());
			m_pDockSite->FloatControlBar(pBar,pt);
			continue;
		}
		if(IsVert())
			pBar->m_sizeVert.cx=nWidth;
		else	
			pBar->m_sizeHorz.cy=nWidth; //todas se hacen con el mismo ancho
		nMinSpace+=IsVert() ? pBar->m_sizeVert.cy:pBar->m_sizeHorz.cx; //minimo espacio para alinear las barras
		nRealBars++;	//cuantas barras realmente existen
	}
	
	//si el tama駉 de las barras en la fila es mayor que 
	//el espacio disponible, luego la solucion salomonica es 
	//repartir el espacio entre todas.
	if (nRealBars == 1 )
	{
		if (bHorz)
			return m_sizeHorz= CSize(Len,m_sizeHorz.cy);
		else
			return m_sizeVert=CSize(m_sizeVert.cx,Len);
		
	}
	
	

	int nDif=Len-nMinSpace;
	if (abs(nDif) !=0)
	{
		BOOL bGrow=FALSE;
		if (nDif > 0)
			bGrow=TRUE;
		nDif=abs(nDif);
		while(nDif > 0)
		{
			for (int nPos = m_First; nPos <= m_Last; nPos++)
			{
				CGuiControlBar* pBar = GetGuiControlBar(nPos);
				if (pBar== NULL) continue;
				if(IsVert())
				{
					if(bGrow)
						pBar->m_sizeVert.cy+=1;
					else
					{
						
						if (pBar->m_sizeVert.cy-1 < pBar->m_sizeMinV.cy)
						{
							nDif--; //bug fixed
							continue;
						}
						pBar->m_sizeVert.cy-=1;
						
					}
				}
				else
				{
					if(bGrow)
						pBar->m_sizeHorz.cx+=1;
					else
					{
						
						if (pBar->m_sizeHorz.cx-1 < pBar->m_sizeMinH.cx)
						{
							nDif--; //bug fixed
							continue;
						}
						pBar->m_sizeHorz.cx-=1;
						
					}
					
				}
				
				nDif--;
				if(nDif==0) break;
			}
				
		}

	}
	
   //--reubicar las ventanas, sin esta rutina nada funciona
  RecalWindowPos();
  
	if (IsHorz())
		return 	m_sizeHorz;
	else
		return 	m_sizeVert;
}


//esta rutina dispone de la posici髇 en el Dockbar de la pila de  ventanas 
void CGuiControlBar::RecalWindowPos()
{
	int m_First=GetFirstPos();
	int m_Last=GetLastPos();
	int m_This=m_pDockBar->FindBar(this);
	
	CRect rcWin=GetDockRect();
	int m_VertPos=0;
	for(int i=m_First; i<= m_Last; i++)
	{
		CGuiControlBar* pBar = GetGuiControlBar(i);
		if (pBar == NULL) continue;
		CRect rcBar;
		pBar->GetWindowRect(rcBar);
		rcBar.OffsetRect(-rcWin.TopLeft());
		if (IsVert())
		{
	 	 if (i==m_First)
		 {
			rcBar.top=0;
		 }
		 else
		 	rcBar.top=m_VertPos;
		}
		else
		{
			if (i==m_First) 
				rcBar.left=0;
			else
		 		rcBar.left=m_VertPos;
		}
		pBar->MoveWindow(rcBar);
		m_VertPos+=IsVert()? rcBar.Height():rcBar.Width();

	}

	m_pDockSite->DelayRecalcLayout();
		m_pDockSite->DelayRecalcLayout();

}

CRect CGuiControlBar::GetDockRect()
{
	CRect rcWin;
	if (IsVert())
		if (IsLeft())
			m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_LEFT)->GetWindowRect(rcWin);
		else
			m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_RIGHT)->GetWindowRect(rcWin);
	else
		if(IsBottom())
			m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_BOTTOM)->GetWindowRect(rcWin);
		else
			m_pDockSite->GetControlBar(AFX_IDW_DOCKBAR_TOP)->GetWindowRect(rcWin);
	return rcWin;
}



int CGuiControlBar::GetWidthMax()
{
	m_pos=m_pDockBar->FindBar(this);
	m_Last=GetLastPos();
	int nWidth=0;
	for (int nPos = GetFirstPos(); nPos <= m_Last; nPos++)
	{
		CGuiControlBar* pBar = GetGuiControlBar(nPos);
		if (pBar== NULL) continue;
		nWidth=max(nWidth,IsVert() ? pBar->m_sizeVert.cx:pBar->m_sizeHorz.cy);
	}
	return nWidth;
}



CGuiControlBar* CGuiControlBar::GetGuiControlBar(int nPos,BOOL bAll) const
{
	CGuiControlBar* pResult = (CGuiControlBar*)m_pDockBar->m_arrBars[nPos];
	if (bAll==FALSE)
	{
		if (HIWORD(pResult) == NULL) return NULL;
		else if (!pResult->IsVisible()) return NULL;
		else if (!pResult->IsKindOf(RUNTIME_CLASS(CGuiControlBar))) return NULL;
	}
	else
	{
		if (HIWORD(pResult) == NULL)
		return NULL;
	}
	return pResult;
}

//En esta funci髇 se calcula el tama駉 de la ventana cuando esta flotando
//y gestionar cuando el mouse es presionado en las esquinas.
//#define HTTOPLEFT           13
//#define HTTOPRIGHT          14
//#define HTBOTTOMLEFT        16
//#define HTBOTTOMRIGHT       17


CSize CGuiControlBar::CalcDynamicLayout(int nLength, DWORD nMode)
{

		m_pDockSite->DelayRecalcLayout();

	if (IsFloating())
	{
		// Enable diagonal arrow cursor for resizing
		//m_sizeVert=m_sizeHorz=CSize(200,200); 
		GetParent()->GetParent()->ModifyStyle(MFS_4THICKFRAME/*|WS_CAPTION*/,0);
	} 
	if (nMode & (LM_HORZDOCK | LM_VERTDOCK)) 
	{
		m_pDockSite->DelayRecalcLayout();
		//obligar a reposicionar  la ventana, de lo contrario cuando vuelva de un doble click
		//desde la ventana CMiniFrameWnd queda sin area cliente
		SetWindowPos(NULL, 0, 0, 0, 0,
			SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER |
			SWP_NOACTIVATE | SWP_FRAMECHANGED|SWP_NOREDRAW);
	 	return CControlBar::CalcDynamicLayout(nLength, nMode);
	}
	if (nMode & LM_MRUWIDTH)
        return  m_sizeMinFloating;

    if (nMode & LM_COMMIT)
        return  m_sizeMinFloating ;
    
	if (IsFloating())
	{

		CRect	rcWin;
		POINT	cpt;
		GetCursorPos(&cpt);
		GetParent()->GetParent()->GetWindowRect(&rcWin);
		int nXOffset=0;int nYOffset=0;
		switch (m_pDockContext->m_nHitTest)
		{

			//------------------------------------------------------------------
			case HTLEFT:
				m_pDockContext->m_rectFrameDragHorz= rcWin;
				m_pDockContext->m_rectFrameDragHorz.left = cpt.x;
				m_sizeMinFloating.cx = max(rcWin.right - cpt.x,32)-4 ;
				m_sizeMinFloating.cy = max((rcWin.bottom -rcWin.top)-nGapGripper-5,32)+2 ;
				return m_sizeMinFloating;		
			break;
			case HTTOP:
				m_pDockContext->m_rectFrameDragHorz=rcWin;
				m_pDockContext->m_rectFrameDragHorz.top = cpt.y;
				m_sizeMinFloating.cx = max(rcWin.right-rcWin.left-2,32)-4 ;
				m_sizeMinFloating.cy = max((rcWin.bottom -nGapGripper-cpt.y-3),32) ;
				return m_sizeMinFloating;		
			break;
			case HTRIGHT:
				m_pDockContext->m_rectFrameDragHorz=rcWin;
				m_pDockContext->m_rectFrameDragHorz.right = cpt.x;
				m_sizeMinFloating.cy = max(rcWin.bottom -rcWin.top-nGapGripper-3,32) ;
				m_sizeMinFloating.cx = max(cpt.x-rcWin.left-4,32);
				return m_sizeMinFloating;		
			break;
			case HTBOTTOM:
				m_pDockContext->m_rectFrameDragHorz=rcWin;
				m_sizeMinFloating.cy = max(cpt.y-rcWin.top -nGapGripper-3,32) ;
				m_sizeMinFloating.cx = max(rcWin.right-rcWin.left-2,32)-4 ;
				m_pDockContext->m_rectFrameDragHorz.bottom = cpt.y-4;
				return m_sizeMinFloating;
				break;
			case HTTOPLEFT:
				//---------------------------------------------------------
			//En este caso crece la ventana a izquierda y hacia arriba
			//izquierda incrementa cx y top incrementa cy
				m_sizeMinFloating.cx = max(rcWin.right - cpt.x,32)-3 ;
				m_sizeMinFloating.cy = max(rcWin.bottom -nGapGripper-cpt.y,32)-2 ;
				m_pDockContext->m_rectFrameDragHorz.top = cpt.y-1;
				m_pDockContext->m_rectFrameDragHorz.left = cpt.x-2;

				return m_sizeMinFloating;		
				break;
			case HTTOPRIGHT:
				m_sizeMinFloating.cx = max(cpt.x-rcWin.left,32)-4 ;
				m_sizeMinFloating.cy = max(rcWin.bottom -nGapGripper-cpt.y,32)-2 ;
				m_pDockContext->m_rectFrameDragHorz.top = cpt.y-1;
				m_pDockContext->m_rectFrameDragHorz.right = cpt.x-2;
				return m_sizeMinFloating;		
				break;
			case HTBOTTOMLEFT:
				m_sizeMinFloating.cx = max(rcWin.right - cpt.x,32)-4;
				m_sizeMinFloating.cy = max(cpt.y-rcWin.top -nGapGripper,32)-2 ;
				m_pDockContext->m_rectFrameDragHorz.top = rcWin.top;
				m_pDockContext->m_rectFrameDragHorz.bottom = cpt.y-1;
				m_pDockContext->m_rectFrameDragHorz.left = cpt.x-2;
				return m_sizeMinFloating;		
				break;
			case HTBOTTOMRIGHT:
				m_sizeMinFloating.cx = max(cpt.x-rcWin.left,32);
				m_sizeMinFloating.cy = max(cpt.y-rcWin.top -nGapGripper,32) ;
				m_pDockContext->m_rectFrameDragHorz.top = rcWin.top;
				m_pDockContext->m_rectFrameDragHorz.bottom = cpt.y+1;
				m_pDockContext->m_rectFrameDragHorz.right = cpt.x+2;
				return m_sizeMinFloating;		
				break;
			
				
			
		}
		
	}

	if(nMode & LM_LENGTHY)
		 m_sizeMinFloating.cy = max(nLength,32);
	else
	     m_sizeMinFloating.cx = max(nLength,32);
	return m_sizeMinFloating;
}

void CGuiControlBar::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	if(m_pDockBar != NULL)
	{
		ActiveCaption();
		m_pDockContext->ToggleDocking();
	}
	else
		CWnd::OnLButtonDblClk(nFlags, point);
}
void CGuiControlBar::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default

	if (m_pDockBar != NULL)
    {
        // start the drag
        ClientToScreen(&point);
        m_pDockContext->StartDrag(point);
    }
    else
		CControlBar::OnLButtonDown(nFlags, point);
}

void CGuiControlBar::OnRButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	
	if (m_pDockBar != NULL)
    {
        // start the drag
        ReleaseCapture();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -