www.pudn.com > WinCE_usbVideo.rar > CamTest2.cpp, change:2006-03-21,size:19081b


//====================================================================== 
// CamTest2 - A test program for a webcam driver 
// 
// Copyright (C) 2005 Douglas Boling 
// 
//====================================================================== 
#include <windows.h>                 // For all that Windows stuff 
#include <commctrl.h>                // Command bar includes 
#include <winioctl.h>                // Needed for CTLCODE macro 
 
#include "CamTest2.h"                // Program specific stuff 
#include "resource.h" 
#include "webcamsdk.h" 
#include "mjpeg2bmp.h" 
#include "CameraCode.h" 
 
int StreamToClientWindow (HWND hWnd); 
 
// 
// Debug zone support 
// 
#ifdef DEBUG 
// Debug zone structure 
DBGPARAM dpCurSettings = { 
    TEXT("CamTest2"), { 
    TEXT("Errors"),TEXT("Warnings"),TEXT("Functions"), TEXT("Init"), 
	TEXT("Driver Calls"),TEXT("USBLoad"),TEXT("Thread"),TEXT("Frame Info"),  
	TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined"), 
    TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined"), TEXT("Undefined") }, 
    0x0003 
}; 
#endif //DEBUG 
 
#define PIC_LEFT   5 
#define PIC_TOP    5 
 
#define MAXFORMATS  15 
  
//---------------------------------------------------------------------- 
// Global data 
// 
const TCHAR szAppName[] = TEXT("CamTest2"); 
HINSTANCE hInst;                     // Program instance handle 
//HWND hwndMain; 
// Message dispatch table for MainWindowProc 
const struct decodeUINT MainMessages[] = { 
	WM_SIZE, DoSizeMain, 
	WM_INITMENUPOPUP, DoInitMenuMain, 
	WM_COMMAND, DoCommandMain, 
    WM_PAINT, DoPaintMain, 
    WM_CREATE, DoCreateMain, 
    WM_DESTROY, DoDestroyMain, 
}; 
 
// Command message dispatch for MainWindowProc 
const struct decodeCMD MainCommandItems[] = { 
	ID_FILE_EXIT, DoMainCommandExit, 
	ID_CAMERA_STARTSTREAM, DoCommandStartStream, 
	ID_CAMERA_STOPSTREAM, DoCommandStopStream, 
	ID_CAMERA_SETTINGS,   DoCommandSetSettings, 
	ID_CAMERA_GETSTILLIMAGE, DoCommandGetStillImage, 
	ID_CAMERA_STOPDRAWING, DoCommandStopDrawing, 
 
	ID_CAMERA_IMAGESIZE_1, DoCommandImageSize, 
	ID_CAMERA_IMAGESIZE_1+1, DoCommandImageSize, 
	ID_CAMERA_IMAGESIZE_1+2, DoCommandImageSize, 
	ID_CAMERA_IMAGESIZE_1+3, DoCommandImageSize, 
	ID_CAMERA_IMAGESIZE_1+4, DoCommandImageSize, 
	ID_CAMERA_IMAGESIZE_1+5, DoCommandImageSize, 
	ID_CAMERA_IMAGESIZE_1+6, DoCommandImageSize, 
	ID_CAMERA_IMAGESIZE_1+7, DoCommandImageSize, 
	ID_CAMERA_IMAGESIZE_1+8, DoCommandImageSize, 
	ID_CAMERA_IMAGESIZE_1+9, DoCommandImageSize, 
	ID_CAMERA_IMAGESIZE_1+10, DoCommandImageSize, 
	ID_CAMERA_IMAGESIZE_1+11, DoCommandImageSize, 
	ID_CAMERA_IMAGESIZE_1+12, DoCommandImageSize, 
	ID_CAMERA_IMAGESIZE_1+13, DoCommandImageSize, 
	ID_CAMERA_IMAGESIZE_1+14, DoCommandImageSize, 
 
	ID_CAMERA_IMAGERATE_1, DoCommandImageRate,  // 9 image rates should be enough 
	ID_CAMERA_IMAGERATE_2, DoCommandImageRate, 
	ID_CAMERA_IMAGERATE_3, DoCommandImageRate, 
	ID_CAMERA_IMAGERATE_4, DoCommandImageRate, 
	ID_CAMERA_IMAGERATE_5, DoCommandImageRate, 
	ID_CAMERA_IMAGERATE_6, DoCommandImageRate, 
	ID_CAMERA_IMAGERATE_7, DoCommandImageRate, 
	ID_CAMERA_IMAGERATE_8, DoCommandImageRate, 
	ID_CAMERA_IMAGERATE_9, DoCommandImageRate, 
	ID_HELP_ABOUT, DoMainCommandAbout, 
}; 
 
HDC hdcMain; 
// Format of 1, 1, 3 is 160x120 at 15 fps 
WORD wFmt = 1; 
WORD wFrame = 1;     
WORD wInterval = 3; 
 
int nFmtCount = 0; 
FORMATPROPS Formats[MAXFORMATS]; 
 
HWND g_hwndMlDlg = 0;                // Handle to modeless dialog box 
BOOL fDraw = TRUE; 
 
//====================================================================== 
// 
// Program entry point 
// 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                    LPCMDLINE lpCmdLine, int nCmdShow) { 
    MSG msg; 
    int rc = 0; 
    HWND hwndMain; 
 
 
	// Get frame size from cmd line 
	wFrame = (WORD)_wtol (lpCmdLine); 
	if (wFrame == 0) 
		wFrame = 1; 
 
 
    // Initialize this instance. 
    hwndMain = InitInstance(hInstance, lpCmdLine, nCmdShow); 
    if (hwndMain == 0) 
        return 0x10; 
 
    // Application message loop 
     while (GetMessage (&msg, NULL, 0, 0)) { 
        // If modeless dialog box is created, let it have 
        // the first crack at the message. 
        if ((g_hwndMlDlg == 0) || 
            (!IsDialogMessage (g_hwndMlDlg, &msg))) { 
            TranslateMessage (&msg); 
            DispatchMessage (&msg); 
        } 
    } 
   // Instance cleanup 
    return TermInstance(hInstance, msg.wParam); 
} 
//---------------------------------------------------------------------- 
// InitInstance - Instance initialization 
// 
HWND InitInstance (HINSTANCE hInstance, LPCMDLINE lpCmdLine, int nCmdShow) { 
    HWND hWnd; 
	DWORD dwStyle; 
    WNDCLASS wc; 
	TCHAR sz[256]; 
 
    // Save program instance handle in global variable. 
    hInst = hInstance; 
	DEBUGREGISTER(hInst); 
 
	// See if we can talk to the camera 
	int rc = InitCamera (); 
	if (rc) 
	{ 
		wsprintf (sz, TEXT("Can't open camera driver.\r\nError code = %d") 
		          TEXT("\r\nIs the camera plugged in?\r\n"), rc); 
		MessageBox (NULL, sz, szAppName, MB_OK); 
		return 0; 
	} 
 
	// See if imaging library is installed with JPEG support 
	rc = InitDisplayFrame (TEXT("JPEG")); 
	if (rc == ERROR_NOT_SUPPORTED) 
	{ 
		MessageBox (NULL, TEXT("JPEG decoder not included in this build of the operating sytsem.") 
			        TEXT("\r\nJPEG support is required by this test application"), szAppName, MB_OK); 
		return 0; 
	}  
	else if (rc) 
	{ 
		wsprintf (sz, TEXT("An error occured loading the imaging library.\r\nError code = %d") 
		          TEXT("\r\nIs the imaging component in this build of Windows CE?\r\n"), rc); 
		MessageBox (NULL, sz, szAppName, MB_OK); 
		return 0; 
	} 
	else 
		ReleaseDisplayFrame ();  // Free up the object 
 
 
	// Get the number and data on video formats in camera 
	nFmtCount = dim (Formats); 
	rc = GetVideoFormats (Formats, &nFmtCount); 
	if (rc || (nFmtCount == 0)) 
	{ 
		wsprintf (sz, TEXT("The driver reports no format supported or an error getting formats.\r\nError code = %d"), 
		          rc); 
		MessageBox (NULL, sz, szAppName, MB_OK); 
		return 0; 
	} 
	if (Formats[0].wFormatType != VIDFORMAT_MJPEG) 
	{ 
		wsprintf (sz, TEXT("This test program only supports MJPEG stream formats.\r\n") 
		          TEXT("The driver reports format %d supported\r\n"), Formats[0].wFormatType); 
		MessageBox (NULL, sz, szAppName, MB_OK); 
		return 0; 
	} 
 
    // Register application main window class. 
    wc.style = CS_VREDRAW | CS_HREDRAW;       // Window style 
    wc.lpfnWndProc = MainWndProc;             // Callback function 
    wc.cbClsExtra = 0;                        // Extra class data 
    wc.cbWndExtra = 0;                        // Extra window data 
    wc.hInstance = hInstance;                 // Owner handle 
    wc.hIcon = NULL,                          // Application icon 
	wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Default cursor 
    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); 
    wc.lpszMenuName =  NULL;                  // Menu name 
    wc.lpszClassName = szAppName;             // Window class name 
 
    if (RegisterClass(&wc) == 0) return 0; 
 
 
	// Set style flags, this can't be done inline because CreateWindow is a macro 
	dwStyle = WS_VISIBLE; 
 
