아래 OLE Drag&Drop 설명과 예제입니다..
The WM_DROPFILES message is specifically meant for the transfer of files from
Explorer to an application. Using the message is simple, but as you've
discovered, it's limited. If you're looking to accept drops (i.e., data) from
other applications, you'll need to use OLE drag-drop. Most applications use OLE
for the transfer of data, so if you implement a "drop target" class, you will be
able to accept this data and receive notification of the standard OLE drag-drop
events (i.e., similar to OnDragEnter, OnDragOver, OnDrop, etc.). If you read
the following reference, you can cut and paste the TDropTarget class from the
CAQ and be up and running...
http://bcbcaq.freeservers.com/project_DD.html
In the article, I specifically target file transfers from Explorer. That is,
the TDropTarget::HandleDrop(), DragEnter(), Drop(), and the TForm1::WMOleDrop()
member functions specifically deal with the CF_HDROP format. If you're looking
to accept text from browsers, you'll need to modify these functions to handle
the CF_TEXT format. So, read the CAQ, try to modify it for the CF_TEXT format,
then refer to the following example if you run into trouble...
// in TDropTarget header...
// helper function -- modified for CF_TEXT
void __fastcall HandleDrop(const char* AText);
// in TDropTarget source...
// helper routine to notify Form of drop on target
void __fastcall TDropTarget::HandleDrop(const char* AText)
{
SNDMSG(FFormHandle, WM_OLEDROP, reinterpret_cast<WPARAM>(AText), 0);
}
// modified (for CF_TEXT) DragEnter
STDMETHODIMP TDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState,
POINTL pt, LPDWORD pdwEffect)
{
FORMATETC fmtetc;
fmtetc.cfFormat = CF_TEXT;
fmtetc.ptd = NULL;
fmtetc.dwAspect = DVASPECT_CONTENT;
fmtetc.lindex = -1;
fmtetc.tymed = TYMED_HGLOBAL;
// does the drag source provide CF_TEXT?
if (SUCCEEDED(pDataObj->QueryGetData(&fmtetc)))
{
FAcceptFormat = true;
*pdwEffect = DROPEFFECT_COPY;
}
else
{
FAcceptFormat = false;
*pdwEffect = DROPEFFECT_NONE;
}
return NOERROR;
}
// modified (for CF_TEXT) Drop
STDMETHODIMP TDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
POINTL pt, LPDWORD pdwEffect)
{
FORMATETC fmtetc;
fmtetc.cfFormat = CF_TEXT;
fmtetc.ptd = NULL;
fmtetc.dwAspect = DVASPECT_CONTENT;
fmtetc.lindex = -1;
fmtetc.tymed = TYMED_HGLOBAL;
// user has dropped on us -- get the CF_TEXT data from drag source
STGMEDIUM medium;
HRESULT hr = pDataObj->GetData(&fmtetc, &medium);
if (SUCCEEDED(hr))
{
// grab a pointer to the data
HGLOBAL HData = medium.hGlobal;
char* text = static_cast<char*>(GlobalLock(HData));
try
{
// call the helper routine which will
// notify the Form of the drop
HandleDrop(text);
}
catch (...)
{
// release the pointer to the memory
GlobalUnlock(HData);
ReleaseStgMedium(&medium);
}
// release the pointer to the memory
GlobalUnlock(HData);
ReleaseStgMedium(&medium);
}
else
{
*pdwEffect = DROPEFFECT_NONE;
return hr;
}
return NOERROR;
}
// in Form1 header...
#include "DropTarget.h"
LPDROPTARGET lpDropTarget_;
void __fastcall WMOleDrop(TMessage& AMsg);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_OLEDROP, TMessage, WMOleDrop)
END_MESSAGE_MAP(TForm)
// in Form1 source...
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
// initialize the OLE library
OleInitialize(NULL);
// pass the handle to the Form in the constructor
// so TDropTarget knows which window to send the
// WM_OLEDROP message
lpDropTarget_ =
reinterpret_cast<LPDROPTARGET>(new TDropTarget(Handle));
CoLockObjectExternal(lpDropTarget_, true, true);
// register the Memo as a drop target
RegisterDragDrop(Memo1->Handle, lpDropTarget_);
}
__fastcall TForm1::~TForm1()
{
// remove the Memo from the list of drop targets
RevokeDragDrop(Memo1->Handle);
// delete the TDropTarget instance
lpDropTarget_->Release();
CoLockObjectExternal(lpDropTarget_, false, true);
// uninitialize the OLE library
OleUninitialize();
}
void __fastcall TForm1::WMOleDrop(TMessage& AMsg)
{
const char* text = reinterpret_cast<const char*>(AMsg.WParam);
Memo1->Lines->Add(text);
}
HTH.
Damon C. (TeamB)
이기주 님이 쓰신 글 :
: 탐색기에서 TreeView로 파일을 드래그 할 경우
:
: WM_DROPFILES메세지 처리를 하여 사용하고 있습니다.
:
: 하지만 이메세지는 마우스로 drop하였을 경우에만 발생되지
:
: 드래그 하는중에는 발생되지 않습니다.
:
: 제가 알고싶은것은 바로 drag하는 중인지를 어떻게 알아내는가 하는것입니다.
:
: 알고 계신분의 답변 부탁드립니다.
: