| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996 | 
							- // This is a part of the Microsoft Foundation Classes C++ library.
 
- // Copyright (C) 1992-1998 Microsoft Corporation
 
- // All rights reserved.
 
- //
 
- // This source code is only intended as a supplement to the
 
- // Microsoft Foundation Classes Reference and related
 
- // electronic documentation provided with the library.
 
- // See these sources for detailed information regarding the
 
- // Microsoft Foundation Classes product.
 
- #include "stdafx.h"
 
- #include <malloc.h>
 
- #ifdef AFX_CORE3_SEG
 
- #pragma code_seg(AFX_CORE3_SEG)
 
- #endif
 
- #ifdef _DEBUG
 
- #undef THIS_FILE
 
- static char THIS_FILE[] = __FILE__;
 
- #endif
 
- #define new DEBUG_NEW
 
- /////////////////////////////////////////////////////////////////////////////
 
- // CControlBar
 
- // IMPLEMENT_DYNAMIC for CControlBar is in wincore.cpp for .OBJ granularity reasons
 
- BEGIN_MESSAGE_MAP(CControlBar, CWnd)
 
- 	//{{AFX_MSG_MAP(CControlBar)
 
- 	ON_WM_TIMER()
 
- 	ON_WM_PAINT()
 
- 	ON_WM_CTLCOLOR()
 
- 	ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
 
- 	ON_MESSAGE(WM_SIZEPARENT, OnSizeParent)
 
- 	ON_WM_WINDOWPOSCHANGING()
 
- 	ON_WM_SHOWWINDOW()
 
- 	ON_WM_LBUTTONDOWN()
 
- 	ON_WM_LBUTTONDBLCLK()
 
- 	ON_WM_MOUSEACTIVATE()
 
- 	ON_WM_CANCELMODE()
 
- 	ON_WM_CREATE()
 
- 	ON_WM_DESTROY()
 
- 	ON_MESSAGE_VOID(WM_INITIALUPDATE, OnInitialUpdate)
 
- 	ON_MESSAGE(WM_HELPHITTEST, OnHelpHitTest)
 
- 	ON_WM_ERASEBKGND()
 
- 	//}}AFX_MSG_MAP
 
- #ifndef _AFX_NO_CTL3D_SUPPORT
 
- 	ON_MESSAGE(WM_QUERY3DCONTROLS, OnQuery3dControls)
 
- #endif
 
- END_MESSAGE_MAP()
 
- #ifdef AFX_INIT_SEG
 
- #pragma code_seg(AFX_INIT_SEG)
 
- #endif
 
- CControlBar::CControlBar()
 
- {
 
- 	// no elements contained in the control bar yet
 
- 	m_nCount = 0;
 
- 	m_pData = NULL;
 
- 	// set up some default border spacings
 
- 	m_cxLeftBorder = m_cxRightBorder = 6;
 
- 	m_cxDefaultGap = 2;
 
- 	m_cyTopBorder = m_cyBottomBorder = 1;
 
- 	m_bAutoDelete = FALSE;
 
- 	m_hWndOwner = NULL;
 
- 	m_nStateFlags = 0;
 
- 	m_pDockSite = NULL;
 
- 	m_pDockBar = NULL;
 
- 	m_pDockContext = NULL;
 
- 	m_dwStyle = 0;
 
- 	m_dwDockStyle = 0;
 
- 	m_nMRUWidth = 32767;
 
- }
 
- void CControlBar::SetBorders(int cxLeft, int cyTop, int cxRight, int cyBottom)
 
- {
 
- 	ASSERT(cxLeft >= 0);
 
- 	ASSERT(cyTop >= 0);
 
- 	ASSERT(cxRight >= 0);
 
- 	ASSERT(cyBottom >= 0);
 
- 	m_cxLeftBorder = cxLeft;
 
- 	m_cyTopBorder = cyTop;
 
- 	m_cxRightBorder = cxRight;
 
- 	m_cyBottomBorder = cyBottom;
 
- }
 
- BOOL CControlBar::PreCreateWindow(CREATESTRUCT& cs)
 
- {
 
- 	if (!CWnd::PreCreateWindow(cs))
 
- 		return FALSE;
 
- 	// force clipsliblings (otherwise will cause repaint problems)
 
- 	cs.style |= WS_CLIPSIBLINGS;
 
- 	// default border style translation for Win4
 
- 	//  (you can turn off this translation by setting CBRS_BORDER_3D)
 
- 	if (afxData.bWin4 && (m_dwStyle & CBRS_BORDER_3D) == 0)
 
- 	{
 
- 		DWORD dwNewStyle = 0;
 
- 		switch (m_dwStyle & (CBRS_BORDER_ANY|CBRS_ALIGN_ANY))
 
- 		{
 
- 		case CBRS_LEFT:
 
- 			dwNewStyle = CBRS_BORDER_TOP|CBRS_BORDER_BOTTOM;
 
- 			break;
 
- 		case CBRS_TOP:
 
- 			dwNewStyle = CBRS_BORDER_TOP;
 
- 			break;
 
- 		case CBRS_RIGHT:
 
- 			dwNewStyle = CBRS_BORDER_TOP|CBRS_BORDER_BOTTOM;
 
- 			break;
 
- 		case CBRS_BOTTOM:
 
- 			dwNewStyle = CBRS_BORDER_BOTTOM;
 
- 			break;
 
- 		}
 
- 		// set new style if it matched one of the predefined border types
 
- 		if (dwNewStyle != 0)
 
- 		{
 
- 			m_dwStyle &= ~(CBRS_BORDER_ANY);
 
- 			m_dwStyle |= (dwNewStyle | CBRS_BORDER_3D);
 
- 		}
 
- 	}
 
- 	return TRUE;
 
- }
 
