headerctrlex.cpp

来自「用bcg库编写的java IDE 源码」· C++ 代码 · 共 353 行

CPP
353
字号
// HeaderCtrlEx.cpp : implementation file
//

#include "stdafx.h"
#include "VisualJava.h"
#include "HeaderCtrlEx.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CHeaderCtrlEx
#define BUT_NONE   0x0000
#define BUT_PUSHED 0x0001
#define BUT_RAISED 0x0002
static  CHeaderCtrlEx::__item* m_cur = NULL;

CHeaderCtrlEx::CHeaderCtrlEx()
{
   m_bButtonPressed = FALSE;
   m_pMsgWnd = NULL;m_iClicked = -1;
}

CHeaderCtrlEx::~CHeaderCtrlEx()
{
  m_brBackground.DeleteObject();
    for(int npos = 0; npos<m_lItems.GetSize(); npos++)
	  delete m_lItems[npos];
}


BEGIN_MESSAGE_MAP(CHeaderCtrlEx, CWnd)
	//{{AFX_MSG_MAP(CHeaderCtrlEx)
	ON_WM_PAINT()
	ON_WM_CREATE()
	ON_WM_SETCURSOR()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_NCMOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//	

/////////////////////////////////////////////////////////////////////////////
// CHeaderCtrlEx message handlers

void CHeaderCtrlEx::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
    CDC mdc;
    CRect rc;
    GetClientRect(&rc);

    mdc.CreateCompatibleDC(&dc);
    CBitmap bm;
    bm.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height());
    CBitmap* pOldBm = mdc.SelectObject(&bm);

	//draw basic bk
    mdc.FillRect(&rc,&m_brBackground);

    DrawItems(&mdc);
    dc.BitBlt(0, 0, rc.Width(), rc.Height(), &mdc, 0, 0, SRCCOPY);

    mdc.SelectObject(pOldBm);
    ReleaseDC(&dc);
    bm.DeleteObject();
    mdc.DeleteDC();	// Do not call CStatic::OnPaint() for painting messages
}

void CHeaderCtrlEx::DrawItems(CDC *pDC)
{
    for(int npos = 0; npos<m_lItems.GetSize(); npos++)
	{
	  CHeaderCtrlEx::__item* pItem = m_lItems[npos];

	  /*{
		 CRect rc(pItem->m_rect);
         if (pItem->m_dwFlags & BUT_PUSHED)
		 {
            pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNSHADOW),
               ::GetSysColor(COLOR_BTNHIGHLIGHT));
		 }
         else
         if (pItem->m_dwFlags & BUT_RAISED)
		 {
             pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNHIGHLIGHT),
                ::GetSysColor(COLOR_BTNSHADOW));
		 }
	  }*/

	  CRect imgrc(0,0,pItem->m_imgcxy,pItem->m_imgcxy);

	  //calculate offset, that would enable us to center the image
	  int Yoffset = pItem->m_rect.Height()/2-imgrc.Height()/2;
	  int Xoffset = pItem->m_rect.Width()/2-imgrc.Width()/2;

		
	  //actual image rectangle
	  CRect actimgrc(pItem->m_rect);
	  actimgrc.DeflateRect(Xoffset,Yoffset,Xoffset,Yoffset);
	  //pDC->FillSolidRect(actimgrc,RGB(255,0,0));

		
	  CSize dim(actimgrc.Width(),actimgrc.Height());
	  CPoint    cxy = actimgrc.TopLeft();
	  CPoint    xy  = pItem->m_rect.TopLeft();
      //ASSERT(m_pimgList->DrawIndirect(pDC,pItem->m_iImage,cxy,dim,xy,ILD_NORMAL));
	  m_pimgList->Draw(pDC,pItem->m_iImage,cxy,ILD_TRANSPARENT);
	}

	  //draw text
	CString szpText;
	GetWindowText(szpText);

	int nPrevMode  = pDC->SetBkMode(TRANSPARENT);
	int nPrevColor = pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT));
	CRect rcRect;
	GetClientRect(rcRect);

	pDC->TextOut(rcRect.left+2,rcRect.top+2,szpText);
	pDC->SetBkMode(nPrevMode);
	pDC->SetTextColor(nPrevColor);

	if(m_cur != NULL)
	{
	  pDC->DrawEdge( &m_cur->m_rect, 
                       m_bButtonPressed ? BDR_SUNKENOUTER : BDR_RAISEDINNER, 
                       BF_RECT );
	}
}

int CHeaderCtrlEx::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
   m_brBackground.CreateSolidBrush(GetSysColor(COLOR_3DFACE));	
   //m_wndTip.Create(this);
   return 0;
}

void CHeaderCtrlEx::SetAt(int nIndex,int nImage,int cxy,int imgcxy,CString szpTip)
{
	int ncount = m_lItems.GetSize();
	if(nIndex<ncount)
	{
	  m_lItems[nIndex]->m_iImage = nImage;
	  m_lItems[nIndex]->m_nIndex = nIndex;
	  m_lItems[nIndex]->m_cxy    = cxy;
	  m_lItems[nIndex]->m_imgcxy = imgcxy;

      int offset =  cxy - m_lItems[nIndex]->m_cxy;
	  CRect rt;
	  GetClientRect(&rt);
      
	  //recalculate item rectangle
	  CRect rc(rt.right-cxy,rt.top+1,rt.right,rt.bottom-1);
	  m_lItems[nIndex]->m_rect = rc;

	  //shift all items to the left and right
	  if(offset>0)
	  {
		for(int npos =0; npos<nIndex;npos++)
			m_lItems[npos]->m_rect.OffsetRect(CPoint(-cxy,0));

		for(npos =nIndex+1; npos<ncount;npos++)
			m_lItems[npos]->m_rect.OffsetRect(CPoint(cxy,0));
	  }
	}
    Invalidate();
	UpdateWindow();
}


void CHeaderCtrlEx::AddItem(int nImage,int cxy,int imgcxy,CString szpTip)
{
	int ncount = m_lItems.GetSize();
	{
	  CHeaderCtrlEx::__item* pItem = new CHeaderCtrlEx::__item;
	  pItem->m_iImage = nImage;
	  pItem->m_nIndex = ncount;
	  pItem->m_cxy    = cxy;
	  pItem->m_imgcxy = imgcxy;

	  CRect rt;
	  GetClientRect(&rt);
      
	  //calculate item rectangle
	  CRect rc(rt.right-cxy,rt.top+1,rt.right,rt.bottom-1);
	  //CRect rc(100,0,130,30);
	  pItem->m_rect = rc;

	  //shift all items to the left
	  if(ncount>0)
		for(int npos = 0; npos<m_lItems.GetSize();npos++)
			m_lItems[npos]->m_rect.OffsetRect(CPoint(-cxy,0));

      m_lItems.Add(pItem);
	}

	//m_wndTip.AddTool(this,szpTip);
	Invalidate();
	UpdateWindow();
}

void CHeaderCtrlEx::SetImgList(CImageList *plist)
{
   m_pimgList = plist;
}

BOOL CHeaderCtrlEx::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	return CWnd::OnSetCursor(pWnd, nHitTest, message);
}

CHeaderCtrlEx::__item* CHeaderCtrlEx::getItem(CPoint pt)
{
    for(int npos = 0; npos<m_lItems.GetSize(); npos++)
	{
		CHeaderCtrlEx::__item* pItem = m_lItems[npos];
		if(pItem->m_rect.PtInRect(pt))
		{
		  pItem->m_nIndex = npos;
		  return pItem;
		}
	}return NULL;
}


void CHeaderCtrlEx::OnMouseMove(UINT nFlags, CPoint point) 
{
   if ( !m_bButtonPressed )
   {
      CHeaderCtrlEx::__item* pItem = getItem(point);
      // If found a button, update info
      if (m_cur != pItem)
      {
         InvalidateRect(m_cur->m_rect, FALSE );
         m_cur = pItem;
         InvalidateRect( m_cur->m_rect, TRUE );
      }
   }
   CWnd::OnMouseMove(nFlags, point);
}

void CHeaderCtrlEx::PreSubclassWindow() 
{
   m_brBackground.CreateSolidBrush(GetSysColor(COLOR_3DFACE));		
   CWnd::PreSubclassWindow();
}

void CHeaderCtrlEx::RemoveAt(int nIndex)
{
  //shift to the right all items to the left
  for(int npos = 0; npos<m_lItems.GetSize();npos++)
	m_lItems[npos]->m_rect.OffsetRect(CPoint(m_lItems[nIndex]->m_cxy,0));

  delete m_lItems[nIndex];
  m_lItems.RemoveAt(nIndex);
  
  Invalidate();
  UpdateWindow();
}


void CHeaderCtrlEx::OnLButtonDown(UINT nFlags, CPoint point) 
{
  // Capture the mouse
  SetCapture();

  CHeaderCtrlEx::__item* pItem = getItem(point);
  if(pItem != NULL)
  {
	 m_bButtonPressed = TRUE;

     // Redraw only the affected button
     InvalidateRect(&pItem->m_rect, FALSE );
     UpdateWindow();
  }
  CWnd::OnLButtonDown(nFlags, point);
}



void CHeaderCtrlEx::OnNcMouseMove(UINT nHitTest, CPoint point) 
{
   // Redraw the affected button
   InvalidateRect(m_cur->m_rect,FALSE);
   m_cur = getItem(point);
   InvalidateRect(m_cur->m_rect,TRUE);
   
   CWnd::OnNcMouseMove(nHitTest, point);
}

void CHeaderCtrlEx::OnLButtonUp(UINT nFlags, CPoint point) 
{
   // Find the button
	CHeaderCtrlEx::__item* pitem = getItem(point);

   // Accept only clicks that occur on the same button where the mouse was pressed
   if(pitem == m_cur)
   {
      // Take action, if necessary
      if(m_cur != NULL)
	  {
		m_iClicked = pitem->m_nIndex;
		m_pMsgWnd->PostMessage(HD_MESSAGE_LCLICK,(WPARAM)pitem->m_nIndex,(LPARAM)this);
	  }
   }

   // Set default conditions
   m_bButtonPressed = FALSE;

   // Redraw
   Invalidate( FALSE );

   // Memorize last
   m_cur = pitem;

   // Release mouse capture
   ReleaseCapture();
	
   CWnd::OnLButtonUp(nFlags, point);
}

void CHeaderCtrlEx::OnSize(UINT nType, int cx, int cy) 
{
	CWnd::OnSize(nType, cx, cy);
		
	int nCount = m_lItems.GetSize();

	CRect rt;
	GetClientRect(&rt);
      
	//calculate item rectangle
	if(nCount>0)
	{
	  CRect rc(rt.right-m_lItems[nCount-1]->m_cxy,rt.top+1,rt.right,rt.bottom-1);

	  //shift all items to the left
	 for(int npos = nCount-1; npos>=0;npos--)
	 {
	   m_lItems[npos]->m_rect = rc;
	   rc.OffsetRect(CPoint(-m_lItems[npos]->m_cxy,0));
	 }
	}
}

⌨️ 快捷键说明

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