#ifndef _WIN32_WCE 
	dwStyle |= WS_OVERLAPPEDWINDOW; 
#endif //not WIN32_WCE 
 
    // Create main window. 
    hWnd = CreateWindow (szAppName,           // Window Class 
                         szAppName,           // Window Title 
                         dwStyle,             // Style flags 
						 CW_USEDEFAULT,       // x 
						 CW_USEDEFAULT,       // y 
						 CW_USEDEFAULT,       // cx 
						 CW_USEDEFAULT,       // cy 
                         NULL,                // Parent 
                         NULL,                // Menu/id 
                         hInstance,           // App instance 
                         NULL);               // Ptr to create params 
 
    // Return fail code if window not created. 
    if (!IsWindow (hWnd)) return 0; 
 
    // Standard show and update calls 
    ShowWindow (hWnd, nCmdShow); 
    UpdateWindow (hWnd); 
    return hWnd; 
} 
//---------------------------------------------------------------------- 
// TermInstance - Program cleanup 
// 
int TermInstance (HINSTANCE hInstance, int nDefRC)  
{ 
	ShutdownCamera (); 
    return nDefRC; 
} 
//====================================================================== 
// Message handling procedures for main window 
// 
 
//---------------------------------------------------------------------- 
// MainWndProc - Callback function for application window 
// 
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT wMsg, WPARAM wParam,  
                             LPARAM lParam) { 
    INT i; 
    // 
    // Search message list to see if we need to handle this 
    // message.  If in list, call procedure. 
    // 
    for (i = 0; i < dim(MainMessages); i++) { 
        if (wMsg == MainMessages[i].Code) 
            return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam); 
    } 
    return DefWindowProc(hWnd, wMsg, wParam, lParam); 
} 
//---------------------------------------------------------------------- 
// DoCreateMain - Process WM_CREATE message for window. 
// 
LRESULT DoCreateMain (HWND hWnd, UINT wMsg, WPARAM wParam,  
                      LPARAM lParam) { 
	int nHeight = 0; 
#ifdef USECMDBAR 
    HWND hwndCB; 
 
    // Create a command bar. 
    hwndCB = CommandBar_Create (hInst, hWnd, IDC_CMDBAR); 
	// Insert the menu. 
	CommandBar_InsertMenubar (hwndCB, hInst, IDR_MENU1, 0); 
    // Add exit button to command bar.  
    CommandBar_AddAdornments (hwndCB, 0, 0); 
 
	nHeight = CommandBar_Height (hwndCB); 
#endif // USECMDBAR 
 
	hdcMain = GetDC (hWnd); 
 
	StreamToClientWindow (hWnd); 
    return 0; 
} 
//---------------------------------------------------------------------- 
//  
// 
LRESULT DoDrawImageMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) 
{ 
	HDC hdc = GetDC(hWnd); 
	RECT rect; 
 
	SetRect (&rect, 5, 30, 200, 200); 
	DisplayFrame ((LPBYTE)wParam, 512, lParam, hdc, &rect); 
	ReleaseDC (hWnd, hdc); 
    return 0; 
} 
//---------------------------------------------------------------------- 
// DoSizeMain - Process WM_SIZE message for window. 
// 
LRESULT DoSizeMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) 
{ 
	return 0; 
} 
//---------------------------------------------------------------------- 
// DoInitMenuMain - Process WM_INITMENUPOPUP message for window. 
// 
LRESULT DoInitMenuMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) 
{ 
	HMENU hMenu = (HMENU)wParam; 
	int i; 
	TCHAR szName[128]; 
 
	HMENU hSub = GetSubMenu (hMenu, 3); 
	// Delete the old menu items 
	for (i = 0; ; i++) 
	{ 
		if (!DeleteMenu (hSub, ID_CAMERA_IMAGESIZE_1+i, MF_BYCOMMAND)) 
			break; 
	} 
 
	// Set the resolutions on the screen size sub menu 
	for (i = 0; (i < nFmtCount); i++) 
	{ 
		wsprintf (szName, TEXT("&%d  %d x %d"), i+1, Formats[i].dwWidth, Formats[i].dwHeight); 
		AppendMenu (hSub, MF_STRING, ID_CAMERA_IMAGESIZE_1+i, szName); 
 
		// Check the resolution currently in use 
		if (i+1 == wFrame) 
		{ 
			CheckMenuItem (hSub, ID_CAMERA_IMAGESIZE_1+i,  
			               MF_BYCOMMAND | MF_CHECKED); 
		} 
	} 
 
	hSub = GetSubMenu (hMenu, 4); 
	// Delete the old menu items 
	for (i = 0; ; i++) 
	{ 
		if (!DeleteMenu (hSub, ID_CAMERA_IMAGERATE_1+i, MF_BYCOMMAND)) 
			break; 
	} 
 
	// Set the frame speed on the Frame rate sub menu 
	if (Formats[wFrame-1].nNumInterval) 
	{ 
		for (i = 0; (i < Formats[wFrame-1].nNumInterval); i++) 
		{ 
			wsprintf (szName, TEXT("%d fps"), 1000/(Formats[wFrame-1].dwInterval[i]/10000)); 
			AppendMenu (hSub, MF_STRING, ID_CAMERA_IMAGERATE_1+i, szName); 
 
			if (i == wInterval) 
			{ 
				// Check the resolution currently in use 
				CheckMenuItem (hMenu, ID_CAMERA_IMAGERATE_1+i,  
							   MF_BYCOMMAND | MF_CHECKED ); 
			} 
		} 
	} 
	if (fDraw) 
		CheckMenuItem (hMenu, ID_CAMERA_STOPDRAWING,  
					   MF_BYCOMMAND | MF_UNCHECKED); 
	else 
		CheckMenuItem (hMenu, ID_CAMERA_STOPDRAWING,  
					   MF_BYCOMMAND | MF_CHECKED); 
		 
	return 0; 
} 
//---------------------------------------------------------------------- 
// DoCommandMain - Process WM_COMMAND message for window. 
//  
LRESULT DoCommandMain (HWND hWnd, UINT wMsg, WPARAM wParam,  
					   LPARAM lParam) { 
	WORD idItem, wNotifyCode; 
	HWND hwndCtl; 
	int  i; 
 
	// Parse the parameters. 
	idItem = (WORD) LOWORD (wParam); 
	wNotifyCode = (WORD) HIWORD (wParam); 
	hwndCtl = (HWND) lParam; 
 
	// Call routine to handle control message. 
	for (i = 0; i < dim(MainCommandItems); i++) { 
		if (idItem == MainCommandItems[i].Code) 
			return (*MainCommandItems[i].Fxn)(hWnd, idItem, hwndCtl,  
											  wNotifyCode); 
	} 
	return 0; 
} 
//---------------------------------------------------------------------- 
// DoPaintMain - Process WM_PAINT message for window. 
// 
LRESULT DoPaintMain (HWND hWnd, UINT wMsg, WPARAM wParam,  
                     LPARAM lParam) { 
    PAINTSTRUCT ps; 
    RECT rect; 
    HDC hdc; 
 
    // Adjust the size of the client rectangle to take into account 
    // the command bar height. 
    GetClientRect (hWnd, &rect); 
    rect.top += CommandBar_Height (GetDlgItem (hWnd, IDC_CMDBAR)); 
 
    hdc = BeginPaint (hWnd, &ps);  
 
 
    EndPaint (hWnd, &ps);  
    return 0; 
} 
//---------------------------------------------------------------------- 
// DoDestroyMain - Process WM_DESTROY message for window. 
// 
LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam,  
                       LPARAM lParam) { 
 
	StopStreaming (); 
 
	ReleaseDC (hWnd, hdcMain); 
 
    PostQuitMessage (0); 
    return 0; 
} 
//====================================================================== 
// Menu handlers 
// 
//---------------------------------------------------------------------- 
// DoMainCommandExit - Process Program Exit command. 
// 
LPARAM DoMainCommandExit (HWND hWnd, WORD idItem, HWND hwndCtl,  
						  WORD wNotifyCode) { 
	SendMessage (hWnd, WM_CLOSE, 0, 0); 
	return 0; 
} 
//---------------------------------------------------------------------- 
// DoCommandImageSize - Process Image size menu items 
// 
LPARAM DoCommandImageSize (HWND hWnd, WORD idItem, HWND hwndCtl,  
						   WORD wNotifyCode) { 
 
	// Stop the current stream 
	StopStreaming (); 
 
	// Get frame index 
	wFrame = idItem - ID_CAMERA_IMAGESIZE_1 + 1; 
 
	// Restart the stream 
	StreamToClientWindow (hWnd); 
	return 0; 
} 
//---------------------------------------------------------------------- 
// DoCommandImageRate - Process Image frame rate menu items 
// 
LPARAM DoCommandImageRate (HWND hWnd, WORD idItem, HWND hwndCtl,  
						   WORD wNotifyCode) { 
 
	// Stop the current stream 
	StopStreaming (); 
 
	// Get frame index 
	wInterval = idItem - ID_CAMERA_IMAGERATE_1; 
 
	// Restart the stream 
	StreamToClientWindow (hWnd); 
	return 0; 
} 
//---------------------------------------------------------------------- 
// DoCommandStartStream - Process Start Stream command 
// 
LPARAM DoCommandStartStream (HWND hWnd, WORD idItem, HWND hwndCtl,  
						     WORD wNotifyCode) { 
 
	// Start the stream 
	StreamToClientWindow (hWnd); 
	return 0; 
} 
//---------------------------------------------------------------------- 
// DoCommandStopDrawing -  
// 
LPARAM DoCommandStopDrawing (HWND hWnd, WORD idItem, HWND hwndCtl,  
						     WORD wNotifyCode) { 
	// Stop the stream 
	if (fDraw) 
		fDraw = FALSE; 
	else 
		fDraw = TRUE; 
	return 0; 
} 
 
