www.pudn.com > ToolBar_ATL.rar > KToolBarCtrl.cpp


     // KToolBarCtrl.cpp : Implementation of CKToolBarCtrl 
 
#include "stdafx.h" 
#include "KToolBar.h" 
#include "KToolBarCtrl.h" 
 
///////////////////////////////////////////////////////////////////////////// 
// CKToolBarCtrl 
 
BSTR ConvertLPSTRToBSTR(LPSTR lpstrIn) 
{ 
	BSTR retBS=NULL; 
	if(lpstrIn){ 
		int StrLen = strlen(lpstrIn) + 1; 
		WCHAR *wStr = new WCHAR[StrLen]; 
		MultiByteToWideChar( CP_ACP, 0, lpstrIn,StrLen, wStr,StrLen); 
		retBS = ::SysAllocString(wStr); 
		delete[] wStr; 
	} 
	return retBS; 
} 
 
char* ConvertBSTRToLPSTR(BSTR bstrIn) 
{ 
	LPSTR pszOut = NULL; 
	if (bstrIn != NULL) 
	{ 
		int nInputStrLen = SysStringLen(bstrIn); 
		//Must add 2 bytes. 
		int nOutPutStrLen = nInputStrLen+2; 
		 
		pszOut = new char[nOutPutStrLen]; 
		 
		if(pszOut) 
		{ 
			memset(pszOut, 0x0, sizeof(char)*(nOutPutStrLen)); 
			WideCharToMultiByte(CP_ACP, 0, bstrIn, nInputStrLen, pszOut, nOutPutStrLen, 0, 0); 
		} 
	} 
	return pszOut; 
} 
CKToolBarCtrl::CKToolBarCtrl() 
{ 
	this->m_bWindowOnly = TRUE; 
 
	//m_listBtns.clear(); 
	 
	//m_nBtnCnt = 3; 
	m_MouseCaptured = FALSE; 
 
	m_MouseLState = MOUSE_UP; 
 
	m_BtnTrace = FALSE; 
 
	m_picHolder.CreateEmpty(); 
	//char arrDisp[100]; 
	//itoa((long)this->m_hWndCD,arrDisp,10); 
	//::MessageBox(NULL,arrDisp,0,0); 
 
	//itoa(sizeof(m_pTBItems),arrDisp,10); 
	//::MessageBox(NULL,arrDisp,0,0); 
 
	m_pDoc = new CToolBarDoc(); 
	m_pView = new CToolBarView(m_pDoc); 
} 
 
CKToolBarCtrl::~CKToolBarCtrl() 
{ 
	//int i; 
 
	if(m_pDoc){ 
		free(m_pDoc); 
	} 
 
	if(m_pView){ 
		free(m_pView); 
	} 
} 
 
HRESULT CKToolBarCtrl::OnDraw(ATL_DRAWINFO& di) 
{ 
	m_pView->SetRectBar(*(RECT*)di.prcBounds); 
	m_pView->ReDraw(di.hdcDraw,TRUE); 
	return S_OK; 
} 
 
LRESULT CKToolBarCtrl::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 
{ 
	return S_OK; 
} 
 
LRESULT CKToolBarCtrl::OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 
{ 
	POINT ptCursor; 
	TBItem *pBtn; 
	int nCurHoverIndex; 
 
	ptCursor.x = LOWORD(lParam); 
	ptCursor.y = HIWORD(lParam); 
	m_MouseLState = MOUSE_DOWN; 
 
	nCurHoverIndex = m_pDoc->GetCurHoverIndex(); 
 
	if(nCurHoverIndex != -1){ 
		RECT rect; 
		pBtn = m_pDoc->GetButton(nCurHoverIndex); 
		rect.left = pBtn->cx; 
		rect.top = pBtn->cy; 
		rect.right = rect.left + pBtn->width; 
		rect.bottom = rect.top + pBtn->height; 
 
		if(::PtInRect(&rect, ptCursor) == TRUE){ 
			pBtn->State = BTN_DOWN; 
 
			HDC hDC = ::GetDC(m_hWndCD); 
			m_pView->ReDraw(hDC,FALSE); 
			::ReleaseDC(m_hWndCD, hDC); 
			//FireViewChange(); 
 
			if(m_BtnTrace == FALSE){ 
				::SetCapture(this->m_hWndCD); 
				m_BtnTrace = TRUE; 
			} 
		} 
	} 
	bHandled = TRUE; 
	return S_OK; 
} 
 
