www.gusucode.com > 一个左侧带树形菜单的VC++界面设计实例源码程序 > 一个左侧带树形菜单的VC++界面设计实例/IECtrlBar/IECtrlBar/IEBar.cpp

    // IEBar.cpp : implementation file
/***********************************************************
		Written by : FanWenSheng
		Address    : HeFei University of Technology
		Email      : fanwenshengcom@sohu.com
		Copyright (c) 2002.8.27 
***********************************************************/

#include "stdafx.h"
#include "IECtrlBar.h"
#include "IEBar.h"

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

/////////////////////////////////////////////////////////////////////////////
// CIEBar dialog

#ifndef IE_FRM_WIDTH
#define IE_FRM_WIDTH 6
#endif

CIEBar::CIEBar(CWnd* pParent /*=NULL*/)
	: CDialogBar()
{
	m_TitleTxt           = _T("浏览器");
	m_cyTitle            = 22;
	m_cxIEBar            = 200;
	pTreeCtrl            = NULL;

	m_HideBtnRc.left     =
	m_HideBtnRc.top      =
	m_HideBtnRc.right    =
	m_HideBtnRc.bottom   = 0;
	
	m_VirClientRc.left   =
	m_VirClientRc.top    =
	m_VirClientRc.right  =
	m_VirClientRc.bottom = 0;

	m_PrePnt.x           =
	m_PrePnt.y           = 0;

	m_bResize            =
	m_bTrack             =
	m_bRaised            = 
	m_bPressed           = false;
}


void CIEBar::DoDataExchange(CDataExchange* pDX)
{
	CDialogBar::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CIEBar)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CIEBar, CDialogBar)
	//{{AFX_MSG_MAP(CIEBar)
	ON_WM_LBUTTONDBLCLK()
	ON_WM_LBUTTONDOWN()
	ON_WM_PAINT()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_WM_SETCURSOR()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CIEBar message handlers

BOOL CIEBar::InitIEBar()
{
	UpdateData(FALSE);

	SetWindowText("IE Control Bar");
	m_Font.CreateFont(-12,0,0,0,400,0,0,0,134,3,2,1,2,"宋体");
	SetFont(&m_Font);

	// create the tree control
	pTreeCtrl = new CTreeCtrl();
	ASSERT(pTreeCtrl);
	if(!pTreeCtrl->Create(WS_CHILD | WS_VISIBLE, CRect(0,0,0,0), this, 101))
	{
		TRACE0("Failed to create tree control!");
		return FALSE;
	}

    // create the tool tip
    if(!m_TipCtrl.Create(this))
		return FALSE;
	
	return TRUE;
}

// for tooltips
BOOL CIEBar::PreTranslateMessage(MSG* pMsg) 
{
    m_TipCtrl.RelayEvent(pMsg);
    return CWnd::PreTranslateMessage(pMsg);
}

BOOL CIEBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{	
	ChangeCursor();
	return TRUE;  // avoid the cross cursor flash
}

// change cursor
void CIEBar::ChangeCursor()
{
	if(!m_VirClientRc.IsRectEmpty())
	{
		CPoint t_CurPnt;
		::GetCursorPos(&t_CurPnt);
		ScreenToClient(&t_CurPnt);

		CRect t_CursorRc(m_VirClientRc);
		t_CursorRc.left = m_VirClientRc.right;
		t_CursorRc.right = t_CursorRc.left + IE_FRM_WIDTH;

		HCURSOR hCursor = NULL;
		if(t_CursorRc.PtInRect(t_CurPnt))
			hCursor = AfxGetApp()->LoadCursor(IDC_RESIZE);
		else
			hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
		::SetCursor(hCursor);
	}
}

void CIEBar::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	// don't floating
	return;
}

void CIEBar::OnLButtonDown(UINT nFlags, CPoint point) 
{	
	SetCapture();       // capture mouse

	if(!m_HideBtnRc.IsRectEmpty())
	{
		m_bTrack  = true;   // track enable
		m_bRaised = false;

		if(m_HideBtnRc.PtInRect(point))
			m_bPressed = true;
		InvalidateRect(&m_HideBtnRc);
	}
	
	// whether track mouse for risize IE bar
	CRect t_CursorRc(m_VirClientRc);
	t_CursorRc.left = m_VirClientRc.right;
	t_CursorRc.right = t_CursorRc.left + IE_FRM_WIDTH;
	if(t_CursorRc.PtInRect(point))
		m_bResize = true;

	// don't floating
	return;
}

void CIEBar::OnLButtonUp(UINT nFlags, CPoint point) 
{	
	ReleaseCapture();

	m_bTrack   = 
	m_bRaised  =
	m_bPressed = false;

	// hide previous drag line
	if(m_PrePnt != CPoint(0, 0))
	{
		DrawDragLine(m_PrePnt);
		m_PrePnt = CPoint(0, 0);
	}

	// hide itself
	if(!m_HideBtnRc.IsRectEmpty())
		if(m_HideBtnRc.PtInRect(point))
			GetDockingFrame()->ShowControlBar(this, FALSE, FALSE);

	// adjust IE bar size
	ResizeIEBar();
	m_bResize = false;

	CDialogBar::OnLButtonUp(nFlags, point);
}

