Board index » cppbuilder » How to get drag operation started from an other application

How to get drag operation started from an other application


2003-11-18 05:11:21 PM
cppbuilder113
Hi all,
I want to use a ListView in my application. And want to be able to Drag and
Drop items from Windows Explorer to my Listview. How can a do that.. I write
the DragOver event handler with Accept=true; but it does not fire if the
drag operation has started from an other application..
Thanks.
 
 

Re:How to get drag operation started from an other application

murat wrote:
Quote
I want to use a ListView in my application. And want to be able to Drag and
Drop items from Windows Explorer to my Listview. How can a do that.. I write
the DragOver event handler with Accept=true; but it does not fire if the
drag operation has started from an other application..
The Drag stuff in VCL components is just for other VCL components. To
get stuff from Explorer, you need another component. The Turbopower
Shellshock component library has a nice easy to use TFileDrop component:
sourceforge.net/projects/tpshellshock/
And perhaps someday Anders Melander will get his wonderful Drag 'n' Drop
suite back up on the Internet. It is incredible, and a waste that he hasn't
had time to put it back up.
--
Jonathan Arnold C/C++/CBuilder Keen Advice:
www.keen.com/categories/categorylist_expand.asp
Comprehensive C++Builder link site:
www.buddydog.org/C++Builder/c++builder.html
 

Re:How to get drag operation started from an other application

"murat" < XXXX@XXXXX.COM >wrote in message
Quote
I want to use a ListView in my application. And want to be able
to Drag and Drop items from Windows Explorer to my Listview.
How can a do that..
What kind of items exactly? There are two different ways to proceed,
depending on what exactly you are dragging.
If you are dragging actual files, and you just want to extract the
filenames, then have a look at the DragAcceptFiles() and DragQueryFile()
functions, and intercepting the WM_DROPFILES message.
If, on the other hand, you are dragging anything else, then you have to
instead implement your own IDropTarget COM interface implementation and use
RegisterDragDrop() to associate the IDropTarget with your form's window.
The OS will call into the methods of the IDropTarget when needed, such as
DragEnter(), Drop(), etc. Your Drop() method then needs to query the
provided IDataObject interface for the physical dropped data that you are
interested in.
Quote
I write the DragOver event handler with Accept=true; but it does
not fire if the drag operation has started from an other application..
It is not supposed to. The OnDrag... events are for the VCL's own internal
drag&drop operations within the same application. They have nothing to do
with the outside world at all.
Gambit
 

{smallsort}

Re:How to get drag operation started from an other application

"Jonathan Arnold" < XXXX@XXXXX.COM >wrote in message
Quote
And perhaps someday Anders Melander will get his wonderful
Drag 'n' Drop suite back up on the Internet. It is incredible, and
a waste that he hasn't had time to put it back up.
Ander's components are available at CodeCentral:
codecentral.borland.com/codecentral/ccweb.exe/listing
Gambit
 

Re:How to get drag operation started from an other application

Remy Lebeau (TeamB) wrote:
Quote
"Jonathan Arnold" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...


>And perhaps someday Anders Melander will get his wonderful
>Drag 'n' Drop suite back up on the Internet. It is incredible, and
>a waste that he hasn't had time to put it back up.

Ander's components are available at CodeCentral:
codecentral.borland.com/codecentral/ccweb.exe/listing
Yeah, but that's the old one. I helped him out with his latest
incarnation, and it is a beaut. I've offered to host it on my C++Builder
web site, but he says he wants to keep it close to hand until his
own web site is ready. He mentioned he was going to get the new version
up to CodeCentral, but I don't see it yet. You might drop him an
email at "anders at aztech.dk" to encourage him forward:-)
--
Jonathan Arnold C/C++/CBuilder Keen Advice:
www.keen.com/categories/categorylist_expand.asp
Comprehensive C++Builder link site:
www.buddydog.org/C++Builder/c++builder.html
 

Re:How to get drag operation started from an other application

Remy Lebeau (TeamB) wrote:
Quote
"murat" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>I want to use a ListView in my application. And want to be able
>to Drag and Drop items from Windows Explorer to my Listview.
>How can a do that..

What kind of items exactly? There are two different ways to proceed,
depending on what exactly you are dragging.

