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

📄 bcfcontrolctl.cpp

📁 htm网页格式的参考资料
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			// release it
			::ReleaseStgMedium(&sCustomStgMedium);

		sCustomStgMedium.tymed = TYMED_HGLOBAL;
		sCustomStgMedium.hGlobal = hGlobal;
		sCustomStgMedium.pUnkForRelease = NULL;
	}
}

void CBCFControlControl::GetDataFromClipboard(void)
{
	// get an IDataObject pointer
	IDataObject * ipClipboardDataObj = NULL;

	// do we have an IDataObject on the clipboard?
	if(::OleIsCurrentClipboard((IDataObject *) this) == S_OK)
	{
		// get the global data for this format and lock down the memory
		LPTSTR lpTempBuffer = (LPTSTR) ::GlobalLock(sTextStgMedium.hGlobal);

		// 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(lpTempBuffer) + 1];

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

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

		return;
	}
	else if(::OleGetClipboard(&ipClipboardDataObj) == S_OK)
	{
		// transfer the data to the control
		this->GetDataFromTransfer(ipClipboardDataObj);

		// release the IDataObject
		ipClipboardDataObj->Release();
	}
}

void CBCFControlControl::GetDataFromTransfer(IDataObject * ipDataObj)
{	
	IEnumFORMATETC * ipenumFormatetc;
	BOOL bFound = FALSE;

	// get a FORMATETC enumerator
	if(ipDataObj->EnumFormatEtc(DATADIR_GET, &ipenumFormatetc) == S_OK)
	{
		// reset the enumerator just to be safe
		ipenumFormatetc->Reset();

		FORMATETC etc;

		// while there are formats to enumerate
		while(ipenumFormatetc->Next(1, &etc, NULL) == S_OK)
		{
			// is this a format that we are looking for?
			if(etc.cfFormat == CF_TEXT && etc.tymed & TYMED_HGLOBAL)
			{
				STGMEDIUM sStgMediumData;

				// get the data from the stgmedium
				if(ipDataObj->GetData(&etc, &sStgMediumData) == S_OK)
				{
					// get the global data for this format and lock down the memory
					LPTSTR lpTempBuffer = (LPTSTR) ::GlobalLock(sStgMediumData.hGlobal);

					// 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(lpTempBuffer) + 1];

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

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

					// release the storage medium
					::ReleaseStgMedium(&sStgMediumData);

					// indicate success
					bFound = TRUE;
				}
			}
			// is this a format that we are looking for?
			else if(m_uiCustomFormat && etc.cfFormat == m_uiCustomFormat && etc.tymed & TYMED_HGLOBAL)
			{
				STGMEDIUM sStgMediumData;

				// get the data from the stgmedium
				if(ipDataObj->GetData(&etc, &sStgMediumData) == S_OK)
				{
					// get the global data for this format and lock down the memory
					LONG * lpTempBuffer = (LONG *) ::GlobalLock(sStgMediumData.hGlobal);

					// get the data 
					m_state.lAlignment = *lpTempBuffer;

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

					// release the storage medium
					::ReleaseStgMedium(&sStgMediumData);

					// indicate success
					bFound = TRUE;
				}
			}
		}
			   
		// release the enumerator
		ipenumFormatetc->Release();
	}

	// if we found a format
	if(bFound == TRUE)
		// force the control to repaint itself
		this->InvalidateControl(NULL);
}

void CBCFControlControl::CopyStgMedium(LPSTGMEDIUM lpTargetStgMedium, LPSTGMEDIUM lpSourceStgMedium, CLIPFORMAT cfSourceFormat)
{
	// copy the stgmedium members
	lpTargetStgMedium->tymed = lpSourceStgMedium->tymed;
	lpTargetStgMedium->pUnkForRelease = lpSourceStgMedium->pUnkForRelease;
	lpTargetStgMedium->hGlobal = ::OleDuplicateData(lpSourceStgMedium->hGlobal, cfSourceFormat, GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT);
}

STDMETHODIMP CBCFControlControl::GetData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)
{
	// if this is a format that we can deal with
	if(lpFormatEtc->cfFormat == CF_TEXT && lpFormatEtc->tymed & TYMED_HGLOBAL)
	{
		// get a copy of the current stgmedium
		this->CopyStgMedium(lpStgMedium, &sTextStgMedium, CF_TEXT);

		return S_OK;
	}
	else if(m_uiCustomFormat && lpFormatEtc->cfFormat == m_uiCustomFormat && lpFormatEtc->tymed & TYMED_HGLOBAL)
	{
		// get a copy of the current stgmedium
		this->CopyStgMedium(lpStgMedium, &sCustomStgMedium, m_uiCustomFormat);

		return S_OK;
	}
	else
		return DATA_E_FORMATETC;
}

