📄 atlcontrolwin.cpp
字号:
// 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 + -