Drag&Drop from Outlook (Express) - Possible?

Just starting out? Need help? Post your questions and find answers here.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Drag&Drop from Outlook (Express) - Possible?

Post by srod »

IDataObject is just a definition for an interface; nothing more. In drag/drop operations the client has to implement the iDropTarget interface (I posted a simple example recently in Fangbeast's thread regarding drag/drop from explorer in Win 8.1). PB for Windows implements this interface as part of it's drag/drop library. Some of the methods of this interface are provided with an IDataObject object pointer which they can use to query the data being dragged etc. None of this is beyond Purebasic at all (as I showed with my aformentioned example).

So there is no limitation with PB here. If Outlook (or whatever program we are talking about) allows global drags then PB's drag/drop library should allow you to receive the drops. Once you identify the underlying clipboard format then EventDropType() and EventDropBuffer() etc. should allow you to get ahold of the data. If it turns out that PB cannot handle the dropped data through it's 'drop buffer', then you will probably need to implement IDropTarget yourself which, as I say, is not too difficult. See my aformentioned example if you need it, though there are others in these forums.
I may look like a mule, but I'm not a complete ass.
mesozorn
Enthusiast
Enthusiast
Posts: 171
Joined: Fri Feb 20, 2009 2:23 am

Re: Drag&Drop from Outlook (Express) - Possible?

Post by mesozorn »

Thanks for the reply, SROD. The problem seems to be that the only thing received through EventDropBuffer() is the pointer to a FileDescriptor structure in this case, and nothing more. That is only useful up to a point, since it gives you the filename and a few other attributes like size, creation time etc.. but nothing that can be used to ascertain or examine the memory location where the filecontent data resides.

I will take a look around for your code to see what is involved in implementing IDropTarget myself, as it does seem like PB's inherent commands only receive and process the one very limited filegroupdescriptor/filedescriptor data header set, and not the raw data itself.

Wish me luck...
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Drag&Drop from Outlook (Express) - Possible?

Post by srod »

If you do go down that path then know that in the \Drop() method of the iDropTarget class (which you implement yourself), the \GetData() method of the IDataObject which is provided by the drag source will fill in a STGMEDIUM structure. This is where you access the data dropped. Now the Purebasic drop library deals with a few possible storage mediums, notably bitmaps and hGlobals. In your case you may have to look at IStream or IStorage mediums which I am guessing PB overlooks.
I may look like a mule, but I'm not a complete ass.
mesozorn
Enthusiast
Enthusiast
Posts: 171
Joined: Fri Feb 20, 2009 2:23 am

Re: Drag&Drop from Outlook (Express) - Possible?

Post by mesozorn »

srod wrote:If you do go down that path then know that in the \Drop() method of the iDropTarget class (which you implement yourself), the \GetData() method of the IDataObject which is provided by the drag source will fill in a STGMEDIUM structure. This is where you access the data dropped. Now the Purebasic drop library deals with a few possible storage mediums, notably bitmaps and hGlobals. In your case you may have to look at IStream or IStorage mediums which I am guessing PB overlooks.
Crikey... both the above-described endeavour along with your original code which is presumably here:
http://www.purebasic.fr/english/viewtop ... 79#p436579

...are admittedly causing my eyes to glaze over from the sheer overwhelmingly unfamiliar parameters of the venture. What a lot of extraordinary extra rigmarole to go through just to drag-and-drop a file from Outlook! To handle a drag-dropped file from the regular Windows filesystem/explorer, two or three lines of native PB code. To handle a file drag-dropped from an Outlook email... 15,000 lines of hybrid API/C++ code to re-invent a very cumbersome wheel!

I am going to take my best shot at this, but something tells me it will take more code to accomplish this one little section of the program than the all of the program's other unrelated code put together. I have zero experience with C/C++ although I'm passingly familiar with it through MSDN documentation and examples, so the notion of implementing these complex classes from scratch is.... unappealing.

Still, I'm grateful for your help and guidance and will take a crack at it.. probably many months of trial and error ahead, but no other option seems available...

EDIT: Your example code is throwing an error because #PB_Label is not a recognized constant. What is the value of that supposed to be?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Drag&Drop from Outlook (Express) - Possible?

Post by srod »

#PB_Label is used with the 'Defined' compiler directive. As far as I know it has been in PB for a while, though I am using PB 5.21 LTS.

Feel free to remove all the CompilerIf / CompilerEndIf statements from the example though and it should run fine.

I wouldn't get hung up too much on c/c++ when dealing with COM, although it is fair to say that many c examples of using particular interfaces will translate directly to PB without too much hassle. Accessing COM classes is nothing to be scared of... at least not when you get used to it.
I may look like a mule, but I'm not a complete ass.
mesozorn
Enthusiast
Enthusiast
Posts: 171
Joined: Fri Feb 20, 2009 2:23 am

Re: Drag&Drop from Outlook (Express) - Possible?

Post by mesozorn »

srod wrote:#PB_Label is used with the 'Defined' compiler directive. As far as I know it has been in PB for a while, though I am using PB 5.21 LTS.

Feel free to remove all the CompilerIf / CompilerEndIf statements from the example though and it should run fine.

I wouldn't get hung up too much on c/c++ when dealing with COM, although it is fair to say that many c examples of using particular interfaces will translate directly to PB without too much hassle. Accessing COM classes is nothing to be scared of... at least not when you get used to it.
Heh, that is the catch right there... I'm completely unfamiliar with them so they are daunting. I've been programming for a couple of decades and can do many things capably enough, but venturing into brand new alien territory like COM when I've avoided it for aeons, always gives me headaches and nightmares for weeks. It is sort of the equivalent of someone who's spoken regular English fluently and effortlessly for years, suddenly encountering extremely obtuse-sounding medical jargon and feeling like an ignorant kindergarten pupil again.

But, no other way to learn I suppose...
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Drag&Drop from Outlook (Express) - Possible?

Post by srod »

I have just found some examples in VB 6 which would need reworking and combining with an iDropTarget interface implementation (such as the one in my example), but it is all here. It is a bit messy because you will need to deal with iStorage objects as well (though you will not need to implement them).

http://www.mvps.org/emorcillo/en/code/vb6/index.shtml

Scroll down to the 'Getting attachments from Outlook messages dropped on a form' listing. You can open the 'OutlookDragDrop.cls' class file in notepad.

Actually, thinking about it, I reckon you can use PB's drop library for getting ahold of the iStorage interface pointer which will give you access to the file contents etc. You just need to use RegisterClipboardFormat_() (as Sparkie did in his code in this thread) and then, in reference to Sparkie's code, look at the :

Code: Select all

Case cf_content
statement. From here we just need to second guess what PB throws into the EventDropBuffer(). If it is a STGMEDIUM structure then you basically have access to the iStorage interface... and this is where the hard work would start! ;)

