📄 guicontrolbar.cpp
字号:
gripper.right-=IsVert()?6:4;
gripper.bottom =gripper.top +nGapGripper-3;
//si la ventana esta activa pintamos el caption o el area del titulo de color azul
if (IsFloating())
m_bActive=TRUE;
if(!m_bActive)
{
CPen cp(PS_SOLID,1,::GetSysColor(COLOR_BTNSHADOW));
CPen* cpold=pDC->SelectObject(&cp);
//linea superior
pDC->MoveTo(gripper.left+1,gripper.top);
pDC->LineTo(gripper.right,gripper.top);
//linea izquierda
pDC->MoveTo(gripper.left,gripper.top+1);
pDC->LineTo(gripper.left,gripper.bottom);
//linea inferior
pDC->MoveTo(gripper.left+1,gripper.bottom);
pDC->LineTo(gripper.right,gripper.bottom);
//linea derecha
pDC->MoveTo(gripper.right,gripper.top+1);
pDC->LineTo(gripper.right,gripper.bottom);
pDC->SelectObject(&cpold);
}
else
{
CBrush cb;
cb.CreateSolidBrush(::GetSysColor(COLOR_ACTIVECAPTION));//GuiDrawLayer::GetRGBCaptionXP());
pDC->FillRect(gripper,&cb);
}
gripper.DeflateRect(1, 1);
CString m_caption;
GetWindowText(m_caption);
CFont m_cfont;
m_cfont.CreateFont(-11,0,0,0,400,0,0,0,0,1,2,1,34,"Verdana");
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;
int cont=SizeCad.cx;
while(cont > 1 && gripper.Width() > 0)
{
CSize coor=pDC->GetTextExtent(m_caption,m_caption.GetLength());
if(coor.cx > gripper.Width()-10)
{
m_caption=m_caption.Left(m_caption.GetLength()-1);
}
else
break;
cont--;
}
if (gripper.Width() > 0 )
if (!m_bActive)
pDC->TextOut(rCText.left+3,rCText.top,m_caption);
else
{
pDC->SetTextColor(RGB(255,255,255));
pDC->TextOut(rCText.left+3,rCText.top,m_caption);
}
//CRect gripper;
//------------------------------------------------
GetWindowRect( gripper );
ScreenToClient( gripper );
gripper.OffsetRect( -gripper.left, -gripper.top );
gripper.left=gripper.right-20;
gripper.right-=7;
gripper.top+=6;
gripper.bottom=gripper.top+13;
m_rcCloseBtn=gripper;
//m_rcCloseBtn.left-=4;
//ClientToScreen(m_rcCloseBtn);
if(!m_bActive)
m_CloseBtn.Paint(pDC,m_stateBtn,gripper,::GetSysColor(COLOR_BTNFACE));
else
m_CloseBtn.Paint(pDC,m_stateBtn,gripper,::GetSysColor(COLOR_ACTIVECAPTION));
//------------------------------------------------
pDC->SetBkMode(nMode);
pDC->SelectObject(&m_fontOld);
}
//en esta funci髇 se calcula el area cliente que podra ser utilizado
//por ventanas que deriven esta clase.
void CGuiControlBar::OnNcCalcSize(BOOL /*bCalcValidRects*/, NCCALCSIZE_PARAMS* lpncsp)
{
// adjust non-client area for border space
lpncsp->rgrc[0].left +=!IsFloating()?5:2;
lpncsp->rgrc[0].top +=!IsFloating()?nGapGripper+3:3;
lpncsp->rgrc[0].right -=!IsFloating()?IsVert()?7:4:2;
lpncsp->rgrc[0].bottom -=!IsFloating()?3:2;
}
//Aqui la idea es verificar que si se da clic sobre otra ventana de este tipo
//automaticamente emita un mensaje eliminando el caption que la identifica como
//ventana default.
void CGuiControlBar::OnWindowPosChanged(WINDOWPOS* lpwndpos)
{
CRect rc;
GetClientRect(rc);
nDockBarAling = GetParent()->GetDlgCtrlID();
//envie un recalculo del area cliente solo si el tama駉 ha sido
//cambiado, de lo contrario permanezca igual
lpwndpos->flags |= SWP_FRAMECHANGED;
CControlBar::OnWindowPosChanged(lpwndpos);
CWnd* pWnd = GetWindow(GW_CHILD);
if (!m_bSupportMultiView)
{
if (pWnd != NULL)
{
pWnd->MoveWindow(rc);
ASSERT(pWnd->GetWindow(GW_HWNDNEXT) == NULL);
}
}
else
{
while (pWnd != NULL)
{
if (pWnd->IsWindowVisible())
{
pWnd->MoveWindow(rc);
break;
}
pWnd=pWnd->GetWindow(GW_HWNDNEXT);
}
}
}
//este conjunto de clases nos indican el estado de la ventana
//en un momento determinado
BOOL CGuiControlBar::IsLeft()
{
if (nDockBarAling == AFX_IDW_DOCKBAR_LEFT) return TRUE;
return FALSE;
}
BOOL CGuiControlBar::IsRight()
{
if (nDockBarAling == AFX_IDW_DOCKBAR_RIGHT) return TRUE;
return FALSE;
}
BOOL CGuiControlBar::IsTop()
{
if (nDockBarAling == AFX_IDW_DOCKBAR_TOP) return TRUE;
return FALSE;
}
BOOL CGuiControlBar::IsBottom()
{
if (nDockBarAling == AFX_IDW_DOCKBAR_BOTTOM) return TRUE;
return FALSE;
}
BOOL CGuiControlBar::IsVert()
{
if (IsLeft() || IsRight()) return TRUE;
return FALSE;
}
BOOL CGuiControlBar::IsHorz()
{
if (IsTop() || IsBottom()) return TRUE;
return FALSE;
}
BOOL CGuiControlBar::IsFloating()
{
if (nDockBarAling == AFX_IDW_DOCKBAR_FLOAT) return TRUE;
return FALSE;
}
void CGuiControlBar::OnPaint()
{
CPaintDC dc(this); // device context for painting
m_pDockSite->DelayRecalcLayout();//si quita esto se tiene problemas
// TODO: Add your message handler code here
// Do not call CControlBar::OnPaint() for painting messages
}
UINT CGuiControlBar::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髇 esta dado en el mismo sentido.
GetWindowRect(rcWindow);
int it=0;
// if (IsFloating())
// return CControlBar::OnNcHitTest(point);
CRect rcT=m_rcCloseBtn;
ClientToScreen(rcT);
CPoint pt=point;
pt.y+=23;
pt.x+=5;
//pt.Offset(-rcT.left,-rcT.top);
if (rcT.PtInRect(pt))
return HTCLOSE;
CRect rcTemp;
for (int i=0; i< 4; i++)
{
rcTemp=rcWindow;
if (i== 0) //left
{
it= rcTemp.left;
it+=4;
rcTemp.right=it;
m_rcBorder=rcTemp;
if (rcTemp.PtInRect(point))
if(IsLegal(HTLEFT)) return m_SideMove=HTLEFT;
}
if (i==1) //top
{
it= rcTemp.top;
it+=4;
rcTemp.bottom=it;
m_rcBorder=rcTemp;
if (rcTemp.PtInRect(point))
if(IsLegal(HTTOP)) return m_SideMove=HTTOP ;
}
if (i==2) //right
{
it= rcTemp.right;
it-=4;
rcTemp.left=it;
m_rcBorder=rcTemp;
if (rcTemp.PtInRect(point))
if (IsLegal(HTRIGHT)) return m_SideMove=HTRIGHT;
}
if (i==3) //bottom
{
it= rcTemp.bottom;
it-=4;
rcTemp.top=it;
m_rcBorder=rcTemp;
if (rcTemp.PtInRect(point))
if (IsLegal(HTBOTTOM))return m_SideMove=HTBOTTOM;
}
}
it=0;
rcTemp=rcWindow;
it= rcTemp.top+nGapGripper;
rcTemp.bottom=it;
if (rcTemp.PtInRect(point))
{
SetCursor(::LoadCursor(NULL,IDC_ARROW));
return m_SideMove=HTCAPTION;
}
return CControlBar::OnNcHitTest(point);
}
//-----------------------------------------------------------
//aqui se verifica que las coordenadas de cambio de tama駉
//sean las correctas
BOOL CGuiControlBar::IsLegal(UINT uAlin)
{
m_First=GetFirstPos();
// if (IsFloating()) return FALSE;
switch(uAlin)
{
case HTLEFT:
if (IsHorz() && m_pos >0 && (m_pos != m_Last && m_pos != m_First)) return TRUE;
if (IsVert() && m_pos <= m_Last && IsRight() ) return TRUE;
return FALSE;
break;
case HTTOP:
if (m_pos != m_First && IsVert()) return TRUE;
if (IsHorz() && m_pos <= m_Last && IsBottom() ) return TRUE;
return FALSE;
break;
case HTRIGHT:
if (m_pos <= m_Last && IsVert() && IsLeft() ) return TRUE;
if (IsHorz() && m_pos >0 && m_pos != m_Last) return TRUE;
return FALSE;
case HTBOTTOM:
if ((m_pos != m_Last && m_pos != m_First) && IsHorz() && IsBottom()) return TRUE;
if (m_pos <= m_Last && IsHorz() && IsTop()) return TRUE;
//if (IsVert() && m_pos >0 ) return TRUE;
return FALSE;
break;
}
return FALSE;
}
//----------------------------------------------
//debemos obtener cuantas barras existen en esta columnas
//porque si intentamos obtener el conteo con la funciones de dockbar
//siempre obtendremos nuestra actual barra mas otra de otra fila, por lo que
//el conteo es incorrecto, luego despues de nuestra barra la siguiente nula
//es el final de esta fila.
int CGuiControlBar::GetLastPos()
{
int nNumBars=(int)m_pDockBar->m_arrBars.GetSize();
int m_pos=m_pDockBar->FindBar(this);
for(int i=m_pos+1; i< nNumBars;i++)
{
if (m_pDockBar->m_arrBars[i]== NULL)
return i-1;
}
return -1;
}
//--------------------------------------------
//esta rutina funciona algo parecido a la anterior
//con la diferencia que ahora se parte desde la posicion
//que indetifica m_pos hacia atraz hasta encontrar el nulo
int CGuiControlBar::GetFirstPos()
{
int m_pos=m_pDockBar->FindBar(this);
for(int i=m_pos; i>=0;i--)
{
if (m_pDockBar->m_arrBars[i]== NULL)
return i+1;
}
return -1;
}
//------------------------------------------------------------------------
BOOL CGuiControlBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
if (IsFloating()) return 0;
CPoint ptCursor;
::GetCursorPos (&ptCursor);
if(nHitTest == HTLEFT ||nHitTest == HTRIGHT)
SetCursor(AfxGetApp ()->LoadCursor (AFX_IDC_HSPLITBAR));
else if(nHitTest == HTTOP ||nHitTest == HTBOTTOM)
SetCursor(AfxGetApp ()->LoadCursor (AFX_IDC_VSPLITBAR));
else
return CControlBar::OnSetCursor(pWnd, nHitTest, message);
return 1;
}
void CGuiControlBar::OnInvertTracker(const CRect& rect)
{
ASSERT_VALID(this);
ASSERT(!rect.IsRectEmpty());
CRect rcWin=GetDockRect();
CDC *pDC = m_pDockSite->GetDCEx(NULL,
DCX_WINDOW|DCX_CACHE|DCX_LOCKWINDOWUPDATE);
CRect rcBar;
GetWindowRect(rcBar);
if (IsVert()) //el sentido de las barras es vertical
{
if (m_SideMove==HTLEFT || m_SideMove==HTRIGHT) //el mouse esta en el borde izquierdo o derecho
{
rcWin.OffsetRect(-rect.left,-rect.top);
rcWin.top+=10;
rcWin.left=rect.left+2;
rcWin.right=rect.right+2;
}
else //el mouse esta el borde de arriba pero de una barra vertical
{
rcBar.OffsetRect(-rect.TopLeft());
rcWin=rcBar;
if (IsLeft() || IsRight()) //a la izquierda
{
rcWin.top=rect.top-2;
rcWin.bottom=rect.bottom-2;
}
//
}
}
else //el sentido de las barras es horizontal
{
if (m_SideMove==HTTOP || m_SideMove==HTBOTTOM) //el mouse esta en el borde de arriba o abajo
{
rcWin.OffsetRect(-rect.left,-rect.top);
rcWin.top=rect.top-2;
rcWin.bottom=rect.bottom-2;
}
else //el mouse esta en el borde derecho
{
rcBar.OffsetRect(-rect.TopLeft());
rcWin=rcBar;
if (IsBottom() || IsTop()) //abajo
{
rcWin.left=rect.left+2;
rcWin.right=rect.right+2;
}
}
}
ClientToScreen(&rcWin);
GetParentFrame()->ScreenToClient(&rcWin);
// invert the brush pattern (looks just like frame window sizing)
CBrush* pBrush = CDC::GetHalftoneBrush();
HBRUSH hOldBrush = NULL;
if (pBrush != NULL)
hOldBrush = (HBRUSH)SelectObject(pDC->m_hDC, pBrush->m_hObject);
pDC->PatBlt(rcWin.left, rcWin.top, rcWin.Width(), rcWin.Height(), PATINVERT);
if (hOldBrush != NULL)
SelectObject(pDC->m_hDC, hOldBrush);
m_pDockSite->ReleaseDC(pDC);
}
void CGuiControlBar::OnSize(UINT nType, int cx, int cy)
{
// CControlBar::OnSize(nType, cx, cy);
CWnd* pWnd = GetWindow(GW_CHILD);
if (!m_bSupportMultiView)
{
if (pWnd != NULL)
{
pWnd->MoveWindow(0, 0, cx, cy);
ASSERT(pWnd->GetWindow(GW_HWNDNEXT) == NULL);
}
}
else
{
while (pWnd != NULL)
{
if (pWnd->IsWindowVisible())
{
pWnd->MoveWindow(0, 0, cx, cy);
break;
}
pWnd=pWnd->GetWindow(GW_HWNDNEXT);
}
}
// TODO: Add your message handler code here
}
void CGuiControlBar::SetColorFondo(COLORREF clrFondo)
{
m_clrFondo=clrFondo;
}
//enum State{NORMAL=0,OVER=1,PRESS=2};
void CGuiControlBar::LoadStateBar(CString sProfile)
{
CWinApp* pApp = AfxGetApp();
TCHAR szSection[256];
wsprintf(szSection, "%s-Bar%d",sProfile,GetDlgCtrlID());
m_sizeHorz.cx=pApp->GetProfileInt(szSection, "sizeHorz.cx",200 );
m_sizeHorz.cy=pApp->GetProfileInt(szSection, "sizeHorz.cy",100 );
m_sizeVert.cx=pApp->GetProfileInt(szSection, "sizeVert.cx",200 );
m_sizeVert.cy=pApp->GetProfileInt(szSection, "sizeVert.cy",100 );
}
void CGuiControlBar::SaveBar(CString sProfile)
{
CWinApp* pApp = AfxGetApp();
TCHAR szSection[256];
wsprintf(szSection, "%s-Bar%d", sProfile,GetDlgCtrlID());
pApp->WriteProfileString(szSection, NULL, NULL);
pApp->WriteProfileInt(szSection, "sizeHorz.cx", m_sizeHorz.cx);
pApp->WriteProfileInt(szSection, "sizeHorz.cy", m_sizeHorz.cy);
pApp->WriteProfileInt(szSection, "sizeVert.cx", m_sizeVert.cx);
pApp->WriteProfileInt(szSection, "sizeVert.cy", m_sizeVert.cy);
}
void CGuiControlBar::OnNcMouseMove(UINT nHitTest, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (m_stateBtn != NORMAL) return;
if (nHitTest == HTCLOSE)
{
m_stateBtn=OVER;
SetTimer(1,100,0);
}
SendMessage(WM_NCPAINT);
CControlBar::OnNcMouseMove(nHitTest, point);
}
void CGuiControlBar::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=m_rcCloseBtn;
ClientToScreen(rcT);
pt.y+=23;
pt.x+=5;
if (!rcT.PtInRect(pt))
{
m_stateBtn=NORMAL;
KillTimer(1);
SendMessage(WM_NCPAINT);
}
CControlBar::OnTimer(nIDEvent);
}
void CGuiControlBar::OnNcLButtonDblClk(UINT nFlags, CPoint point)
{
if(m_pDockBar != NULL)
{
m_pDockContext->ToggleDocking();
m_rcOldBorder=CRect(0,0,0,0);
}
}
void CGuiControlBar::SetSizes(int cx,int cy)
{
if(IsHorz()) m_sizeHorz.cy=cy;
else if(IsVert()) m_sizeVert.cx=cx;
else m_sizeMinFloating=CSize(cx,cy);
RecalWindowPos();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -