Приветствую читающего.
Добавил функционал drag-n-drop в программу. Из адресной строки браузера перетаскиваю текст в Memo или ListBox программы.
Возникла следующая проблема: при запуске программы из-под Builder_а в Memo или ListBox без проблем перетаскивается текст ссылки, который беру из адресной строки браузера (FF). Когда запускаю программу скомпилированным exe-файлом ни Memo, ни ListBox текст не принимают.
Кто что может сказать по этому поводу?
MainF.cpp
Код:
#include <vcl.h>
#include <ComObj.hpp>
#pragma hdrstop
#include "MainF.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
OleInitialize(0);
// Регистрируем окно, как приемник Drag-n-Drop операций
OleCheck(RegisterDragDrop(this->Handle, this));
// уведомляем систему о том, что наша форма умеет обрабатывать еще и WM_DROPFILES
DragAcceptFiles(this->Handle, true);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
// ну, и по привычке, чистим за собой перед выходом
DragAcceptFiles(this->Handle, false);
// Заодно прекращаем регистрацию приемника
RevokeDragDrop(this->Handle);
OleUninitialize();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::WMDropFiles(TWMDropFiles &Message)
{
HDROP drop_handle = (HDROP)Message.Drop;
TCHAR fName[256];
// количество перетягиваемых файлов
int count = DragQueryFile(drop_handle, -1, NULL, NULL);
for (int i=0; i<count; i++)
{
// Получаем имя каждого файла
DragQueryFile(drop_handle, i, fName, 256);
// и обрабатываем его нужным образом (для примера - просто добавляем в ListBox)
ListBox1->Items->Add(fName);
};
DragFinish(drop_handle);
}
//---------------------------------------------------------------------------
// Реализация методов интерфейса IDropTarget
STDMETHODIMP TForm1::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
*pdwEffect = DROPEFFECT_COPY;
return S_OK;
}
// ---------------------------------------------------------------------------
STDMETHODIMP TForm1::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
*pdwEffect = DROPEFFECT_COPY;
return S_OK;
}
// ---------------------------------------------------------------------------
STDMETHODIMP TForm1::DragLeave()
{
return S_OK;
}
// ---------------------------------------------------------------------------
// Основной метод - при отпускании объекта на форме вызывается именно он
STDMETHODIMP TForm1::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
{
FORMATETC fmtetc;
fmtetc.cfFormat = CF_UNICODETEXT; // или просто CF_TEXT, если собирается неюникодный проект
fmtetc.ptd = NULL;
fmtetc.dwAspect = DVASPECT_CONTENT;
fmtetc.lindex = -1;
fmtetc.tymed = TYMED_HGLOBAL;
STGMEDIUM medium;
// получаем данные из перетягиваемого объекта
HRESULT hr = pDataObj->GetData(&fmtetc, &medium);
// если при этом не было ошибки
if (!FAILED(hr))
{
HGLOBAL hTxt = medium.hGlobal;
// то вытягиваем текст, который перетянули на форму
LPCTSTR pData = (LPCTSTR)GlobalLock(hTxt);
// и заносим его в Memo
Memo1->Text = pData;
// после чего разблокируем память
GlobalUnlock(hTxt);
// и освобождаем Storage medium
ReleaseStgMedium(&medium);
}
else // если была ошибка при получении данных из IDataObject
{
*pdwEffect = DROPEFFECT_NONE;
// то ничего не делаем и возвращаем код этой ошибки
return hr;
}
return S_OK;
}
// ---------------------------------------------------------------------------
MainF.h
Код:
#ifndef MainFH
#define MainFH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm, public IDropTarget
{
__published: // IDE-managed Components
TListBox *ListBox1;
TMemo *Memo1;
void __fastcall FormDestroy(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
private: // User declarations
protected:
void __fastcall WMDropFiles(TWMDropFiles &Message);
BEGIN_MESSAGE_MAP MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, WMDropFiles);
END_MESSAGE_MAP(TForm);
// IUnknown
STDMETHOD_(ULONG, AddRef)()
{
return 1;
}
STDMETHOD_(ULONG, Release)()
{
return 1;
}
// IDropTarget
STDMETHOD(DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
STDMETHOD(DragLeave)();
STDMETHOD(Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif