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;
}