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:
#include "aygshell.h"
#if _WIN32_WCE < 0x0500
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);
HRESULT SHCameraCapture(PSHCAMERACAPTURE pshcc);
#endif // _WIN32_WCE < 0x0500
#if _WIN32_WCE < 0x0500
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;
}
hr = funcSHCameraCapture(pshcc);
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.