// adjust IE bar size
void CIEBar::ResizeIEBar()
{
	if(m_bResize)
	{
		CPoint t_CurPnt;
		::GetCursorPos(&t_CurPnt);
		ScreenToClient(&t_CurPnt);
		m_cxIEBar = t_CurPnt.x;

		CRect t_ClientRc;
		GetClientRect(&t_ClientRc);
		ClientToScreen(&t_ClientRc);
		t_ClientRc.right = t_ClientRc.left + m_cxIEBar;

		// resize right of the "t_ClientRc"
		if(t_ClientRc.Width() < 11)
		{
			t_ClientRc.right = t_ClientRc.left + 11;
			m_cxIEBar = 11;
		}
		else
		{
			CRect t_FrmRc;
			GetDockingFrame()->GetClientRect(&t_FrmRc);
			if(t_ClientRc.Width() > t_FrmRc.Width() / 2)
			{
				t_ClientRc.right = t_ClientRc.left + t_FrmRc.Width() / 2;
				m_cxIEBar = t_FrmRc.Width() / 2;
			}
		}

		GetDockingFrame()->ShowControlBar(this, FALSE, FALSE);
		MoveWindow(&t_ClientRc);
		GetDockingFrame()->ShowControlBar(this, TRUE, FALSE);
	}
}

void CIEBar::OnMouseMove(UINT nFlags, CPoint point) 
{	
	CDialogBar::OnMouseMove(nFlags, point);
	
	// draw tracking line
	if(m_bResize)
	{
		// hide previous drag line
		if(m_PrePnt != CPoint(0, 0))
			DrawDragLine(m_PrePnt);

		// draw new drag line
		CPoint t_ScrPnt(GetFitPnt());
		ClientToScreen(&t_ScrPnt);
		DrawDragLine(t_ScrPnt);
		
		// for draw previous drag line
		m_PrePnt = t_ScrPnt;
	}

	// draw hide-button for raised and pressed
	DrawHideBtnFace(point);
}

// draw hide-button for raised and pressed
void CIEBar::DrawHideBtnFace(CPoint point)
{
	if(!m_HideBtnRc.IsRectEmpty())
	{
		if(m_HideBtnRc.PtInRect(point))
		{
			SetCapture();

			if(m_bRaised)  // only draw once
				return;
			m_bRaised  = m_bTrack ? false : true;
			m_bPressed = m_bTrack ? true : false;
		}
		else
		{
			if(!m_bTrack)
				ReleaseCapture();

			if(!m_bRaised && !m_bPressed)  // only draw once
				return;
			m_bRaised  = 
			m_bPressed = false;
		}
		InvalidateRect(&m_HideBtnRc);
	}
}

// get fit point
CPoint CIEBar::GetFitPnt() 
{
	CRect t_FrmRc;
	GetDockingFrame()->GetClientRect(&t_FrmRc);

	POINT t_CurPnt;
	::GetCursorPos(&t_CurPnt);
	ScreenToClient(&t_CurPnt);

	if(t_CurPnt.x < 0)
		return CPoint(0, t_CurPnt.y);
	if(t_CurPnt.x > t_FrmRc.Width() / 2)
		return CPoint(t_FrmRc.Width() / 2, t_CurPnt.y);
	return t_CurPnt;
}

// draw draging line
void CIEBar::DrawDragLine(CPoint point)
{
	CRect t_ClientRect;
	GetClientRect(&t_ClientRect);
	ClientToScreen(&t_ClientRect); 
	
	CRect t_FocusRect(point.x, t_ClientRect.top,
		point.x, t_ClientRect.bottom);
	t_FocusRect.InflateRect(2, 0, -2, -43);
	
	CDC dc;
	dc.Attach(::GetWindowDC(NULL));  // note: this dc is used in screen coordinates
	int t_OldMode = dc.SetROP2(R2_NOT);
	
	for(int i=0; i<2; i++)           // draw drag lines here
	{
		t_FocusRect.left  += 2;
		t_FocusRect.right += 2;
		dc.DrawFocusRect(&t_FocusRect);
	}
	
	dc.SetROP2(t_OldMode);
	dc.DeleteDC();
}

CSize CIEBar::CalcDynamicLayout(int nLength, DWORD dwMode)
{
	// get rectangle for main frame
	CRect t_FrmRc;
	GetDockingFrame()->GetClientRect(&t_FrmRc);

	// resize tree control size
	if(pTreeCtrl)
	{
		if(pTreeCtrl->m_hWnd != NULL)
		{
			CRect t_TreeRc(5, 8, m_cxIEBar-2-IE_FRM_WIDTH, t_FrmRc.Height() - 51);
			t_TreeRc.top += m_cyTitle + 1;
			pTreeCtrl->MoveWindow(&t_TreeRc);
		}
	}

	// set IE bar size
	return CSize(m_cxIEBar, t_FrmRc.Height());
}