STDMETHODIMP CBCFControlControl::GetDataHere(LPFORMATETC /*lpFormatEtc*/, LPSTGMEDIUM /*lpStgMedium*/)
{
	return E_NOTIMPL;
}

STDMETHODIMP CBCFControlControl::QueryGetData(LPFORMATETC /*lpFormatEtc*/)
{
	return E_NOTIMPL;
}

STDMETHODIMP CBCFControlControl::GetCanonicalFormatEtc(LPFORMATETC /*lpFormatEtcIn*/, LPFORMATETC /*lpFormatEtcOut*/)
{
	return E_NOTIMPL;
}

STDMETHODIMP CBCFControlControl::SetData(LPFORMATETC /*lpFormatEtc*/, LPSTGMEDIUM /*lpStgMedium*/, BOOL /*bRelease*/)
{
	return E_NOTIMPL;
}

STDMETHODIMP CBCFControlControl::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC* ppenumFormatEtc)
{
	// we support "get" operations
	if(dwDirection == DATADIR_GET)
	{
		// make the assignment
		*ppenumFormatEtc = (IEnumFORMATETC *) this;
		
		// increment the reference count
		(*ppenumFormatEtc)->AddRef();

		// return success
		return S_OK;
	}

	return E_NOTIMPL;
}

STDMETHODIMP CBCFControlControl::DAdvise(FORMATETC * /*pFormatEtc*/, DWORD /*advf*/, LPADVISESINK /*pAdvSink*/, DWORD * /*pdwConnection*/)
{
	return E_NOTIMPL;
}

STDMETHODIMP CBCFControlControl::DUnadvise(DWORD /*dwConnection*/)
{
	return E_NOTIMPL;
}

STDMETHODIMP CBCFControlControl::EnumDAdvise(LPENUMSTATDATA * /*ppenumAdvise*/)
{
	return E_NOTIMPL;
}

STDMETHODIMP CBCFControlControl::Next(ULONG celt, FORMATETC __RPC_FAR * rgelt, ULONG __RPC_FAR * pceltFetched) 
{
	// if we are at the beginning of the enumeration
	if(ulFORMATETCElement == 0 && celt > 0)
	{
		// copy all of the members
		rgelt->cfFormat = CF_TEXT;
		rgelt->ptd = NULL;
		rgelt->dwAspect = 0; 
		rgelt->lindex = -1; 
		rgelt->tymed = TYMED_HGLOBAL; 
		
		// if the caller wants to know how many we copied
		if(pceltFetched)
			*pceltFetched = 1;

		// increment the counter
		ulFORMATETCElement++;

		// return success
		return S_OK;
	}
	else if(m_uiCustomFormat && ulFORMATETCElement == 1 && celt > 0)
	{
		// copy all of the members
		rgelt->cfFormat = m_uiCustomFormat;
		rgelt->ptd = NULL;
		rgelt->dwAspect = 0; 
		rgelt->lindex = -1; 
		rgelt->tymed = TYMED_HGLOBAL; 
		
		// if the caller wants to know how many we copied
		if(pceltFetched)
			*pceltFetched = 1;

		// increment the counter
		ulFORMATETCElement++;

		// return success
		return S_OK;
	}
	else
		// return failure
		return S_FALSE;
}

STDMETHODIMP CBCFControlControl::Skip(ULONG celt)
{
	// move the counter by the number of elements supplied
	ulFORMATETCElement += celt;
	
	// return success
	return S_OK;
}

STDMETHODIMP CBCFControlControl::Reset(void)
{
	// reset to the beginning of the enumerator
	ulFORMATETCElement = 0;
	
	// return success
	return S_OK;
}

STDMETHODIMP CBCFControlControl::Clone(IEnumFORMATETC __RPC_FAR *__RPC_FAR * /*ppenum*/)
{
	return E_NOTIMPL;
}

