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