- void CControlBar::SetBarStyle(DWORD dwStyle)
 
- {
 
- 	ASSERT((dwStyle & CBRS_ALL) == dwStyle);
 
- 	EnableToolTips(dwStyle & CBRS_TOOLTIPS);
 
- 	if (m_dwStyle != dwStyle)
 
- 	{
 
- 		DWORD dwOldStyle = m_dwStyle;
 
- 		m_dwStyle = dwStyle;
 
- 		OnBarStyleChange(dwOldStyle, dwStyle);
 
- 	}
 
- }
 
- void CControlBar::OnBarStyleChange(DWORD, DWORD)
 
- {
 
- 	// can be overridden in derived classes
 
- }
 
- BOOL CControlBar::AllocElements(int nElements, int cbElement)
 
- {
 
- 	ASSERT_VALID(this);
 
- 	ASSERT(nElements >= 0 && cbElement >= 0);
 
- 	ASSERT(m_pData != NULL || m_nCount == 0);
 
- 	// allocate new data if necessary
 
- 	void* pData = NULL;
 
- 	if (nElements > 0)
 
- 	{
 
- 		ASSERT(cbElement > 0);
 
- 		if ((pData = calloc(nElements, cbElement)) == NULL)
 
- 			return FALSE;
 
- 	}
 
- 	free(m_pData);      // free old data
 
- 	// set new data and elements
 
- 	m_pData = pData;
 
- 	m_nCount = nElements;
 
- 	return TRUE;
 
- }
 
- #ifdef AFX_CORE3_SEG
 
- #pragma code_seg(AFX_CORE3_SEG)
 
- #endif
 
- CControlBar::~CControlBar()
 
- {
 
- 	ASSERT_VALID(this);
 
- 	DestroyWindow();    // avoid PostNcDestroy problems
 
- 	// also done in OnDestroy, but done here just in case
 
- 	if (m_pDockSite != NULL)
 
- 		m_pDockSite->RemoveControlBar(this);
 
- 	// free docking context
 
- 	CDockContext* pDockContext = m_pDockContext;
 
- 	m_pDockContext = NULL;
 
- 	delete pDockContext;
 
- 	// free array
 
- 	if (m_pData != NULL)
 
- 	{
 
- 		ASSERT(m_nCount != 0);
 
- 		free(m_pData);
 
- 	}
 
- 	_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
 
- 	if (pThreadState->m_pLastStatus == this)
 
- 	{
 
- 		pThreadState->m_pLastStatus = NULL;
 
- 		pThreadState->m_nLastStatus = -1;
 
- 	}
 
- }
 
- void CControlBar::PostNcDestroy()
 
- {
 
- 	if (m_bAutoDelete)      // Automatic cleanup?
 
- 		delete this;
 
- }
 
- /////////////////////////////////////////////////////////////////////////////
 
- // Attributes
 
- CSize CControlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
 
- {
 
- 	CSize size;
 
- 	size.cx = (bStretch && bHorz ? 32767 : 0);
 
- 	size.cy = (bStretch && !bHorz ? 32767 : 0);
 
- 	return size;
 
- }
 
- CSize CControlBar::CalcDynamicLayout(int, DWORD nMode)
 
- {
 
- 	return CalcFixedLayout(nMode & LM_STRETCH, nMode & LM_HORZ);
 
- }
 
- BOOL CControlBar::IsDockBar() const
 
- {
 
- 	return FALSE;
 
- }
 
- /////////////////////////////////////////////////////////////////////////////
 
- // Fly-by status bar help
 
- #define ID_TIMER_WAIT   0xE000  // timer while waiting to show status
 
- #define ID_TIMER_CHECK  0xE001  // timer to check for removal of status
 
- void CControlBar::ResetTimer(UINT nEvent, UINT nTime)
 
- {
 
- 	KillTimer(ID_TIMER_WAIT);
 
- 	KillTimer(ID_TIMER_CHECK);
 
- 	VERIFY(SetTimer(nEvent, nTime, NULL));
 
- }
 
- void CControlBar::OnTimer(UINT nIDEvent)
 
