|
I recommend to use Simple MAPI as a way to send file attachments and still not worry about the user's email client itself.
RSS feed
|
|
|
|
|
instead of implementing the IDataObject (that has many bugs btw!) you can re-use the shell version. here is how.
#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), (static_cast<iunknown *="">(*(ppType)),reinterpret_cast<void**>(ppType))
HRESULT GetUIObjectByName(PCWSTR pszName, REFIID riid, void **ppv)
{
LPITEMIDLIST pidl;
HRESULT hr = SHParseDisplayName(pszName, NULL, &pidl, 0, NULL);
if (SUCCEEDED(hr))
{
IShellFolder *psf;
LPCITEMIDLIST pidlChild;
hr = SHBindToParent(pidl, IID_PPV_ARGS(&psf), &pidlChild);
if (SUCCEEDED(hr))
{
hr = psf->GetUIObjectOf(NULL, 1, &pidlChild, riid, NULL, ppv);
psf->Release();
}
CoTaskMemFree(pidl);
}
return hr;
}
// here is a sample use of the above helper to get the DataObject handler
IDataObject *pdtobj;
hr = GetUIObjectByName(TEXT("C:\\foo.txt"), IID_PPV_ARGS(&pdtobj));
if (SUCCEEDED(hr))
{
// use the data object here!
pdtobj->Release();
}
Chris Guzak (ms)
|
|
|
|
|
Thanks. I get the idea even though this code won't let them have (1) multiple file attachments (2) and from different folders.
I am especially reluctant to the shell API by the way, when you know that real world software often is required to work on both NT4.0 and other systems as well.
This article was posted since it was more like a technical challenge but I have to admit that, because of the asynchronous nature of the call this is made once you have a working IDataObject to play with, I used a simple MAPI code at a time I had to implement this as part of a software product. MAPI just managed the default client e-mail synchronously and thus worked best.
I have a question for you regarding IDataObject by the way. Do you regard it reliable somehow to play with IDataObject across process boundaries, instead of playing with the clipboard? More particularly, are you aware of any limitations (left aside the usual COM stuff) ? I am thinking of a replacement of some old code using the clipboard to pass pictures between two apps (Word and Excel, namely).
Thanks. It's good to see you post again!
RSS feed
|
|
|
|
|
You can pass multiple items from the same folder to ::GetUIObjectOf(). That adds some complexity but it can be done. You can also use the results folder to get the multiple items from different folders, but that is a more complicated thing to do.
CLSID_SendMail does not exist on NT 4.0 so you aren't going to get this to work on that platform anyway. in general you have to make a trade off of how much work you are going to do to support multiple platforms. at this point I hope most ISVs are choosing Win2K or above. the WinXP specific APIs that my sample uses can be implemented for down level platforms as they are built on top of existing shell name space architecture. (SHBindToParentIDList). I can post implementations of those if you are interested.
your data object implementation needs to be completed before this sample is going to work reliably. I know the bad QI impl will cause problems since the shell will QI the dataobject for interfaces to discover imore things about it (for example IMarshal!).
On your cross process question, IDataObject is often marshaled across processes, this is the case for drag and drop and the clipboard. of course your code needs to play nice to support this, for example continuing to dispatch messages. your sample calls Sleep() and that would likely be a problem, instead go into a GetMessage() loop.
Chris Guzak (ms)
|
|
|
|
|
|
Check out my implementation. I can send it to you.
|
|
|
|
|
Hi everybody
my knowledge of C is too poor to understand that pretty stuff. Is there a possibility to translate all of it in VB6 ?
Thanks
Ti
|
|
|
|
|
Did you download my implementation with source code?
|
|
|
|
|
This code seems to work on W2K but every XP system I've tested it on
GPFs deep in the system. I'm executing this from an MFC Dialog based app.
Any ideas ?
Thanks in advance
Tony Teveris
Gerber Scientific Products
Senior Software Engineer
Phone: 860 896 2073
Fax: 860 648 8214
83 Gerber Road West
South Windsor, CT 06074
|
|
|
|
|
I was wondering if anyone had investigated this using .NET (C#)
Chris Koiak
|
|
|
|
|
Sure. All works fine. Just use sources provided by jonny instead of link above (see forum for that sources), compile and include lib to your program (C# analogue of the next VB string:"Private Declare Function SendToDefaultEmail Lib "SendToLib.dll" (ByVal szPName$, ByVal szFFiles$) As Long")
, call SendToDefaultEmail routine within your C# sources, have a fun playing with it
|
|
|
|
|
You seem to have miss understood. I want to create the com addin using .NET to intercept the call. Is this posisble??
|
|
|
|
|
Hmm.. I guess it can cause a lot of trouble for you - but why not? There is one really significant thing needs to be implemented - CoCreateInstance(guidDropTarget, NULL, CLSCTX_ALL,IID_IDropTarget, (void **)&pDropTarget))
once you have this instance no problem to implement DragEnter / Drop. Just IMHO, do not want to check - my choice was to use dll call from my .NET project - it's fast and bugless (yep, laziest boy decision)
|
|
|
|
|
Doesnt work on XP Pro with Outlook Express 6
SendTo in Exporer does work
It fails on
if (pFormatetc->cfFormat != CF_HDROP || !pmedium)
return S_FALSE;
If I remove this line ie accept any format then
raises an access violation
Please mail me
golfer_scratch@hotmail.com
LostGolfBall
|
|
|
|
|
Did you try my version of the code?
|
|
|
|
|
No, I didnt see it, or yes I did see it but didnt realize whole program in it.
Will have a look, in the mean time I tried to get MAPI working, what a buggy piece of crap that is.
LostGolfBall
|
|
|
|
|
I got it compiled and zipped if you want it. I need email. If someone could give me a place to upload it so people could get it I'd leave it there.
|
|
|
|
|
johnnycrash... oooo you good dude
Works on XP
I'm not sure what the difference is between your and Rods code, seems to be in using IDataObject in the shell, and not simulating (impl) the interface.
Probably some subtle change from NT to XP.
On NT I notice in Rods code it doesnt call unknown interface, but on XP it goes crazy. Naturally the shell on XP will know how to deal with the different conversation, and your code allows for that.
I think Rod had a fantastic "reverse engineering" idea, and I think you nailed the code.
I think you should mail your code to Rod and let him update this article with your alternative.
I took your code out of the DLL and ran it in a WTL app, on NT and XP, works.
Do have some questions, I dont really understand shell programming too good, IData on a collection of files seems strange to me. I was wondering if that collection can be across paths, or more to the point, do you think its possible to trick the shell into attaching files from different drives.
One solution is to create copies in a temp folder, but I was wondering anyway.
Anyway well done, I searched the web and found nothing like this... should call it RodsCrash technique.
Should also send it to Microsoft with a footnote, "if you still do C++, heres an idea"
LostGolfBall
|
|
|
|
|
HEY IT WORKS ON XP! You are the first to test it there. I hadn't got to it yet. Thanks!
I can't take much credit for this, Rod explained it all and reversed it waay cool. Fuchs (check his posts) worked on the xp thing by using the Seashell Code (that seashell guy is a shell god - you should download that code and check it out) but from what Fuchs was saying, Fuchs still was using Rods code (even though I don't think it was executing). I pretty much stared at all 3 of these guys' code for half a day and simplified it (I think). I'm not going to give microsoft any credit for making this easy, but it is kind of cool the way you can just hand it any file (after doing 50 pain in the arse steps that is) and get the already created interfaces. It actually does work if you pass it the full path and filename of any link in the "send to" folder instead of the classid of the drop target. It doesnt work for some reason if you pass it the full path and filename of the sendmail.dll.
I don't know didly about shell programming, and as a matter of fact, when they started sticking 'I' in front of everything a couple years back I just hid out in vb6 waiting for it all to go away. So this was my first attempt doing anything with GUID's and COM. From what I could tell about the IDataObject, it looks like it only supports one folder.
pFolder->GetUIObjectOf(NULL,cFiles,apIdlFiles,IID_IDataObject,NULL,(void**)&pDataObject)
"pFolder" implies the Idl's have to be relative to 1 folder. Then in GetUIObjectOf, MS says apIdlFiles is an "address of an array of pointers to ITEMIDLIST structures (I think it is really an array of pointers, not an address of an array), each of which uniquely identifies a file object or subfolder relative to the parent folder. Each item identifier list must contain exactly one SHITEMID structure followed by a terminating zero." Well if you can only give it an Idl that is one SHITEMID deep, then you can only provide files (or folders), no paths\filenames, since a path entry (entry1:\entry2\entry3\entry4.ext) counts as one (or more) SHITEMID's in an idl and a file would count as another. I tried to hand it longer Idl's and it barfed. So I ended up doing the temp folder thing, just like you said.
- Crash
|
|
|
|
|
You can see why rods IDataObject Implementation fails on XP, when you run your code on XP and attach jpegs, it doesnt just attach them, it asks you if you want to make them smaller because email will go quicker etc.
All that stuff I imagine means the IDataObject and the IDropTarget are having a huge conversation, even IPicture and stuff must get involved. Your way, that stuff doesnt matter.
One thing I have noticed and I'm not sure if it has anything to do with the shell, but if one allocates strings like
TCHAR *lpString = new TCHAR[500];
and then later
delete [] lpString;
it doesnt like it.
Probably have to use IMalloc and do things like you did it, which is totally foreign to me.
Anyway thanks again
LostGolfBall
|
|
|
|
|
Wow! Where did you see documentation about asking for smaller files? Amazing. Yeah, I pretty much figured if it was all done by the shell, then it should work everywhere. I think doing it the way I did is the way it was intended. Who knows, the dang thing is so complex. There are at least 50 ISomethingOrAnother interfaces in the shell api.
IMalloc. Whenever microsoft gives you a new way to allocate memory when using a set of functions, I always figure its a lot safer to use it. Differnent mechanisms to allocate memory use different heaps, local, global, shared memory, etc who knows. Wouldn't surprise me if new worked or if it didn't work. You can't tell till you try. It makes sense that it does not work, since it looks like there is some interprocess stuff going on. New is your local heap obviously.
Your welcome, thanks for testing it on XP.
By the way if you are going to use it for doing email attachements, and you don't know the email client, you might want to make the clsid for the drop target a setting that can be changed. Thats what I did. sendmail.dll seems to be used by eudora, outlook and outlook express. I downloaded a email client called calypso, and it did not use sendmail.dll. Calypso added their own send to link. I just change the classid to "c:\\blah\\blah\\calypsosendorsomething.lnk" and it works.
Also I noticed you can pass %program files% as the path. I think you can also pass %send to% as well. There are things called CSIDL's (search for CSIDL Values) that are paths to all the standard paths.
Johnnycrash
|
|
|
|
|
Thanks to everyone in this forum, I was able to make a dll that can be called from vb6 (in case anyone cares). This sure was a pain in the butt, without this article and subsequent posts, I never would have figured this out. If someone can tell me where to put it on some ftp site, I would love to upload it (compiled dll with all sourceode). Until then here is the source, and you can email me if you want the dll.
My method is a modification of the base method that requires no extra classes (yeah!), helper functions or anything. In the original example, stephan had to create a IDataObject derived class. In solving the XP problem, fuchs showed how the shell already has IDataObjects for files that you can use.
I think it is easy to understand (for com). It has to be since I knew diddly about c++ com programming until today. If I did some stupid stuff please tell me. I only tested this a couple times, so it probably has a bug. I will fix the bugs as I am using this in a deliverable, and I will repost.
Tested on Outlook express and Outlook.
Anyway, here is all the code
---------------------------------
vb code to call it. Throw this on a form with a button.
---------------------------------
Option Explicit
Private Declare Function SendToDefaultEmail Lib "xmain32b.dll" (ByVal szPName$, ByVal szFFiles$) As Long
Private Sub Command1_Click()
' separate multiple files with "|"
' must put path with backslash, files with no paths
SendToDefaultEmail "c:\", "boot.ini|bootlog.txt"
End Sub
---------------------------------
dll source code follows...
Use vc6 to make a simple win32 dll named xMain32b, and then replace stdafx.h and xmain32b.cpp with the below code, and add xmain32b.def.
---------------------------------
---------------------------------
xmain32b.cpp
---------------------------------
// xMain32b.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
// this guy is global because outlook express flips out if you kill this before hitting the send button.
IDropTarget *_pDropTarget = NULL;
BOOL APIENTRY DllMain(HANDLE hModule, DWORD fReason, LPVOID lpReserved)
{
HRESULT hr;
switch (fReason) {
case DLL_PROCESS_ATTACH:
OleInitialize (NULL);
// create an instance, and mimic drag-and-drop
hr = ::CoCreateInstance(INLINE_UUID( "9E56BE60-C50F-11CF-9A2C-00A0C90A90CE"),
NULL, CLSCTX_ALL,IID_IDropTarget, (void **)&_pDropTarget);
if (!SUCCEEDED(hr))
_pDropTarget = NULL;
break;
case DLL_PROCESS_DETACH:
if (_pDropTarget)
_pDropTarget->Release();
OleUninitialize ();
break;
}
return TRUE;
}
/*
launch default email client with one or more attachment files. All files must be in same dir.
szFFiles = null term string of one or more files, with files separated with "|", no trailing "|". This will get munged.
szPName = put path with backslash
Example:
1 file --> SendToDefaultEmail "c:\\", "boot.ini"
2 files --> SendToDefaultEmail "c:\\", "boot.ini|bootlog.txt"
*/
DllExport LONG WINAPI SendToDefaultEmail(char *szPName, char *szFFiles)
{
int cFiles, cbFiles, ich;
char *szFName;
IDataObject *pDataObject;
HRESULT hr = 0;
wchar_t wzPName[MAX_PATH];
wchar_t wzFName[MAX_PATH];
LPSHELLFOLDER pDeskTopFolder,pFolder;
LPITEMIDLIST pIdlFolder,pIdlFile;
LPCITEMIDLIST *apIdlFiles = NULL;
POINTL pt = {0,0};
DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE | DROPEFFECT_LINK;
if (!(cbFiles = strlen(szFFiles))) goto ExitFunc;
for (cFiles=1,ich=0 ; szFFiles[ich] ; ++ich)
if (szFFiles[ich] == '|')
++cFiles;
if (!(apIdlFiles = (LPCITEMIDLIST*)calloc(cFiles,sizeof(LPCITEMIDLIST)))) {
hr = -2;
goto ExitFunc;
}
// get any IShellFolder - desktop is convenient
if ((hr = SHGetDesktopFolder(&pDeskTopFolder)) != 0) goto ExitFunc;
// use that to Get a pidl for the folder.
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szPName,-1,wzPName,MAX_PATH);
if ((hr = pDeskTopFolder->ParseDisplayName(NULL, 0, wzPName, NULL, &pIdlFolder, NULL)) != 0) goto ExitFunc;
// use that to Get the IShellfolder for the folder containing the files
if ((hr = pDeskTopFolder->BindToObject(pIdlFolder,NULL,IID_IShellFolder,(void**)&pFolder)) != 0) goto ExitFunc;
// use that to Get the pidl for each file.
for (cFiles=0,szFName = strtok(szFFiles,"|") ; szFName ; szFName = strtok(NULL,"|")) {
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szFName,-1,wzFName,MAX_PATH);
if ((hr = pFolder->ParseDisplayName(NULL, 0, wzFName, NULL, &pIdlFile, NULL)) != 0) goto ExitFunc;
apIdlFiles[cFiles++] = pIdlFile;
}
// get the IDAtaObject for all the files.
if ((hr = pFolder->GetUIObjectOf(NULL,cFiles,apIdlFiles,IID_IDataObject,NULL,(void**)&pDataObject)) != 0) goto ExitFunc;
// serve up the drag and drop - our pDataObject onto _pDropTarget, the .mapimail drop target
if ((hr = _pDropTarget->DragEnter(pDataObject, MK_LBUTTON, pt, &dwEffect)) != 0) goto ExitFunc;
if (!dwEffect) {
hr = -1;
goto ExitFunc;
}
if ((hr = _pDropTarget->Drop(pDataObject, MK_LBUTTON, pt, &dwEffect)) != 0) goto ExitFunc;
ExitFunc:
if (apIdlFiles) free(apIdlFiles);
return hr;
}
---------------------------------
xmain32b.def
---------------------------------
LIBRARY OSRegExp01
DESCRIPTION "Implements usefull functions for openscan programs"
EXPORTS
SendToDefaultEmail @1
---------------------------------
stdafx.h
---------------------------------
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__F63181D9_FBE8_4BD0_8835_5EEC2FD181BB__INCLUDED_)
#define AFX_STDAFX_H__F63181D9_FBE8_4BD0_8835_5EEC2FD181BB__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Insert your headers here
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
// TODO: reference additional headers your program requires here
#include <ole2.h> // IDataObject
#include <shlobj.h> // DROPFILES
#include <tchar.h> // TCHAR
#define DllExport __declspec( dllexport )
extern "C" {
DllExport LONG WINAPI SendToDefaultEmail(char *szPFiles, char *szFFiles);
}
#define INLINE_UUID(x) __uuidof(struct __declspec(uuid(x)))
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__F63181D9_FBE8_4BD0_8835_5EEC2FD181BB__INCLUDED_)
|
|
|
|
|
Hey this thing removed all my indentation. Sorry!
|
|
|
|
|
I tested this on a couple email programs and it works fine for outlook, outlook express, and eudora. I downloaded a random email client calypso and of course, they don't follow the standard. Calypso adds their own entry "Calypso E-mail" to the send to menu. It is implemented by a shortcut put into the sendo to directory. I looked in the internet explorer settings dialog under Tools|Internet Options|Programs and Calypso is listed there. Calypso is hooked into the mailto url.
Can this code easily be modified to work with .lnk files...how do you get the IDropTarget interface?
|
|
|
|
|
Ok, this does it all. I am done. You can send to anything that supports IDropTarget. This includes GUID's, .lnk files, .dll files, .exe files, and maybe more, I don't know. I can send files to anything in the send to folder easily. Use this dll (or code) to mimic Send To | Mail Recipient. I still don't have an ftp site to upload the zip file with the compiled dll and source code, so eMail me if you want it.
main code file
<br />
<br />
#include "stdafx.h"<br />
<br />
BOOL APIENTRY DllMain(HANDLE hModule, DWORD fReason, LPVOID lpReserved)<br />
{<br />
return TRUE;<br />
}<br />
<br />
DllExport LONG WINAPI SendToDefaultEmail(char *szPName, char *szFFiles) <br />
{<br />
return SendToDropTarget("{9E56BE60-C50F-11CF-9A2C-00A0C90A90CE}",szPName,szFFiles);<br />
}<br />
<br />
DllExport LONG WINAPI SendToDropTarget(char *szFPOrGUIDDropTarget, char *szPName, char *szFFiles) <br />
{<br />
int iFile,<br />
cFiles, <br />
cbFiles,<br />
ich;<br />
DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE | DROPEFFECT_LINK;<br />
POINTL pt = {0,0};<br />
char *szFName;<br />
HRESULT hr = 0;<br />
wchar_t wzBuf[MAX_PATH];<br />
IDataObject *pDataObject = NULL;<br />
IDropTarget *pDropTarget = NULL;<br />
LPSHELLFOLDER pDeskTopFolder = NULL,<br />
pFolder = NULL;<br />
LPITEMIDLIST pIdlFolder = NULL,<br />
pIdlFile = NULL;<br />
LPCITEMIDLIST *apIdlFiles = NULL;<br />
LPMALLOC pMalloc = NULL;<br />
GUID guidDropTarget;<br />
<br />
SHGetMalloc(&pMalloc);<br />
<br />
if (!szFPOrGUIDDropTarget || !szFPOrGUIDDropTarget[0] || !szPName || !szPName[0] || <br />
!szFFiles || !(cbFiles = strlen(szFFiles))) goto ExitFunc;<br />
for (cFiles=1,ich=0 ; szFFiles[ich] ; ++ich)<br />
if (szFFiles[ich] == '|')<br />
++cFiles;<br />
if (!(apIdlFiles = (LPCITEMIDLIST*)calloc(cFiles,sizeof(LPCITEMIDLIST)))) {<br />
hr = -2;<br />
goto ExitFunc;<br />
}<br />
<br />
if ((hr = SHGetDesktopFolder(&pDeskTopFolder)) != 0) goto ExitFunc; <br />
<br />
<br />
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szFPOrGUIDDropTarget,-1,wzBuf,MAX_PATH);<br />
if (IIDFromString(wzBuf,&guidDropTarget) == S_OK) {<br />
if ((hr = CoCreateInstance(guidDropTarget, NULL, CLSCTX_ALL,IID_IDropTarget, (void **)&pDropTarget)) != 0) goto ExitFunc;<br />
} else {<br />
char szDDropTarget[MAX_PATH],szPDropTarget[MAX_PATH],szFDropTarget[MAX_PATH],szExtDropTarget[MAX_PATH] ;<br />
_splitpath(szFPOrGUIDDropTarget,szDDropTarget,szPDropTarget,szFDropTarget,szExtDropTarget);<br />
strcpy(szPDropTarget,strcat(szDDropTarget,szPDropTarget));<br />
strcat(szFDropTarget,szExtDropTarget);<br />
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szPDropTarget,-1,wzBuf,MAX_PATH);<br />
if ((hr = pDeskTopFolder->ParseDisplayName(NULL, 0, wzBuf, NULL, &pIdlFolder, NULL)) != 0) goto ExitFunc;<br />
if ((hr = pDeskTopFolder->BindToObject(pIdlFolder,NULL,IID_IShellFolder,(void**)&pFolder)) != 0) goto ExitFunc;<br />
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szFDropTarget,-1,wzBuf,MAX_PATH);<br />
if ((hr = pFolder->ParseDisplayName(NULL, 0, wzBuf, NULL, &pIdlFile, NULL)) != 0) goto ExitFunc;<br />
if ((hr = pFolder->GetUIObjectOf(NULL,1,(LPCITEMIDLIST*)&pIdlFile,IID_IDropTarget,NULL,(void**)&pDropTarget)) != 0) goto ExitFunc;<br />
pMalloc->Free(pIdlFile); <br />
pIdlFile = NULL;<br />
pMalloc->Free(pIdlFolder); <br />
pIdlFolder = NULL;<br />
pFolder->Release();<br />
pFolder = NULL;<br />
}<br />
<br />
<br />
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szPName,-1,wzBuf,MAX_PATH);<br />
if ((hr = pDeskTopFolder->ParseDisplayName(NULL, 0, wzBuf, NULL, &pIdlFolder, NULL)) != 0) goto ExitFunc;<br />
if ((hr = pDeskTopFolder->BindToObject(pIdlFolder,NULL,IID_IShellFolder,(void**)&pFolder)) != 0) goto ExitFunc;<br />
for (cFiles=0,szFName = strtok(szFFiles,"|") ; szFName ; szFName = strtok(NULL,"|")) {<br />
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szFName,-1,wzBuf,MAX_PATH);<br />
if ((hr = pFolder->ParseDisplayName(NULL, 0, wzBuf, NULL, &pIdlFile, NULL)) != 0) goto ExitFunc;<br />
apIdlFiles[cFiles++] = pIdlFile;<br />
}<br />
if ((hr = pFolder->GetUIObjectOf(NULL,cFiles,apIdlFiles,IID_IDataObject,NULL,(void**)&pDataObject)) != 0) goto ExitFunc;<br />
<br />
<br />
if ((hr = pDropTarget->DragEnter(pDataObject, MK_LBUTTON, pt, &dwEffect)) != 0) goto ExitFunc;<br />
if (!dwEffect) {<br />
hr = -1;<br />
goto ExitFunc;<br />
}<br />
if ((hr = pDropTarget->Drop(pDataObject, MK_LBUTTON, pt, &dwEffect)) != 0) goto ExitFunc;<br />
<br />
Sleep(100);<br />
<br />
ExitFunc:<br />
<br />
if (pDataObject) pDataObject->Release();<br />
if (apIdlFiles) {<br />
for (iFile = 0 ; iFile < cFiles ; ++iFile) <br />
if ((void*)apIdlFiles[iFile])<br />
pMalloc->Free((void*)apIdlFiles[iFile]);<br />
free(apIdlFiles);<br />
}<br />
if (pFolder) pFolder->Release();<br />
if (pIdlFolder) pMalloc->Free(pIdlFolder);<br />
if (pDropTarget) pDropTarget->Release();<br />
if (pMalloc) pMalloc->Release();<br />
if (pDeskTopFolder) pDeskTopFolder->Release();<br />
return hr;<br />
}<br />
header file:
<br />
<br />
#if !defined(AFX_STDAFX_H__F63181D9_FBE8_4BD0_8835_5EEC2FD181BB__INCLUDED_)<br />
#define AFX_STDAFX_H__F63181D9_FBE8_4BD0_8835_5EEC2FD181BB__INCLUDED_<br />
<br />
#if _MSC_VER > 1000<br />
#pragma once<br />
#endif // _MSC_VER > 1000<br />
<br />
<br />
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers<br />
<br />
#include <windows.h><br />
<br />
<br />
#include <ole2.h>
#include <shlobj.h>
#include <tchar.h>
<br />
#define DllExport __declspec( dllexport )<br />
extern "C" {<br />
DllExport LONG WINAPI SendToDefaultEmail(char *szPFiles, char *szFFiles);<br />
DllExport LONG WINAPI SendToDropTarget(char *szFPOrGUIDDropTarget, char *szPName, char *szFFiles);<br />
}<br />
<br />
#define INLINE_UUID(x) __uuidof(struct __declspec(uuid(x)))<br />
<br />
<br />
#endif // !defined(AFX_STDAFX_H__F63181D9_FBE8_4BD0_8835_5EEC2FD181BB__INCLUDED_)<br />
<br />
def file:
<br />
LIBRARY OSRegExp01<br />
DESCRIPTION "Implements Drop Target Functions"<br />
<br />
EXPORTS<br />
<br />
SendToDefaultEmail @1<br />
SendToDropTarget @2<br />
|
|
|
|
|