⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atlcontrolwin.cpp

📁 用VC开发activex 一书实例1 ATLControl
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// ATLControlWin.cpp : Implementation of CATLControlWin
#include "stdafx.h"
#include "ATLControl.h"
#include "ATLControlWin.h"

/////////////////////////////////////////////////////////////////////////////
// CATLControlWin

STDMETHODIMP CATLControlWin::InterfaceSupportsErrorInfo(REFIID riid)
{
	static const IID* arr[] = 
	{
		&IID_IATLControlWin,
	};
	for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
	{
		if (InlineIsEqualGUID(*arr[i],riid))
			return S_OK;
	}
	return S_FALSE;
}

HRESULT CATLControlWin::OnDraw(ATL_DRAWINFO & di)
{
// ****** Get the text font ******
// **
	HFONT hFont = NULL, hOldFont = NULL;

	// if there isn't a font object
	if(!m_pFont)
		// try to load one
		this->LoadFont();

	if(m_pFont)
	{
		// get a font handle
		m_pFont->get_hFont(&hFont);

		// increment the ref count so the font doesn't drop
		// out from under us
		m_pFont->AddRefHfont(hFont);

		::SelectObject(di.hdcDraw, hFont);
	}
// **
// ****** Get the text font ******

// ****** Get the colors ******
// **
	// use the window color as the background color
	OLE_COLOR tColor;
	this->get_BackColor(&tColor);
	COLORREF clrTextBackgroundColor = this->TranslateColor(tColor);

	//  then use the normal windows color for the text
	COLORREF clrTextForegroundColor = this->TranslateColor(::GetSysColor(COLOR_WINDOWTEXT));

	// set to the system color
	COLORREF clrEdgeBackgroundColor = ::GetSysColor(COLOR_3DFACE);
	COLORREF clrEdgeForegroundColor = ::GetSysColor(COLOR_3DFACE);
// **
// ****** Get the colors ******

// ****** Draw the background ******
// **
	// set the text color
	COLORREF clrOldBackgroundColor = ::SetBkColor(di.hdcDraw, clrTextBackgroundColor);
	COLORREF clrOldForegroundColor = ::SetTextColor(di.hdcDraw, clrTextForegroundColor);

	// if we don't have a brush
	if(hBrush == NULL)
		// create a solid brush
		hBrush = ::CreateSolidBrush(clrTextBackgroundColor);

	// select the brush and save the old one
	hOldBrush = (HBRUSH)::SelectObject(di.hdcDraw, hBrush);

	// draw the background
	::Rectangle(di.hdcDraw, di.prcBounds->left, di.prcBounds->top, di.prcBounds->right, di.prcBounds->bottom);
// **
// ****** Draw the background ******

// ****** Draw the text ******
// **
	int iHor, iVer;

	// get the size of the text for this DC
	int cx = 0, cy = 0;
	this->GetTextExtent(di.hdcDraw, m_lptstrCaption, cx, cy);

	switch(m_lAlignment)
	{
	case EALIGN_CENTER:
		iHor = (di.prcBounds->right - cx) / 2;
		iVer = di.prcBounds->top + 3;
	break;
	case EALIGN_RIGHT:
		iHor = di.prcBounds->right - cx - 3;
		iVer = di.prcBounds->top + 3;
	break;
//	case EALIGN_LEFT:
	default:
		iHor = di.prcBounds->left + 3;
		iVer = di.prcBounds->top + 3;
	break;
	}

	// output our text
	::ExtTextOut(di.hdcDraw, iHor, iVer, ETO_CLIPPED | ETO_OPAQUE, (LPCRECT) di.prcBounds, m_lptstrCaption, lstrlen(m_lptstrCaption), NULL);
// **
// ****** Draw the text ******

// ****** Draw the border ******
// **
	// set the edge style and flags
	UINT uiBorderStyle = EDGE_SUNKEN;
	UINT uiBorderFlags = BF_RECT;

	// set the edge color
	::SetBkColor(di.hdcDraw, clrEdgeBackgroundColor);
	::SetTextColor(di.hdcDraw, clrEdgeForegroundColor);

	// draw the 3D edge
	::DrawEdge(di.hdcDraw, (LPRECT)(LPCRECT) di.prcBounds, uiBorderStyle, uiBorderFlags);
// **
// ****** Draw the border ******

// ****** Reset the colors ******
// **
	// restore the original colors
	::SetBkColor(di.hdcDraw, clrOldBackgroundColor);
	::SetTextColor(di.hdcDraw, clrOldForegroundColor);
// **
// ****** Reset the colors ******

// ****** release the text font ******
// **
	if(hOldFont)
		// select the old object
		::SelectObject(di.hdcDraw, hOldFont);

	// increment the ref count so the font doesn't drop
	// out from under us
	if(m_pFont && hFont)
		m_pFont->ReleaseHfont(hFont);
// **
// ****** Get the text font ******

	// The container does not support optimized drawing.
	if(!di.bOptimize)
	{
		// select the old brush back
		::SelectObject(di.hdcDraw, hOldBrush);

		// destroy the brush we created
		::DeleteObject(hBrush);

		// clear the brush handles
		hBrush = hOldBrush = NULL;
	}

    return S_OK;
}

