注:这是老版本 (BCB6 及之前版本) 的程序,
2009 之后的新版本 (解决字符编码问题) 请点击:新版文字拖放到 Memo 里
需要用 COM 接口的 OLE 拖放目标, 程序新建一个支持拖放目标的 UnitTMyDropTarget
单元, 在这个单元里创建一个 TMyDropTarget 类。
这个程序可以使从写字板或者网页等定义的文本块用鼠标拖动, 放到程序的 Memo 里, 插入到 Memo 的拖放的位置。
首先看看如何使用这个 TMyDropTarget 类:
在 Form 的头文件里 (例如 Unit1.h) 需要增加的内容(蓝色部分是新增内容):
#include
"UnitTMyDropTarget.h" class
TForm1 : public TForm
{ private: //
User declarations TMyDropTarget
*DropMemo1; //自定义的拖放目标类
void
__fastcall DropMemo1Text(IDropTarget
*Sender, AnsiString AText, DWORD KeyState, TPoint pt);
//拖放事件 public: //
User declarations __fastcall
TForm1(TComponent* Owner); __fastcall
~TForm1(); }; |
在 From 的 .cpp 文件里 (例如 Unit1.cpp), 需要增加的内容(蓝色部分是新增内容):
__fastcall
TForm1::TForm1(TComponent*
Owner) : TForm(Owner)
{ OleInitialize(NULL);
DropMemo1 = new TMyDropTarget(Memo1);
DropMemo1->OnProcessText = DropMemo1Text;
} //---------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
DropMemo1->Release();//delete
DropMemo1;
OleUninitialize();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DropMemo1Text(IDropTarget
*Sender, AnsiString AText, DWORD KeyState, TPoint pt)
{
POINTS p={pt.x,pt.y};
*(long*)&p=SendMessage(Memo1->Handle,EM_CHARFROMPOS,0,*(long*)&p);
Memo1->SelStart = p.x;
Memo1->SelLength = 0;
Memo1->SelText = AText;
} //--------------------------------------------------------------------------- |
TMyDropTarget 类的实现:
头文件 UnitTMyDropTarget.h 的内容:
//---------------------------------------------------------------------------
#ifndef UnitTMyDropTargetH
#define UnitTMyDropTargetH //---------------------------------------------------------------------------
#include "oleidl.h"
#include "controls.hpp" //---------------------------------------------------------------------------
class TMyDropTarget: public
IDropTarget { public:
__property void __fastcall
(__closure *OnGetFormat)(IDropTarget *Sender,
IDataObject *DataObject, DWORD KeyState, TPoint pt, DWORD &dpe,
bool &bDataOK) = { read=_FGetFormat, write=_FGetFormat
}; __property void __fastcall
(__closure *OnProcessData)(IDropTarget *Sender,
IDataObject *DataObject, DWORD KeyState, TPoint pt) = { read=_FProcessData,
write=_FProcessData }; __property
void __fastcall (__closure *OnProcessText)(IDropTarget
*Sender, AnsiString AText, DWORD KeyState, TPoint pt) = { read=_FProcessText,
write=_FProcessText }; TMyDropTarget(TWinControl
*AOwner); ~TMyDropTarget();
HRESULT __stdcall
QueryInterface(const GUID &iid, void
**ppv);
ULONG __stdcall
AddRef(void) { return
++_iRefCount; }
ULONG __stdcall
Release(void) { if(--_iRefCount==0){delete
this;} return
_iRefCount; }
HRESULT __stdcall
DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL
pt, DWORD *pdwEffect); HRESULT __stdcall
DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
HRESULT __stdcall DragLeave(void);
HRESULT __stdcall Drop(IDataObject
*pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect);
private: ULONG
_iRefCount; IDataObject *_lpDataObj;
TWinControl *_OwnerControl; void
__fastcall (__closure *_FGetFormat)(IDropTarget
*Sender, IDataObject *DataObject, DWORD KeyState, TPoint pt,
DWORD &dpe, bool &bDataOK); void
__fastcall (__closure *_FProcessData)(IDropTarget
*Sender, IDataObject *DataObject, DWORD KeyState, TPoint pt);
void __fastcall (__closure
*_FProcessText)(IDropTarget *Sender, AnsiString AText, DWORD
KeyState, TPoint pt); bool
__fastcall FDataFormatOK(DWORD KeyState, POINTL pt,
DWORD &dpe); void __fastcall
FProcessData(DWORD KeyState, POINTL pt); };
//---------------------------------------------------------------------------
#endif //--------------------------------------------------------------------------- |
UnitTMyDropTarget.cpp 的内容:
//---------------------------------------------------------------------------
#include "UnitTMyDropTarget.h"
//---------------------------------------------------------------------------
TMyDropTarget::TMyDropTarget(TWinControl *AOwner) {
_OwnerControl = AOwner; _iRefCount
= 0; _lpDataObj
= NULL; _FGetFormat = NULL;
_FProcessData = NULL; _FProcessText
= NULL; RegisterDragDrop(_OwnerControl->Handle,this);
} //---------------------------------------------------------------------------
TMyDropTarget::~TMyDropTarget() { RevokeDragDrop(_OwnerControl->Handle);
} //---------------------------------------------------------------------------
HRESULT __stdcall TMyDropTarget::QueryInterface(const
GUID &iid, void **ppv)
{ if((iid==IID_IUnknown)||(iid==IID_IDropTarget))
{ *ppv=this;
AddRef();
} else
{ *ppv=NULL;
return
E_NOINTERFACE; }
return S_OK;
} //---------------------------------------------------------------------------
HRESULT __stdcall TMyDropTarget::DragEnter(IDataObject
*pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{ _lpDataObj =
pDataObject; FDataFormatOK(grfKeyState,pt,*pdwEffect);
return S_OK; }
//---------------------------------------------------------------------------
HRESULT __stdcall TMyDropTarget::DragOver(DWORD
grfKeyState, POINTL pt, DWORD *pdwEffect) {
FDataFormatOK(grfKeyState,pt,*pdwEffect);
return S_OK; }
//---------------------------------------------------------------------------
HRESULT __stdcall TMyDropTarget::DragLeave(void)
{ return
S_OK; } //---------------------------------------------------------------------------
HRESULT __stdcall TMyDropTarget::Drop(IDataObject
*pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
{ _lpDataObj =
pDataObject; if(FDataFormatOK(grfKeyState,pt,*pdwEffect))
FProcessData(grfKeyState,pt);
return S_OK; }
//---------------------------------------------------------------------------
bool __fastcall TMyDropTarget::FDataFormatOK(DWORD
KeyState, POINTL pt, DWORD &dpe) {
FORMATETC fetc={CF_TEXT,0,DVASPECT_CONTENT,-1,DWORD(-1)};
bool bOK=_lpDataObj->QueryGetData(&fetc)==S_OK;
dpe = bOK?DROPEFFECT_COPY:DROPEFFECT_NONE;
if(_FGetFormat)
{ TPoint
point(pt.x,pt.y); ::ScreenToClient(_OwnerControl->Handle,&point);
_FGetFormat(this,_lpDataObj,KeyState,point,dpe,bOK);
} return
bOK; } //---------------------------------------------------------------------------
void __fastcall TMyDropTarget::FProcessData(DWORD
KeyState, POINTL pt) { if(_FProcessData)
{ TPoint
point(pt.x,pt.y); ::ScreenToClient(_OwnerControl->Handle,&point);
_FProcessData(this,_lpDataObj,KeyState,point);
} else
if(_FProcessText) {
STGMEDIUM smed;
FORMATETC fetc={CF_TEXT,0,DVASPECT_CONTENT,-1,DWORD(-1)};
BOOL bValue=(_lpDataObj->GetData(&fetc,&smed)==S_OK);
if(bValue)
{
HGLOBAL
hData = GlobalLock(smed.hGlobal); if(hData)
{
TPoint
point(pt.x,pt.y); ::ScreenToClient(_OwnerControl->Handle,&point);
_FProcessText(this,(char*)hData,KeyState,point);
GlobalUnlock(hData);
GlobalFree(hData);
}
}
} }
//--------------------------------------------------------------------------- |
相关链接:
• 2009之后新版本 (解决字符编码问题):把其他程序(网页或文字编辑等)里面的文字拖拽到 Memo 编辑框里面
• 把文件拖拽到窗口里面,获取文件列表并且显示出来
|