// get tree control
CTreeCtrl* CIEBar::GetTreeCtrl()
{
	if(pTreeCtrl)
		return pTreeCtrl;
	else
		return NULL;
}

void CIEBar::OnPaint() 
{
	CPaintDC dc(this); // device context for painting

	DrawFrm(dc);       // draw big frame for IE bar
	DrawTitleTxt(dc);  // draw title text
	DrawHideBtn(dc);   // draw hide button
}

// draw big frame for IE bar
void CIEBar::DrawFrm(CDC& dc)
{
	CRect t_ClientRc;
	GetClientRect(&t_ClientRc);
	t_ClientRc.DeflateRect(3, 6, IE_FRM_WIDTH, 49);

	dc.SelectStockObject(NULL_BRUSH);
	dc.Draw3dRect(&t_ClientRc,
		          ::GetSysColor(COLOR_GRAYTEXT),
		          ::GetSysColor(COLOR_GRAYTEXT));

	dc.SelectStockObject(WHITE_PEN);
	// draw left single line
	dc.MoveTo(t_ClientRc.left + 1, t_ClientRc.top + 1);
	dc.LineTo(t_ClientRc.left + 1, t_ClientRc.bottom - 1);
	// draw top single line
	dc.MoveTo(t_ClientRc.left + 1, t_ClientRc.top + 1);
	dc.LineTo(t_ClientRc.right - 1, t_ClientRc.top + 1);
	// draw right single line
	dc.MoveTo(t_ClientRc.right, t_ClientRc.top);
	dc.LineTo(t_ClientRc.right, t_ClientRc.bottom);
	// draw bottom single line
	dc.MoveTo(t_ClientRc.left, t_ClientRc.bottom);
	dc.LineTo(t_ClientRc.right + 1, t_ClientRc.bottom);

	// get virtual rectangle
	m_VirClientRc = t_ClientRc;
	m_VirClientRc.InflateRect(-1, -1, 0, 0); 
}

// draw title text
void CIEBar::DrawTitleTxt(CDC& dc)
{
	CFont* pOldFont = dc.SelectObject(GetFont());
	ASSERT(pOldFont);
	int t_cxTxt = dc.GetTextExtent(m_TitleTxt).cx;

	CRect t_TxtRc(m_VirClientRc);
	t_TxtRc.left    += 5;
	t_TxtRc.right   =  t_TxtRc.left + t_cxTxt;
	t_TxtRc.bottom  =  t_TxtRc.top + m_cyTitle;

	int t_OldMode   = dc.SetBkMode(TRANSPARENT);
	dc.DrawText(m_TitleTxt,
		        &t_TxtRc, 
				DT_CENTER|DT_VCENTER|DT_SINGLELINE);

	dc.SelectObject(pOldFont);
	dc.SetBkMode(t_OldMode);

	// draw bottom single line for similar to 3d rectangle
	CPen t_BottomPen(PS_SOLID, 1, ::GetSysColor(COLOR_GRAYTEXT));
	CPen* pOldPen = dc.SelectObject(&t_BottomPen);
	dc.MoveTo(m_VirClientRc.left+1, t_TxtRc.bottom);
	dc.LineTo(m_VirClientRc.right, t_TxtRc.bottom);
	dc.SelectObject(pOldPen);
}

// draw hide button
void CIEBar::DrawHideBtn(CDC& dc)
{
	CRect t_HideBtnRc(m_VirClientRc);
	t_HideBtnRc.right  -= 5;
	t_HideBtnRc.left   = t_HideBtnRc.right - m_cyTitle;
	t_HideBtnRc.bottom = t_HideBtnRc.top + m_cyTitle;
	t_HideBtnRc.DeflateRect(7, 4, -1, 3);
	
	// get hide button rectangle area
	m_HideBtnRc = t_HideBtnRc;

	// add a tip for hide button
	if(m_TipCtrl.GetToolCount())
		m_TipCtrl.DelTool(this, 1);
	m_TipCtrl.AddTool(this, "关闭", t_HideBtnRc, 1);

	// draw 3d face
	dc.SelectStockObject(NULL_BRUSH);
	if(m_bRaised)
		dc.Draw3dRect(&t_HideBtnRc,
		              ::GetSysColor(COLOR_BTNHIGHLIGHT),
		              ::GetSysColor(COLOR_BTNSHADOW));
	else if(m_bPressed)
		    dc.Draw3dRect(&t_HideBtnRc,
		                  ::GetSysColor(COLOR_BTNSHADOW),
		                  ::GetSysColor(COLOR_BTNHIGHLIGHT));

	HICON hIcon = AfxGetApp()->LoadIcon(IDI_HIDE_BTN);
	ASSERT(hIcon);
	::DrawIconEx(dc.m_hDC, 
				 t_HideBtnRc.left, 
				 t_HideBtnRc.top, 
				 hIcon, 
				 16, 16, 0, 
			 	 NULL, 
				 DI_NORMAL);
}