 |

|
Hi, sorry to bother you again. But I've been working mostly on XP here with my program, but at this moment I'm testing it on Windows 2000. And the drag image does not appear. It doesn't do that in your demo project either.
Do you know anything about this problem? According to the documentation in msdn it should be supported. What've you been working with yourself? If you're also using 2000, then perhaps it's a problem with the computer over here.
Thanks.
|
|
|
|

|
Hi,
Interesting, there was one of the previous posts saying "No drag image on XP"
I've been using Windows 2000 and the image was there. But I've upgraded to Windows XP since then. I'll try next week when I have access to Win2k and let you know.
Thanks a lot
|
|
|
|

|
Yea, I saw that one too hehe.
Thanks for taking your time on testing it, I'd really appreciate it. I'll see if I can get someone to test it on another win2k machine in the meantime.
|
|
|
|

|
I tried it on win2k (sp4+latest updates). Both IDragSourceHelper::InitializeFromBitmap and IDragSourceHelper::InitializeFromWindow return E_FAIL. I remembered, it
did work on win2k that i used for development. You can see it from screenshot.
Maybe one of updates breaks it? Or maybe it doesn't like the bitmap given to it.
|
|
|
|

|
I don't know. I'm testing with SP3 here now, and it doesn't work.
I put in some debug lines, and GetLastError returns error #8: "Not enough storage is available to process this command.". Although I'm not so sure if this makes any sense when it comes to OLE.
The HRESULT returned ended up being an "Unspecified error". So that isn't very helpful either
|
|
|
|
|

|
Yes that's the correct behavior. The mouse cursor state is controlled by whatever drop target window the mouse is over and by the responses of that drop target. Otherwise how would user know if they can drop on underlying window or not? You can most likely change the default behavior. To provide your own cursor return S_OK from GiveFeedback. And draw image manually if you want it.
|
|
|
|
|

|
I never tried it myself. Try putting the code in GiveFeedback and returning S_OK
|
|
|
|

