There is nothing wrong with your television set. Do not attempt to adjust the picture.
Status
Latest version: 5.2
Released: 17 aug 2010
Download
The Drag and Drop Component Suite is a freeware VCL component library that enables your Delphi and C++Builder applications to support COM based drag and drop and integrate with the Windows clipboard.
The drag and drop system that is built into the VCL, is limited in that it only supports drag and drop within the same application. If you need to drag data from your application to other applications (e.g. Word, Explorer or Outlook), or if you need to be able to accept data dropped from other application (e.g. the Explorer), you have to use COM based drag and drop. COM based drag and drop is an integral and very important part of the Windows user interface and the Drag and Drop Component Suite makes it very easy to leverage all the features of COM based drag and drop in your own Delphi and C++Builder applications.
Every drag and drop operation involves two objects: A drop source and a drop target. The drop source provides the data to be dragged, and the drop target accepts the dragged data.
Likewise there are basically two sets of components in the Drag and Drop Component Suite; Drop source components and drop target components. Most of the source and target components are specialized to handle just one type of data, but a few of the components supports a wider range of data types or are completely generic.
In addition to the drag and drop components, the Drag and Drop Component Suite also includes components that can be used to build Windows Shell Extensions. While these components aren’t all related to Drag and Drop, they benefit from the Drag and Drop Component Suite framework and allow you to write Windows Shell Extensions with very little code. But most important; I had a lot of fun writing them :-).
IDropSource, IDropTarget, IDataObject and IAsyncOperation interfaces.The Drag and Drop Component Suite contains the following components:
| Drop Sources | Drop Targets | |
|---|---|---|
|
|
| Shell Extensions | Additional |
|
|---|---|---|
|
|

This work is licensed under a
Creative Commons Attribution-Share Alike 3.0 Unported License.
The library has been tested with the following versions of Delphi:
| D1 | D2 | D3 | D4 | D5 | D6 | D7 | D2005 | D2006 | D2007 | D2009 | D2010 |
If you can confirm compatibility with any of the untested versions of Delphi (or C++ Builder for that matter), please let me know and I will update the table.
I have done absolutely no testing with C++ Builder so I don’t know if the code works with it or not. That said, according to feedback I have received, the current release should work with C++ Builder.
| Download: | The Drag and Drop Component Suite v5.2 |
|---|---|
| Version: | 5.2 |
| Updated: | 17 August, 2010 |
| Size: | 505.61 KB |
| Notes: | Includes component source and demo applications. |
| Downloads: | 7,974 |
Old versions can be found on the downloads page.
Packages folder, find the design time package that matches your version of Delphi. Open it in Delphi, Compile and Install.Library sub-folder that matches your version of Delphi. Add it to the Delphi library search path.Source folder to the Delphi browsing path.Drag and Drop Component Suite design time package.Library folder from the Delphi library search path.Source folder from the Delphi browsing path.Changes since version 4.2:
TRawClipboardFormat.TRawClipboardFormat that caused it to stop functioning after first use.TDropContextMenu now properly supports nested context menus.DragDetectPlus has been improved to make it possible to use it with popup menus and TTreeView:
TCustomDropTarget.Enabled has been improved.AutoScroll feature
ResetScrollZone method.ResetScrollZone in both DragEnter and DragOver. DragOver will not call ResetScrollZone if a custom scroll zone has been specified through the NoScrollZone property thus if the user specifies a custom scroll zone in OnDragEnter then the scroll zone will not be automatically reset in DragOver.TOutlookDataFormat and TStorageDataFormat has been improved based on user feedback.TFileContentsStreamClipboardFormat and TFileContentsStorageClipboardFormat now handles both Ansi and Unicode data. Among other things this fixes problems with Outlook drop targets.TRawClipboardFormat.CopyFromStgMedium and CopyToStgMedium methods are now functions that return a boolean. The return values indicates if the method was able to perform the requested operation.TDropFileSource.Files and MappedNames properties are no longer published. They are now public properties.MakeRTF function in the DragDropText unit failed to compile with some versions of Delphi.DragDetectPlus no longer eats right-click mouse messages.OnGetData event) instead of when the data is dropped (OnDrop event). This change was made to handle application that require the files to be physically present when ever they query the drop source for the file names.TListView’s internal mouse message handling makes it impossible to handle right-click correctly.TCustomDropTarget.Enabled property.TMessages class (used for Outlook drag/drop) now support sessions. This can be (and is) used to work around the various quirks in Outlook’s interface reference counting mechanism.TAnsiStringClipboardFormat.GetClipboardFormat has been implemented.TCustomDropTarget.PasteFromClipboard no longer clears the data after the OnDrop event has fired.TClipboardFormat.GetData that caused drop targets to reject data after first drop.TTextDataFormat that mainly affected TDropTextTarget.TDropComboTarget.OptimizedMove and TDropFileTarget.OptimizedMove is now declared correctly.TStrings but is Assign/AssignTo compatible with it.TWideStringList for Unicode support, now use the new TUnicodeStringList instead.DragDetectPlus function now leave mouse click messages (WM_xBUTTONDOWN, WM_xBUTTONUP, etc) in the message queue.MakeRTF utility function now support Unicode strings and generate proper RTF formatted text.TRichTextClipboardFormat class).TCustomDropSource.OnGetDragImage event added.TFileGroupDescriptor*ClipboardFormat, TFileContents*ClipboardFormat and TVirtualFileStreamDataFormat classes has been moved to the DragDropFile unit.T*TextClipboardFormat classes has been moved to the DragDropText unit.CreateIStreamFromIStorage and CreateIStorageOnHGlobal which primarily affected drag/drop from Outlook.TFileGroupDescriptorCustomClipboardFormat.TFilenameClipboardFormat has been renamed TAnsiFilenameClipboardFormat.TFilenameWClipboardFormat has been renamed TUnicodeFilenameClipboardFormat.TFilenameClipboardFormat is now an alias for the native (ansi or unicode) format.TFilenameMapClipboardFormat has been renamed TAnsiFilenameMapClipboardFormat.TFilenameMapWClipboardFormat has been renamed TUnicodeFilenameMapClipboardFormat.TFilenameMapClipboardFormat is now an alias for the native (ansi or unicode) format.TFileGroupDescriptorClipboardFormat has been renamed TAnsiFileGroupDescriptorClipboardFormat.TFileGroupDescriptorWClipboardFormat has been renamed TUnicodeFileGroupDescriptorClipboardFormat.TFileGroupDescriptorClipboardFormat is now an alias for the native (ansi or unicode) format.TTextClipboardFormat has been renamed TAnsiTextClipboardFormatTCustomTextClipboardFormat has been renamed TCustomAnsiTextClipboardFormatTCustomWideTextClipboardFormat has been renamed TCustomUnicodeTextClipboardFormatTTextClipboardFormat is now an alias for the native (ansi or unicode) format.TDropTextTarget, TDropTextSource and TTextDataFormat now keeps string data data in the source format and only converts between unicode and ansi on demand.Text property of TDropTextTarget, TDropTextSource and TTextDataFormat is now named AnsiText.Text property of TDropTextTarget, TDropTextSource and TTextDataFormat now returns the native string format.RichText, OEMText, CSVText and HTML properties of the TDropTextTarget, TDropTextSource and TTextDataFormat classes are no longer supported and have been removed.TDropContextMenu component.TDropContextMenu.OnPrepareMenu event.TDropContextMenu.FolderPIDL and TDropContextMenu.Folder properties.TDragDropHandler.GetFolderPIDL function has been replaced with the FolderPIDL property.TURLClipboardFormat has been renamed TAnsiURLClipboardFormatTURLWClipboardFormat has been renamed TUnicodeURLClipboardFormatTURLClipboardFormat is now an alias for the native (ansi or unicode) format.Title property of TDropURLTarget, TDropURLSource and TURLDataFormat is now a Unicode string.const directive to interface parameters.TFileGroupDescriptorCustomClipboardFormat as common ancestor for TFileGroupDescriptorClipboardFormat and TFileGroupDescriptorWClipboardFormat.In short, you can’t.
You must understand that the drag/drop API works the same for all applications that uses it, and the Explorer is just like any other application. The drag/drop API provides a framework that facilitates the interaction between a drop source and the target, but since the drop target can do anything it wants with the data it receives, there is no way to communicate the destiny of the data back to the drop source in a uniform way.
One target may chose to display the dropped data (e.g. notepad), another one to upload it to a web server (e.g. a FTP client), a third to move and rename the file (e.g. the Recycle Bin) and a fourth may chose to copy or move the file (e.g. Explorer).
In my experience there is never any real need to know the destination of a drop to the Explorer. If you find that you do need this, you should rethink your solution. - and feel free to ask for help.
AllowAsyncTransfer property and the Execute methods’ Asynchronous parameter?The Execute methods Asynchronous parameter specifies if the source should perform the transfer in a thread.
The AllowAsyncTransfer property specifies if the drop target is allowed to perform an asynchronous transfer.
The two are completely independent. One does not have priority over the other.
Asynchronous transfer on the source side is an “invention” of mine. It can be done even if the drop target doesn’t support, and thus doesn’t take an active part in, asynchronous transfer.
Asynchronous transfer on the target side is a COM drag/drop feature (see IAsyncOperation in MSDN). It requires that both the source and the target support asynchronous transfer. All the Drag and Drop Component Suite components support asynchronous transfer, but apart from Windows Explorer few applications has implemented the feature.
An optimized move is simply a move operation where the drop target moves the data from the source to the destination location.
In a conventional move operation, the source and the target must cooperate in order to complete the operation. First the target makes a copy of the data at the desired location. Then, when the target has completed copying the data, it hands control back to the source who then deletes the original data. This procedure can be very inefficient because it requires two simultaneous copies of the data.
With an optimized move, the target handles the entire move operation and signals the source that an optimized move took place upon completion.
The Drag and Drop Component Suite supports Optimized Move on both the source and target side.
When migrating from pre-5.0 releases, are there any guidelines? Code that needs to be changed, "gotchas" to look out for, etc.
Thanks.
It depends…
If you are using custom drop target or drop source classes, or using the data- and clipboard format classes directly, then things have changed quite a lot. Many classes have been renamed and reimplemented.
If you are just using the standard components then you should be good to go. I have made a great effort to maintain high level backward compatibility.
One thing to look out for is that
TDropFileTarget.FilesandTDropFileSource.Filesis now a custom string list which doesn't descend fromTStrings. This will not be a problem in most cases and the compiler will catch it for you if it is. I.e. if it compiles, then it works.When attempting to compile/install the D-and-D Component Suite 5 in D5 I get two errors:
"Cannot find the resource file …DragDropD5.res. Recreated" (which is a minor problem…)
and a fatal error: "Could not create output file …\DropSource.dcu".
The package fails to install.
Is there a problem somewhere?
The missing
.resfile is normal. Since the.resfile will be recreated by Delphi when you open the package, I decided not to include it in the zip file this time. The same goes for the.projand.group_projfiles used by D2005 and later.The "Cannot create out file…" error is likely caused by a missing folder. The zip file contains a number of empty folders under the
DragDrop\Libraryfolder. When you unzipped the file these folders should have been recreated even though they are empty. I known that WinZip, 7-zip and WinRar supports this - did you use something else?The Delphi 5 package outputs the binary files (
.dcu,.bpl,.dcp) in theDragDrop\Library\Delphi 5folder. Try creating that folder and recompile the package.Yes, as you said. Now it installs OK. Many thanks!
great work! would you consider about creating an online svn/cvs repository?
The source currently lives in a StarTeam repository on a SAN hosted by a cluster situated in a nuclear proof bunker. The only downside is that I can only access it through VPN.
It would be nice if I could give the public access to the source, or move the source to a public repository, but I'm afraid there's nothing "in it for me" - only more work.
Excelent component! I'll be using it from now on..
P.S. A lot of demo apps are raising weird exceptions at startup. Please, have a look. I'm using Delphi 7 on Windows 2003 Server R2..
The DropTarget component is working easy and nice as it's supposed to.
Congratulations for your great work!
That is because the forms has been opened (by me) with a newer version of Delphi than the one you are using. It's a quite common problem when working with multiple versions of Delphi.
To resolve the problem just open the forms and save them and then recompile.
Just downloaded and tested some of your demos. In the file source demo I can drag files FROM my application into any Windows Explorer window, except on the desktop. Why? Isn't the windows desktop just another instance of explorer.exe?
What am I missing?
It's a bug.
One of the classes that converts between filenames and PIDLs has a problem that prevents the "Link" drop kind from working.
I have already fixed it internally and will post a new version ASAP.
Regarding the SourceDemo
Can the following two kinds of drag'n'drop co-exisit:
1. Drag the ListView items to other applications, eg Explorer (this is a behavior of the SourceDemo)
2. If the user drag'n'drop the ListView items within the ListView, I want the items to be re-sorted.
Please advise. Thank you.
That's actually quite easy:
TDropFileTargetcomponent to turn the listview into a drop target.TListView.OnMouseDownhandler). Clear the flag whenTDropFileSource.Executereturns.TDropFileTarget.OnEnterhandler reject the drop unless the flag has been set.TDropFileTarget.OnDrophandler move the currently selected listview items to the drop location. You can useTListView.GetItemAtto find the drop location.See also: Rearrange Multiple TListView Items using Drag and Drop.
Thanks for your components it is a wonderful gift To the community but..
it fails to compile so does not install.
[DCC Error] DragDropText.pas(325): E2011 Low bound exceeds high boundI hope you can fix it soon .
Merry Christmas - Peace
Philippe Watel
Which version of Delphi are you using?
Hello. I trying to make drag&drop images from browser to my program.
using DropComboTarget.
With Firefox it works fine. I get Bitmap and working with it, but with IE and Chrome i got only Text and Url when drop image. I tried to look at Source Analyzer Demo: when i drop image from
)
Chrome i got "filecontents" and this is content of dropped image, but in DropComboTarget i got only Text & Url … (sorry if my English was bad, hope u understand me
As far as I can tell this is caused by a bug in IE8 (as far as I remember it used to work in previous versions of IE): IE does offer the FileContents clipboard format, but fails to actually fill it with any data. The Drop Source Analyzer indicates this by drawing the medium (GlobalMem) in red.
If you are seeing something different please state your version of IE and mail me the data format list (select Save list… from the toolbar) from the Source Analyzer.
Further tests show that IE8 can drag images, but only if the image isn't wrapped in an A tag (i.e. a link). I'm afraid there's nothing I can do about this strange behavior.
hi
delphi 2010 but i tried with 2009 and it was the same
bye
PW
I'm afraid I can't reproduce your problem with either D2009 or D2010 but try rewriting the case statement like this:
We have same error happened as
[DCC Error] DragDropText.pas(325): E2011 Low bound exceeds high bound. But It's OK now after modify those code from you.Thanks for the feedback.
Although I still cannot reproduce the error I have now applied the change to my source so the problem doesn't reappear.
Hello!
Delphi 2009, component
TDropFileSource.In popup menu:
It's a known problem.
I will see if I can find time to upload a new version this week.
This works beautifully in Delphi 6 but …
I had a lot of trouble getting this to install. I am now having to reinstall my system after a crash and so far have not been able to pesuade Delphi to compile D & D again (yes the folder does exist per above comment by David).
Thank you for this package. I appreciate the work put into its creation as I was part way through trying to work this out myself when I found your components.
What error are you getting from the compiler?
Thank you for the reply. The error message is
Could not create output file …\DropSource.dcu
On a hunch I tried adding the contents of the source folder to
Delphi6\Liband placingDragDropD6.dpkin the same folder, double clicked onDragDropD6.dpkand it installed.Hope this helps Paul
I just checked the Delphi 6 package files and it appears that they were not configured correctly.
With the files back in their original locations try editing the package source files in notepad:
DragDropD6.dofchange the[Directories]section:DragDropD6.dpkupdate the path to the source files:The
DragDropD2006.dpkandDragDropD2007.dpkfiles also needs to have their{$R}directives adjusted.Thank you for the help.
Hello,
I have an application which will get all the email addresses in the server, and put them in the listview. Now I want this email addresses could be dragged from my listview to contacts in Outlook 2007.
could this be possible?
thanks and best regards
Yes it is possible.
There are two ways to do it:
Use the
TDropFileSourcecomponent to drag a vCard file. See the VirtualFile demo for an example of how to drag an in-memory vCard.See the Outlook source demo for an example of how to drag Outlook items back into Outlook. The hard part with this solution is the construction of the Outlook contact COM object and I'm afraid I cannot provide any help beyond what the demo provides.
The vCard approach is by far the easiest and I recommend that you use it if possible. You can easily test it with the VirtualFile demo.
WRT messing with Outlook Contact objects I just remembered this old comment.
Hello. My program is using Version 4 of the toolkit, and, based on ExtractDemo, I've been working on having it allow the user to drag a .WAV file within the program onto a target location, including other apps that accept .WAV files dropped onto them.
My program renders the file at the time the file dropped to the target location, when
DropFileSource1Dropis executed by my program. This works fine for some apps, however, in testing, there are reports that it doesn't work for some apps. One target app that I tested appears to require a fully-formed valid file to be present on disk at the time the mouse cursor is moved over it, otherwise the mouse cursor stays at "no drop allowed" cursor. Windows Media Player had a similar problem, in that it required a file with the target name to be present on disk, but I was able to get my program to drop into WMP by creating a small dummy file with the target file name, beforeDropFileSource1.Files.AddandDropFileSource1.Executeare called. Then, when theDropFileSource1Dropmethod is executed to do the actual drop, my program just erases the dummy file and re-creates it and WMP received it.The problem: Unlike Windows Media Player, this other program requires the dummy .WAV file to be a VALID .WAV in order for the mouse cursor to indicate the program will accept the file, but if I try erase the file and then recreate it during
DropFileSource1Drop, or if I have my program attempt to open the existing file and add to it, then it won't work because the other program (or windows) has taken control of the file and blocked my app from accessing it or erasing it.Wondering if there is any solution to this problem? How can I prevent the target app from taking control of the file before the
DropFileSource1Dropis executed? Also I am curious how the target app even knows the name of the file when the mouse cursor is hovering over the app, but beforeDropFileSource1Dropis executed?Thanks,
Jeff
The drop target can query the drop target about the data being dragged at any time during the drag operation. It does so using the
IDataObjectthat is passed to it whenIDropTarget.DragEnteris called.The solution to your problem is to create the source files if, and when, the target reads the file names from the drop source source's data object. Fortunately this is very easy: All you have to do is move the creation of the files from the
OnDrophandler to theOnGetDataevent handler.There are a few things you need to be aware of though:
OnGetDataevent is fired each time the drop target callsIDataObject.GetData.IDataObject.GetDatamany times during a drag operation. Each call will fire theOnGetDataevent.IDataObject.GetDatadoes not mean that it will eventually accept the drop.The following changes implement the above in the ExtractDemo application:
I hope this makes sense.
Makes sense. Thanks.
Hi! I've found your components tonight and am amazed. Thanks for the massive amount of work. However, I have to issues trying to simulate file-Drag&Drop from my application to a foreign target application that does not accept data from remote otherwise:
1. Is it possible at all to programatically drag and drop files to the target without moving the mouse cursor to the target "in real-time" with SetCursorPos?
2. The target seems to accept drops from Windows Explorer only. What is so special about Explorer that it can be identified by the target? How can I mimic Explorer's behaviour? Tomorrow, I will use your Source and Target analyzers to find out differences between my DataObjects and those of Explorer. Anyway, if you have an idea, any help is appreciated.
During a drag from Explorer it will most often be the active process. It is however possible to change the active process during a drag with Alt+Tab or by hovering over the task bar.
The target components does supply the InShellDragLoop format automatically but not the Shell Object Offsets format.
Hello, i just tried this one with D2005, using the include path to the source. I took that TargetDemo of the Demos, and modified it, since i can't include packages to my Delphi IDE because of the Delphi version.This one works fine with D5000 ! You should add something like the following, if you can't add packages like me:
I have released version 5.1.
All known bugs and problems fixed.
I have confirmed that these components ARE compatible with Delphi 2006.
By the way… nice job!!!! And much appreciated.
Thanks. I have updated the list.
Is there a way to know the source application?
I mean whether there is a way to know from which application, say WORD, EXCEL, Internet Explorer or FireFox, the data is dragged?
Thanks in advance.
No - not really.
You can examine the data formats offered by the source application and from that you can make an educated guess, but it's only a guess and you will have to have analyzed the different drop sources beforehand to learn of their "fingerprint".
Downloaded the DragDrop components, awesome. Ran the Outlook demo with Delphi 6, everything worked great. Ran the Outlook demo with Delphi 2010, the opening of attachements isn't working (ActionAttachmentOpenExecute). Saving the attachment appears to be failing, yet I'm not getting any errors. I have rights to the directory, not an expert with streams….any ideas?
I have reproduced and fixed the problem.
The function used to create the attachment file,
OpenStreamOnFile(), was declared wrong. The filename parameter must be aPAnsiChareven when Unicode is used.To correct the problem you can cast the filename to a
AnsiStringand then to aPAnsiCharinActionAttachmentOpenExecute:Great suite.
I am trying to make some simple copy/paste but I would like to copy a stream into the clipboard to be paste onto Explorer as a file. Is there any specific example in which this capability can be visualized ?
I am also thinking about how to create a shell handler to transfer this files directly by drag'n'drop (my application actually has the files centralized in a server and each time I need to open or copy them it is a remote operation, so they need to be downloaded first). Will appreciate any help… Thanks !
The VirtualFileStream example does what you need; It demonstrates how to drag data as a file stream or copy it onto the clipboard.
Wrt your second scenarion, check out the AsyncFTPClient example. It drags files from a remote FTP server. The files are transferred from the server on-demand as the drop source requests them.
I cannot help you with the Shell Namespace Extension as I have no experience with that. There are 3rd party solutions that can help with that if you do not wish to get your hands dirty.
Thanks for all the comments. I have tried some piece of code using as basis "onGetStream" event and work very fine to get files from the server and also to interpretate streams from Outlook (all the message or only file attachments, for example). Congratulation for you very powerfull suite.
Many thanks for the Drag & Drop Components (also TGIFImage). Your hard work is appreciated (glad it was fun!)
I compiled the Drag & Drop Components into my Delphi Turbo Explorer (2006) application and they have worked fine on Windows XP for some time now, however when I installed the application on a Windows 2000 system they don't seem to work. Is there something else I need to install? (I use this application to drag emails and attachments from Outlook 2003 to my application on the XP system, but I'm using Outlook Express from IE6 SP1 on the 2000 computer).
Thanks
I have not tested version 5 on W2K at all, but as far as I remember I haven't used any APIs that doesn't exist on W2K. If you can get any of the examples to fail on W2K let me know and I will try to reproduce the problem here. One of my kids computer is still running W2K - but not for much longer.
WRT Outlook Express you should be aware that you cannot use the same method to receive data from Outlook and Outlook Express. How do you get the data from Outlook Express?
Hi,
thanks for your components…
"Simple Source Demo" can't Drop files to Explorer or Desktop on Windows 7(32). A Dos-Box accept files.
Thanks
Try temporarily turning off UAC. If that solves the problem then the cause of the problem is that you are trying to drag between two applications that are running with different security levels.
As far as I know Vista has the exact same problem.
Using DragDrop component suite with a dynamic package runtime package may cause memory leak. I have create a sample project to show the leak, please download from here.
This sample project built with Drag and Drop component suite version 5.1 in Delphi 2007.
The memory leak should occurs in a method
TCustomSimpleClipboardFormat.DoSetDataof unitDragDropFormats.pas:An instance of
TOLEStreamand an instance ofTFixedStreamAdaptercause the leak.The memory leak only occurs if DragDrop components used in this dynamic runtime package behavior.
It doesn't happen if using DragDrop in static binding package.
I have tried your example and I'm afraid I cannot reproduce your problem.
I can't spot any problems with what the
DoSetDatamethod is doing either. TheTOleStreamobject is owned (and thus destroyed) by theTFixedStreamAdapterobject. TheTFixedStreamAdapterobject is owned, through itsIStreaminterface, by the caller and should be destroyed when the caller callsReleaseStgMedium. Since the caller is Explorer it is Explorer that is responsible for freeing theIStreamobject with a call toReleaseStgMedium.It is possible that your memory leak detection is fooled by the fact that the objects are allocated in one process and freed in another. That happens a lot.
You can verify that the
TFixedStreamAdapterobject is indeed destroyed by introducing a destructor inTFixedStreamAdapterand setting a break point in it.Btw, I should mention that I found two real memory leaks (nothing serious though) while I investigated this one so the effort wasn't wasted.
First, Anders, thank you for this nice library!
Chee Yang, did you get anywhere with this? I do not get a breakpoint at
TFixedStreamAdapter.Destroy. The leak is reported in the big application. In a test application it is not reported, but the breakpoint does not fire. Feeling a bit confused.TIA,/DI recently purchased Rapware's EasyMapi components and was wondering if it's ok to modify your
DragDropInternet.pasto work with Rapware's mapi units? Would a better approach be to make my ownTEasyMapiOutlookDataFormatobject in it's own unit instead?I'm looking for both it's ok to do this answer and this would be easier/better answer.
Daniel
I cannot tell which solution is the better or easiest since I don't know EasyMapi at all
I would generally advise against modifying the units as that can easily become a maintenance nightmare.
The
TOutlookDataFormatandTMessagesclasses are fairly simple so it would probably be quite easy to make a custom version of them in a new unit. I doubt that you will gain anything from it though.TMessagesis just a thin wrapper aroundOpenIMsgOnIStg()andTOutlookDataFormatdoesn't really do anything in itself.Finally even if EasyMapi provides its own stub for
OpenIMsgOnIStg()I can't see why it would be an advantage to use that instead of the one I have implemented.EasyMapi does have a wrapper for the Message Store but my application handles the mapi session differently than the
TMessagesimplementation. Basically I already have a mapi session that I want theTMessagesto use. I'm going to try and create a new unit containingTMyMessages.Yes, I see.
Would it be any help if I made it possible for you to override the MAPI session management? Something like this:
Possibly, but let me think about this for a while more. I'm still trying to wrap my head around both TDragDrop components source and the EasyMapi components source. Both are new to me as is the outlook object model, so it's taking me a bit to fit this puzzle together.
Hi Anders,
Thank you for the new version of Drag and Drop Component Suite. I'm a paid customer of Raize DropMaster because at an earlier time Drag and Drop Component Suite was lack of a function I needed (although I cannot remember what that was it) But now things have been changed, Raize DropMaster does not support UNICODE in pre-2009 versions of Delphi, but your excellent component suite does! and yours offers almost all features I needed! Thank you!
One question if you don't mind, the
TVirtualFileStreamDataFormat.FileNamesproperty isTStringsinstead ofTUnicodeStrings, do you have a plan to add UNICODE support to this class?Thank you.
欢迎光临 Edwin,
It should be fairly easy to make
TVirtualFileStreamDataFormatwork with Unicode strings. As far as I can see all it takes is to makeTFileDescriptorToFilenameStringsderive fromTUnicodeStringsinstead ofTStringsand then make the necessary adjustments. It is definitely my plan to make this change (as is evident in the source comments). It will probably be in the next version - if I remember it…Hi, a remark regarding the
OnDropEvent: the functionTCustomDropTarget.Dropcatches all exceptions. It should IMHO not catch exceptions that occur in the user defined callback.There are several good reasons why the
DragEnter,DragOver,DragLeaveandDropmethods all "eat" exceptions.This is from the source code:
They would end up at the caller of the methods which is the Windows drag/drop system and ultimately the drop source application. Now why should the drop source receive an exception about an error that occurred in your application and which the drop source most likely doesn't have a clue about.
There is simply no way to get the exceptions to end up in the drop target application.
Ok, I see the reason. Then the OnDrop has to handle that itself.
Thanks for the reply.
I have just started using this component and I love it. I am working on an interface to allow a user to drag an email to it and then I will save the email in a specific folder.
I have used the OutlookDemo as a model
I can see the
IMessageobject and am able to extract the subject, attachments, and sender etcI am hoping that there is a simple method I can use like
AMessage.SaveAs ('c:\test.msg')orAMessage.export ('c:\test.msg').I am using Delphi 2009.
Thank you
The
TMessageclass has aSaveToStreammethod you can use. See theActionMessageSaveExecute()method in the OutlookDemo example.Thank you for your Reply, I was trying to incorporate this into my Code, but am stumbling on the Tmessage vs Amessage vs Imessage.
in Simple terms I have modified your code as below:
When I call
ActionMessageSaveExecute(Sender);I get an Exception violation in the following line of codeI am guessing it has to do with how I am assigning
FCurrentMessage. Any documentation or just help you could offer would be awesomeJohn,
Um… The second parameter to
TMessage.Create()must be anIStorageinterface pointer. Since you are passing nil you will naturally get an AV when a method on that interface is used.You need to get the
IStorageinterface from theTOutlookDataFormatobject. Check the OutlookDemo source again.Dear all,
If the need is to save the entire message as a "message.msg", I think the best way is to use
TVirtualFileStreamDataFormatdirectly and catch the entire stream from the Drag Source or Clipboard (sorry If I misunderstood the question).Good point.
The VirtualFile and VirtualFileStream examples demonstrates how to do it.
Thank you both it is now working great
Great product. Thank you!
I have 2 questions.
How can I retrieve, in the OutlookDemo (OutlookTarget.pas) the Message ID and the Message Received Time?
I am unable to get these to values. I was using
PR_MESSAGE_DELIVERY_TIMEandPR_ENTRYID.Thank you
This is the Drag and Drop Component Suite. There are much better places for Outlook and MAPI questions. That said…
The
PR_MESSAGE_DELIVERY_TIMEproperty works for me:Both the
PR_ENTRYIDandPR_LONGTERM_ENTRYID_FROM_TABLEproperties fails with the errorMAPI_E_NOT_FOUND. I have no explanation for this and I have not been able to Google any clues. I suggest you ask for help in one of the places I linked to above. Let me know what you find out.Thank you for the answer. I could not find anything in the web explaining why PR_ENTRYID fails, but I managed to make it work by going back to Outlook and do a search on the subject line.
I modified your demo to capture all the email information. I can send it to you if you want to include it in your distribution package.
I have another question. How do I get Thunderbird emails? I looked at the examples and couldn't see anything related to Thunderbird.
Last question. Do you accept donations? If so, how do I donate money to the project?
Thank you again!
Yes please send me your modifications. I can't promise that I will use them but I'd like to see what you've done.
AFAIR Thunderbird v2 doesn't support drag of messages outside of it without custom plug-ins.
Thunderbird v3 however will support it. It passes mail messages in the FileContents (and FileGroupDescriptor) clipboard format. The FileContents data contains the mail message in mboxrd format (RFC 2822) - basically the raw mail message text. I think you should be able to use the TIdMessage class in Indy (idMessage unit) to parse the message. See the VirtualFile and VirtualFileStream demos for examples of how to handle the FileContent and FileGroupDescriptor formats.
I used to have an example of drag from the Netscape mail client but of course that stopped working a long time ago. If time permits I will make a Thunderbird example for the next release.
When investigating what drag/drop formats an application supports the first thing one should do is to run the Drop Source Analyzer and drop some data on it from the application in question.
The Drop Target Analyzer does the same thing, just with drop targets. Be aware though that the Target Analyzer exposes a bug in Thunderbird v3 that causes both the source and target to hang.
Donations are rare but welcome
Preferably in the form of books. I have a wishlist on Amazon and Amazon UK.
Anders,
I sent you a little something via Amazon, as a token of my gratitude. It should be there tomorrow.
Thanks again!
It actually got here today. Thanks Francisco. That was very kind of you.
Hi Anders,
I found the the
TDropFileSource.MappedNamesdoes not work with Outlook 2007, although it works with the Windows Explorer, any comment about this? Thank you.Define "does not work".
To my knowledge Outlook does not support the FileNameMap clipboard format which is what the
MappedNamesproperty interfaces to.In order for
MappedNamesto have any effect the drop target must support the FileNameMap clipboard format. Explorer is the only application I know of that does so.Thank yo for the info, Anders!
TObject.Free v.s FreeAndNil
I think the code in TOutlookDataFormat.Destory is backwards. Instead of calling inherited Destroy first, IMHO destructors should always call it last after freeing their own resources.
destructor TOutlookDataFormat.Destroy;
begin
inherited Destroy; //<—- Should be called last
FMessages.Free;
end;
In the case of the TOutlookDataFormat calling inherited Destroy last, will cause an access violation. This is caused by the following chain of events.
TOutlookDataFormat.Destroy
TMessages.Destroy
TMessages.Clear
TMessages.FMessages.Free
(Inherited)
TStorageDataFormat.Destory
TStorageDataFormat.Clear – (polymorphism calls TOutlookDataFormats.Clear method here, which then tries to access FMessages member which has already been freed.)
I don’t think the Clear methods are ever called outside of the DragDropInternet.pas unit, but in any case by changing the TOutlookDataFormat.Destroy to use FreeAndNil you could then change the TOutlookDataFormat.Clear method to test for nil. Thereby correcting the aforementioned access violation assuming you correct the destructor to call inherited Destory last.
destructor TOutlookDataFormat.Destroy;
begin
FreeAndNil(FMessages);
inherited Destroy;
end;
procedure TOutlookDataFormat.Clear;
begin
inherited Clear;
if FMessages <> nil then
FMessages.Clear;
end;
Just my thoughts…
PS: Ever think about setting up a newsgroup instead of these comments?
I completely agree.
I normally always call inherited Destroy last except when I know the base class destructors can have side effects though polymorphism, as it has in this case.
Unfortunately this particular pattern (Destroy calling a polymorphic Clear method) is something I run into fairly often. I would prefer not to be forced to implement the Clear method defensibly, but it's probably the best solution. It just doesn't "feel" right, but then neither does the alternative.
Anyway, I have implemented your suggestion.
PS: Ever think about setting up a newsgroup instead of these comments?
Every day.
I have experimented with a bbPress forum but I want something that integrates properly with the existing WordPress site and is actively maintained. Even though "they" plan to run bbPress into a WordPress plug-in it doesn't appear to be going anywhere at the moment.
Now that BuddyPress can be used on stand-alone WordPress sites I may give that a try instead (ironically BuddyPress internally uses bbPress to implement its forum feature). Unfortunately I will have to update my existing WordPress installation first. Not a simple task since I have customized just about every theme and plug-in installed.
Customizing WordPress theme's and plug-ins eh? I'd like to quote your response to one of my previous posts:
"I would generally advise against modifying the units as that can easily become a maintenance nightmare."
Ouch! There's nothing worse than being lectured with your own words
But you are (or is it "I am" - I'm confused) right. I certainly won't mess that much with them next time. Luckily I won't have to as the newer versions has (almost) all the features I need. I will also switch to a fluid theme while I'm at it. A fixed width layout like this isn't good when you have lots of code snippets.
There's no better way to learn to respect guns than to shoot yourself in the foot a few times. The trick is to survive the process
Compiler Warning:
In the
TDropContextMenu.InitializeI'm getting a warning saying return value might be undefined. Do you see a problem with movingResult := NOERRORto the top of the method?Looks good.
How can my application (main form) be a droptarget for both files and outlook objects?
oh, wait, multiple DataFormatAdapters, not drop targets….
Exactly.
You can also use a
TDropFileTargetand extend it with aTDataFormatAdapter.Hello! In windows7 use Drag and Drop Component Suite Version 5.1 have been if the program using the Run as administrator can not be realized drag and drop! ! !
Does this help?
I'm trying to follow your reply to this comment where the files don't exist when the drag drop starts but get created on the
GetDataandOnDropevents.Do I still populate the
TDropFileSource.Filesbefore I callTDropFileSource.Executeor should I populate theTDropFileSource.Filesin one of the events likeGetData?Either way should work. Give it a try and use the method that suits your purpose best.
Filling
TDropFileSource.Filesduring theExtractFilesmethod which gets called on theOnGetDataevent seems to be working.Email Attachments
I can't seem to figure out how to get my application to accept email attachments if I drag the attachment from an open email window (outlook 2007). I'm not dragging the email, just the attachment in the email. Any ideas?
Generally:
To spare you some time, try the VirtualFile and VirtualFileStream examples.
I tried the SourceAnalyzer but soon after I posted the question I tried the VirtualFile demo and that worked. I came back here to edit my response to save you time but I was to late.
Hi, guys, I have a problem but I have no place to ask for help.
I have used the following code to get the HTML Format code of a webpage:
but unfortunately, some of the HTML Format code snippets are unreadable.
examples here:
Version:0.9StartHTML:00000151
EndHTML:00000893
StartFragment:00000185
EndFragment:00000857
SourceURL:http://blog.ifeng.com/article/4665556.html
<html><body>
<!–StartFragment–> ?????€???????<!–EndFragment–>
</body>
</html>
It is dragged from a Chinese webpage. But the part between
StartFragmentandEndFragmentcannot be read.I am sure there must be one solution to this, but i can't find it. I would be grateful if any advice is given.
Thanks in advance.
I've examined the data in the SourceAnalyzer and I think it might be UTF-8 encoded. Have you tried UTF-8 decoding it?
Update: Yes it is indeed UTF-8. Here’s what the documentation for the CF_HTML format says:
If I have two data format adapters on a form that prompt the user during the OnDrop event for both formats, I can get it to error out in a rather unlikely scenario. In this example I'm using TOutlookDataFormat and a TFileDataFormat adapter.
1) Drop an email on the form, leave the modal dialog unanswered.
2) Now drop a file on the form and try to answer the modal dialogs.
This results in an AV. I've tried to disable the TDropEmptyTarget but it still lets me drop while I'm in the OnDrop event.
Under normal circumstances it should not be possible to get into the OnDrop event while a previous drop is still being processed. The Windows drag/drop system is not reentrant and neither is the drag/drop components.
My guess is that you have enabled asynchronous operation on the drop targets. In asynchronous mode, the OnDrop event is delegated to a separate thread which allows the main thread to return and process another drop. If the thread should block during the OnDrop event (e.g. if someone displays a modal dialog box in the OnDrop handler), then the scenario you are seeing could be possible.
If you run it in the debugger you should be able to see which thread(s) the OnDrop handler is being executed on.
Anyhow, it is not a good idea to display a modal dialog from inside a drag/drop event handler. If you need to display a prompt then you must post a message to yourself and display the prompt in the message handler.
I'll have to investigate why setting Enabled doesn't do anything. It's a fairly new feature so I might have missed something there.
Hi,
I want to detect if a file has a specific file format before allowing it to be dragged onto my application. Is this code safe, or is there a better way to do it? I'm a little concerned about the call to
.clear, should that be there if my program refuses the file?Thanks
I'm not quite sure what you are trying to do but my guess is that you should not be calling
Clearunless you are rejecting the drop. I.e.:However, the correct way to reject the drop is to set the
Effectparameter toDROPEFFECT_NONE:If you do that then the components will call
Clearfor you (fromTCustomDropTarget.DragLeave) and inform the drop source that you rejected the drop.Hello,
I try to use OutlookDemo. But i've a problem when i drop a mail message on it.
only one message and i've a blank memo and nothing is display. more than one Access Violation and nothing is display
I'm using Delphi 2009 and Outlook 2000 under XP/SP2
In debug
// Get an IMessage interface
if (Supports(OutlookDataFormat.Messages[i], IMessage, AMessage)) then
begin
try
Item := ListViewBrowser.Items.Add;
… GetSender and GetSubject - > Return always ''
because if (Succeeded(HrGetOneProp(AMessage, PR_SUBJECT, Prop))) always False
GetTime(AMessage); — > return a good day but a bad time same with PR_MESSAGE_DELIVERY_TIME
Item.Data := TMessage.Create(AMessage, OutlookDataFormat.Storages[i]);
…
also in function ViewMessage
for j := 0 to Rows.aRow[i].cValues-1 do
begin
{$ifdef UNICODE}
{ TODO : TSPropValue.Value.lpszW is declared wrong }
Value := PWideChar(Rows.aRow[i].lpProps[0].Value.lpszW); – > EAccessViolation (item.data)
{$else}
Thanks for your help, i don't know what to do
I really like your Drag & Drop component 5.1 but I am not able to use it under the Creative Common license. I need a royalty free license that will allow me to use it in a closed source commercial application. Are you open to licensing it under alternate license in a conventional Delphi component model? If so how much would you license it for per developer? Thanks.
The license I'm using allows royalty free, closed source, commercial usage, but you can use the MPL license if you prefer.
Hi, I'm tried this package on Delphi 5. All works fine for me, thank You. But I'm find one big problem. Your components / demos does not work on Windows 7 64bit (tested on Outlook demo), the form does not accept drag. Please correct this.
Thank You, Petr
I'm looking at replacing my drag drop event that contains a loop which requires user interaction for each file dropped on the form. From everything I've read (and one of your previous posts) it's not good to do something modal in the
OnDropevent because I'm holding up the shell's thread.I've tried
PostMessageto self but the DataFormatAdapters are empty by the time my message handler fires. Do I need to save down the files myself to a temp location and process them in my message handler or is there a better way to accomplish this?Daniel
You're on the right track. Save a copy of the data somewhere, do a PostMessage and do your modal stuff in the message handler.
Hi Anders,
Thanks for a great set of components. Have you thought about providing them for Lazarus (Free Pascal) which could allow development for Macs?
The question has been asked before but I doubt that anything will happen.
I don't have the time or motivation and those that use Lazarus and FPC doesn't seem to care.
Thanks Anders - I understand your position.
I think you are wrong about Lazarus users not seeming to care though as I've now had a closer look at the Lazarus IDE and the good news is - there's a Form Boolean property called
AllowDropFileswhich allows easy drag and drop straight on to a form from another application window.The feature is really easy to set up - there's no need to set
DragModeor write any code forDragOverandDragDropevents. The only thing you have to do is write the code for theOnDropFilesevent.This is quite an impressive feature which does not appear to exist in the versions of Delphi that I've seen (D1 to D2009).
Although it's fine for most people I'm not sure I'd call it impressive. A
WM_DROPFILESwrapper (which I'm sure is what it is) can be done with something like 10-20 lines of code. A generic drag/drop implementation would be more like 10K-20K lines of code.Anyway, it's great that you found a solution.
I agree with you if you're thinking in the Windows box only. What impresses me is that Lazarus is cross platform - you can't use Windows API techniques to D&D in Mac OS!! Penile references to numbers of lines of code are irrelevant here.
Anyway, it's great that you've built such a good suite of components for Windows - I've used them before and they've been very reliable.
Thank You! Great Job!
————————–
Missed file in current release of DragDrop (20100129):
DragDrop\Demos\ShellContextMenuHandler\About.rc
Thanks. I'll make sure to get the file included for the next release.
I'm in China right now but I'll post a new version once I get back home. AFAIR there are a few other minor changes waiting to be released.
Love this component, but……
Recently upgraded to D2010 Architect. Installed version 5.1. Demo Project ComboTargetDemo, compiled and ran. From Outlook 2003 dragged attachment(text file) straight from email to drop area. Filename (
DropComboTarget1.Data.names[i]) is empty. Data is intact.Reproduced from more than one machine.
I have reproduced the problem and located the cause of it.
The problem is that the
TFileContentsStreamClipboardFormatclass reads the filenames from the ANSIFileGroupDescriptorclipboard format (CFSTR_FILEDESCRIPTORA) when compiled with an ANSI Delphi and from theFileGroupDescriptorWclipboard format (CFSTR_FILEDESCRIPTORW) when compiled with an Unicode Delphi.Unfortunately Outlook only supports the
FileGroupDescriptorformat.I will have a solution in the next release… but first I need to find out why this comment box is completely borked. Strange that nobody has mentioned it.
I now have a solution that works with both Ansi and Unicode Delphi. New release coming RSN…
Also, the comment box was only broken for me. I had changed Firefox's UserAgent setting and that broke TinyMCE. Duh!
Hi Anders,
I'm looking forward to the new release when it's ready.
I found a problem with
When the context menu contains more than one level of submenus the wrong clickevent could be fired. After looking for bugs in my code, I tracked it down to
TDropContextMenu. Maybe it's among the changes you've already made and in that case you can skip this post cause you probably have a better soluton than I.GetMenuItemnot returning the MenuItem that was actually clicked.I interpreted it as all items not being counted when getting ItemIndex from
LoWord(lpici.lpVerb). Maybe you have a better clue to what's really going on?I've solved the problem by creating a new function
GetClickedMenuItemin "DragDropContext.pas" and calling it instead ofGetMenuItemfrom withinInvokeCommand. So far it's been working and I've tested it with up to four submenu levels. Here's what the function looks like:Thanks for the feedback.
I wasn't aware of that problem and I'll review your fix for inclusion in the next release.
Try this fix instead:
In
TDropContextMenu.QueryContextMenuchange theTraverseprocedure like this:Hi, I just found Drag&Drop. Very nice. Can I donate some money, maybe $100? Do you take VISA?
What would help is a doc that explains a few things. I need to figure out what that
TDropDummyitem is all about. The Async mode makes sense but I need to understand the issue areas. (I am not aTThreadexpert, yet.)Thanks,
Bob Kondner
PS: I write some software used in electronic assembly. Just 1 guy with a shop and a small set of customers. But I do think I have some good ideas for the electronic design marketplace.
The TDropDummy component is just used to enable drag images on controls that are not drop targets. If you have specific questions wrt. asynchronous mode I'll be happy to help.
I'm afraid I don't have time to write documentation anymore. I'm a slow writer and from experience it takes me more time to document a feature than it takes to implement it. Instead I write examples.
That said, I do have some old help written for the V4 components. I guess that's better than nothing. I will see if I can HTMLify it and get it posted online.
Wrt donations I'd prefer a book or two. Much more personal and I avoid paying taxes (60%):
Thanks Anders.
The change in TraverseMenu is working well. I've succesfully used it in Delphi 7, 2007 and 2010.
I'm glad to get rid of the procedure I added.
Hi, maybe this problem is already solved and I did not find the solution. But in the demos when a file is MOVED with TDropFileSource from a ListView to Windows Explorer the ListView is not refreshed to indicate that the source files have been deleted. I've searched for an event to handle this but did not find one, also the OnAfterDrop event does not work for this purpose. Any advice?
Hi,
I was looking through the DropComboTarget and I understood all the drop types except "mfData".
It is read in via a stream. Can you tell me what common apps might generate this format? I assume it is for passing large sextions of data?
Thanks,
Bob Kondner
mfData is for the FileContents clipboard format. Many different applications can supply this format. It is always accompanied with the FileGroupDescriptor format.
You can use the Source Analyzer demo application to determine which formats an application can supply and the Target Analyzer to determine which formats it consumes.
Hi,
The context menu component does not work in Windows 7 64 bit.
After the dll has been registered, the menu doesn't appear in the explorer. It works perfectly in 32bit version.
Is there any special treatment for windows 64bit version ?
Thanks,
Armin
Shell extensions must match the "bitness" of the OS. I.e. for 64-bit Windows you need a 64-bit compiler. Sorry.
Hi,
On ocassion when debugging an app, the app nolong responds that it can accept a drop. Restart of app or Delphi does not help. A machien Restart helps. I probably trashed the drag thread. Any ideas What would do that? The drop even stores the droped info in a variable and returns. A timer is used to start the priocessing of the drop.
Any ideas where I went astray?
Thanks,
Bob Kondner
I haven't got a clue.
It could be a bug in my code, in your code or in the drop source. I've seen memory overwrite bugs do that. Logout/Login usually helps. It shouldn't be necessary to reboot.
hi i found the dragdrop component, works great.
i use the TDropComboTarget the only thing i noticed i cannot drop on non std delphi components like a virtualtreeview ? Can i do anything about that ?
AFAIR VirtualTreeView has its own COM based drag/drop handling but I think it also has a method or property you can use to disable it with.
Hi,
I am looking for a solution which can dragdrop
virtual files and folders which from ftp into explorer,
the example asyncSource very similar to it?
but the example only write stream to files ,
It can not creat folders .
I saw TDataformatAdapterSource has
DataFormatName –> TPIDLDataFormat
Did you have example about it ?
Just add a folder to the filename when it's added to the drop source.
E.g. instead of dragging "foo.txt" you drag "bar\foo.txt".
When debugging in Delphi 2010 (CustomFormat1 demo) I notice that dragging to anywhere else but the correct spot locks up the program and the IDE. When program is killed in the Task Manager the IDE comes to life again. When the program exe is run outside of IDE it works like its supposed to. This makes debugging difficult.
This is caused by a bug in the debugger. The problem only occurs when you drag across the IDE while debugging (so don't do that).
What you are seeing is a dead lock. I believe it's caused by the debugger suspending the debugged application while the IDE handles the drag/drop operation. Since the debugged application is the source of the drop, the IDE waits forever for the drop source to deliver the data.
The problem has been reported in QC:
Report No: 62190 (RAID: 236101) Status: Open
IDE deadlock when debugging COM drop source
http://qc.codegear.com/wc/qcmain.aspx?d=62190
Report No: 23749 (RAID: unavailable) Status: Open
Debugger hang up when OleDragSource drags over IDE
http://qc.codegear.com/wc/qcmain.aspx?d=23749
Hi,
I was working with a TDropComboTarget object and I noticed that a drop of a URL from IE8 results in a Text property with a lot of zeros on the end. I saw your notes about some apps passing binary data and I saw the TrimZero property in TCustomAnsiStringClipboardFormat . Is this TrimZeroes the "Correct" way to resolve the extra Zeros. I was taking them out myself but that seems like a hack.
When it comes to OOPs design in Delphi I am still at Bozo level, could you explain how I access that TrimZeros prperty from the applications level. It seems deeply buried down in the base class.
Also, I would also like to extract the filename from a drop of an Outlook attachement. The data I can read using your example code the Name comes in blank. Can you point me in the right direction to implement this in the TDropComboTarget framework. Again, I realize this might not be the "Correct" location though the TDropComboTarget seems like such a nice application interface point. I can see the file name in the FileGroupDescriptor I just do not see it surfaced in the TDropComboTarget. I would think it should end up in Data.Names property.
Thanks,
Bob Kondner
PS: You have two wish list items on the way. The US wish list needs an address, I could not ship from the US list. I used the UK list.
I'm afraid the
TrimZeroesproperty is for the classes internal use but I'll see if I can do something about getting rid of the zeroes in the URL. In the mean time you can easily trim them yourself by casting the string to aPChar:I'm leaving on a weeks vacation in about 5 minutes so I don't have time to check the Outlook attachment problem now, but I'll look into it when I get back. Please ping me if I haven't responded within 10 days.
Thanks for the books.
I just now noticed that you were referring to the
Textproperty and not theURLproperty.The
URLproperty get its data from theTAnsiURLClipboardFormatclass which, because it is derived fromTCustomAnsiTextClipboardFormat, hasTrimZeroesset to True by default.The
Textproperty get its data, in the case of an URL dropped from IE, from theTFileContentsClipboardFormatclass. This class does not, and should not, haveTrimZeroesset to True.TFileContentsClipboardFormatshould always make the raw data available.So the solution to your problem is simply to use the
URLproperty for URLs.Melander,
I want to thank you for providing these components. They are a big help for a lot of us.
There seems to be a bug in the
TDropComboTargetcomponent when used in D2010.When dragging a FileContents stream (in my case, from an attachment on an Outlook email) to my application, the name of the attachment is returned as an empty string. This DOES work okay in Turbo Delphi 2006. The name is what gets lost, the file stream itself seems to be okay.
My system is:
To re-produce the bug:
Fill in the following code:
If it works correctly, “Label1” will be replaced with the file name of the attachment. If it doesn’t work correctly, the label caption will go blank.
For whatever it is worth, the
TDropEmptyTargetandTDataFormatAdaptercombination does properly pick up the attachment file name in theFileNamesproperty in this situation.Thanks, David Hawk
After preparing this post, I noted it is similar to Bob Kondner’s post a couple days ago. I have provided a simple example to re-create the problem, and a suggestion that
TDropEmptyTargetandTDataFormatAdaptermight be used instead - a possible workaround for Bob, see the VirtualFileStream demo. Meanwhile - I hope you are enjoying your vacation!Bob,
Melander might have a better answer when he gets back from vacation, but I had the same problem (no filename from the drop of an Outlook attachment), and was able to get something working using TDropEmptyTarget and TDataFormatAdapter. Look at the VirtualFileStream demo and look at the code in the DropEmptyTarget1Drop method in main.pas. The FileNames[] property works properly here.
Best,
David Hawk
David,
Thanks for the idea, I did start with that approach but I am not yet at the level to completely understand how I would interwork the Adper class with the Drop Combo class. The Combo is so close and I would like to do something useful like maybe add the Outlook name surfacing to the Combo. That would be useful for everyone.
But, I need some pointers before I can do any serious useful work. And I need a few more read throughs on these tools in general. I am just not at the required level, yet!
Thanks,
Bob Kondner
rkondner circlewitha indexdesigns period_com
Hi Anders,
I just upgraded to version 5.1 of your great drag and drop components Suite. There are two issues in
droptarget.paswhich you may or may not want to fix. It is hard to say when something is a feature and when something is a bugDragOveris not called whenDragEnterreturnsDROPEFFECT_NONE.You write in line 530 in
Droptarget.pas>TCustomDropTarget.DragEnter()First, I can not find this anymore on MSDN (maybe Microsoft removed it), but most importantly not calling
DragOvercauses a problem in some situations.My application contains an component with thumbnails. When I drag one thumbnail over another to sort them, I do not want to accept drops on the dragged thumbnail itself, but only on the other thumbnails. I use
OnGetDropEffectto determine where dropping is allowed.With the current code when I start dragging a thumbnail it is rejected in
DragEnterbecause the thumbnail is dragged over itself. Now when I move the cursor to the neighboring thumbnail the drop is still not accepted becauseDragOveris never called due to the initial rejection. This is why I commented this code out:Droptarget.pas>TCustomDropTarget.DragEnter(), line: 536FNoScrollZoneonly calculated inDragEnterFNoScrollZoneis only calculated inDragEnter. However, sometimes a component resizes while dragging causing scrollbars to appear while dragging. In this case scrolling does not work.An example of a resizing component is a treeview where nodes autoexpand while dragging over them.
FNoScrollZoneshould be calculated inDragOvertoo. Or it should be recalculated when a component that is dragged over resizes.Those are two rather exotic cases so I can understand it if you leave things as they are.
Hi Jan,
IMO the problem isn't really that
DragOverdoesn't get called if the drop is rejected inDragEnter. The problem is that you are rejecting the drop prematurely and misusing theOnGetDropEffectevent.OnGetDropEffectis primarily meant to be used to change the drop mode (copy/move/link/scroll) based on for example shift state.A simply solution to your problem would be to avoid using
OnGetDropEffectand instead use theEffectparameter of theOnEnterandOnDragOverevents. InOnEnteryou can decide if the drag should be completely rejected based on target state or the content of the data being dragged. InOnDropOveryou can accept or reject the drag based on f.ex. mouse position.I have released version 5.2.
Been using your componet for a while - its great! However, we have found it doesn't work to well in windows 7. XP yes, windows 7 no - don't know about vista. Even in your outlooktarget demo it doesn't recognize that a drop can occur.
Any ideas?
Thanks in Advance
I don't use Vista or Windows 7 so I'm afraid I can't reproduce your problem, but from what I've heard UAC has pretty much crippled drag/drop.
Please read this post. Does that help?
Hello Anders,
First of all, thank you for having developed these highly useful components.
I have a technical question about the Async Data Tranfer - Drop Target demo. In its current state, this demo app accepts only files from Outlook.
What change would be required for this app to accept also files from Windows Explorer? The answer may be quite simple. In any case I hope to be able to use the demo project as a starting point for my project and I am willing to pay for assistance. At this moment, however, I am stuck.
Thank you for your help.
Kind regards,
Stefan
The AsyncTransferTarget demo only support the
FileGroupDescriptorandFileContentsformats. The Explorer can accept these formats as a drop target but doesn't support them as a drop source.In order to make AsyncTransferTarget accept drops from the Explorer you must extend it with support for one of the formats offered by Explorer: CF_HDROP or Shell IDList (a PIDL list). See the Adapter demo for an example of how to do this.
Just discovered what the problem is. If you are trying to drag and drop under windows 7 (probably vista too) both dragger and dropper needs to be at the same security level. i.e. administrator,administrtor, or user,user. If they are not at the same level drag and drop doesn't work.
Yes, that was the point of the message I linked to, but It's good to get confirmation.
Thank you. I need one more piece of advice to be able to get started.
I use the AsyncTransferTarget as a basis for my application. The purpose is to transfer files to a network folder. Files have to be moved physically from Outlook to a folder.
In the AsyncTransferTarget demo application, I do not see where and how I have to modify the code or settings to achieve this. I am overlooking something obvious. If I do, I apologise for my lack of knowledge. I have not been able to deduct from the VirtualFile demo either how to do this.
A code snippet would be very useful.
Thank you.
I think I understand what you are trying to do (drag attachments from Outlook to your application and write them to disk) but I'm afraid I don't understand what specifically it is you are asking for.
Please clarify.
Dear Anders, I am really stuck, and I am really sorry having to bother you.You have understood what I am trying to achieve: drag attachments from Outlook to my application and write them to disk.However, I have not been able to figure out from the VirtualFile demo how to physically move an attachment via my application to a location on the hard disk. My application is based on the async data transfer target demo.Your help would be greatly appreciated. If you could just send me some sample code, or indicate how to move an outlook attachment to any location, for example c:\temp, that would get me going.I am willing to pay for any expenses and your time, of course.Thank you.Regards,Stefan
All you need to do is save the stream containing the dropped data to a file.
Try modifying the AsyncTransferTarget demo like this (untested):