STDMETHODIMP CATLControlWin::CaptionMethod(BSTR bstrCaption, VARIANT varAlignment, long * lRetVal)
{
	// needed for the W2A macro
	USES_CONVERSION;

	HRESULT hResult = S_OK;

	// return value initialized to failure result
	*lRetVal = FALSE;

	// convert the string to ANSI
	LPTSTR lptstrTempCaption = W2A(bstrCaption);

	// if the variant is a long just use the value
	if(VT_I4 == varAlignment.vt)
	{
		// assign the value to our member variable
		m_lAlignment = varAlignment.lVal;

		// set the return value
		*lRetVal = TRUE;
	}
	// if the user didn't supply an alignment parameter we will assign the default
	else if(VT_ERROR == varAlignment.vt || VT_EMPTY == varAlignment.vt)
	{
		// assign the value to our member variable
		m_lAlignment = EALIGN_LEFT;

		// set the return value
		*lRetVal = TRUE;
	}
	else
	{
		// get a variant that we can use for conversion purposes
		VARIANT varConvertedValue;

		// initialize the variant
		::VariantInit(&varConvertedValue);

		// see if we can convert the data type to something useful - VariantChangeTypeEx() could also be used
		if(S_OK == ::VariantChangeType(&varConvertedValue, (VARIANT *) &varAlignment, 0, VT_I4))
		{
			// assign the value to our member variable	
			switch(varConvertedValue.lVal)
			{
			case EALIGN_CENTER:			
				m_lAlignment = EALIGN_CENTER;
			break;
			case EALIGN_RIGHT:
				m_lAlignment = EALIGN_RIGHT;
			break;
			default:
				m_lAlignment = EALIGN_LEFT;
			break;
			}

			// set the return value
			*lRetVal = TRUE;
		}
		else
		{
			// at this point we could either throw an error indicating there was a problem converting 
			// the data or change the return type of the method and return the HRESULT value from the 
			// the "VariantChangeType" call.
		}
	}

	// if everything was OK
	if(TRUE == *lRetVal)
	{
		// if we have a string
		if(lptstrTempCaption != NULL)
		{
			// if we have a string
			if(m_lptstrCaption)
			{
				// delete the existing string
				delete [] m_lptstrCaption;

				// clear the reference just to be safe
				m_lptstrCaption = NULL;
			}

			// allocate a new string
			m_lptstrCaption = new TCHAR[lstrlen(lptstrTempCaption) + 1];

			// assign the string to our member variable
			lstrcpy(m_lptstrCaption, lptstrTempCaption);
		}

		// did they pass us bad data?
		if(m_lAlignment < EALIGN_LEFT || m_lAlignment > EALIGN_RIGHT)
			// sure did, lets fix their little red wagon
			m_lAlignment = EALIGN_LEFT;

		// fire the global change event
		this->FireChange();

		// force the control to repaint itself
		this->FireViewChange();
//		this->InvalidateControl(); <== MFC Version
	}

	// return the result of the function call
	return hResult;
}