- {
 
- 	if (GetKeyState(VK_LBUTTON) < 0)
 
- 		return;
 
- 	_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
 
- 	// get current mouse position for hit test
 
- 	CPoint point; GetCursorPos(&point);
 
- 	ScreenToClient(&point);
 
- 	int nHit = OnToolHitTest(point, NULL);
 
- 	if (nHit >= 0)
 
- 	{
 
- 		// determine if status bar help should go away
 
- 		CWnd* pParent = GetTopLevelParent();
 
- 		if (!IsTopParentActive() || !pParent->IsWindowEnabled())
 
- 			nHit = -1;
 
- 		// remove status help if capture is set
 
- 		HWND hWndTip = pThreadState->m_pToolTip->GetSafeHwnd();
 
- 		CWnd* pCapture = GetCapture();
 
- 		if (pCapture != this && pCapture->GetSafeHwnd() != hWndTip &&
 
- 			pCapture->GetTopLevelParent() == pParent)
 
- 		{
 
- 			nHit = -1;
 
- 		}
 
- 	}
 
- 	else
 
- 	{
 
- 		pThreadState->m_nLastStatus = -1;
 
- 	}
 
- 	// make sure it isn't over some other app's window
 
- 	if (nHit >= 0)
 
- 	{
 
- 		ClientToScreen(&point);
 
- 		HWND hWnd = ::WindowFromPoint(point);
 
- 		if (hWnd == NULL || (hWnd != m_hWnd && !::IsChild(m_hWnd, hWnd) &&
 
- 			pThreadState->m_pToolTip->GetSafeHwnd() != hWnd))
 
- 		{
 
- 			nHit = -1;
 
- 			pThreadState->m_nLastStatus = -1;
 
- 		}
 
- 	}
 
- 	// handle the result
 
- 	if (nHit < 0)
 
- 	{
 
- 		if (pThreadState->m_nLastStatus == -1)
 
- 			KillTimer(ID_TIMER_CHECK);
 
- 		SetStatusText(-1);
 
- 	}
 
- 	// set status text after initial timeout
 
- 	if (nIDEvent == ID_TIMER_WAIT)
 
- 	{
 
- 		KillTimer(ID_TIMER_WAIT);
 
- 		if (nHit >= 0)
 
- 			SetStatusText(nHit);
 
- 	}
 
- }
 
- BOOL CControlBar::SetStatusText(int nHit)
 
- {
 
- 	CWnd* pOwner = GetOwner();
 
- 	_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
 
- 	if (nHit == -1)
 
- 	{
 
- 		// handle reset case
 
- 		pThreadState->m_pLastStatus = NULL;
 
- 		if (m_nStateFlags & statusSet)
 
- 		{
 
- 			pOwner->SendMessage(WM_POPMESSAGESTRING, AFX_IDS_IDLEMESSAGE);
 
- 			m_nStateFlags &= ~statusSet;
 
- 			return TRUE;
 
- 		}
 
- 		KillTimer(ID_TIMER_WAIT);
 
- 	}
 
- 	else
 
- 	{
 
- 		// handle setnew case
 
- 		if (!(m_nStateFlags & statusSet) || pThreadState->m_nLastStatus != nHit)
 
- 		{
 
- 			pThreadState->m_pLastStatus = this;
 
- 			pOwner->SendMessage(WM_SETMESSAGESTRING, nHit);
 
- 			m_nStateFlags |= statusSet;
 
- 			ResetTimer(ID_TIMER_CHECK, 200);
 
- 			return TRUE;
 
- 		}
 
- 	}
 
- 	return FALSE;
 
- }
 
- /////////////////////////////////////////////////////////////////////////////
 
- // Default control bar processing
 
- BOOL CControlBar::PreTranslateMessage(MSG* pMsg)
 