The c# examples you linked to earlier have exactly the same kind of code, but a lot of the messier details (iStorage and the like) is hidden in .Net objects etc. The VB 6 code we have contains the most relevant code for PB as it doesn't hide much.

Afraid you do have a bit of a learning curve here. And all of this to deal with drops from just one program; Outlook! :) Can't blame PB though for the idiosyncrasies of Outlook mind. ;)
I may look like a mule, but I'm not a complete ass.
mesozorn
Enthusiast
Enthusiast
Posts: 171
Joined: Fri Feb 20, 2009 2:23 am

Re: Drag&Drop from Outlook (Express) - Possible?

Post by mesozorn »

srod wrote:Actually, thinking about it, I reckon you can use PB's drop library for getting ahold of the iStorage interface pointer which will give you access to the file contents etc. You just need to use RegisterClipboardFormat_() (as Sparkie did in his code in this thread) and then, in reference to Sparkie's code, look at the :

Code: Select all

Case cf_content
statement. From here we just need to second guess what PB throws into the EventDropBuffer(). If it is a STGMEDIUM structure then you basically have access to the iStorage interface... and this is where the hard work would start! ;)
Just want to start by saying a big thanks for helping out with this very obscure operational endeavour. I only post on the forum occasionally over the years but you've always been around and of great assistance and I really appreciate it.

The problem with the EventDropBuffer() in PB is that from extensive testing with Sparkie's example code as well as my own modifications, I can confirm that even with the proper clipboard formats registered and accepted in any given gadget/window, that "cf_content" select-case event is never, ever triggered when dropping a file attachment from Outlook, and the message requester contained in that section is never activated.

The only drop event that is ever triggered is cf_descrip, and as a result the only thing ever loaded into the EventDropBuffer within PB is a corresponding FILEGROUPDESCRIPTOR structure with its information about the file, but no access point to its actual raw data content. If cf_content were ever triggered it would make things a lot easier, but as things stand I think it's impossible to use PB's native drop handling to access an Outlook attachment.

So, it seems I will have to delve into the VB example code you linked in order to try to construct an appropriate custom handler to process attachments. A bit of a mystery why cf_descrip is never in fact activated at all, since you'd think it would be sent at some point by the drag source, but there you have it...
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Drag&Drop from Outlook (Express) - Possible?

Post by Thunder93 »

To drag an email entry from the email program and drop onto the Desktop or Windows Explorer screen, the saved file is of the raw data. As already stated, the attachments data resides in the raw data.

When an email is dropped, it is using a name just extracted from the email subject (except illegal characters usually replaced with something.)


Less is more.

Code: Select all

If OpenWindow(0, 0, 0, 700, 500, "Drag 'n' drop Outlook Express",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  ListIconGadget(1,  10, 10, 680, 100, "Drop Email here", 730)
  cf_email = RegisterClipboardFormat_("Internet Message (rfc822/rfc1522)")
  EnableGadgetDrop(1, cf_email, #PB_Drag_Copy)

  EnableGadgetDrop(1, #PB_Drop_Files, #PB_Drag_Copy)
  EditorGadget(2, 10, 120, 680, 370) 
  Repeat 
    event = WaitWindowEvent()
    If event = #PB_Event_GadgetDrop And EventGadget() = 1
      Select EventDropType()
        Case cf_email
          ClearGadgetItems(1)
          ClearGadgetItems(2)
          *buffer = EventDropBuffer()
          msg$ = PeekS(*buffer)
          subject = FindString(msg$, "Subject: ", 1) + 9
          eos = FindString(msg$, #CRLF$, subject)
          subject$ = Mid(msg$, subject, eos - subject)          
          AddGadgetItem(1, 0, "Subject: " +subject$)
          AddGadgetItem(2, 0, msg$)          
          
      EndSelect
    EndIf
  Until event = #PB_Event_CloseWindow
EndIf 
End
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
mesozorn
Enthusiast
Enthusiast
Posts: 171
Joined: Fri Feb 20, 2009 2:23 am

Re: Drag&Drop from Outlook (Express) - Possible?

Post by mesozorn »

Thunder93 wrote:To drag an email entry from the email program and drop onto the Desktop or Windows Explorer screen, the saved file is of the raw data. As already stated, the attachments data resides in the raw data.
When an email is dropped, it is using a name just extracted from the email subject (except illegal characters usually replaced with something.)
Less is more.
Sorry I should clarify... I am not dragging an email which includes an attachment from Outlook over to a PB program, but rather just the attachment itself, by itself, without the rest of the email.

In Outlook when viewing a message which contains an attachment, the attachment is shown in a small Listview type of control, and you can grab and drag that file ("whatever.pdf" for example) directly and drop it into another program. That is where the issue comes up with PB's drop handling and EventDropBuffer(). If a user were drag-dropping the .eml file itself things might work more easily, but that's not the scenario.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Drag&Drop from Outlook (Express) - Possible?

Post by Thunder93 »

I'll have to go back and re-read what you wanting now.

But if it's access to dropped attachments data, simply add (to my existing example) a new case for EventDropType()

Code: Select all

          Files$ = EventDropFiles()
          Count  = CountString(Files$, Chr(10)) + 1
          For i = 1 To Count
            AddGadgetItem(1, -1, "Files: " + StringField(Files$, i, Chr(10)))
            ;CopyFile(StringField(Files$, i, Chr(10)), "C:\"+GetFilePart(StringField(Files$, i, Chr(10))))   ;;;; Do whatever you like with the file or files...
          Next i
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
mesozorn
Enthusiast
Enthusiast
Posts: 171
Joined: Fri Feb 20, 2009 2:23 am

Re: Drag&Drop from Outlook (Express) - Possible?

Post by mesozorn »

Thunder93 wrote:I'll have to go back and re-read what you wanting now.

But if it's access to dropped attachments data, simply add (to my existing example) a new case for EventDropType()

Code: Select all

                  Case #PB_Drop_Files           
                    AddGadgetItem(1, -1, "Files: " + EventDropFiles())
                    CopyFile(EventDropFiles(), "C:\"+GetFilePart(EventDropFiles()))
Dropping a file attachment from Outlook into PB does not trigger a #PB_Drop_Files event. Outlook does this differently from Windows Explorer/Filesystem, which nicely cooperates and provides a Files-type drop event. Outlook only provides a cf_descrip event and this is more difficult to work with. It cannot be handled by EventDropFiles.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Drag&Drop from Outlook (Express) - Possible?

Post by Thunder93 »

Alright. Not using Outlook, I'm with Microsoft Windows Live Mail. The #PB_Drop_Files is triggered in this case.

I'll have to dig out my old XP laptop. :twisted:
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Drag&Drop from Outlook (Express) - Possible?

Post by Thunder93 »

srod code that uses OLE drop handling, Is working for Outlook Express Attachment drops. Also one of RASHAD's post uses DragQueryFile_ & #WM_DROPFILES – The old way. That also works nicely.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
mesozorn
Enthusiast
Enthusiast
Posts: 171
Joined: Fri Feb 20, 2009 2:23 am

Re: Drag&Drop from Outlook (Express) - Possible?

Post by mesozorn »

Thunder93 wrote:srod code that uses OLE drop handling, Is working for Outlook Express Attachment drops. Also one of RASHAD's post uses DragQueryFile_ & #WM_DROPFILES – The old way. That also works nicely.
On its own without any edits, srod's code linked above will not accept drag-drops from Outlook attachments at all, as per my tests. Dragging a file attachment from an Outlook message over to the program window from the example, will not even cause the mouse cursor to change into a drop-accept recognizable icon. The appropriate clipboard content format presumably needs to be registered/added to the handler procedure before it will accept drops of that type.

Dropping a file from the regular Windows filesystem/explorer works fine, as does presumably (per your report) dragging from Outlook Express, but regular non-express Outlook appears to behave in a manner entirely inconsistent with its more cooperative cousin.

I have not yet located/tried Rashad's code version, but will take a look and give it a try. Most likely an entire custom-constructed handler routine will need to be built as srod indicates above, so at least I have his code as a blueprint on which to expand.

The key however is that Outlook does not send the drag-target as a "file" at all, so all of the #WM_DROPFILES type triggers are likely to be useless in processing them. Instead it seems to send the dragged object as a memory stream, or some such similar godforsaken and unpalatable monstrosity, thus requiring a considerably greater degree of hoop-jumping in order to retrieve it.
Post Reply