STDMETHODIMP CATLControlWin::get_Alignment(long * pVal)
{
	HRESULT hResult = S_OK;

	// return our current setting
	*pVal = m_lAlignment;

	return hResult;
}

STDMETHODIMP CATLControlWin::put_Alignment(long newVal)
{
	HRESULT hResult = S_OK;

	// if we are in the valid range for the property
	if(newVal >= EALIGN_LEFT && newVal <= EALIGN_RIGHT)
	{
		// set the new property value
		m_lAlignment = newVal;

		// let the control know that the property has changed
		this->SetDirty(TRUE);
		// this->SetModifiedFlag(); <== MFC version

		// fire the global change event
		this->FireChange();

		// refresh the property browser
		this->FireOnChanged(dispidAlignment);
		// this->BoundPropertyChanged(dispidAlignment); <== MFC Version
		// force the control to repaint itself

		this->FireViewChange();
//		this->InvalidateControl(); <== MFC Version
	}

	return hResult;
}


STDMETHODIMP CATLControlWin::get_CaptionProp(VARIANT varAlignment, BSTR * pVal)
{
	// needed for the T2OLE macro
	USES_CONVERSION;

	// if there is a string
	if(*pVal)
	{
		// free the string because we are going to replace it
		::SysFreeString(*pVal);

		// clear the reference just to be safe
		*pVal = NULL;
	}

	// convert the ANSI string to an OLECHAR and then allocate a BSTR
	*pVal = ::SysAllocString(T2OLE(m_lptstrCaption));

	return S_OK;
}

STDMETHODIMP CATLControlWin::put_CaptionProp(VARIANT varAlignment, BSTR newVal)
{
	long lRetVal;

	// defer to the CaptionMethod implementation
	HRESULT hResult = this->CaptionMethod(newVal, varAlignment, &lRetVal);

	// if the function returned success
	if(TRUE == lRetVal)
		// let the control know that the property has changed
		this->SetDirty(TRUE);
		// this->SetModifiedFlag(); <== MFC version

	// return the result
	return hResult;
}

STDMETHODIMP CATLControlWin::get_BackColor(OLE_COLOR * pVal)
{
	// return the color
	*pVal = m_BackColor;

	return S_OK;
}

STDMETHODIMP CATLControlWin::put_BackColor(OLE_COLOR newVal)
{
	// if the value is the same
	if(newVal == m_BackColor)
		return S_OK;

	// store the value
	m_BackColor = newVal;

	// let the container know that the value has changed
	this->FireOnChanged(DISPID_BACKCOLOR);
    // this->AmbientPropertyChanged(DISPID_BACKCOLOR); <== MFC Version

	// redraw the control
	this->FireViewChange();
    // this->InvalidateControl(); <== MFC Version

	// set the dirty flag
	this->SetDirty(TRUE);
	// this->SetModifiedFlag(); <== MFC Version

	// exit
    return S_OK;
}

void CATLControlWin::FireChange(void)
{
	// needed for the W2A macro
	USES_CONVERSION;

	// get a BSTR that can be passed via the event
	BSTR bstrCaption = ::SysAllocString(T2OLE(m_lptstrCaption));

	// fire the change event
	this->Fire_Change(&bstrCaption, &m_lAlignment);

	// convert the string to ANSI
	LPTSTR lptstrTempCaption = W2A(bstrCaption);

	// free the data that was passed back
	::SysFreeString(bstrCaption);

	// if we have a string
	if(m_lptstrCaption)
	{
		// delete the existing string
		delete [] m_lptstrCaption;

		// clear the reference just to be safe
		m_lptstrCaption = NULL;
	}

	// allocate a new string
	m_lptstrCaption = new TCHAR[lstrlen(lptstrTempCaption) + 1];

	// assign the string to our member variable
	lstrcpy(m_lptstrCaption, lptstrTempCaption);
}

LRESULT CATLControlWin::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
{
	// if we have a window handle
	if(m_hWnd)
		// revoke the control as a drag and drop target
		::RevokeDragDrop(m_hWnd);

⌨️ 快捷键说明

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