views:

181

answers:

1

Im writing a WPF application that wants to get access to a digital camera, and have been madly Googling around for solutions and Im pretty happy with how its all going.

This is what I have at the moment:

    private const decimal WM_DEVICECHANGE = 0x0219;
    private const int DBT_DEVTYP_HANDLE = 6;
    private const int DBT_DEVNODES_CHANGED = 7;
    private const int BROADCAST_QUERY_DENY = 0x424D5144;
    private const int DBT_DEVICEARRIVAL = 0x8000; // system detected a new device
    private const int DBT_DEVICEQUERYREMOVE = 0x8001;   // Preparing to remove (any program can disable the removal)
    private const int DBT_DEVICEREMOVECOMPLETE = 0x8004; // removed 
    private const int DBT_DEVTYP_VOLUME = 0x00000002; // drive type is logical volume

    protected override void OnSourceInitialized(EventArgs e)
    {
        base.OnSourceInitialized(e);
        var mainFormWinInteropHelper = new System.Windows.Interop.WindowInteropHelper(this);
        System.Windows.Interop.HwndSource.FromHwnd(mainFormWinInteropHelper.Handle).AddHook(HwndHandler);
    }

    private IntPtr HwndHandler(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
    {
        ProcessWinMessage(msg, wparam, lparam);
        handled = false;
        return IntPtr.Zero;
    }

    private void ProcessWinMessage(int msg, IntPtr wparam, IntPtr lparam)
    {
        int deviceType;
        char driveLetter;

        if (msg == WM_DEVICECHANGE)
        {
            var int32 = wparam.ToInt32();

            switch (int32)
            {
                case DBT_DEVICEARRIVAL:
                    Console.WriteLine("Device Arrival");
                    break;
                case DBT_DEVICEQUERYREMOVE:
                    Console.WriteLine("Device Query Removed");
                    break;
                case DBT_DEVICEREMOVECOMPLETE:
                    Console.WriteLine("Device Removed");
                    break;
                case DBT_DEVNODES_CHANGED:
                    Console.WriteLine("Device added or removed");
                    break;
            }
        }
    }

This actually all works great for my digital camera and I can get the photos off it. I should note at this time that when I plug in my camera, it appears in windows under the "devices with removable storage", and it has a drive letter allocated to it.

However, when I plugged in my iPhone to test it, the iPhone does not appears under that section, and does not appear to have a drive letter associated to it...

But here is my main question, why does the windows message DBT_DEVNODES_CHANGED fire when I add the iPhone, but the DBT_DEVICEARRIVAL message fires when I add the camera?

I would ideally like to be able to "get" files from any USB device when the user plugs it in.

Does anyone have any experience with this? My Win32 programming is very limited...

Cheers, Mark

+1  A: 

There are two kinds of USB media providers. The USB Mass Storage devices that act just like drives and Windows Media Devices for simple cameras and portable media players.

Some camera (usually the cheap ones) only implement the Windows Media Device model while others implement the USB Mass Storage model.

From what you explain, the iPhone is treated as a Windows Media Device while the camera is a USB Mass Storage. I know there is an "issues" with some Apple devices (notably the touch generation) suddenly switching to the WMD model when there are pictures or screenshots on the device. Try deleting any screenshots or pictures you've taken with the iPhone and see if it fixes the problem, if so, this is because your code doesn't support the Windows Media Devices model.

The MSDN library can help you sort through that mess. They updated the API several times, discontinued some parts of it, added more elsewhere and now it seems they have a new version that will fix-it-all TM.

Coincoin
Thanks, actually, I'm not too concerned about apple devices not working, I really just need cameras to work. I was more curious about it all, and if its going to be tough, then ill stick with digital cameras at this point in time.
Mark
The problem is most cameras support only the windows media devices model. Cameras acting as USB masss storage are the minority, or at best, they were the minority a few years back. Good luck with that.
Coincoin
I see, so how would I get to the files programatically on a media device?
Mark
Unfortunately, you don't get to the files. You transfer `media` data and then you can delete them. I included a link to the MSDN library.
Coincoin