|
Hi, first of all: Great class!
Second: I had access violations when using it in an MFC project. The problem is the CEnumFormatEtc class. You've created on of your own, but apparently MFC also implements a class with the same name. So every time AddRef was called in CIDataObject::EnumFormatEtc() it somehow ended up in the destructor of MFC's version of CEnumFormatEtc (don't ask me how). Anyway, this kept raising an access violation all the time.
As a solution, I put all your classes in a seperate namespace, and that seemed to solve the problem.
|
|
|
|

|
Hi,
It's probably a good idea to bypass custom implementation of IEnumFORMATETC and use CreateFormatEnumerator instead:
http://msdn.microsoft.com/workshop/networking/moniker/reference/functions/createformatenumerator.asp
I only saw this function after the fact, otherwise I would have probably used it instead of custom implementation
Thanks a lot for the comments
|
|
|
|

|
Another thing. In the function CIDropTarget::QueryDrop() there is the part where you try to figure out what kind of drop effects are possible:
[code]
if(*pdwEffect == 0)
{
// ...
}
[/code]
The first thing you test for is whether there's a copy operation possible. Here a problem arises, if a drop target would accept both copy and move operations, the default action is copy instead of move. As far as I know, move would be the default operation if no modifier keys are being pressed (CTRL in particular).
The solution is simple, just switch the tests like this:
[code]
if (DROPEFFECT_MOVE & dwOKEffects)
*pdwEffect = DROPEFFECT_MOVE;
else if (DROPEFFECT_COPY & dwOKEffects)
*pdwEffect = DROPEFFECT_COPY;
[/code]
This way the default operation will become move, and copy will be the default when CTRL is held.
PS. How the heck do I get code sections without the <pre> tags? UBB doesn't seem to be working :/
Well, maybe UBB just doesn't work for me
|
|
|
|

|
oops Thanks for spotting this I think <pre> tag is the way
|
|
|
|

|
Eacht DragDrop Action (to an other application) leaves the CIDropSource.
The ReferenceCount of the CIDropSource is zero but the debugger dumps it!?
Detected memory leaks!
Dumping objects ->
{452} normal block at 0x00B47C28, 12 bytes long.
Data: < $b > 88 24 62 00 00 00 00 00 01 CD CD CD
Object dump complete.
Does anybody know the reason for this?
FPF
|
|
|
|

|
Hello, Are you using demo project from the article or your own code? I would suggest using new atldbgmem.h in atl7+ To use it in demo project, just include these two lines before any other includes in stdafx.h: #include <windows.h> #include <atldbgmem.h>
Put this line at the end of your WinMain, in demo project DragDrop.cpp: AtlDumpMemoryLeaks();
Run in debug mode (F5). Try same drag & drop as before. Exit the app normally. Then in the output window you should get the filename and line number that is causing the leak. For example i tried the demo project from this article, it only showed leaks from atlbase.h CDynamicStdCallThunk::Init. And it's only because global CAppModule _Module; is not destroyed yet at the point when dump memory leaks is called. If you do this for testing purposes in DragDrop.cpp: CAppModule _Module; struct C { ~C(){AtlDumpMemoryLeaks();} }; Then no leaks show up.
I hope that helps
|
|
|
|

|
Hi,
i'm using the code in an MFC application
where AtlDumpMemoryLeaks() could not be used.
AfxDumpMemoryLeaks() does the same job here.
But including additional traces i found the problem:
CIDropSource pdsrc is never AddRef and Released and thus not deleted.
Adding the following two lines fixes the problem.
LRESULT OnBegindrag(...)
{
CIDropSource* pdsrc = new CIDropSource;
CIDataObject* pdobj = new CIDataObject(pdsrc);
pdsrc->AddRef(); // added FPF
// Init the supported format
FORMATETC fmtetc = {0};
fmtetc.cfFormat = CF_TEXT;
fmtetc.dwAspect = DVASPECT_CONTENT;
fmtetc.lindex = -1;
fmtetc.tymed = TYMED_HGLOBAL;
// Init the medium used
STGMEDIUM medium = {0};
medium.tymed = TYMED_HGLOBAL;
// medium.hGlobal = init to something
// Add it to DataObject
pdobj->SetData(&fmtetc,&medium,TRUE); // Release the medium for me
// add more formats and medium if needed
// Initiate the Drag & Drop
::DoDragDrop(pdobj, pdsrc, DROPEFFECT_COPY, &dwEffect);
pdsrc->Release(); // added FPF
}
Thanks.
...and it works!
FPF
|
|
|
|

|
Yep, the demo project does that.
I hope you find these classes useful!
|
|
|
|

|
I want to drag a picture or text from my application and drop it onto an explorer window and I want it to be saved as a file. How do I do that
|
|
|
|

|
When I compiled this code, there are some errors happened.
The compiler environment is VC6, VS SP5, Win2K, WTL 7.0.
The errors are described as the following:
%VDDIR%\microsoft visual studio\vc98\wtl\include\atlframe.h(273) : error C2501: 'LPNMREBARCHEVRON' : 'identifier' : missing storage-class or type specifiers.
White Lie.
|
|
|
|

|
Does WTL 7 need the latest Platform SDK ? That's what it sounds like
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
|
|
|
|

|
I can't compile this code...
My compiler (VC6 SP4, Win2k) can't
find "IDragSourceHelper", "CLSID_DragDropHelper", and "IID_IDragSourceHelper".. What's more, I can't find them in any header by grepping.
I am writing a vanilla win32 app, no MFC... no ATL includes other than what the source code includes.
...help?
Brian
|
|
|
|

|
Hello Brian,
This is defined in ShlObj.h
of Platform SDK.
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
I only used CSimpleArray from atlbase.h
|
|
|
|

|
My English is poor. Sorry.
First, You are a very good programmer.
I need your advices.
I modify your source and test.
maildlg.h
----------------------------------------------------------------------
....
if(!m_listview.InitDragDrop())
return -1;
//{{ this is my code begin.
SHFILEINFO sfi;
HIMAGELIST himl;
ZeroMemory(&sfi, sizeof(SHFILEINFO) );
himl = (HIMAGELIST)SHGetFileInfo(_T("c:\\"), 0, &sfi, sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
m_listview.SetImageList(himl, LVSIL_SMALL);
//}} this is my code end.
m_listview.InsertColumn(0, "Column 1", LVCFMT_LEFT , 100, -1);
m_listview.InsertItem(0,"item1");
m_listview.InsertItem(1,"item2");
m_listview.InsertItem(2,"item3");
....
----------------------------------------------------------------------
When i drag list item with icon, Drag images are not full-colored.
InitializeFromWindow() don't return valid image.
What's problem?
|
|
|
|

|
Hi,
Very usefull class, thank you very much.
But when running on XP, I cannot see any image being dragged, although the drag and drop works.
|
|
|
|

|
My program is a DROP SOURCE.
I can drag a file from my app and drop it into Explorer
and the file is copied from it's original location to the explorer folder.
It works nice BUT is blocking the main thread of my app.
You can see this happen when you drag/drop big files: the DROP SOURCE is freezed and the UI becomes ugly (not redrawn...).
I've tried these things:
* Do drag/drop into another thread:
impossible: you can drag/drop only from the main thread (is this right ?)
* Try delayed rendering.
doesn't work: still in the main thread.
I know there is a solution because whe you drag a bg file frmom explorer
into another explorer it doesn't block either the source or target window.
Any idea ?
How to make DROP of big files non-blocking ??
|
|
|
|

|
Hi,
If your target is only winme+ and win2k+ then
you can look at IAsyncOperation. As far as i know
that's what current explorer uses. In older versions
i remeber it was freezing the explorer window.
Another easy thing to do is when you're asked for the Data,
create the thread for actual file copying and wait on the
thread handle to exit with let's say 1 sec intervals.
Meanwhile dispatch messages in between the waits. Just make sure
you don't start another drag/drop while you're already in one.
But you can queue it for example.
Thanx
|
|
|
|

|
Excellent !
That's what I was looking for.
It seems the default MFC implementation of a DropSource object does not have this interface. So I need to derive a new class to do it.
Maybe there is a way to do it using delayed rendering,
but nothing I tried worked.
Another question:
the documentation stated that any software with drag/drop enabled must be in COM's 'Single threaded model'.
Now say I need a 'Free Threaded model'. Am I stuck in this old COM model ?
Thks again for IAsyncOperation,
b.
|
|
|
|

|
Yep you're stuck with STA because
OLE Drag and Drop is initialized
by calling OleInitialize(),
which initializes COM to run in STA.
|
|
|
|

|
Ok I've implemented IAsyncOperation and it works nearly wonderfully.
The data transfer is done in a thread of the process where the drop occurs.
I only have one - big - problem:
The "EndOperation" method of IAsyncOperation is never called:
Release() and OnFinalRelease() are never called on the data object
and the data is never freed.
Maybe it's because of the MFC class ? (I derived from COleDataSource and just add the IAsyncOperation interface to it).
Thks,
B.
|
|
|
|

|
I am trying to implement a drag from Windows Explorer onto the window that i opend in my prog. I am running VC++ on win2k. When the drop on my window occurs, all i want is to popup a message that would display the File Name that i dragged. I have written some code n so far, the display only seems to get get me a Blank. I dont know what kind of FORMATETC values i should set for my kinda operation
|
|
|
|

|
I too want the same stuff. ....from explorer to my application...I ned to know what file i draged so as to copy to another location specific to my app.
any help is invited
reg
Philip
|
|
|
|

|
The clipboard format is CF_HDROP
hte FORMATETC you want is something like this:
FORMATETC.dwAspect = DVASPECT_CONTENT
FORMATETC.lindex = -1
FORMATETC.ptd = NULL
FORMATETC.tymed = TYMED_HGLOBAL
FORMATETC.cfFormat = CF_HDROP
get the IDataObject from the OLE Clipboard
call IDataObject::GetData passing in a FORMATETC (filled in like above) and a pointer to a
STGMEDIUM struct.
The STGMEDIUM.hGlobal is what you would pass in to the following function, along with a
vector of strings
I beleive this should work
HRESULT COMUtils::getPidlsFromHGlobal(const HGLOBAL HGlob, std::vector<std::string>& fileNames )
{
LPIDA pCIDA = NULL;
HRESULT result = E_FAIL;
pCIDA = LPIDA(GlobalLock(HGlob));
fileNames.clear();
int count = pCIDA->cidl;
for (int i=0;i < count; i++){
LPCITEMIDLIST pidlf = NULL;
pidlf = (LPCITEMIDLIST)( ((UINT)pCIDA) + pCIDA->aoffset[0]);
char pathf[MAX_PATH] = "";
SHGetPathFromIDList(pidlf, pathf);
String fixedPath( pathf );
LPCITEMIDLIST pidl = NULL;
pidl = (LPCITEMIDLIST)( ((UINT)pCIDA) + pCIDA->aoffset[i+1]);
char path[MAX_PATH] = "";
SHGetPathFromIDList(pidl, path);
String pidlPath( path );
int pos = pidlPath.find_last_of( "\\");
if ( pos != 0 ){
int strLength = pidlPath.length();
strLength -= pos;
String subStr = pidlPath.substr( pos, strLength );
if ( (subStr != "") && (subStr.length() > 0) ){
fixedPath += subStr;
fileNames.push_back( fixedPath );
result = S_OK;
}
}
}
GlobalUnlock(HGlob);
return result;
}
|
|
|
|

|
You can handle ON_WM_DROPFILES() signal which calls OnDropFiles() function with HDROP as a parameter. Then you can use DragQueryFile() function to get the number of files that were droppped into your app window and also the paths of the files that were dropped.
|
|
|
|

|
hi, i cant compile your project. Here is the error which occurs: fatal error RC1015: cannot open include file 'atlres.h' 'atlres.h' is included from dragdrop.rc Peter
|
|
|
|

|
The sample is written with "Windows Template Library WTL 3.1":
http://msdn.microsoft.com/downloads/sample.asp?url=/msdn-files/027/001/586/msdncompositedoc.xml
The source itself doesn't depend on it.
|
|
|
|

|
i want to save some picture to a file ,but i don't how to do with the droped data ,who can tell me ?
|
|
|
|

|
I want use our class, but on Winwows NT4.
Any idea to do?
|
|
|
|

|
Hi,
It should be usable under NT4.
Let me know.
|
|
|
|

|
1. ::CopyStgMedium can be used instead of ::OleDuplicateData. But it requires ie4.0.
So I used ::OleDuplicateData to make it more generic.
http://msdn.microsoft.com/library/psdk/com/ofn_oa2k_61gh.htm
http://msdn.microsoft.com/workshop/networking/moniker/reference/functions/CopyStgMedium.asp
2. ::CreateFormatEnumerator can be used instead of custom implementation of IEnumFORMATETC. It also
depends at least on ie3 to be installed.
http://msdn.microsoft.com/library/psdk/com/ofn_a2o_7zn6.htm
|
|
|
|
 |