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

📄 bcfcontrolctl.cpp

📁 htm网页格式的参考资料
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	// use the "CaptionMethod" implementation
	if(hResult == S_OK && lRetVal)
		// let the container know that the property has changed
		m_fDirty = TRUE;
		// this->SetModifiedFlag(); <== MFC version

	return hResult;
}

STDMETHODIMP CBCFControlControl::get_BackColor(OLE_COLOR * Value)
{
    // make sure that we have a good pointer
	CHECK_POINTER(Value);

    // set the return value
	*Value = m_state.ocBackColor;

	// return the result
    return S_OK;
}

STDMETHODIMP CBCFControlControl::put_BackColor(OLE_COLOR Value)
{
    // if the value is the same
	if (m_state.ocBackColor == Value)
		// exit 
        return S_OK;

	// save the value
    m_state.ocBackColor = Value;

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

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

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

	// exit
    return S_OK;
}

STDMETHODIMP CBCFControlControl::get_ReadyState(long * Value)
{
    // make sure that we have a good pointer
	CHECK_POINTER(Value);

    // set the return value
	*Value = m_state.lReadyState;

	// return the result
    return S_OK;
}

STDMETHODIMP CBCFControlControl::get_TextDataPath(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_lptstrTextDataPath));

	return S_OK;
}