//---------------------------------------------------------------------- 
// DoCommandStopStream - Process Stop Stream command 
// 
LPARAM DoCommandStopStream (HWND hWnd, WORD idItem, HWND hwndCtl,  
						     WORD wNotifyCode) { 
	// Stop the stream 
	StopStreaming (); 
	return 0; 
} 
 
//---------------------------------------------------------------------- 
// DoCommandGetStillImage -  
// 
LPARAM DoCommandGetStillImage (HWND hWnd, WORD idItem, HWND hwndCtl,  
						       WORD wNotifyCode)  
{ 
	LPBYTE pData = 0; 
	DWORD dwSize = 0; 
	FORMATPROPS fp; 
	STILLCAPDLGSTRUCT scStruct; 
	int rc; 
 
	// Display a dialog to get the format and file name 
	rc = DialogBoxParam (hInst, MAKEINTRESOURCE (IDD_STILLCAPDLG), 
		                 hWnd, StillCapDlgProc, (LPARAM)&scStruct); 
	if (rc == 0) 
		return 0; 
 
	// Set the busy cursor since this may take a bit 
	HCURSOR hOld = SetCursor (LoadCursor(NULL, IDC_WAIT)); 
 
	// Go get that image! 
	memset (&fp, 0, sizeof (fp)); 
 
	fp.wFormatIndex = scStruct.wFormat; 
	fp.wFrameIndex = scStruct.wFrame; 
 
	rc = GetStillImage (1, scStruct.wFrame, &fp, &pData, &dwSize); 
	if (rc == 0) 
	{ 
		// Write the file 
		rc = WriteJPEG (scStruct.szFileName, pData, dwSize); 
		if (rc != 0) 
			printf ("Error writing still image to file rc %d\r\n", rc); 
	} 
	else 
	{ 
		printf ("Error capturing still image rc %d\r\n", rc); 
	} 
	// Restore original cursor 
	SetCursor (hOld); 
 
	// Free the buffer 
	LocalFree (pData); 
 
	// Report to the user 
	TCHAR sz[256]; 
	if (rc == 0) 
		lstrcpy (sz, TEXT("Image file created")); 
	else if (rc == 258) 
		wsprintf (sz, TEXT("Timeout Error waiting for still.\r\n")); 
	else  
		wsprintf (sz, TEXT("Error capturing still.\r\nError %d"), rc); 
 
	MessageBox (hWnd, sz, szAppName, MB_OK); 
 
	return 0; 
} 
//---------------------------------------------------------------------- 
// DoCommandSetSettings -  
// 
LPARAM DoCommandSetSettings (HWND hWnd, WORD idItem, HWND hwndCtl,  
						     WORD wNotifyCode)  
{ 
    // Create dialog box only if not already created. 
	if (g_hwndMlDlg == 0) 
		// Use CreateDialog to create modeless dialog box. 
		g_hwndMlDlg = CreateDialog (hInst, MAKEINTRESOURCE (IDC_SETTINGS), hWnd, 
		                            SettingsDlgProc); 
 	return 0; 
} 
//---------------------------------------------------------------------- 
// DoMainCommandAbout - Process the Help | About menu command. 
// 
LPARAM DoMainCommandAbout(HWND hWnd, WORD idItem, HWND hwndCtl,  
						  WORD wNotifyCode) { 
	// Use DialogBox to create modal dialog. 
	MessageBox (hWnd, TEXT("CamTest 0.3\r\nCopyright 2005 Douglas Boling"), 
	            TEXT("About CamTest"), MB_OK); 
	return 0; 
} 
 
//---------------------------------------------------------------------- 
// Helper routine to reduce duplicated code.  Simply starts streaming 
// to a place 5 pixels from left and 5 down from cmd bar 
// 
int StreamToClientWindow (HWND hWnd) 
{ 
	int nHeight = 0; 
#ifdef USECMDBAR 
	nHeight = CommandBar_Height (GetDlgItem (hWnd, IDC_CMDBAR)); 
#endif 
 
	InvalidateRect (hWnd, NULL, NULL); 
 
	// Setting right and bot to 0 tells the code to use frame size 
	RECT rect; 
	SetRect (&rect, PIC_LEFT, nHeight + PIC_TOP, 0, 0); 
 
	// Find the frames per second value  
	DWORD dwFrameInterval = -1;  // Assume slowest interval 
	if (wInterval < Formats[wFrame].nNumInterval) 
		dwFrameInterval = Formats[wFrame].dwInterval[wInterval]; 
 
	StartStreaming (hdcMain, &rect, wFmt, wFrame, dwFrameInterval); 
	return 0; 
}