If you are dragging actual files, and you just want to extract the
filenames, then have a look at the DragAcceptFiles() and DragQueryFile()
functions, and intercepting the WM_DROPFILES message.
Here's a simple way is to accept dropped files. This is from Wang Weijun:
Three steps:
1. Add a line
DragAcceptFiles(Handle, true);
in TForm1::Create
2. In unit1.h, add these lines in class TForm1 declaration
void __fastcall WhenDropFile(TWMDropFiles& Message);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, WmDropFiles)
END_MESSAGE_MAP(TForm)
3. Implement the WhenDropFile() function like this
char buffer[ENOUGH_LONG];
HDROP hDrop = (HDROP)Message.Drop;
DragQueryFile(hDrop, 0, buffer, sizeof(buffer));
now buffer contains the first filename. if you want to frag more than one file,
DragQueryFile(hDrop, -1, NULL, NULL) returns how many
--
Jonathan Arnold C/C++/CBuilder Keen Advice:
www.keen.com/categories/categorylist_expand.asp
Comprehensive C++Builder link site:
www.buddydog.org/C++Builder/c++builder.html
 

Re:How to get drag operation started from an other application

"Jonathan Arnold" < XXXX@XXXXX.COM >wrote in message
Quote
1. Add a line
DragAcceptFiles(Handle, true);
in TForm1::Create
Do not use the OnCreate event is C++. It is a Delphi remnant that is
unstable in C++, as it can be triggered before the constructor, which is
illegal in C++. Use the constructor instead.
Quote
3. Implement the WhenDropFile() function like this
That implementation informs the program when files are dragged over any part
of the form, not necessarily the ListView only. But murat does not want to
drop the files onto the form, he wants to drop them onto the ListView. So,
yeed would need to use DragQueryPoint() to know where the drop actually
occured within the form, and then see if those coordinates fall within the
ListView or not before then processing the filenames.
Quote
char buffer[ENOUGH_LONG];
You should use MAX_PATH instead:
char buffer[MAX_PATH+1];
Quote
now buffer contains the first filename. if you want to frag more than
one file,
DragQueryFile(hDrop, -1, NULL, NULL) returns how many
You forgot to mention that the second parameter of DragQueryFile() is an
index. So when you specify -1, you get the number of files returned, and
then you can loop through that count specifying the current index as the
second parameter during each iteration of the loop.
Also, don't forget to call DragFinish() when you are done with everything,
otherwise resources will be leaked.
Also don't forget to call DragAcceptFiles() again when closing the program,
setting the fAccept parameter to FALSE.
Try this implementation:
class TForm1 : public TForm
{
__published: // IDE-managed Components
TListView *ListView1;
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
private: // User declarations
void __fastcall WMDropFiles(TWMDropFiles &Message);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, WMDropFiles)
END_MESSAGE_MAP(TForm)
};
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
DragAcceptFiles(Handle, TRUE);
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
DragAcceptFiles(Handle, FALSE);
}
void __fastcall TForm1::WMDropFiles(TWMDropFiles &Message)
{
char buffer[MAX_PATH+1] = {0};
HDROP hDrop = (HDROP)Message.Drop;
POINT p;
DragQueryPoint(hDrop, &p);
TControl *ctrl = ControlAtPos(p, false, true);
if( (ctrl) && (ctrl == ListView1) )
{
UINT count = DragQueryFile(hDrop, -1, NULL, 0);
for(UINT u = 0; u < count; ++u)
{
if( DragQueryFile(hDrop, u, buffer, MAX_PATH) )
{
// do something with buffer and ListView
}
}
}
DragFinish(hDrop);
}
Gambit
 

Re:How to get drag operation started from an other application

Thanks a lot to all...
Jonathan Arnold < XXXX@XXXXX.COM >wrote in message
Quote
Remy Lebeau (TeamB) wrote:

>"Jonathan Arnold" < XXXX@XXXXX.COM >wrote in message
>news: XXXX@XXXXX.COM ...
>
>
>>And perhaps someday Anders Melander will get his wonderful
>>Drag 'n' Drop suite back up on the Internet. It is incredible, and
>>a waste that he hasn't had time to put it back up.
>
>Ander's components are available at CodeCentral:
>
codecentral.borland.com/codecentral/ccweb.exe/listing

Yeah, but that's the old one. I helped him out with his latest
incarnation, and it is a beaut. I've offered to host it on my C++Builder
web site, but he says he wants to keep it close to hand until his
own web site is ready. He mentioned he was going to get the new version
up to CodeCentral, but I don't see it yet. You might drop him an
email at "anders at aztech.dk" to encourage him forward:-)

--
Jonathan Arnold C/C++/CBuilder Keen Advice:
www.keen.com/categories/categorylist_expand.asp
Comprehensive C++Builder link site:
www.buddydog.org/C++Builder/c++builder.html