STDMETHODIMP CBCFControlControl::put_TextDataPath(BSTR bstrNewValue)
{
	HRESULT hResult = S_OK;

	// get a ANSI string from the BSTR
	MAKE_ANSIPTR_FROMWIDE(lpctstrTextDataPath, bstrNewValue);

	// if we have a string
	if(lpctstrTextDataPath != NULL)
	{
		// if we have a string
		if(m_lptstrTextDataPath)
		{
			// delete the existing string
			delete [] m_lptstrTextDataPath;

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

		// allocate a new string
		m_lptstrTextDataPath = new TCHAR[lstrlen(lpctstrTextDataPath) + 1];

		// assign the string to our member variable
		lstrcpy(m_lptstrTextDataPath, lpctstrTextDataPath);
	}

	// start the asynchronous download of the data
	this->SetupDownload(OLESTRFROMANSI(m_lptstrTextDataPath), dispidTextDataPath);

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

	return hResult;
}

HRESULT CBCFControlControl::OnData(DISPID propId, DWORD bscfFlag, IStream * strm, DWORD dwSize)
{
	HRESULT	hr = NOERROR;

	// if this is the first notification
	if(bscfFlag & BSCF_FIRSTDATANOTIFICATION)
	{
		// if we have a reference
		if(m_lptstrCaption)
		{
			// delete the string buffer
			delete [] m_lptstrCaption;

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

	// alloc a temp buffer
	LPTSTR lptstrTempBuffer = new TCHAR[dwSize + 1];
																
	ULONG ulBytesRead;
	// read the data to a temp buffer
	hr = strm->Read(lptstrTempBuffer, dwSize, &ulBytesRead);

	// if we read in any data
	if(hr == S_OK && ulBytesRead)
	{
		// nul terminate the amount of data the was actually read in
		lptstrTempBuffer[ulBytesRead] = '\0';

		// get a new buffer with enough space to hold all of the data
		LPTSTR lptstrNewBuffer = new TCHAR[lstrlen(m_lptstrCaption) + ulBytesRead + 1];

		// copy the existing data to the new buffer
		lstrcpy(lptstrNewBuffer, m_lptstrCaption);

		// add the new data to the buffer
		lstrcat(lptstrNewBuffer, lptstrTempBuffer);

		// remove the existing string
		delete [] m_lptstrCaption;

		// copy the data to the buffer
		m_lptstrCaption = lptstrNewBuffer;

		// set the dirty flag
		m_fDirty = TRUE;

		// redraw the control
		this->InvalidateControl(NULL);
	}

	// if this is our last notification
	if(bscfFlag & BSCF_LASTDATANOTIFICATION)
	{
		// set the ready state of the control
		m_state.lReadyState = READYSTATE_COMPLETE;

		// set the dirty flag
		m_fDirty = TRUE;
	}

	// return the result
	return(hr);
}

STDMETHODIMP CBCFControlControl::MapPropertyToPage(DISPID, LPCLSID)
{
	return E_NOTIMPL;
}

STDMETHODIMP CBCFControlControl::GetPredefinedStrings(DISPID dispid, CALPOLESTR * lpcaStringsOut, CADWORD * lpcaCookiesOut)
{
	HRESULT hResult = S_FALSE;

	// we should have gotten two pointers if we didn't
	if((lpcaStringsOut == NULL) || (lpcaCookiesOut == NULL))
		// we are out of here
		return E_POINTER;

	// if this is the property that we are looking for
	if(dispid == dispidAlignment)
	{
		ULONG ulElems = 3;

		// allocate the memory for our string array
		lpcaStringsOut->pElems = (LPOLESTR *) ::CoTaskMemAlloc(sizeof(LPOLESTR) * ulElems);

		// if we couldn't allocate the memory
		if(lpcaStringsOut->pElems == NULL)
			// were out of here
			return E_OUTOFMEMORY;

		// allocate the memory for our cookie array
		lpcaCookiesOut->pElems = (DWORD*) ::CoTaskMemAlloc(sizeof(DWORD*) * ulElems);

		// if we couldn't allocate the memory
		if (lpcaCookiesOut->pElems == NULL)
		{
			// free the string array
			::CoTaskMemFree(lpcaStringsOut->pElems);

			// exit the function
			return E_OUTOFMEMORY;
		}

		// store the number of elements in each array
		lpcaStringsOut->cElems = ulElems;
		lpcaCookiesOut->cElems = ulElems;

		// allocate the strings
		lpcaStringsOut->pElems[0] = OLESTRFROMANSI(EALIGN_LEFT_TEXT);
		lpcaStringsOut->pElems[1] = OLESTRFROMANSI(EALIGN_CENTER_TEXT);
		lpcaStringsOut->pElems[2] = OLESTRFROMANSI(EALIGN_RIGHT_TEXT);

		// assign the cookie value
		lpcaCookiesOut->pElems[0] = EALIGN_LEFT;
		lpcaCookiesOut->pElems[1] = EALIGN_CENTER;
		lpcaCookiesOut->pElems[2] = EALIGN_RIGHT;

		hResult = S_OK;
	}

	return hResult;
}

STDMETHODIMP CBCFControlControl::GetPredefinedValue(DISPID dispid, DWORD dwCookie, VARIANT* lpvarOut)
{
	BOOL bResult = FALSE;

	// which property is it
	switch(dispid)
	{
	case dispidAlignment:
		// clear the variant
		::VariantInit(lpvarOut);
		// set the type to a long
		lpvarOut->vt = VT_I4;
		// set the value to the value that was stored with the string
		lpvarOut->lVal = dwCookie;
		// set the return value
		bResult = TRUE;
	break;
	}

	return bResult;
}

STDMETHODIMP CBCFControlControl::GetDisplayString(DISPID dispid, BSTR* lpbstr)
{
	HRESULT hResult = S_FALSE;

	// which property is it
	switch(dispid)
	{
	case dispidAlignment:
	{
		switch(m_state.lAlignment)
		{
		case EALIGN_LEFT:
			*lpbstr = BSTRFROMANSI(EALIGN_LEFT_TEXT);
		break;
		case EALIGN_CENTER:
			*lpbstr = BSTRFROMANSI(EALIGN_CENTER_TEXT);
		break;
		case EALIGN_RIGHT:
			*lpbstr = BSTRFROMANSI(EALIGN_RIGHT_TEXT);
		break;
		}

		// set the return value
		hResult = S_OK;
	}
	break;
	}

	return hResult;
}

void CBCFControlControl::FireChange(void)
{
	// get a BSTR that can be passed via the event
	BSTR bstrCaption = ::SysAllocString(OLESTRFROMANSI(m_lptstrCaption));

	// fire the change event
	this->FireEvent(&(m_rgBCFControlEvents[BCFControlEvent_Change]), &bstrCaption, &m_state.lAlignment);

	// create an ANSI string
	MAKE_ANSIPTR_FROMWIDE(lpctstrCaption, 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(lpctstrCaption) + 1];

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

static FONTDESC _fdDefault = 
{
    sizeof(FONTDESC),
    L"MS Sans Serif",
    FONTSIZE(8),
    FW_NORMAL,
    DEFAULT_CHARSET,
    FALSE,
    FALSE,
    FALSE
};

void CBCFControlControl::LoadFont(void)
{
    // if there isn't a font object
	if(!m_pFont)
        // get the font from the container
		this->GetAmbientFont(&m_pFont);

	// if there still isn't a font object
	if(!m_pFont)
		// create a default font object
		::OleCreateFontIndirect(&_fdDefault, IID_IFont, (void **) &m_pFont);
}

void CBCFControlControl::GetTextExtent(HDC hDC, LPCTSTR lpctstrString, int & cx, int & cy)
{
	// if we haven't gotten the dimensions yet
	if(!bRetrievedDimensions)
	{
		// get all of the widths for all of the chars
		::GetCharWidth(hDC, 0, 255, &iCharWidthArray[0]);

		// get the spacing between the chars
		iCharacterSpacing = ::GetTextCharacterExtra(hDC);

		// make sure that this only executes once
		bRetrievedDimensions = TRUE;

		// get the metrics of this DC
		TEXTMETRIC tmMetrics;
		::GetTextMetrics(hDC, &tmMetrics);

		// get the height
		iCharacterHeight = tmMetrics.tmHeight;
	}

	// return the height
	cy = iCharacterHeight;

	// set the initial value to 0
	int iTextWidth = 0;

	// get the number of characters in our string
	long lTextLength = lstrlen(lpctstrString);

	// if we have a character
	if(lTextLength)
	{
		long lEndCharPos = lTextLength - 1;

		// add up the widths of the characters and the spacing
		for(long lCount = 0; lCount <= lEndCharPos; lCount++)
			iTextWidth += (iCharWidthArray[(BYTE)(lpctstrString[lCount])] + iCharacterSpacing);
	}

	// return the width
	cx = iTextWidth;
}

void CBCFControlControl::CopyDataToClipboard(void)
{ 
	BOOL bHaveClipboard = TRUE;

	// if we don't have an IDataObject on the clipboard?
	if(::OleIsCurrentClipboard((IDataObject *) this) != S_OK)
		// set the flag
		bHaveClipboard = FALSE;

	// put data in the storage
	this->PrepareDataForTransfer();

	// if we don't have the clipboard
	if(!bHaveClipboard)
	{
		// clear the clipboard
		::OleFlushClipboard();

		// put the data on the clipboard
		::OleSetClipboard((IDataObject *) this);
	}
}

void CBCFControlControl::PrepareDataForTransfer(void)
{
	// get the length of the data to copy
	long lLength = lstrlen(m_lptstrCaption) + 1;

	// create a global memory object
	HGLOBAL hGlobal = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, sizeof(TCHAR) * lLength);
		
	// lock the memory down
	LPTSTR lpTempBuffer = (LPTSTR) ::GlobalLock(hGlobal);

	// copy the string
	for(long lCount = 0; lCount < lLength - 1; lCount++)
		lpTempBuffer[lCount] = m_lptstrCaption[lCount];

	// null terminate the string
	lpTempBuffer[lCount] = '\0';

	// unlock the memory
 	::GlobalUnlock(hGlobal);

	// copy all of the members
	sTextFormatEtc.cfFormat = CF_TEXT;
	sTextFormatEtc.ptd = NULL;
	sTextFormatEtc.dwAspect = 0; 
	sTextFormatEtc.lindex = -1; 
	sTextFormatEtc.tymed = TYMED_HGLOBAL; 

	// if we have already allocated the data
	if(sTextStgMedium.hGlobal)
		// release it
		::ReleaseStgMedium(&sTextStgMedium);

	sTextStgMedium.tymed = TYMED_HGLOBAL;
	sTextStgMedium.hGlobal = hGlobal;
	sTextStgMedium.pUnkForRelease = NULL;

	// if we have custom clipboard format support
	if(m_uiCustomFormat)
	{
		// create a global memory object
		HGLOBAL hGlobal = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, sizeof(m_state.lAlignment));
			
		// lock the memory down
		LONG * lpTempBuffer = (LONG *) ::GlobalLock(hGlobal);

		// set our data buffer
		*lpTempBuffer = m_state.lAlignment;

		// unlock the memory
 		::GlobalUnlock(hGlobal);

		// copy all of the members
		sCustomFormatEtc.cfFormat = m_uiCustomFormat;
		sCustomFormatEtc.ptd = NULL;
		sCustomFormatEtc.dwAspect = 0; 
		sCustomFormatEtc.lindex = -1; 
		sCustomFormatEtc.tymed = TYMED_HGLOBAL; 

		// if we have already allocated the data
		if(sCustomStgMedium.hGlobal)

⌨️ 快捷键说明

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