- {
 
- 	ASSERT_VALID(this);
 
- 	ASSERT(m_hWnd != NULL);
 
- 	// allow tooltip messages to be filtered
 
- 	if (CWnd::PreTranslateMessage(pMsg))
 
- 		return TRUE;
 
- 	UINT message = pMsg->message;
 
- 	CWnd* pOwner = GetOwner();
 
- 	// handle CBRS_FLYBY style (status bar flyby help)
 
- 	if (((m_dwStyle & CBRS_FLYBY) ||
 
- 		message == WM_LBUTTONDOWN || message == WM_LBUTTONUP) &&
 
- 		((message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) ||
 
- 		 (message >= WM_NCMOUSEFIRST && message <= WM_NCMOUSELAST)))
 
- 	{
 
- 		_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
 
- 		// gather information about current mouse position
 
- 		CPoint point = pMsg->pt;
 
- 		ScreenToClient(&point);
 
- 		TOOLINFO ti; memset(&ti, 0, sizeof(TOOLINFO));
 
- 		ti.cbSize = sizeof(AFX_OLDTOOLINFO);
 
- 		int nHit = OnToolHitTest(point, &ti);
 
- 		if (ti.lpszText != LPSTR_TEXTCALLBACK)
 
- 			free(ti.lpszText);
 
- 		BOOL bNotButton =
 
- 			message == WM_LBUTTONDOWN && (ti.uFlags & TTF_NOTBUTTON);
 
- 		if (message != WM_LBUTTONDOWN && GetKeyState(VK_LBUTTON) < 0)
 
- 			nHit = pThreadState->m_nLastStatus;
 
- 		// update state of status bar
 
- 		if (nHit < 0 || bNotButton)
 
- 		{
 
- 			if (GetKeyState(VK_LBUTTON) >= 0 || bNotButton)
 
- 			{
 
- 				SetStatusText(-1);
 
- 				KillTimer(ID_TIMER_CHECK);
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			if (message == WM_LBUTTONUP)
 
- 			{
 
- 				SetStatusText(-1);
 
- 				ResetTimer(ID_TIMER_CHECK, 200);
 
- 			}
 
- 			else
 
- 			{
 
- 				if ((m_nStateFlags & statusSet) || GetKeyState(VK_LBUTTON) < 0)
 
- 					SetStatusText(nHit);
 
- 				else if (nHit != pThreadState->m_nLastStatus)
 
- 					ResetTimer(ID_TIMER_WAIT, 300);
 
- 			}
 
- 		}
 
- 		pThreadState->m_nLastStatus = nHit;
 
- 	}
 
- 	// don't translate dialog messages when in Shift+F1 help mode
 
- 	CFrameWnd* pFrameWnd = GetTopLevelFrame();
 
- 	if (pFrameWnd != NULL && pFrameWnd->m_bHelpMode)
 
- 		return FALSE;
 
- 	// since 'IsDialogMessage' will eat frame window accelerators,
 
- 	//   we call all frame windows' PreTranslateMessage first
 
- 	while (pOwner != NULL)
 
- 	{
 
- 		// allow owner & frames to translate before IsDialogMessage does
 
- 		if (pOwner->PreTranslateMessage(pMsg))
 
- 			return TRUE;
 
- 		// try parent frames until there are no parent frames
 
- 		pOwner = pOwner->GetParentFrame();
 
- 	}
 
- 	// filter both messages to dialog and from children
 
- 	return PreTranslateInput(pMsg);
 
- }
 
- LRESULT CControlBar::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
 
- {
 
- 	ASSERT_VALID(this);
 
- 	LRESULT lResult;
 
- 	switch (nMsg)
 
- 	{
 
- 	case WM_NOTIFY:
 
- 	case WM_COMMAND:
 
- 	case WM_DRAWITEM:
 
- 	case WM_MEASUREITEM:
 
- 	case WM_DELETEITEM:
 
- 	case WM_COMPAREITEM:
 
- 	case WM_VKEYTOITEM:
 
- 	case WM_CHARTOITEM:
 
- 		// send these messages to the owner if not handled
 
- 		if (OnWndMsg(nMsg, wParam, lParam, &lResult))
 
- 			return lResult;
 
- 		else
 
- 		{
 
- 			// try owner next
 
- 			lResult = GetOwner()->SendMessage(nMsg, wParam, lParam);
 
- 			// special case for TTN_NEEDTEXTA and TTN_NEEDTEXTW
 
- 			if(nMsg == WM_NOTIFY)
 
- 			{
 
- 				NMHDR* pNMHDR = (NMHDR*)lParam;
 
- 				if (pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW)
 
- 				{
 
- 					TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
 
- 					TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
 
- 					if ((pNMHDR->code == TTN_NEEDTEXTA && (!pTTTA->lpszText || !*pTTTA->lpszText)) ||
 
- 						(pNMHDR->code == TTN_NEEDTEXTW && (!pTTTW->lpszText || !*pTTTW->lpszText)))
 
- 					{
 
- 						// not handled by owner, so let bar itself handle it
 
- 						lResult = CWnd::WindowProc(nMsg, wParam, lParam);
 
- 					}
 
- 				}
 
- 			}
 
- 			return lResult;
 
- 		}
 
- 	}
 
- 	// otherwise, just handle in default way
 
- 	lResult = CWnd::WindowProc(nMsg, wParam, lParam);
 
- 	return lResult;
 
- }
 
- LRESULT CControlBar::OnHelpHitTest(WPARAM, LPARAM lParam)
 
- {
 
- 	ASSERT_VALID(this);
 
- 	int nID = OnToolHitTest((DWORD)lParam, NULL);
 
- 	if (nID != -1)
 
- 		return HID_BASE_COMMAND+nID;
 
- 	nID = _AfxGetDlgCtrlID(m_hWnd);
 
- 	return nID != 0 ? HID_BASE_CONTROL+nID : 0;
 
- }
 
- void CControlBar::OnWindowPosChanging(LPWINDOWPOS lpWndPos)
 
- {
 
- 	// WINBUG: We call DefWindowProc here instead of CWnd::OnWindowPosChanging
 
- 	//  (which calls CWnd::Default, which calls through the super wndproc)
 
- 	//  because certain control bars that are system implemented (such as
 
- 	//  CToolBar with TBSTYLE_FLAT) do not implement WM_WINDOWPOSCHANGING
 
- 	//  correctly, causing repaint problems.  This code bypasses that whole
 
- 	//  mess.
 
- 	::DefWindowProc(m_hWnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)lpWndPos);
 
- 	if (lpWndPos->flags & SWP_NOSIZE)
 
- 		return;
 
- 	// invalidate borders on the right
 
- 	CRect rect;
 
- 	GetWindowRect(&rect);
 
- 	CSize sizePrev = rect.Size();
 
- 	int cx = lpWndPos->cx;
 
- 	int cy = lpWndPos->cy;
 
- 	if (cx != sizePrev.cx && (m_dwStyle & CBRS_BORDER_RIGHT))
 
- 	{
 
- 		rect.SetRect(cx-afxData.cxBorder2, 0, cx, cy);
 
- 		InvalidateRect(&rect);
 
- 		rect.SetRect(sizePrev.cx-afxData.cxBorder2, 0, sizePrev.cx, cy);
 
- 		InvalidateRect(&rect);
 
- 	}
 
- 	// invalidate borders on the bottom
 
- 	if (cy != sizePrev.cy && (m_dwStyle & CBRS_BORDER_BOTTOM))
 
- 	{
 
- 		rect.SetRect(0, cy-afxData.cyBorder2, cx, cy);
 
- 		InvalidateRect(&rect);
 
- 		rect.SetRect(0, sizePrev.cy-afxData.cyBorder2, cx, sizePrev.cy);
 
- 		InvalidateRect(&rect);
 
- 	}
 
- }
 
