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

📄 bcfcontrolctl.cpp

📁 htm网页格式的参考资料
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
STDMETHODIMP CBCFControlControl::SaveTextState
(
    IPropertyBag *pPropertyBag,
    BOOL          fWriteDefaults
)
{
    HRESULT hr = S_OK;
    VARIANT v;

    if(lstrlen(m_lptstrCaption) || fWriteDefaults)
	{
		::VariantInit(&v);
		v.vt = VT_BSTR;
		v.bstrVal = ::SysAllocString(OLESTRFROMANSI(m_lptstrCaption));
		if (!v.bstrVal) return E_OUTOFMEMORY;
		hr = pPropertyBag->Write(OLESTRFROMANSI("Caption"), &v);
		::SysFreeString(v.bstrVal);
		RETURN_ON_FAILURE(hr); 
	}

    if(m_DefaultState.lAlignment != m_state.lAlignment || fWriteDefaults)
	{
		::VariantInit(&v);
		v.vt = VT_I4;
		v.lVal = m_state.lAlignment;
		hr = pPropertyBag->Write(OLESTRFROMANSI("Alignment"), &v);
		RETURN_ON_FAILURE(hr); 
	}

    if(m_DefaultState.ocBackColor != m_state.ocBackColor || fWriteDefaults)
	{
		::VariantInit(&v);
		v.vt = VT_I4;
		v.lVal = m_state.ocBackColor;
		hr = pPropertyBag->Write(OLESTRFROMANSI("BackColor"), &v);
		RETURN_ON_FAILURE(hr);
	}

    if(lstrlen(m_lptstrTextDataPath) || fWriteDefaults)
	{
		::VariantInit(&v);
		v.vt = VT_BSTR;
		v.bstrVal = ::SysAllocString(OLESTRFROMANSI(m_lptstrTextDataPath));
		if (!v.bstrVal) return E_OUTOFMEMORY;
		hr = pPropertyBag->Write(OLESTRFROMANSI("TextDataPath"), &v);
		::SysFreeString(v.bstrVal);
		RETURN_ON_FAILURE(hr); 
	}

    return hr;
}

//=--------------------------------------------------------------------------=
// CBCFControlControl::SaveBinaryState
//=--------------------------------------------------------------------------=
// save out the binary state for this control, using the given IStream object.
//
// Parameters:
//    IStream  *             - [in] save to which you should save.
//
// Output:
//    HRESULT
//
// Notes:
//    - it is important that you seek to the end of where you saved your
//      properties when you're done with the IStream.
//
STDMETHODIMP CBCFControlControl::SaveBinaryState
(
    IStream *pStream
)
{
	HRESULT hr = S_OK;

	// store the length of the string and the NULL
	m_state.lCaptionLength = lstrlen(m_lptstrCaption) + 1;

	// store the length of the string and the NULL
 	m_state.lTextDataPathLength = lstrlen(m_lptstrTextDataPath) + 1;

	// write the state of the data to the stream
	hr = pStream->Write(&m_state, sizeof(m_state), NULL);
	RETURN_ON_FAILURE(hr);

	// write the string and the NULL
	hr = pStream->Write(m_lptstrTextDataPath, m_state.lCaptionLength, NULL);
	RETURN_ON_FAILURE(hr);

	// write the string and the NULL
	hr = pStream->Write(m_lptstrCaption, m_state.lTextDataPathLength, NULL);
	RETURN_ON_FAILURE(hr);

    return S_OK;
}