LRESULT CKToolBarCtrl::OnLButtonUP(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 
{	 
	POINT ptCursor; 
	TBItem *pBtn; 
	int nCurHoverIndex; 
 
	ptCursor.x = LOWORD(lParam); 
	ptCursor.y = HIWORD(lParam); 
	m_MouseLState = MOUSE_UP; 
 
	nCurHoverIndex = m_pDoc->GetCurHoverIndex(); 
 
	if(nCurHoverIndex != -1){ 
		RECT rect; 
		pBtn = m_pDoc->GetButton(nCurHoverIndex); 
		rect.left = pBtn->cx; 
		rect.top = pBtn->cy; 
		rect.right = rect.left + pBtn->width; 
		rect.bottom = rect.top + pBtn->height; 
		 
		if(::PtInRect(&rect, ptCursor) == TRUE && pBtn->Enabled == TRUE){ 
			pBtn->State = BTN_HOVER; 
			Fire_BtnClick(nCurHoverIndex); 
		}else{ 
			m_pDoc->SetPrevHoverIndex(nCurHoverIndex); 
			m_pDoc->SetCurHoverIndex(-1); 
		} 
 
		HDC hDC = ::GetDC(m_hWndCD); 
		m_pView->ReDraw(hDC,FALSE); 
		::ReleaseDC(m_hWndCD, hDC); 
		//FireViewChange(); 
	} 
 
	if(m_BtnTrace == TRUE){ 
		ReleaseCapture(); 
		m_BtnTrace = FALSE; 
	} 
	bHandled = TRUE; 
	 
	return S_OK; 
} 
 
LRESULT CKToolBarCtrl::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 
{ 
	BOOL isRedraw = FALSE; 
	BOOL isCurInBar = FALSE; 
 
	POINT ptCursor; 
	ptCursor.x = LOWORD(lParam); 
	ptCursor.y = HIWORD(lParam); 
	 
	//鼠标移到了工具栏上 
	if(m_BtnTrace == FALSE){ 
		isCurInBar = TRUE; 
	}else{ 
		isCurInBar = (::WindowFromPoint(ptCursor) == this->m_hWndCD); 
	} 
 
	//根据鼠标位置确定Button Index 
	isRedraw = SetBtnState(ptCursor, isCurInBar); 
	 
	//鼠标移进了工具栏 
	if(isCurInBar == TRUE){ 
		if(m_BtnTrace == FALSE){ 
			::SetCapture(this->m_hWndCD); 
			m_BtnTrace = TRUE; 
		} 
	//鼠标移出工具栏 
	}else{ 
		if(m_MouseLState == MOUSE_UP){ 
			if(m_BtnTrace == TRUE){ 
				::ReleaseCapture(); 
				m_BtnTrace = FALSE; 
			} 
		} 
	} 
	 
	if(isRedraw == TRUE){ 
		HDC hDC = ::GetDC(m_hWndCD); 
		m_pView->ReDraw(hDC,FALSE); 
		::ReleaseDC(m_hWndCD, hDC); 
		//FireViewChange(); 
	} 
	 
	bHandled = TRUE; 
	return S_OK; 
} 
 
 
//根据当前鼠标位置和状态(是否按下), 设置按钮状态 
BOOL CKToolBarCtrl::SetBtnState(POINT point, BOOL isCursorInBar) 
{ 
	BOOL isReDraw; 
	int NewIndex; 
	int nPrevHoverIndex = m_pDoc->GetPrevHoverIndex(); 
	int nCurHoverIndex = m_pDoc->GetCurHoverIndex(); 
	TBItem *pBtn; 
	 
	isReDraw  = FALSE; 
 
	//There is a button with "hover" state. 
	if(nPrevHoverIndex != -1){ 
		//The left mouse is up 
		if(m_MouseLState == MOUSE_UP){ 
			NewIndex = m_pView->SearchBtnIndex(point); 
			//移出了当前按钮 
			if(NewIndex != nCurHoverIndex){ 
				isReDraw = TRUE; 
				m_pDoc->GetButton(nPrevHoverIndex)->State = BTN_NORMAL; 
				m_pDoc->SetPrevHoverIndex(nCurHoverIndex); 
 
				//进入了一个新的按钮 
				if(NewIndex != -1){ 
					pBtn = m_pDoc->GetButton(NewIndex); 
					pBtn->State = BTN_HOVER; 
					if(pBtn->Style == BTN_SEPARATOR){ 
						m_pDoc->SetCurHoverIndex(-1); 
					}else{ 
						m_pDoc->SetCurHoverIndex(NewIndex); 
					} 
				}else{ 
					m_pDoc->SetCurHoverIndex(-1); 
				} 
			} 
		//The left mouse is down, don't change button status. 
		}else{ 
			BOOL ptInButton; 
			RECT rect; 
			pBtn = m_pDoc->GetButton(nCurHoverIndex); 
			rect.left = pBtn->cx; 
			rect.top = pBtn->cy; 
			rect.right = rect.left + pBtn->width; 
			rect.bottom = rect.top + pBtn->height; 
			//鼠标是否在当前按钮上 
			ptInButton = ::PtInRect(&rect, point); 
			if(ptInButton == TRUE){ 
				if(pBtn->State == BTN_HOVER){ 
					pBtn->State = BTN_DOWN; 
					isReDraw = TRUE; 
				} 
			}else{ 
				if(pBtn->State == BTN_DOWN){ 
					pBtn->State = BTN_HOVER; 
					isReDraw = TRUE; 
				} 
			} 
		} 
	//There is no button with "hover" state. 
	}else{ 
		m_pDoc->SetPrevHoverIndex(nCurHoverIndex); 
		int NewIndex = m_pView->SearchBtnIndex(point); 
		if(NewIndex != -1){ 
			pBtn = m_pDoc->GetButton(NewIndex); 
			pBtn->State = BTN_HOVER; 
			isReDraw = TRUE; 
			if(pBtn->Style == BTN_SEPARATOR){ 
				m_pDoc->SetCurHoverIndex(-1); 
			}else{ 
				m_pDoc->SetCurHoverIndex(NewIndex); 
			} 
		}else{ 
			m_pDoc->SetCurHoverIndex(-1); 
		} 
	} 
 
	return isReDraw; 
} 
 
 
/* 
STDMETHODIMP CKToolBarCtrl::get_Button(short Index, VARIANT *pVal) 
{ 
	// TODO: Add your implementation code here 
	VARIANT vnt; 
	IRecordInfo *pRI; 
	HRESULT hr; 
 
	hr = GetRecordInfoFromGuids(LIBID_KTOOLBARLib, 1, 0, 0x409, SID_BUTTON, &pRI); 
	VariantInit(&vnt); 
	vnt.vt = VT_RECORD; 
	vnt.pvRecord = &m_pTBItems[Index]; 
	vnt.pRecInfo = pRI; 
 
	pRI = NULL; 
	pVal = &vnt; 
	return S_OK; 
} 
*/ 
 
/* 
STDMETHODIMP CKToolBarCtrl::put_Button(short Index, VARIANT newVal) 
{ 
	// TODO: Add your implementation code here 
 
	return S_OK; 
} 
*/ 
 
STDMETHODIMP CKToolBarCtrl::get_BtnEnabled(short Index, BOOL *pVal) 
{ 
	// TODO: Add your implementation code here 
	*pVal = m_pDoc->GetButton(Index)->Enabled; 
	return S_OK; 
} 
 
STDMETHODIMP CKToolBarCtrl::put_BtnEnabled(short Index, BOOL newVal) 
{ 
	// TODO: Add your implementation code here 
	m_pDoc->GetButton(Index)->Enabled = newVal; 
	return S_OK; 
} 
 
STDMETHODIMP CKToolBarCtrl::get_BtnStyle(short Index, BTNSTYLE *pVal) 
{ 
	// TODO: Add your implementation code here 
	*pVal = m_pDoc->GetButton(Index)->Style; 
	return S_OK; 
} 
 
STDMETHODIMP CKToolBarCtrl::put_BtnStyle(short Index, BTNSTYLE newVal) 
{ 
	// TODO: Add your implementation code here 
	m_pDoc->GetButton(Index)->Style = newVal; 
 
	//Calculate position of every button. 
	if(Index == m_pDoc->GetBtnCnt()-1){ 
		m_pView->CalCoor(); 
		FireViewChange(); 
	} 
 
	return S_OK; 
} 
 
STDMETHODIMP CKToolBarCtrl::get_BtnIcon(short Index, LPPICTUREDISP *pVal) 
{ 
	// TODO: Add your implementation code here 
	*pVal = m_pDoc->GetButton(Index)->Icon; 
	return S_OK; 
} 
 
STDMETHODIMP CKToolBarCtrl::put_BtnIcon(short Index, LPPICTUREDISP newVal) 
{ 
	// TODO: Add your implementation code here 
	LONG cbSize=0; 
 
	if(newVal != NULL){ 
		//写入一个测试流,得到图片多少字节 
		m_picHolder.SetPictureDispatch(newVal); 
 
		IStream* stmTestLen; 
		HGLOBAL hGlobal = ::GlobalAlloc(GMEM_MOVEABLE, 0); 
		if(hGlobal){ 
			HRESULT hr = CreateStreamOnHGlobal(hGlobal,TRUE,&stmTestLen); 
			if(SUCCEEDED(hr)){ 
				m_picHolder.m_pPict->SaveAsFile(stmTestLen,FALSE,&cbSize); 
			}else{ 
				cbSize = 0; 
			} 
			::GlobalFree(hGlobal); 
			stmTestLen->Release(); 
		} 
 
		m_pDoc->GetButton(Index)->Icon = m_picHolder.GetPictureDispatch(); 
		m_pDoc->GetButton(Index)->IconSize = cbSize; 
		//m_picHolder.m_pPict->get_Handle((OLE_HANDLE*)m_pDrawBtns[Index].Icon); 
	}else{ 
		m_pDoc->GetButton(Index)->Icon = NULL; 
		m_pDoc->GetButton(Index)->IconSize = 0; 
	} 
 
	if(Index == m_pDoc->GetBtnCnt()-1){ 
		FireViewChange(); 
	} 
	 
	return S_OK; 
} 
 
STDMETHODIMP CKToolBarCtrl::get_Value(short *pVal) 
{ 
	// TODO: Add your implementation code here 
	*pVal = m_Value; 
	return S_OK; 
} 
 
STDMETHODIMP CKToolBarCtrl::put_Value(short newVal) 
{ 
	// TODO: Add your implementation code here 
	m_Value = newVal; 
	return S_OK; 
} 
 
STDMETHODIMP CKToolBarCtrl::get_BtnCnt(short *pVal) 
{ 
	// TODO: Add your implementation code here 
 
	*pVal = m_pDoc->GetBtnCnt(); 
	return S_OK; 
} 
 
STDMETHODIMP CKToolBarCtrl::put_BtnCnt(short newVal) 
{ 
	// TODO: Add your implementation code here 
	 
	BOOL bUserMode; 
	//User mode: FALSE--Design moed, TRUE--Run Mode 
	this->GetAmbientUserMode(bUserMode); 
	if(bUserMode == TRUE){ 
		return CTL_E_SETNOTSUPPORTED; 
	}else{ 
		m_pDoc->SetBtnCnt(newVal); 
 
		if(newVal == 0){ 
			FireViewChange(); 
		} 
		return S_OK; 
	} 
} 
 
 
STDMETHODIMP CKToolBarCtrl::get_BtnToolTips(int Index, BSTR *pVal) 
{ 
	// TODO: Add your implementation code here 
	*pVal = ConvertLPSTRToBSTR(m_pDoc->GetButton(Index)->ToolTips); 
 
	return S_OK; 
} 
 
STDMETHODIMP CKToolBarCtrl::put_BtnToolTips(int Index, BSTR newVal) 
{ 
	// TODO: Add your implementation code here 
	if(m_pDoc->GetButton(Index)->ToolTips){ 
		delete[] m_pDoc->GetButton(Index)->ToolTips; 
	} 
	m_pDoc->GetButton(Index)->ToolTips = ConvertBSTRToLPSTR(newVal); 
	if(m_pDoc->GetButton(Index)->ToolTips){ 
		m_pDoc->GetButton(Index)->ToolTipsSize = strlen(m_pDoc->GetButton(Index)->ToolTips); 
	}else{ 
		m_pDoc->GetButton(Index)->ToolTipsSize = 0; 
	} 
	return S_OK; 
} 
 
STDMETHODIMP CKToolBarCtrl::get_BtnKey(int Index, BSTR *pVal) 
{ 
	// TODO: Add your implementation code here 
	*pVal = ConvertLPSTRToBSTR(m_pDoc->GetButton(Index)->Key); 
	return S_OK; 
} 
 
STDMETHODIMP CKToolBarCtrl::put_BtnKey(int Index, BSTR newVal) 
{ 
	// TODO: Add your implementation code here 
	if(m_pDoc->GetButton(Index)->Key){ 
		delete[] m_pDoc->GetButton(Index)->Key; 
	} 
	m_pDoc->GetButton(Index)->Key = ConvertBSTRToLPSTR(newVal); 
 
	if(m_pDoc->GetButton(Index)->Key){ 
		m_pDoc->GetButton(Index)->KeySize = strlen(m_pDoc->GetButton(Index)->Key); 
	}else{ 
		m_pDoc->GetButton(Index)->KeySize = 0; 
	} 
	return S_OK; 
}