CLOG

A coder's BLOG from Todd S. Murchison

Recent posts

Disclaimer

The opinions expressed herein are my own and do not represent any other individual or organization.

© Copyright 2010

Windows Mobile 5, CF1, and the camera dialog

So, you're coding a Mobile 5 app that uses Microsoft's canned camera dialog (because let's face it, DirectShow is not much fun), but you want to do most of your work in Compact Framework version 1 (let's all thank Microsoft for not shipping CF2 in time to be included with most mobile devices). Well, this can easily be done with a small amount of C++ code and a bit of interop.

The first thing you need to know is that, although Microsoft didn't get CF2 onto most Mobile 5 devices, they DID get that Camera Dialog in there. So the camera dialog is actually available on all Mobile 5 devices (as far as I know). The next thing you need to know is that the Win32 function you'll need is called SHCameraCapture(). This function is well documented in the MSDN libraries, etc.

The general approach to take is to code up a small C++ DLL to make the SHCameraCapture() call. You'll likely want to wrap the call in your own C++ DLL to simplify the interop calls from CF1. Beware the limitations of interop marshaling in CF1, CF2 interop is MUCH nicer. Here is a bit of sample code that might resemble a couple of the entry points in such a DLL:

//---------------------------------------------------------------------------------------------
extern "C" SCANRCAMERA_API WCHAR* fnCameraCapture(
    WCHAR* szInitialDir, WCHAR* szDefaultFileName, WCHAR* szTitle, int iWidth, int iHeight)
{
    WCHAR* szResultImagePath = new WCHAR[MAX_PATH];
    memset(szResultImagePath, '\0', MAX_PATH);

    HRESULT hResult;
    SHCAMERACAPTURE shcc;
    ZeroMemory(&shcc, sizeof(shcc));

    shcc.cbSize = sizeof(shcc);
    shcc.hwndOwner = GetActiveWindow();
    shcc.pszInitialDir = szInitialDir;
    shcc.pszDefaultFileName = szDefaultFileName;
    shcc.pszTitle = szTitle;
    shcc.nResolutionWidth = iWidth;
    shcc.nResolutionHeight = iHeight;
    shcc.Mode = CAMERACAPTURE_MODE_STILL;
    shcc.StillQuality = CAMERACAPTURE_STILLQUALITY_HIGH;

    // Display the Camera Capture dialog.
    hResult = SHCameraCapture(&shcc);

    if(hResult != S_OK) { return(NULL); }
    wcscpy(szResultImagePath, shcc.szFile);
    return(szResultImagePath);
}

//---------------------------------------------------------------------------------------------
extern "C" SCANRCAMERA_API void fnFreeMemory(void *p) {
    delete(p);
}

You will likely notice the odd "free memory" method my DLL is exposing. This is my favored way to make sure I'm dealing with allocated memory correctly while interoping from CF1. It's best to try not to leak too much memory while haphazardly bouncing back and forth between managed and unmanaged code. This will make more sense after having a look at the sample C# code that uses this DLL.

// Import the DLL entry points
[DllImport(@"CF1Camera.dll")]
public static extern IntPtr fnCameraCapture(
    String initialDir, String defaultFileName, String windowTitle, int imageWidth, int imageHeight);

[DllImport(@"CF1Camera.dll")]
public static extern void fnFreeMemory(IntPtr p);

// At some point later use your DLL
IntPtr imagePathPtr = fnCameraCapture(@"\Temp", "test.jpg", "Camera DLL Test", 800, 600);
if(imagePathPtr == IntPtr.Zero) {
    int win32ErrorCode = Marshal.GetLastWin32Error();
    throw (new ApplicationException("fnCameraCapture() failed. Error code: " + win32ErrorCode.ToString()));
}
string imagePath = Marshal.PtrToStringUni(imagePathPtr);
fnFreeMemory(imagePathPtr);

And there you go. You've just used the pre-packaged camera dialog to capture an image from CF1. Like I say, PInvoking from CF2 is a lot nicer. You could work your way through doing a direct PInvoke to SHCameraCapture() from CF1, but I found this approach to be much easier.

-Todd

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by toddm on Friday, July 28, 2006 6:56 AM
Permalink | Comments (0) | Post RSSRSS comment feed