Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 833017
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T04:27:07+00:00 2026-05-15T04:27:07+00:00

I started trying to implement drag-and-drop of virtual files (from a C# 4/WPF app)

  • 0

I started trying to implement drag-and-drop of virtual files (from a C# 4/WPF app) with this codeproject tutorial. After spending some time trying to figure out a DV_E_FORMATETC error, I figured out I need to support the “Shell IDList Array” data format. But there seems to be next to zero documentation on what this format actually does.

After some searching, I found this page on advanced data transfer which said that a Shell IDList Array was a pointer to a CIDA structure. This CIDA structure then contains the number of PIDLs, and a list of offsets to them. So what the hell is a PIDL? After some more searching, this page sort of implies it’s a pointer to an ITEMIDLIST, which itself contains a single member that is a list of SHITEMIDs.

I did some more reading, I still can’t tell what multiple PIDLs are for, but there’s one SHITEMID for each “level” in the path. At least that’s one mystery solved.

My next idea was to try dragging a file from another application with virtual files (WinSCP). I just got a MemoryStream back for this format. At least I know what class to provide for the thing, but that doesn’t help at all for explaining what to put in it. I tried examining this MemoryStream based on the formats in the links above, but I’ve had no success. I just got back garbage data, and one of the ‘cb’ fields told me it was 18000 bytes long when the whole stream was only 539 bytes.

In addition, upon further reading, this page seems to imply that the data contained in a PIDL actually winds up being a path, and examining the contents of said MemoryStream in a hex editor yielded a path inside my local Temp directory (split into parts, anyway).

It seems that WinSCP just uses a shell extension to handle dropping on explorer, something I really don’t want to resort to. However, it has an alternate mode where it aborts the dragdrop until after it transfers to a temp folder – this is acceptable to me, but I haven’t the faintest idea how to do it.

My questions are now:

  1. What is a valid “abID” member for a SHITEMID? These virtual files only exist with my program; will the thing they are dragged to pass the “abID” back later when it executes GetData? Do they have to be system-unique?
  2. How can I manage the abort-and-redo-later drag and drop thing that WinSCP does?
  3. If I have to implement a shell extension for this, how would I even go about that? I’m sure I can easily find explanations of shell extension theory but how would I support custom PIDLs or whatever?

Any help or even links that explain what I should be doing would be greatly appreciated.

Edit: So here’s how I actually did it in the end:

I scrapped most of the code from the CodeProject tutorial above, keeping the functions for creating the FileGroupDescriptor. I then reimplemented the .Net IDataObject interface (and actually, I didn’t have to use the COM IDataObject interface at all). I then am forced to synchronously download the file in the background, and pass a MemoryStream back out from GetData(). Conveniently, the actual copying is in the background, but the waiting for data is in the foreground. Thanks, explorer. Any reasonably large files are slow, but for now it “works” which is more than I can say for the past few weeks.

I did try passing the PipeStream class I use internally for transfers, but explorer isn’t happy with this:

  • It tries to Seek, despite this class having CanSeek be false.
  • It ignores the size I send in the FileGroupDescriptor and just downloads whatever’s in the stream right now.

So, I’m not sure the ideal case is actually possible. Still, thanks for all of your help. I’m giving the bounty to JPW because his replies eventually set me on the right path.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-15T04:27:07+00:00Added an answer on May 15, 2026 at 4:27 am

    Disclaimer: I’m neither an expert in Windows Shell programming nor in COM programming, and especially not in COM programming using .NET.

    Disclaimer 2: Shell programming is rather complex and Windows Explorer is likely to crash. (Be sure to read the information on MSDN on debugging shell extensions.)

    This is what I can provide to answer your questions:

    1. The abID value of a SHITEMID is dertermined by the folder which contains the corresponding item. Therefore there a no valid or invalid information as this data is only meaingful to the folder. Windows Explorer will pass this data in order to identify a specific item. abID must not be system-unique but it will probably be unique in its containing folder (though this is not guaranteed). Under certain circumstances the SHITEMID may be persisted, so in some cases it must be valid after a reboot (because of this memory references in abID should be avoided).
    2. As I understand it, IDataObject::GetData will only be called if the actual data is required (and i may be wrong with this). So it should be fine, if you extract the data to a temp file in GetData and return a PIDL to that file (see http://support.microsoft.com/kb/132750/en-us, though I remember that there was a convinient method for this offered by the shall, but I can’t remember its name). Unfortunately I can’t see a good way on when to delete the temp file (as a last resort you could do this when the IDataObject is destroyed, but this will result in may temp files which are not needed anymore).
    3. You would probably need to support custom PIDLs (including a custom PIDL manager) and implement a custom IShellFolder. Most documentation on shell extensions, however, is for C++ and many functions are not documented very well or not documented at all. For more information on PIDLs I would recommend reading http://msdn.microsoft.com/en-us/library/cc144090.aspx . Furthermore you should search for “Shell namespace extension” on the Internet as there might be some information on the topic. Also have a look into the examples provided by Windows SDK on this topic.

    I hope some information will be usefull to you.

    Edit: You could also implement QueryGetData and EnumerableFormatEtc appropriately to indicate that your object does not support the format in question. Maybe Windows Explorer tries a different format then.

    Edit 2: Though you’ve already settled on a solution, here is a some more information on how to drag and drop asynchronously (for large files), maybe you (or at least somebody looking for an answer to a simulary problem, who reads this) find it useful: http://msdn.microsoft.com/en-us/library/bb776904(VS.85).aspx#async

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to implement simple Event Bus I started like this: public class RegistrationData
I'm trying to implement a SurfaceView , calling its onDraw() method from a Thread
Hi I'm trying to implement jquery token input according to railscasts #258 http://railscasts.com/episodes/258-token-fields Where
I'm trying to implement a checkpoint function to checkpoint a process. I do it
I've been trying to follow this Railscast: http://railscasts.com/episodes/213-calendars I've implemented the controls and all
I am attempting to pull some information from my tnsnames file using regex. I
After having read Ian Boyd 's constructor series questions ( 1 , 2 ,
I am trying to use MVVM in Silverlight, but I am quite new to
I have been trying to figure out why my AnimationListener events are not being
I am trying to develop a simple (?) application for N900 using Qt, but

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.