- int CControlBar::OnCreate(LPCREATESTRUCT lpcs)
 
- {
 
- 	if (CWnd::OnCreate(lpcs) == -1)
 
- 		return -1;
 
- 	if (m_dwStyle & CBRS_TOOLTIPS)
 
- 		EnableToolTips();
 
- 	CFrameWnd *pFrameWnd = (CFrameWnd*)GetParent();
 
- 	if (pFrameWnd->IsFrameWnd())
 
- 	{
 
- 		m_pDockSite = pFrameWnd;
 
- 		m_pDockSite->AddControlBar(this);
 
- 	}
 
- 	return 0;
 
- }
 
- void CControlBar::OnDestroy()
 
- {
 
- 	_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
 
- 	if (pThreadState->m_pLastStatus == this)
 
- 	{
 
- 		SetStatusText(-1);
 
- 		ASSERT(pThreadState->m_pLastStatus == NULL);
 
- 	}
 
- 	if (m_pDockSite != NULL)
 
- 	{
 
- 		m_pDockSite->RemoveControlBar(this);
 
- 		m_pDockSite = NULL;
 
- 	}
 
- 	CWnd::OnDestroy();
 
- }
 
- BOOL CControlBar::DestroyWindow()
 
- {
 
- 	if (m_hWnd != NULL && IsFloating())
 
- 		return GetDockingFrame()->DestroyWindow();
 
- 	else
 
- 		return CWnd::DestroyWindow();
 
- }
 
- int CControlBar::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT nMsg)
 
- {
 
- 	// call default when toolbar is not floating
 
- 	if (!IsFloating())
 
- 		return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, nMsg);
 
- 	// special behavior when floating
 
- 	ActivateTopParent();
 
- 	return MA_NOACTIVATE;   // activation already done
 
- }
 
- void CControlBar::OnPaint()
 
- {
 
- 	// background is already filled in gray
 
- 	CPaintDC dc(this);
 
- 	// erase background now
 
- 	if (IsVisible())
 
- 		DoPaint(&dc);       // delegate to paint helper
 
- }
 
- void CControlBar::EraseNonClient()
 
- {
 
- 	// get window DC that is clipped to the non-client area
 
- 	CWindowDC dc(this);
 
- 	CRect rectClient;
 
- 	GetClientRect(rectClient);
 
- 	CRect rectWindow;
 
- 	GetWindowRect(rectWindow);
 
- 	ScreenToClient(rectWindow);
 
- 	rectClient.OffsetRect(-rectWindow.left, -rectWindow.top);
 
- 	dc.ExcludeClipRect(rectClient);
 
- 	// draw borders in non-client area
 
- 	rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top);
 
- 	DrawBorders(&dc, rectWindow);
 
- 	// erase parts not drawn
 
- 	dc.IntersectClipRect(rectWindow);
 
- 	SendMessage(WM_ERASEBKGND, (WPARAM)dc.m_hDC);
 
- 	// draw gripper in non-client area
 
- 	DrawGripper(&dc, rectWindow);
 
- }
 
- HBRUSH CControlBar::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
 
- {
 
- 	LRESULT lResult;
 
- 	if (pWnd->SendChildNotifyLastMsg(&lResult))
 
- 		return (HBRUSH)lResult;     // eat it
 
- 	// force black text on gray background all the time
 
- 	if (!GrayCtlColor(pDC->m_hDC, pWnd->GetSafeHwnd(), nCtlColor,
 
- 	   afxData.hbrBtnFace, afxData.clrBtnText))
 
- 		return (HBRUSH)Default();
 
- 	return afxData.hbrBtnFace;
 
- }
 
- void CControlBar::OnLButtonDown(UINT nFlags, CPoint pt)
 
- {
 
- 	// only start dragging if clicked in "void" space
 
- 	if (m_pDockBar != NULL && OnToolHitTest(pt, NULL) == -1)
 
- 	{
 
- 		// start the drag
 
- 		ASSERT(m_pDockContext != NULL);
 
- 		ClientToScreen(&pt);
 
- 		m_pDockContext->StartDrag(pt);
 
- 	}
 
- 	else
 
- 	{
 
- 		CWnd::OnLButtonDown(nFlags, pt);
 
- 	}
 
- }
 
- void CControlBar::OnLButtonDblClk(UINT nFlags, CPoint pt)
 
- {
 
- 	// only toggle docking if clicked in "void" space
 
- 	if (m_pDockBar != NULL && OnToolHitTest(pt, NULL) == -1)
 
- 	{
 
- 		// start the drag
 
- 		ASSERT(m_pDockContext != NULL);
 
- 		m_pDockContext->ToggleDocking();
 
- 	}
 
- 	else
 
- 	{
 
- 		CWnd::OnLButtonDblClk(nFlags, pt);
 
- 	}
 
- }
 
- LRESULT CControlBar::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM)
 