void CBCFControlControl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	BOOL bHandled = FALSE;

  	// find out if the shift key is being held down
	short sShift = ::GetKeyState(VK_SHIFT);
  	// find out if the control key is being held down
	short sControl = ::GetKeyState(VK_CONTROL);

	switch(nChar)
	{
	// PASTE
	case 0x56: // 'V'
	case 0x76: // 'v'					 
		// if the control key is being held down
		if(sControl & 0x8000)
		{
			// get any text from the clipboard
			this->GetDataFromClipboard();

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

			// we don't need to pass this key to the base implementation
			bHandled = TRUE;
		}
	// COPY or PASTE
	case 0x43: // 'C'
	case 0x63: // 'c'					 
	case VK_INSERT:
		// if the control key is being held down
		if(sControl & 0x8000)
		{
			// copy the data to the clipboard
			this->CopyDataToClipboard();

			// we don't need to pass this key to the base implementation
			bHandled = TRUE;
		}
		// if the shift key is being held down it is a PASTE
		else if(sShift & 0x8000 && nChar == VK_INSERT)
		{
			// get any text from the clipboard
			this->GetDataFromClipboard();

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

			// we don't need to pass this key to the base implementation
			bHandled = TRUE;
		}
	break;
	case 0x58: // 'X'
	case 0x78: // 'x'
	case VK_DELETE:
		// if this is a shift delete OR CTRL-X/x
		if((nChar == VK_DELETE && (sShift & 0x8000)) || ((nChar == 0x58 || nChar == 0x78) && (sControl & 0x8000)))
		{
			this->CopyDataToClipboard();

			// clear the string since this is a CUT operation
			delete [] m_lptstrCaption;

			// NULL terminate the string reference
			m_lptstrCaption = new TCHAR[1];
			m_lptstrCaption[0] = '\0';

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

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

			// we don't need to pass this key to the base implementation
			bHandled = TRUE;
		}
	break;
	}

	// if we didn't handle the character
	if(!bHandled)
	{
		// and the control key is not being held down
		if(!(sControl & 0x8000))
			// send to the default handler
			this->OcxDefWindowProc(WM_KEYDOWN, (WPARAM) nFlags, MAKELPARAM(nRepCnt, nFlags));
	}
}

void CBCFControlControl::OnLButtonDown(UINT nFlags, short sHor, short sVer) 
{
	// call the common data preparation function
	this->PrepareDataForTransfer();

	DWORD dwDropEffect = DROPEFFECT_NONE;
	
	// start the Drag and Drop operation
	::DoDragDrop((IDataObject *) this, (IDropSource *) this, DROPEFFECT_COPY, &dwDropEffect);
}

STDMETHODIMP CBCFControlControl::QueryContinueDrag(BOOL fEscapePressed, DWORD dwKeyState)
{
	// if the left button has been released
	if(!(dwKeyState & MK_LBUTTON))
		// it is OK to drop
		return DRAGDROP_S_DROP;
	else
		// return success
		return S_OK;
}

STDMETHODIMP CBCFControlControl::GiveFeedback(DWORD dwEffect)
{
	// use the default cursors
	return DRAGDROP_S_USEDEFAULTCURSORS;
}

STDMETHODIMP CBCFControlControl::DragEnter(LPDATAOBJECT pDataObject, DWORD dwKeyState, POINTL pt, LPDWORD pdwEffect)
{
	// if the left mouse button is being held down
	if(dwKeyState & MK_LBUTTON)
	{
		IEnumFORMATETC * ipenumFormatetc;
		BOOL bFound = FALSE;

		// get a FORMATETC enumerator
		if(pDataObject->EnumFormatEtc(DATADIR_GET, &ipenumFormatetc) == S_OK)
		{
			// reset the enumerator just to be safe
			ipenumFormatetc->Reset();

			FORMATETC etc;

			// while there are formats to enumerate
			while(ipenumFormatetc->Next(1, &etc, NULL) == S_OK && !bFound)
			{
				// is this a format that we are looking for?
				if(etc.cfFormat == CF_TEXT && etc.tymed & TYMED_HGLOBAL)
					bFound = TRUE;
			}

			// release the enumerator
			ipenumFormatetc->Release();
		}

		// is there a text format available
		if(bFound)
			*pdwEffect =  DROPEFFECT_COPY;
		// everything else we can't deal with
		else
			*pdwEffect = DROPEFFECT_NONE;
	}
	else
		// not the left mouse
		*pdwEffect = DROPEFFECT_NONE;

	// return success
	return S_OK;
}

STDMETHODIMP CBCFControlControl::DragOver(DWORD dwKeyState, POINTL pt, LPDWORD pdwEffect)
{
	// if the left mouse button is being held down
	if(dwKeyState & MK_LBUTTON)
		// copy
		*pdwEffect = DROPEFFECT_COPY;
	else
		// not the left mouse
		*pdwEffect = DROPEFFECT_NONE;

	// return success
	return S_OK;
}

STDMETHODIMP CBCFControlControl::DragLeave(void)
{
	return E_NOTIMPL;
}

STDMETHODIMP CBCFControlControl::Drop(LPDATAOBJECT pDataObject, DWORD dwKeyState, POINTL pt, LPDWORD pdwEffect)
{
	// transfer the data to the control
	this->GetDataFromTransfer(pDataObject);

	// return success
	return S_OK;
}

⌨️ 快捷键说明

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