Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / WinMobile

Using SHCameraCapture from a Pocket PC 2003 Application

5.00/5 (1 vote)
26 Mar 2009CPOL1 min read 35.5K   463  
This mini-series is a pair of articles on two scenarios using SHCameraCapture.

Introduction

This mini-series is a pair of articles on two scenarios using SHCameraCapture.

Background

The first one is called Using SHCameraCapture from a Pocket PC 2003 Application. This article describes the steps needed to access the SHCameraCapture API from a C++ project built for a Pocket PC 2003 device.

The second one is called What to do if SHCameraCapture Returns E_FAIL?. In this article, I describe my experiences with the API, and the way I could work around it in the end.

What’s the problem with using SHCameraCapture from a Pocket PC 2003 project? Well, you shouldn’t be doing it in the first place: SHCameraCapture is only available for Windows Mobile 5 and up. In my case, however, the application has to run on Pocket PC 2003 and newer devices, and it should gracefully degrade if the device is not the newest of platforms. Image capturing is such a feature: if the device has a camera, and its OS is WM5 or newer, it should support image capturing. If it is older, it should still work, without this feature.

So, we built the application for the ARM architecture, and we used the Pocket PC 2003 SDK (quite a pain, really). It means that the compiler does not know about this API, although the feature is there for most of our devices.

Here’s how to do it.

To access the API through COM, use the following code:

C++
#include "aygshell.h"

#if _WIN32_WCE < 0x0500
// We are compiling for a pre-WindowsMobile5 platform.

//////////////////////////////////////////////////////////////////////////////
//
// Interface for camera capture UI
//
// aygshell.dll is loaded dynamically to make compiling for PocketPC2003 possible.
// When executed on Windows Mobile 5 or later, tha camera is supported (by
// loading the aygshell.dll).

typedef enum {
 CAMERACAPTURE_MODE_STILL = 0,
 CAMERACAPTURE_MODE_VIDEOONLY,
 CAMERACAPTURE_MODE_VIDEOWITHAUDIO,
} CAMERACAPTURE_MODE;

typedef enum {
 CAMERACAPTURE_STILLQUALITY_DEFAULT = 0,
 CAMERACAPTURE_STILLQUALITY_LOW,
 CAMERACAPTURE_STILLQUALITY_NORMAL,
 CAMERACAPTURE_STILLQUALITY_HIGH,
} CAMERACAPTURE_STILLQUALITY;

typedef enum {
 CAMERACAPTURE_VIDEOTYPE_ALL = 0xFFFF,
 CAMERACAPTURE_VIDEOTYPE_STANDARD = 1,
 CAMERACAPTURE_VIDEOTYPE_MESSAGING = 2,
} CAMERACAPTURE_VIDEOTYPES;

typedef struct tagSHCAMERACAPTURE
{
 DWORD   cbSize;
 HWND    hwndOwner;
 TCHAR   szFile[MAX_PATH];   
 LPCTSTR pszInitialDir;
 LPCTSTR pszDefaultFileName;
 LPCTSTR pszTitle;
 CAMERACAPTURE_STILLQUALITY   StillQuality;
 CAMERACAPTURE_VIDEOTYPES   VideoTypes;
 DWORD   nResolutionWidth;
 DWORD   nResolutionHeight;
 DWORD   nVideoTimeLimit;
 CAMERACAPTURE_MODE   Mode;
} SHCAMERACAPTURE, *PSHCAMERACAPTURE;

HRESULT SHCameraCapture(PSHCAMERACAPTURE pshcc);

typedef HRESULT (*fnSHCameraCapture)(PSHCAMERACAPTURE pshcc);

// Wrapper for the SHCameraCapture method in aygshell.dll.
// It loads the dll, invokes SHCameraCapture(), and unloads the dll.
HRESULT SHCameraCapture(PSHCAMERACAPTURE pshcc);
#endif // _WIN32_WCE < 0x0500
        

#if _WIN32_WCE < 0x0500
// We are compiling for a pre-WindowsMobile5 platform.

//------------------------------------------------------------------
// Wrapper method for pre-Windows Mobile 5 platforms.
// The SHCameraCapture call exists on WM5, but not on previous WINCE OSs.
// This wrapper makes it available if the client supports it, even if we compile
// for Pocket PC 2003 clients.
//
// Parameters:
// pshcc - (Pointer to a ) PSHCAMERACAPTURE structure.
//        See the documentation of SHCameraCapture for details.
//
// Return value:
// HRESULT - See the documentation of SHCameraCapture for details.
// 
//------------------------------------------------------------------
HRESULT SHCameraCapture(PSHCAMERACAPTURE pshcc)
{
 HRESULT hr = S_OK;
 HINSTANCE hAygShell = LoadLibrary(TEXT("aygshell.dll"));
 fnSHCameraCapture funcSHCameraCapture = NULL;

 if (!hAygShell) {
  hr = HRESULT_FROM_WIN32(GetLastError());
  goto FuncExit;
 }

 funcSHCameraCapture =
  (fnSHCameraCapture)GetProcAddress(hAygShell, _T("SHCameraCapture"));

 if (!funcSHCameraCapture) {
  hr = HRESULT_FROM_WIN32(GetLastError());
  goto FuncExit;
 }

 // call the API now
 hr = funcSHCameraCapture(pshcc);
 // Possible errors returned:
 // E_INVALIDARG (0x80070057L)
 // E_OUTOFMEMORY 
 FuncExit:
 if (hAygShell) {
  FreeLibrary(hAygShell);
 }
 
 return hr;
}

#endif // _WIN32_WCE < 0x0500

Comment: for the above solution, I used someone's code from the web, but I couldn't find it again to add a reference. If you find that the method above resembles your code, please drop a comment, and I'll add a reference.

The first part of the code comes from Microsoft header files.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)