- {
 
- 	// handle delay hide/show
 
- 	BOOL bVis = GetStyle() & WS_VISIBLE;
 
- 	UINT swpFlags = 0;
 
- 	if ((m_nStateFlags & delayHide) && bVis)
 
- 		swpFlags = SWP_HIDEWINDOW;
 
- 	else if ((m_nStateFlags & delayShow) && !bVis)
 
- 		swpFlags = SWP_SHOWWINDOW;
 
- 	m_nStateFlags &= ~(delayShow|delayHide);
 
- 	if (swpFlags != 0)
 
- 	{
 
- 		SetWindowPos(NULL, 0, 0, 0, 0, swpFlags|
 
- 			SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
 
- 	}
 
- 	// the style must be visible and if it is docked
 
- 	// the dockbar style must also be visible
 
- 	if ((GetStyle() & WS_VISIBLE) &&
 
- 		(m_pDockBar == NULL || (m_pDockBar->GetStyle() & WS_VISIBLE)))
 
- 	{
 
- 		CFrameWnd* pTarget = (CFrameWnd*)GetOwner();
 
- 		if (pTarget == NULL || !pTarget->IsFrameWnd())
 
- 			pTarget = GetParentFrame();
 
- 		if (pTarget != NULL)
 
- 			OnUpdateCmdUI(pTarget, (BOOL)wParam);
 
- 	}
 
- 	return 0L;
 
- }
 
- void CControlBar::OnInitialUpdate()
 
- {
 
- 	// update the indicators before becoming visible
 
- 	OnIdleUpdateCmdUI(TRUE, 0L);
 
- }
 
- DWORD CControlBar::RecalcDelayShow(AFX_SIZEPARENTPARAMS* lpLayout)
 
- {
 
- 	ASSERT(lpLayout != NULL);
 
- 	// resize and reposition this control bar based on styles
 
- 	DWORD dwStyle = (m_dwStyle & (CBRS_ALIGN_ANY|CBRS_BORDER_ANY)) |
 
- 		(GetStyle() & WS_VISIBLE);
 
- 	// handle delay hide/show
 
- 	if (m_nStateFlags & (delayHide|delayShow))
 
- 	{
 
- 		UINT swpFlags = 0;
 
- 		if (m_nStateFlags & delayHide)
 
- 		{
 
- 			ASSERT((m_nStateFlags & delayShow) == 0);
 
- 			if (dwStyle & WS_VISIBLE)
 
- 				swpFlags = SWP_HIDEWINDOW;
 
- 		}
 
- 		else
 
- 		{
 
- 			ASSERT(m_nStateFlags & delayShow);
 
- 			if ((dwStyle & WS_VISIBLE) == 0)
 
- 				swpFlags = SWP_SHOWWINDOW;
 
- 		}
 
- 		if (swpFlags != 0)
 
- 		{
 
- 			// make the window seem visible/hidden
 
- 			dwStyle ^= WS_VISIBLE;
 
- 			if (lpLayout->hDWP != NULL)
 
- 			{
 
- 				// clear delay flags
 
- 				m_nStateFlags &= ~(delayShow|delayHide);
 
- 				// hide/show the window if actually doing layout
 
- 				lpLayout->hDWP = ::DeferWindowPos(lpLayout->hDWP, m_hWnd, NULL,
 
- 					0, 0, 0, 0, swpFlags|
 
- 					SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			// clear delay flags -- window is already in correct state
 
- 			m_nStateFlags &= ~(delayShow|delayHide);
 
- 		}
 
- 	}
 
- 	return dwStyle; // return new style
 
- }
 
- LRESULT CControlBar::OnSizeParent(WPARAM, LPARAM lParam)
 
- {
 
- 	AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;
 
- 	DWORD dwStyle = RecalcDelayShow(lpLayout);
 
- 	if ((dwStyle & WS_VISIBLE) && (dwStyle & CBRS_ALIGN_ANY) != 0)
 
- 	{
 
- 		// align the control bar
 
- 		CRect rect;
 
- 		rect.CopyRect(&lpLayout->rect);
 
- 		CSize sizeAvail = rect.Size();  // maximum size available
 
- 		// get maximum requested size
 
- 		DWORD dwMode = lpLayout->bStretch ? LM_STRETCH : 0;
 
- 		if ((m_dwStyle & CBRS_SIZE_DYNAMIC) && m_dwStyle & CBRS_FLOATING)
 
- 			dwMode |= LM_HORZ | LM_MRUWIDTH;
 
- 		else if (dwStyle & CBRS_ORIENT_HORZ)
 
- 			dwMode |= LM_HORZ | LM_HORZDOCK;
 
- 		else
 
- 			dwMode |=  LM_VERTDOCK;
 
- 		CSize size = CalcDynamicLayout(-1, dwMode);
 
- 		size.cx = min(size.cx, sizeAvail.cx);
 
- 		size.cy = min(size.cy, sizeAvail.cy);
 
- 		if (dwStyle & CBRS_ORIENT_HORZ)
 
- 		{
 
- 			lpLayout->sizeTotal.cy += size.cy;
 
- 			lpLayout->sizeTotal.cx = max(lpLayout->sizeTotal.cx, size.cx);
 
- 			if (dwStyle & CBRS_ALIGN_TOP)
 
- 				lpLayout->rect.top += size.cy;
 
- 			else if (dwStyle & CBRS_ALIGN_BOTTOM)
 
- 			{
 
- 				rect.top = rect.bottom - size.cy;
 
- 				lpLayout->rect.bottom -= size.cy;
 
- 			}
 
- 		}
 
- 		else if (dwStyle & CBRS_ORIENT_VERT)
 
- 		{
 
- 			lpLayout->sizeTotal.cx += size.cx;
 
- 			lpLayout->sizeTotal.cy = max(lpLayout->sizeTotal.cy, size.cy);
 
- 			if (dwStyle & CBRS_ALIGN_LEFT)
 
- 				lpLayout->rect.left += size.cx;
 
- 			else if (dwStyle & CBRS_ALIGN_RIGHT)
 
- 			{
 
- 				rect.left = rect.right - size.cx;
 
- 				lpLayout->rect.right -= size.cx;
 
- 			}
 
- 		}
 
- 		else
 
- 		{
 
- 			ASSERT(FALSE);      // can never happen
 
- 		}
 
- 		rect.right = rect.left + size.cx;
 
- 		rect.bottom = rect.top + size.cy;
 
- 		// only resize the window if doing layout and not just rect query
 
- 		if (lpLayout->hDWP != NULL)
 
- 			AfxRepositionWindow(lpLayout, m_hWnd, &rect);
 
- 	}
 
- 	return 0;
 
- }
 
- void CControlBar::DelayShow(BOOL bShow)
 
- {
 
- 	m_nStateFlags &= ~(delayHide|delayShow);
 
- 	if (bShow && (GetStyle() & WS_VISIBLE) == 0)
 
- 		m_nStateFlags |= delayShow;
 
- 	else if (!bShow && (GetStyle() & WS_VISIBLE) != 0)
 
- 		m_nStateFlags |= delayHide;
 
- }
 
- BOOL CControlBar::IsVisible() const
 
- {
 
- 	if (m_nStateFlags & delayHide)
 
- 		return FALSE;
 
- 	if ((m_nStateFlags & delayShow) || ((GetStyle() & WS_VISIBLE) != 0))
 
- 		return TRUE;
 
- 	return FALSE;
 
- }
 
- void CControlBar::DoPaint(CDC* pDC)
 
- {
 
- 	ASSERT_VALID(this);
 
- 	ASSERT_VALID(pDC);
 
- 	// paint inside client area
 
- 	CRect rect;
 
- 	GetClientRect(rect);
 
- 	DrawBorders(pDC, rect);
 
- 	DrawGripper(pDC, rect);
 
- }
 
- void CControlBar::DrawBorders(CDC* pDC, CRect& rect)
 
- {
 
- 	ASSERT_VALID(this);
 
- 	ASSERT_VALID(pDC);
 
- 	DWORD dwStyle = m_dwStyle;
 
- 	if (!(dwStyle & CBRS_BORDER_ANY))
 
- 		return;
 
- 	// prepare for dark lines
 
- 	ASSERT(rect.top == 0 && rect.left == 0);
 
- 	CRect rect1, rect2;
 
- 	rect1 = rect;
 
- 	rect2 = rect;
 
- 	COLORREF clr = afxData.bWin4 ? afxData.clrBtnShadow : afxData.clrWindowFrame;
 
- 	// draw dark line one pixel back/up
 
- 	if (dwStyle & CBRS_BORDER_3D)
 
- 	{
 
- 		rect1.right -= CX_BORDER;
 
- 		rect1.bottom -= CY_BORDER;
 
- 	}
 
- 	if (dwStyle & CBRS_BORDER_TOP)
 
- 		rect2.top += afxData.cyBorder2;
 
- 	if (dwStyle & CBRS_BORDER_BOTTOM)
 
- 		rect2.bottom -= afxData.cyBorder2;
 
- 	// draw left and top
 
- 	if (dwStyle & CBRS_BORDER_LEFT)
 
- 		pDC->FillSolidRect(0, rect2.top, CX_BORDER, rect2.Height(), clr);
 
- 	if (dwStyle & CBRS_BORDER_TOP)
 
- 		pDC->FillSolidRect(0, 0, rect.right, CY_BORDER, clr);
 
- 	// draw right and bottom
 
- 	if (dwStyle & CBRS_BORDER_RIGHT)
 
- 		pDC->FillSolidRect(rect1.right, rect2.top, -CX_BORDER, rect2.Height(), clr);
 
- 	if (dwStyle & CBRS_BORDER_BOTTOM)
 
- 		pDC->FillSolidRect(0, rect1.bottom, rect.right, -CY_BORDER, clr);
 
- 	if (dwStyle & CBRS_BORDER_3D)
 
- 	{
 
- 		// prepare for hilite lines
 
- 		clr = afxData.clrBtnHilite;
 
- 		// draw left and top
 
- 		if (dwStyle & CBRS_BORDER_LEFT)
 
- 			pDC->FillSolidRect(1, rect2.top, CX_BORDER, rect2.Height(), clr);
 
- 		if (dwStyle & CBRS_BORDER_TOP)
 
- 			pDC->FillSolidRect(0, 1, rect.right, CY_BORDER, clr);
 
- 		// draw right and bottom
 
- 		if (dwStyle & CBRS_BORDER_RIGHT)
 
- 			pDC->FillSolidRect(rect.right, rect2.top, -CX_BORDER, rect2.Height(), clr);
 
- 		if (dwStyle & CBRS_BORDER_BOTTOM)
 
- 			pDC->FillSolidRect(0, rect.bottom, rect.right, -CY_BORDER, clr);
 
- 	}
 
- 	if (dwStyle & CBRS_BORDER_LEFT)
 
- 		rect.left += afxData.cxBorder2;
 
- 	if (dwStyle & CBRS_BORDER_TOP)
 
- 		rect.top += afxData.cyBorder2;
 
- 	if (dwStyle & CBRS_BORDER_RIGHT)
 
- 		rect.right -= afxData.cxBorder2;
 
- 	if (dwStyle & CBRS_BORDER_BOTTOM)
 
- 		rect.bottom -= afxData.cyBorder2;
 
- }
 
- #define CX_GRIPPER  3
 
- #define CY_GRIPPER  3
 
- #define CX_BORDER_GRIPPER 2
 
- #define CY_BORDER_GRIPPER 2
 
- void CControlBar::DrawGripper(CDC* pDC, const CRect& rect)
 
- {
 
- 	// only draw the gripper if not floating and gripper is specified
 
- 	if ((m_dwStyle & (CBRS_GRIPPER|CBRS_FLOATING)) == CBRS_GRIPPER)
 
- 	{
 
- 		// draw the gripper in the border
 
- 		if (m_dwStyle & CBRS_ORIENT_HORZ)
 
- 		{
 
- 			pDC->Draw3dRect(rect.left+CX_BORDER_GRIPPER,
 
- 				rect.top+m_cyTopBorder,
 
- 				CX_GRIPPER, rect.Height()-m_cyTopBorder-m_cyBottomBorder,
 
- 				afxData.clrBtnHilite, afxData.clrBtnShadow);
 
- 		}
 
- 		else
 
- 		{
 
- 			pDC->Draw3dRect(rect.left+m_cyTopBorder,
 
- 				rect.top+CY_BORDER_GRIPPER,
 
- 				rect.Width()-m_cyTopBorder-m_cyBottomBorder, CY_GRIPPER,
 
- 				afxData.clrBtnHilite, afxData.clrBtnShadow);
 
- 		}
 
- 	}
 
- }
 
- // input CRect should be client rectangle size
 
- void CControlBar::CalcInsideRect(CRect& rect, BOOL bHorz) const
 
- {
 
- 	ASSERT_VALID(this);
 
- 	DWORD dwStyle = m_dwStyle;
 
- 	if (dwStyle & CBRS_BORDER_LEFT)
 
- 		rect.left += afxData.cxBorder2;
 
- 	if (dwStyle & CBRS_BORDER_TOP)
 
- 		rect.top += afxData.cyBorder2;
 
- 	if (dwStyle & CBRS_BORDER_RIGHT)
 
- 		rect.right -= afxData.cxBorder2;
 
- 	if (dwStyle & CBRS_BORDER_BOTTOM)
 
- 		rect.bottom -= afxData.cyBorder2;
 
- 	// inset the top and bottom.
 
- 	if (bHorz)
 
- 	{
 
- 		rect.left += m_cxLeftBorder;
 
- 		rect.top += m_cyTopBorder;
 
- 		rect.right -= m_cxRightBorder;
 
- 		rect.bottom -= m_cyBottomBorder;
 
- 		if ((m_dwStyle & (CBRS_GRIPPER|CBRS_FLOATING)) == CBRS_GRIPPER)
 
- 			rect.left += CX_BORDER_GRIPPER+CX_GRIPPER+CX_BORDER_GRIPPER;
 
- 	}
 
- 	else
 
- 	{
 
- 		rect.left += m_cyTopBorder;
 
- 		rect.top += m_cxLeftBorder;
 
- 		rect.right -= m_cyBottomBorder;
 
- 		rect.bottom -= m_cxRightBorder;
 
- 		if ((m_dwStyle & (CBRS_GRIPPER|CBRS_FLOATING)) == CBRS_GRIPPER)
 
- 			rect.top += CY_BORDER_GRIPPER+CY_GRIPPER+CY_BORDER_GRIPPER;
 
- 	}
 
- }
 
- /////////////////////////////////////////////////////////////////////////////
 
- // CControlBar diagnostics
 
- #ifdef _DEBUG
 
- void CControlBar::AssertValid() const
 
- {
 
- 	CWnd::AssertValid();
 
- 	ASSERT(m_nCount == 0 || m_pData != NULL);
 
- 	ASSERT((m_dwStyle & CBRS_ALL) == m_dwStyle);
 
- }
 
- void CControlBar::Dump(CDumpContext& dc) const
 
- {
 
- 	CWnd::Dump(dc);
 
- 	dc << "\nm_cxLeftBorder = " << m_cxLeftBorder;
 
- 	dc << "\nm_cxRightBorder = " << m_cxRightBorder;
 
- 	dc << "\nm_cyTopBorder = " << m_cyTopBorder;
 
- 	dc << "\nm_cyBottomBorder = " << m_cyBottomBorder;
 
- 	dc << "\nm_cxDefaultGap = " << m_cxDefaultGap;
 
- 	dc << "\nm_nCount = " << m_nCount;
 
- 	dc << "\nm_bAutoDelete = " << m_bAutoDelete;
 
- 	dc << "\n";
 
- }
 
- #endif
 
- /////////////////////////////////////////////////////////////////////////////
 
 
  |