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

📄 atlcontrolwin.cpp

📁 用VC开发activex 一书实例1 ATLControl
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	// 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_lAlignment));
			
		// lock the memory down
		LONG * lpTempBuffer = (LONG *) ::GlobalLock(hGlobal);

		// set our data buffer
		*lpTempBuffer = m_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)
			// release it
			::ReleaseStgMedium(&sCustomStgMedium);

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

void CATLControlWin::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);
}

void CATLControlWin::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 CATLControlWin::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_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->FireViewChange();
//		this->InvalidateControl(); <== MFC Version
}

STDMETHODIMP CATLControlWin::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 IDataObjectImpl<CATLControlWin>::GetData(lpFormatEtc, lpStgMedium);
}

STDMETHODIMP CATLControlWin::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 IDataObjectImpl<CATLControlWin>::EnumFormatEtc(dwDirection, ppenumFormatEtc);
}

STDMETHODIMP CATLControlWin::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 CATLControlWin::Skip(ULONG celt)
{
	// move the counter by the number of elements supplied
	ulFORMATETCElement += celt;
	
	// return success
	return S_OK;
}

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

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

LRESULT CATLControlWin::OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
{
//	Un-comment these parameters if you need them
//	UINT nFlags = wParam;
//	short sHor = (short) LOWORD(lParam);
//	short sVer = (short) HIWORD(lParam);
	
	// call the common data preparation function
	this->PrepareDataForTransfer();

	DWORD dwDropEffect = DROPEFFECT_NONE;
	
	// start the Drag and Drop operation
	::DoDragDrop(reinterpret_cast<IDataObject*>
			(static_cast<IDataObjectImpl<CATLControlWin>*>(this)),
			(IDropSource *) this, DROPEFFECT_COPY, &dwDropEffect);

	return TRUE;
}

STDMETHODIMP CATLControlWin::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 CATLControlWin::GiveFeedback(DWORD dwEffect)
{
	// use the default cursors
	return DRAGDROP_S_USEDEFAULTCURSORS;
}

LRESULT CATLControlWin::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
{
	// if we have a window handle
	if(m_hWnd)
		// register the control as a drag and drop target
		::RegisterDragDrop(m_hWnd, (IDropTarget *) this);

	return TRUE;
}

STDMETHODIMP CATLControlWin::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 CATLControlWin::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 CATLControlWin::DragLeave(void)
{
	return E_NOTIMPL;
}

STDMETHODIMP CATLControlWin::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 + -