//=--------------------------------------------------------------------------=
// CBCFControlControl::OnDraw
//=--------------------------------------------------------------------------=
// "I don't very much enjoy looking at paintings in general.  i know too
//  much about them.  i take them apart."
//    - georgia o'keeffe (1887-1986)
//
// Parameters:
//    DWORD              - [in]  drawing aspect
//    HDC                - [in]  HDC to draw to
//    LPCRECTL           - [in]  rect we're drawing to
//    LPCRECTL           - [in]  window extent and origin for meta-files
//    HDC                - [in]  HIC for target device
//    BOOL               - [in]  can we optimize dc handling?
//
// Output:
//    HRESULT
//
// Notes:
//
HRESULT CBCFControlControl::OnDraw
(
    DWORD    dvAspect,
    HDC      hdcDraw,
    LPCRECTL prcBounds,
    LPCRECTL prcWBounds,
    HDC      hicTargetDevice,
    BOOL     fOptimize
)
{
// ****** 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(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(hdcDraw, clrTextBackgroundColor);
	COLORREF clrOldForegroundColor = ::SetTextColor(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 = ::SelectObject(hdcDraw, hBrush);

	// draw the background
	::Rectangle(hdcDraw, prcBounds->left, prcBounds->top, prcBounds->right, 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(hdcDraw, m_lptstrCaption, cx, cy);

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

	// output our text
	::ExtTextOut(hdcDraw, iHor, iVer, ETO_CLIPPED | ETO_OPAQUE, (LPCRECT) 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(hdcDraw, clrEdgeBackgroundColor);
	::SetTextColor(hdcDraw, clrEdgeForegroundColor);

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

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

// ****** release the text font ******
// **
	if(hOldFont)
		// select the old object
		::SelectObject(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(!fOptimize)
	{
		// select the old brush back
		::SelectObject(hdcDraw, hOldBrush);

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

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

    return S_OK;
}

//=--------------------------------------------------------------------------=
// CBCFControlControl::WindowProc
//=--------------------------------------------------------------------------=
// window procedure for this control.  nothing terribly exciting.
//
// Parameters:
//     see win32sdk on window procs [sans HWND -- it's in m_hwnd if you have one]
//
// Notes:
//
LRESULT CBCFControlControl::WindowProc(UINT msg, WPARAM wParam, LPARAM lParam)
{
    LRESULT lRetVal = FALSE;

	switch(msg)
	{
	case WM_KEYDOWN:
		this->OnKeyDown(wParam, LOWORD(lParam), HIWORD(lParam));
	break;
	case WM_LBUTTONDOWN:
		this->OnLButtonDown(wParam, (short) LOWORD(lParam), (short) HIWORD(lParam));
		this->OcxDefWindowProc(msg, wParam, lParam);
	break;
	default:
		lRetVal = this->OcxDefWindowProc(msg, wParam, lParam);
	break;
	}

	return lRetVal;
}

//=--------------------------------------------------------------------------=
// CBCFControlControl::AboutBox
//=--------------------------------------------------------------------------=
// prints up an about box.  fweeeee.
//
// Notes:
//
void CBCFControlControl::AboutBox
(
    void
)
{
    // TODO: Ideally, one would use DialogBox, and some sort of Dialog Box here if
    // they wanted a slightly more interesting About Box ...  you should
    // still call ModalDialog first, however.
    //
    ModalDialog(TRUE);
    MessageBox(NULL, "This is My Control", "About BCFControl", MB_OK | MB_TASKMODAL);
    ModalDialog(FALSE);
}

STDMETHODIMP CBCFControlControl::CaptionMethod(BSTR bstrCaption, VARIANT varAlignment, long FAR * lRetVal)
{
	HRESULT hResult = S_OK;

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

	MAKE_ANSIPTR_FROMWIDE(lpctstrCaption, bstrCaption);

	// if the variant is a long just use the value
	if(VT_I4 == varAlignment.vt)
	{
		// assign the value to our member variable
		m_state.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_state.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_state.lAlignment = EALIGN_CENTER;
			break;
			case EALIGN_RIGHT:
				m_state.lAlignment = EALIGN_RIGHT;
			break;
			default:
				m_state.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(lpctstrCaption != 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(lpctstrCaption) + 1];

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

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

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

		// force the control to repaint itself
		this->InvalidateControl(NULL);
	}

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

STDMETHODIMP CBCFControlControl::get_Alignment(long FAR* Value)
{
	HRESULT hResult = S_OK;

	// return our current setting
	*Value = m_state.lAlignment;

	return hResult;
}

STDMETHODIMP CBCFControlControl::put_Alignment(long Value)
{
	HRESULT hResult = S_OK;

	// if we are in the valid range for the property
	if(Value >= EALIGN_LEFT && Value <= EALIGN_RIGHT)
	{
		// set the new property value
		m_state.lAlignment = Value;

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

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

		// refresh the property browser
		this->PropertyChanged(dispidAlignment);
		// this->BoundPropertyChanged(dispidAlignment); <== MFC Version
	}

	return hResult;
}

STDMETHODIMP CBCFControlControl::get_CaptionProp(VARIANT varAlignment, BSTR FAR* bstrRetVal)
{
	// if there is a string
	if(*bstrRetVal);
	{
		// free the string because we are going to replace it
		::SysFreeString(*bstrRetVal);

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

	// return the caption as a BSTR
	*bstrRetVal = ::SysAllocString(OLESTRFROMANSI(m_lptstrCaption));

	return S_OK;
}

STDMETHODIMP CBCFControlControl::put_CaptionProp(VARIANT varAlignment, BSTR lpszNewValue)
{
	long lRetVal;
	HRESULT hResult = this->CaptionMethod(lpszNewValue, varAlignment, &lRetVal);

⌨️ 快捷键说明

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