www.pudn.com > Twain.rar > Captest.c, change:1998-12-21,size:36497b


/* 
* File:         captest.c 
* RCS:          $Header: $ 
* Description:  Capability negotiation for Twacker 
* Author:       TWAIN Working Group 
* Created:      Feb 5,92 
* Modified:     " 
* Language:     C 
* Package:      N/A 
* Status:       Test tool 
* 
* (c) Copyright 1992, Hewlett-Packard Company, all rights reserved. 
* 
*	Copyright  1998 TWAIN Working Group: Adobe Systems Incorporated,  
*	Canon Information Systems, Eastman Kodak Company,  
*	Fujitsu Computer Products of America, Genoa Technology,  
*	Hewlett-Packard Company, Intel Corporation, Kofax Image Products,  
*	JFL Peripheral Solutions Inc., Ricoh Corporation, and Xerox Corporation.   
*	All rights reserved. 
*/ 
//---------------------------------------------------------------------- 
//                            I n c l u d e s 
//---------------------------------------------------------------------- 
#include <windows.h>         // Req. for twain.h type defs and ... 
#include <stdio.h>   
#include <stdlib.h> 
#include <string.h>  
#include <commdlg.h> 
 
#include "..\\twcommon\\twain.h" 
#include "..\\twcommon\\twndebug.h" 
 
#include "table.h" 
#include "dca_app.h" 
#include "dca_glue.h" 
#include "dca_acq.h" 
#include "captest.h"  
#include "special.h" 
 
#ifdef WIN32 
#include "res_32.h" 
#else 
#include "res_16.h" 
#endif 
 
#define CAP_AUTOFINAL CAP_CUSTOMBASE+1 
 
//---------------------------------------------------------------------- 
//                            V a r i a b l e s 
//---------------------------------------------------------------------- 
static int AutoFeedBOOL = FALSE; 
static int MessageLevelVAR = ERROR; //To display what is happening 
extern HWND g_hMainDlg; 
 
//---------------------------------------------------------------------- 
//                            F u n c t i o n s 
//---------------------------------------------------------------------- 
 
TW_UINT16 AltTWItemSize(TW_INT16 ItemType); 
 
void GetItem (char *Text, TW_UINT16 datatype, LPSTR pData); 
 
/* 
* Function: TWXferMech --  
* Author: TWAIN Working Group 
* Input: 
*		hWnd - handle to window 
* Output: 
*		TW_INT16 
* Comments: 
*		Set the current transfer mechanism for Twain based on the menus 
* that have been checked by the user. 
*/ 
TW_INT16 TWXferMech(HWND hWnd) 
 
{ 
	TW_CAPABILITY   cap; 
	pTW_ONEVALUE    pval = NULL; 
	TW_INT16        status = TWRC_FAILURE;   
	OPENFILENAME    ofn; 
	char szDirName[256]; 
	char szFile[256]; 
	char szFileTitle[256]; 
	char chReplace = '|'; 
	char szFilter[256]; 
	UINT i = 0, cbString = 0; 
 
	/* 
	*	Initialize all structures 
	*/ 
	memset(szDirName, 0, sizeof(char[256])); 
	memset(szFile, 0, sizeof(char[256])); 
	memset(szFileTitle, 0, sizeof(char[256])); 
	memset(szFilter, 0, sizeof(char[256])); 
	memset(&cap, 0, sizeof(TW_CAPABILITY)); 
	memset(&ofn, 0, sizeof(OPENFILENAME)); 
 
	ASSERT(hWnd); 
 
	LogMessage("TWXferMech\r\n"); 
 
	cap.Cap = ICAP_XFERMECH; 
	cap.ConType = TWON_ONEVALUE; 
 
	/* 
	* alloc the container 
	*/ 
	if (cap.hContainer = GlobalAlloc(GHND, sizeof(TW_ONEVALUE))) 
	{ 
		pval = (pTW_ONEVALUE)GlobalLock(cap.hContainer); 
		pval->ItemType = TWTY_UINT16; 
 
		if (GetMenuState (GetMenu (hWnd), TW_APP_BUFFER, MF_BYCOMMAND) & MF_CHECKED)        
		{ 
			/* 
			* memory transfer 
			*/ 
			pval->Item = TWSX_MEMORY; 
		} 
		else if (GetMenuState (GetMenu (hWnd), TW_APP_FILE, MF_BYCOMMAND) & MF_CHECKED)        
		{ 
			/* 
			* file transfer 
			*/ 
			pval->Item = TWSX_FILE; 
 
			/* 
			* file transfer currently fixed to bitmap format 
			* 
			* get the filename to save as 
			* check formats supported by the source             
			*/ 
 
			/* 
			*	Make sure only .bmp file extensions are possible 
			*/ 
			GetCurrentDirectory(sizeof(szDirName), szDirName); 
			szFile[0] = '\0'; 
			cbString = LoadString(hInst, IDS_FILTERSTRING, szFilter,  
										sizeof(szFilter)); 
			for(i = 0;szFilter[i] != '\0';i++) 
			{ 
				if(szFilter[i] == chReplace) 
				{ 
					szFilter[i] = '\0'; 
				} 
			} 
 
			memset(&ofn, 0, sizeof(OPENFILENAME)); 
 
			ofn.lStructSize = sizeof(OPENFILENAME); 
			ofn.hwndOwner = hWnd; 
			ofn.hInstance = NULL; 
			ofn.lpstrFilter = szFilter; 
			ofn.lpstrCustomFilter = (LPSTR)NULL; 
			ofn.nFilterIndex = 1; 
			ofn.lpstrFile = szFile; 
			ofn.nMaxFile = sizeof(szFile); 
			ofn.lpstrFileTitle = szFileTitle; 
			ofn.nMaxFileTitle = sizeof(szFileTitle); 
			ofn.lpstrInitialDir = szDirName; 
			ofn.lpstrTitle = (LPSTR)NULL; 
			ofn.Flags = OFN_SHOWHELP|OFN_OVERWRITEPROMPT; 
			ofn.nFileOffset = 0; 
			ofn.nFileExtension = 0; 
			ofn.lpstrDefExt = (LPSTR)"bmp"; 
			ofn.lCustData = 0L; 
			ofn.lpfnHook = NULL; 
			ofn.lpTemplateName = (LPSTR)NULL; 
 
			if (GetSaveFileName(&ofn)==FALSE) 
			{ 
				GlobalUnlock(cap.hContainer); 
				GlobalFree(cap.hContainer); 
				cap.hContainer = NULL; 
				return(TWRC_FAILURE); 
			} 
			else 
			{ 
				lstrcpy(Filename, szFileTitle); 
			} 
		} 
		else  
		{ 
			pval->Item = TWSX_NATIVE; 
		} 
 
		GlobalUnlock(cap.hContainer); 
 
		status = CallDSMEntry(&appID, 
						&dsID, 
						DG_CONTROL,  
						DAT_CAPABILITY,  
						MSG_SET, 
						(TW_MEMREF)&cap); 
 
		GlobalFree((HANDLE)cap.hContainer); 
 
		if (status != TWRC_SUCCESS) 
		{ 
			if (MessageLevel() >= ML_ERROR) 
			{ 
				ShowRC_CC(hWnd, 1, status, 1, "","MSG_SET of ICAP_XFERMECH");  
			} 
		}  
	} 
	else 
	{ 
		status = TWRC_FAILURE; 
		if (MessageLevel() >= ML_ERROR) 
		{ 
			ShowRC_CC(hWnd, 0, 0, 0, "Memory Allocation Failed","MSG_SET of ICAP_XFERMECH");  
		} 
	} 
	return status; 
}   
 
/* 
* Function: TWAutofeed --  
* Author: TWAIN Working Group 
* Input: 
*		hWnd - handle to window 
* Output: 
*		TW_INT16 
* Comments: 
*		Checks if the autofeed option on the FILE menu is 
* checked and if so begins a capability negotiation.  If the ADF is already 
* enabled, (check this) the return value is ??? otherwise the application 
* negotiates with the source to enable the capability 
* 
* If the ADF at the source cannot be enabled, the application should post an  
* error and not allow a transfer (ie: the Source's UI to come up). 
*/ 
TW_INT16 TWAutofeed(HWND hWnd) 
{ 
	TW_CAPABILITY   cap; 
	pTW_ONEVALUE    pval = NULL; 
	TW_INT16        status = TWRC_SUCCESS; 
	char            Details[128]; 
 
	memset(&cap, 0, sizeof(TW_CAPABILITY)); 
	memset(Details, 0, sizeof(char[128])); 
 
	ASSERT(hWnd); 
 
	AutoFeedBOOL = FALSE; 
	strcpy(Details, ""); 
 
	/* 
	* If Automatic Feeding > CAP_AUTOFEED On is checked 
	*/ 
	if (!(GetMenuState (GetMenu (hWnd), TW_APP_AUTOFEED, MF_BYCOMMAND) & MF_CHECKED)) 
	{ 
		return (status); 
	} 
 
	cap.Cap = CAP_FEEDERENABLED; 
	cap.ConType = TWON_ONEVALUE; 
 
	status = CallDSMEntry(&appID, 
					&dsID, 
					DG_CONTROL,  
					DAT_CAPABILITY,  
					MSG_GET, 
					(TW_MEMREF)&cap); 
 
	if (status != TWRC_SUCCESS) 
	{ 
		status = TWRC_FAILURE; 
		lstrcpy(Details, "CAP_FEEDERENABLED"); 
		GlobalFree(cap.hContainer); 
	} 
	else 
	{    
		pval = (pTW_ONEVALUE)GlobalLock(cap.hContainer); 
		if (pval->Item == TRUE) 
		{    
			/* 
			* Feeder is enabled no need to negotiate 
			*/ 
			GlobalUnlock(cap.hContainer); 
			GlobalFree((HANDLE)cap.hContainer);  
		} 
		else      
		{ 
			/* 
			* Negotiate with the source 
			* Try to turn on CAP_FEEDERENABLED 
			*/ 
			pval->ItemType = TWTY_BOOL; 
			pval->Item = TRUE; 
			GlobalUnlock(cap.hContainer); 
 
			status = CallDSMEntry(&appID, 
							&dsID, 
							DG_CONTROL,  
							DAT_CAPABILITY,  
							MSG_SET, 
							(TW_MEMREF)&cap); 
 
			/* 
			* free here because the GET call will allocate a new container 
			*/ 
			GlobalFree(cap.hContainer); 
 
			if (status == TWRC_SUCCESS) 
			{    
				/* 
				* Verify that CAP_FEEDERENABLED is now TRUE 
				*/ 
				status = CallDSMEntry(&appID, 
								&dsID, 
								DG_CONTROL,  
								DAT_CAPABILITY,  
								MSG_GET, 
								(TW_MEMREF)&cap); 
 
				if (status == TWRC_SUCCESS) 
				{ 
					pval = (pTW_ONEVALUE)GlobalLock(cap.hContainer); 
					if (pval->Item != TRUE)  
					{ 
						/* 
						* Verification failed -- CAP_FEEDERENABLED is FALSE even after successful set to TRUE 
						*/ 
						status = TWRC_FAILURE; 
						strcpy(Details, "CAP_FEEDERENABLED"); 
					} 
					GlobalUnlock(cap.hContainer); 
					GlobalFree((HANDLE)cap.hContainer);     
				} 
				else 
				{ 
					status = TWRC_FAILURE;                   
					strcpy(Details, "CAP_FEEDERENABLED");                    
				}                
			} 
			else 
			{     
				/* 
				* MSG_SET of CAP_FEEDERENABLED to TRUE did not succeed 
				*/ 
				strcpy(Details, "CAP_FEEDERENABLED"); 
				status = TWRC_FAILURE; 
			} 
		} 
 
		if (status == TWRC_SUCCESS) 
		{ 
			/* 
			* CAP_AUTOFEED 
			*/ 
			cap.Cap = CAP_AUTOFEED; 
			cap.ConType = TWON_ONEVALUE; 
 
			status = CallDSMEntry(&appID, 
							&dsID, 
							DG_CONTROL,  
							DAT_CAPABILITY,  
							MSG_GET, 
							(TW_MEMREF)&cap); 
 
			if (status != TWRC_SUCCESS) 
			{ 
				/* 
				* MSG_GET on CAP_AUTOFEED did not succeed 
				*/ 
				status = TWRC_FAILURE; 
				strcpy(Details, "CAP_AUTOFEED");             
			} 
 
			/* 
			* MSG_GET on CAP_AUTOFEED returned success 
			*/ 
			pval = (pTW_ONEVALUE)GlobalLock(cap.hContainer); 
			if (pval->Item == TRUE) 
			{ 
				/* 
				* CAP_AUTOFEED is on 
				*/ 
				GlobalUnlock(cap.hContainer); 
				GlobalFree((HANDLE)cap.hContainer);          
			} 
			else 
			{ 
				/* 
				* Try to set CAP_AUTOFEED to TRUE 
				*/ 
				pval->ItemType = TWTY_BOOL; 
				pval->Item = TRUE; 
				GlobalUnlock(cap.hContainer); 
 
				status = CallDSMEntry(&appID, 
									&dsID, 
									DG_CONTROL,  
									DAT_CAPABILITY,  
									MSG_SET, 
									(TW_MEMREF)&cap); 
 
				GlobalFree((HANDLE)cap.hContainer);      
 
				if (status == TWRC_SUCCESS) 
				{    
					/* 
					* Verify that CAP_AUTOFEED is on 
					*/ 
					status = CallDSMEntry(&appID, 
									&dsID, 
									DG_CONTROL,  
									DAT_CAPABILITY,  
									MSG_GET, 
									(TW_MEMREF)&cap); 
 
					if (status == TWRC_SUCCESS) 
					{ 
						pval = (pTW_ONEVALUE)GlobalLock(cap.hContainer); 
						if (pval->Item != TRUE) 
						{ 
							status = TWRC_FAILURE; 
							strcpy(Details, "CAP_AUTOFEED");             
							/* 
							* CAP_AUTOFEED returns FALSE even after succesful set to TRUE 
							*/ 
						} 
						GlobalUnlock(cap.hContainer); 
						GlobalFree((HANDLE)cap.hContainer);  
					} 
					else 
					{ 
						status = TWRC_FAILURE; 
						strcpy(Details, "CAP_AUTOFEED");             
					} 
				} 
				else 
				{ 
					/* 
					* MSG_SET of CAP_AUTOFEED to TRUE did not succeed 
					*/ 
					status = TWRC_FAILURE; 
					strcpy(Details, "CAP_AUTOFEED"); 
				} 
			}    
		}    
	}    
 
	/* 
	* Set Local Autofeed Variable on/off         
	*/ 
	if (status == TWRC_SUCCESS) 
	{ 
		AutoFeedBOOL = TRUE; 
	} 
	else 
	{ 
		AutoFeedBOOL = FALSE; 
		if (MessageLevel() >= ML_ERROR) 
		{ 
			ShowRC_CC(hWnd, 0, 0, 0, Details, "CAP_AUTOFEED ERROR"); 
		} 
	} 
	return status; 
}   
 
/////////////////////////////////////////////////////////////////////////// 
// FUNCTION: AutoFeedOn 
// 
// ARGS:    none 
// 
// RETURNS: current state of Source Manager (open/closed) 
// 
// NOTES:   Just a way to reduce the number of global vars 
// 
BOOL AutoFeedOn (VOID) 
{ 
	return (AutoFeedBOOL); 
} 
  
/////////////////////////////////////////////////////////////////////////// 
// Function: TWAutofeedMenu --  
// Author: TWAIN Working Group 
// Input: 
//		hWnd - handle to window 
// Output: 
//		TW_INT16 
// Comments: 
//		Set the current Autofeed Options and Flags based on the menus 
// that have been checked by the user. 
// 
TW_INT16 TWAutofeedMenu(HWND hWnd) 
{ 
	TW_INT16      status = TWRC_FAILURE; 
 
	ASSERT(hWnd); 
 
	status = TWAutofeed(hWnd); 
	return (status);     
} 
 
/* 
* Function: FloatToFIX32 --  
* Author: TWAIN Working Group 
* Input: 
*		floater - 
* Output: 
* TW_FIX32 
* Comments: 
*		Convert a floating point value into a FIX32. 
*/ 
TW_FIX32 FloatToFIX32(float floater) 
{ 
	TW_FIX32 Fix32_value; 
	TW_BOOL sign = (floater < 0)?TRUE:FALSE; 
	TW_INT32 value = (TW_INT32) (floater * 65536.0 + (sign?(-0.5):0.5)); 
 
	memset(&Fix32_value, 0, sizeof(TW_FIX32)); 
 
	Fix32_value.Whole = LOWORD(value >> 16); 
	Fix32_value.Frac = LOWORD(value & 0x0000ffffL); 
 
	return (Fix32_value); 
} 
 
/////////////////////////////////////////////////////////////////////////// 
// Function: FIX32ToFloat --  
// Author: TWAIN Working Group 
// Input: 
//		fix32 
// Output: 
//		float 
// Comments: 
//		Convert a FIX32 value into a floating point value 
// 
float FIX32ToFloat (TW_FIX32 fix32) 
{ 
	float   floater = 0; 
 
	floater = (float) fix32.Whole + (float) (fix32.Frac / 65536.0); 
	return(floater); 
} 
 
//////////////////////////////////////////////////////////////////////////// 
// Function: ShowImageInfo -- 
// Author: TWAIN Working Group 
// Input: 
//		hWndofApp - handle to window 
// Output: none 
// Comments: 
// 
void ShowImageInfo (HWND hWndofApp) 
{ 
	TW_UINT16       twRC = TWRC_FAILURE; 
	TW_UINT16       ccRC = TWRC_FAILURE; 
	TW_IMAGEINFO    twImageInfo; 
	char            Details [255]; 
	char            Details2 [1024]; 
	pTW_FIX32       pTWFix32 = NULL; 
	TW_UINT16       index = 0; 
 
	memset(&twImageInfo, 0, sizeof(TW_IMAGEINFO)); 
	memset(Details, 0, sizeof(char[255])); 
	memset(Details2, 0, sizeof(char[1024])); 
 
	ASSERT(hWndofApp); 
 
	// Check ImageInfo information 
	twRC = CallDSMEntry(&appID, 
					&dsID,  
					DG_IMAGE, 
					DAT_IMAGEINFO,  
					MSG_GET,  
					(TW_MEMREF)&twImageInfo); 
 
	//Return Code from Operation 
	wsprintf(Details2, "%s %d\n", "RETURN CODE:", twRC); 
 
	switch (twRC) 
	{ 
		case TWRC_SUCCESS: 
			sprintf (Details, "\n%s %.2f", "XResolution:", FIX32ToFloat(twImageInfo.XResolution)); 
			strcat(Details2, Details); 
 
			pTWFix32 = &(twImageInfo.YResolution); 
			sprintf (Details, "\n%s %.2f", "YResolution:", FIX32ToFloat(*pTWFix32)); 
			strcat(Details2, Details); 
 
			wsprintf (Details, "\n%s %ld", "ImageWidth:", twImageInfo.ImageWidth); 
			strcat(Details2, Details); 
 
			wsprintf (Details, "\n%s %ld", "ImageLength:", twImageInfo.ImageLength); 
			strcat(Details2, Details); 
 
			wsprintf (Details, "\n%s %d", "SamplesPerPixel:", twImageInfo.SamplesPerPixel); 
			strcat(Details2, Details); 
 
			wsprintf (Details, "\n%s %d", "BitsPerSample:", twImageInfo.BitsPerSample[0]); 
			strcat(Details2, Details); 
			for (index = 1; index < 8; index++) 
			{ 
				wsprintf (Details, ", %d", twImageInfo.BitsPerSample[index]); 
				strcat(Details2, Details); 
			}            
 
			wsprintf (Details, "\n%s %d", "BitsPerPixel:", twImageInfo.BitsPerPixel); 
			strcat(Details2, Details); 
 
			wsprintf (Details, "\n%s %d", "Planar:", twImageInfo.Planar); 
			strcat(Details2, Details); 
 
			wsprintf (Details, "\n%s %d", "PixelType:", twImageInfo.PixelType); 
			strcat(Details2, Details); 
 
			wsprintf (Details, "\n%s %d", "Compression:", twImageInfo.Compression); 
			strcat(Details2, Details); 
			break; 
 
		case TWRC_FAILURE: 
		default: 
			// determine details of failure from Source 
 
			if (ccRC == TWRC_SUCCESS) 
			{ 
				wsprintf(Details, "\n%s %d", "Condition Code:", gGlobalStatus.ConditionCode); 
				strcat(Details2, Details); 
			}  
			else  
			{ 
				wsprintf(Details, "\n%s", "Condition Code Check Failed"); 
				strcat(Details2, Details); 
			} 
			break; 
	} 
 
	ShowRC_CC(hWndofApp,0,0,0,Details2,"TW_IMAGEINFO"); 
	return; 
} 
 
//////////////////////////////////////////////////////////////////////////// 
// Function: ShowImageLayout 
// Author: TWAIN Working Group 
// Input: 
//		hWndofApp - handle to window 
// Output: none 
// Comments: 
// 
void ShowImageLayout (HWND hWndofApp) 
 
{ 
	TW_UINT16       twRC = TWRC_FAILURE; 
	TW_UINT16       ccRC = TWRC_FAILURE; 
	TW_IMAGELAYOUT  twImageLayout; 
	char            Details [255]; 
	char            Details2 [1024]; 
 
	memset(&twImageLayout, 0, sizeof(TW_IMAGELAYOUT)); 
	memset(Details, 0, sizeof(char[255])); 
	memset(Details2, 0, sizeof(char[1024])); 
 
	ASSERT(hWndofApp); 
 
	// Check ImageLayout information 
	twRC = CallDSMEntry(&appID, 
					&dsID,  
					DG_IMAGE, 
					DAT_IMAGELAYOUT,  
					MSG_GET,  
					(TW_MEMREF)&twImageLayout); 
 
	//Return Code from Operation 
	wsprintf(Details2, "%s %d\n", "RETURN CODE:", twRC); 
 
	switch (twRC) 
	{ 
		case TWRC_SUCCESS: 
			sprintf (Details, "\n%s %.2f", "Frame.Left:", FIX32ToFloat(twImageLayout.Frame.Left)); 
			strcat(Details2, Details); 
			sprintf (Details, "\n%s %.2f", "Frame.Top:", FIX32ToFloat(twImageLayout.Frame.Top)); 
			strcat(Details2, Details); 
			sprintf (Details, "\n%s %.2f", "Frame.Right:", FIX32ToFloat(twImageLayout.Frame.Right)); 
			strcat(Details2, Details); 
			sprintf (Details, "\n%s %.2f", "Frame.Bottom:", FIX32ToFloat(twImageLayout.Frame.Bottom)); 
			strcat(Details2, Details); 
 
			wsprintf (Details, "\n%s %d", "DocumentNumber:", twImageLayout.DocumentNumber); 
			strcat(Details2, Details); 
 
			wsprintf (Details, "\n%s %d", "PageNumber:", twImageLayout.PageNumber); 
			strcat(Details2, Details); 
 
			wsprintf (Details, "\n%s %d", "FrameNumber:", twImageLayout.FrameNumber); 
			strcat(Details2, Details); 
			break; 
 
		case TWRC_FAILURE: 
		default: 
			// determine details of failure from Source 
 
			if (ccRC == TWRC_SUCCESS) 
			{ 
				wsprintf(Details, "\n%s %d", "Condition Code:", gGlobalStatus.ConditionCode); 
				strcat(Details2, Details); 
			}  
			else  
			{ 
				wsprintf(Details, "\n%s", "Condition Code Check Failed"); 
				strcat(Details2, Details); 
			}                    
			break; 
	} 
 
	ShowRC_CC(hWndofApp,0,0,0,Details2,"TW_IMAGELAYOUT"); 
	return; 
} 
 
/////////////////////////////////////////////////////////////////////////// 
// Function: ShowTW_ID -- 
// Author: TWAIN Working Group 
// Input: 
//		hWndofApp - handle to window 
//		twID -  
//		text - pointer on 
// Output: none 
// Comments: 
// 
void ShowTW_ID (HWND hWndofApp, TW_IDENTITY twID, char *text) 
{ 
	char Details [255]; 
	char Details2 [1024]; 
 
	memset(Details, 0, sizeof(char[255])); 
	memset(Details2, 0, sizeof(char[1024])); 
 
	ASSERT(hWndofApp); 
	ASSERT(text); 
 
	wsprintf(Details2, "\n%s %d", "Id:", twID.Id); 
	wsprintf (Details, "\n%s %d", "TW_VERSION.MajorNum:", twID.Version.MajorNum); 
	strcat(Details2, Details); 
	wsprintf (Details, "\n%s %d", "TW_VERSION.MinorNum:", twID.Version.MinorNum); 
	strcat(Details2, Details); 
	wsprintf (Details, "\n%s %d", "TW_VERSION.Language:", twID.Version.Language); 
	strcat(Details2, Details); 
	wsprintf (Details, "\n%s %d", "TW_VERSION.Country:", twID.Version.Country); 
	strcat(Details2, Details); 
	wsprintf (Details, "\n%s %s", "TW_VERSION.Info:", twID.Version.Info); 
	strcat(Details2, Details); 
	wsprintf (Details, "\n%s %d", "ProtocolMajor:", twID.ProtocolMajor); 
	strcat(Details2, Details); 
	wsprintf (Details, "\n%s %d", "ProtocolMinor:", twID.ProtocolMinor); 
	strcat(Details2, Details); 
	wsprintf (Details, "\n%s %d", "SupportedGroups:", twID.SupportedGroups); 
	strcat(Details2, Details); 
	wsprintf (Details, "\n%s %s", "Manufacturer:", twID.Manufacturer); 
	strcat(Details2, Details); 
	wsprintf (Details, "\n%s %s", "ProductFamily:", twID.ProductFamily); 
	strcat(Details2, Details); 
	wsprintf (Details, "\n%s %s", "ProductName:", twID.ProductName); 
	strcat(Details2, Details); 
 
	ShowRC_CC(hWndofApp,0,0,0,Details2,text); 
	return; 
} 
 
//////////////////////////////////////////////////////////////////////////// 
// Function: ShowCapability -- 
// Author: TWAIN Working Group 
// Input: 
//		hWndofApp - handle to window 
//		Cap -  
// Output: none 
// Comments: 
// 
void ShowCapability (HWND hWndofApp, TW_UINT16 Cap) 
{ 
	TW_UINT16           twRC = TWRC_FAILURE; 
	TW_UINT16           ccRC = TWRC_FAILURE; 
	TW_CAPABILITY       twCapability; 
	char                Details [255]; 
	char                Details2 [1024]; 
	TW_UINT16           index = 0; 
	pTW_ENUMERATION     pEnum = NULL; 
	pTW_ONEVALUE        pOneV = NULL; 
	pTW_RANGE           pRange = NULL; 
	pTW_ARRAY           pArray = NULL; 
	LPSTR               pData = NULL; 
	TW_INT16            datasize = 0; 
 
	memset(&twCapability, 0, sizeof(TW_CAPABILITY)); 
	memset(Details, 0, sizeof(char[255])); 
	memset(Details2, 0, sizeof(char[1024])); 
 
	ASSERT(hWndofApp); 
 
	twCapability.Cap = Cap; 
	twCapability.ConType = TWON_DONTCARE16; 
 
	// Check Capability information 
	twRC = CallDSMEntry(&appID, 
					&dsID,  
					DG_CONTROL, 
					DAT_CAPABILITY,  
					MSG_GET,  
					(TW_MEMREF)&twCapability); 
 
	//Return Code from Operation 
	wsprintf(Details, "%s %d\n", "RETURN CODE:", twRC); 
	strcpy(Details2, Details); 
 
	//Show TW_CAPABILITY Contents 
	MatchTwainInt(Capability, MAX_CAP, twCapability.Cap,  
								Details); 
	strcat(Details2, "\nCap: "); 
	strcat(Details2, Details); 
 
	switch (twRC) 
	{ 
		case TWRC_SUCCESS: 
 
			MatchTwainInt(ConType, MAX_CONTYPE, twCapability.ConType,  
										Details); 
			strcat(Details2, "\nConType: "); 
			strcat(Details2, Details); 
 
			//Show Container Contents 
			strcat(Details2, "\nhContainer."); 
			switch(twCapability.ConType) 
			{ 
				case TWON_ONEVALUE: 
					pOneV = (pTW_ONEVALUE)GlobalLock(twCapability.hContainer); 
 
					strcat(Details2, "\n     ItemType: "); 
					MatchTwainInt(Types, MAX_TYPES, pOneV->ItemType,  
												Details); 
					strcat(Details2, Details); 
 
					strcat(Details2, "\n     Item: "); 
					GetItem(Details, pOneV->ItemType, (LPSTR)&(pOneV->Item)); 
					strcat(Details2, Details); 
 
					GlobalUnlock(twCapability.hContainer); 
					GlobalFree((HANDLE)twCapability.hContainer);    
					break; 
 
				case TWON_ENUMERATION: 
					pEnum = (pTW_ENUMERATION)GlobalLock(twCapability.hContainer); 
 
					strcat(Details2, "\n     ItemType: "); 
					MatchTwainInt(Types, MAX_TYPES, pEnum->ItemType,  
												Details); 
 
					datasize = (TW_INT16)AltTWItemSize(pEnum->ItemType); 
					strcat(Details2, Details); 
 
					wsprintf (Details, "\n     %s %d", "NumItems:", pEnum->NumItems); 
					strcat(Details2, Details); 
 
					wsprintf (Details, "\n     %s %d", "CurrentIndex:", pEnum->CurrentIndex); 
					strcat(Details2, Details); 
 
					wsprintf (Details, "\n     %s %d", "DefaultIndex:", pEnum->DefaultIndex); 
					strcat(Details2, Details); 
 
					strcat(Details2, "\n     ItemList: "); 
					pData = pEnum->ItemList; 
					//index=0 
					GetItem(Details, pEnum->ItemType, pData); 
					strcat(Details2, Details); 
					pData+=datasize; 
					for (index=1; index < pEnum->NumItems; index++) 
					{ 
						strcat(Details2, ", "); 
						GetItem(Details, pEnum->ItemType, pData); 
						strcat(Details2, Details); 
						pData+=datasize; 
					} 
					GlobalFree(twCapability.hContainer);    
					break; 
 
				case TWON_RANGE: 
					pRange = (pTW_RANGE)GlobalLock(twCapability.hContainer); 
 
					strcat(Details2, "\n     ItemType: "); 
					MatchTwainInt(Types, MAX_TYPES, pRange->ItemType,  
												Details); 
					strcat(Details2, Details); 
 
					strcat(Details2, "\n     MinValue: "); 
					GetItem(Details, pRange->ItemType, (LPSTR)&(pRange->MinValue)); 
					strcat(Details2, Details); 
 
					strcat(Details2, "\n     MaxValue: "); 
					GetItem(Details, pRange->ItemType, (LPSTR)&(pRange->MaxValue)); 
					strcat(Details2, Details); 
 
					strcat(Details2, "\n     StepSize: "); 
					GetItem(Details, pRange->ItemType, (LPSTR)&(pRange->StepSize)); 
					strcat(Details2, Details); 
 
					strcat(Details2, "\n     DefaultValue: "); 
					GetItem(Details, pRange->ItemType, (LPSTR)&(pRange->DefaultValue)); 
					strcat(Details2, Details); 
 
					strcat(Details2, "\n     CurrentValue: "); 
					GetItem(Details, pRange->ItemType, (LPSTR)&(pRange->CurrentValue)); 
					strcat(Details2, Details); 
 
					GlobalFree(twCapability.hContainer);     //bad 
					break; 
 
				case TWON_ARRAY: 
					pArray = (pTW_ARRAY)GlobalLock(twCapability.hContainer); 
 
					strcat(Details2, "\n     ItemType: "); 
					MatchTwainInt(Types, MAX_TYPES, pArray->ItemType,  
												Details); 
					datasize = (TW_INT16)AltTWItemSize(pArray->ItemType); 
					strcat(Details2, Details); 
 
					wsprintf (Details, "\n     %s %d", "NumItems:", pArray->NumItems); 
					strcat(Details2, Details); 
 
					strcat(Details2, "\n     ItemList: "); 
					pData = pArray->ItemList; 
					//index=0 
					GetItem(Details, pArray->ItemType, pData); 
					strcat(Details2, Details); 
					pData+=datasize; 
					for (index=1; index < pArray->NumItems; index++) 
					{ 
						strcat(Details2, ", "); 
						GetItem(Details, pArray->ItemType, pData); 
						strcat(Details2, Details); 
						pData+=datasize; 
					} 
					GlobalFree(twCapability.hContainer);    //bad 
					break; 
 
				default: 
					break; 
			} 
			break; 
 
		case TWRC_FAILURE:		 
			// determine details of failure from Source 
 
			if (ccRC == TWRC_SUCCESS) 
			{ 
				wsprintf(Details, "\n%s %d", "Condition Code:", gGlobalStatus.ConditionCode); 
				strcat(Details2, Details); 
			}  
			else  
			{ 
				wsprintf(Details, "\n%s %d", "Condition Code:", gGlobalStatus.ConditionCode); 
				strcat(Details2, Details);          
			} 
			break; 
	} 
 
	ShowRC_CC(hWndofApp,0,0,0,Details,"TW_CAPABILITY"); 
	return; 
} 
 
//////////////////////////////////////////////////////////////////////////// 
// Function: GetItem --  
// Author: TWAIN Working Group 
// Input: 
//		test -  
//		datatype -  
//		pData -  
// Output: none 
// Comments: 
// 
void GetItem (char * Text, TW_UINT16 datatype, LPSTR pData) 
{ 
	ASSERT(pData); 
	ASSERT(Text); 
 
	switch (datatype) 
	{ 
		case 0: //TWTY_INT8 
			{ 
				TW_INT8 value = *(pTW_INT8)pData; 
				wsprintf(Text, "%d", (TW_INT16)value); 
			}    
			break; 
 
		case 3: // TWTY_UINT8 
			{ 
				TW_UINT8 value = *(pTW_UINT8)pData; 
				wsprintf(Text,"%u", (TW_UINT16)value); 
			}    
			break; 
 
		case 1: // TWTY_INT16 
		case 44:// TWTY_HANDLE 
			{ 
				TW_INT16 value = *(pTW_INT16)pData; 
				wsprintf(Text,"%d", value); 
			}    
			break; 
 
		case 4: // TWTY_UINT16 
		case 6: // TWTY_BOOL 
			{ 
				TW_UINT16 value = *(pTW_UINT16)pData; 
				wsprintf(Text,"%u", value); 
			}    
			break; 
 
		case 2: // TWTY_INT32 
			{ 
				TW_INT32 value = *(pTW_INT32)pData; 
				wsprintf(Text,"%ld", value); 
			}    
			break; 
 
		case 5: // TWTY_UINT32 
		case 43: // TWTY_MEMREF 
			{ 
				TW_UINT32 value = *(pTW_UINT32)pData; 
				wsprintf(Text,"%lu", value); 
			}    
			break; 
 
		case 7: // TWTY_FIX32 
			{ 
				float value = 0; 
				TW_FIX32 fix32; 
 
				memset(&fix32, 0, sizeof(TW_FIX32)); 
 
				fix32.Whole = ((pTW_FIX32)pData)->Whole; 
				fix32.Frac = ((pTW_FIX32)pData)->Frac; 
				value = FIX32ToFloat(fix32); 
				sprintf(Text, "%f", value); 
			}    
			break; 
 
		case 9:  //TWTY_STR32 
		case 10: //TWTY_STR64 
		case 11: //TWTY_STR128 
		case 12: //TWTY_STR255 
		default: 
			lstrcpy(Text, pData); 
			break; 
	}    
	return; 
} 
 
/////////////////////////////////////////////////////////////////////////// 
// Function: ShowPendingXfers -- 
// Author: TWAIN Working Group 
// Input: 
//		hWndofApp - handle to window 
// Output: none 
// Comments: 
// 
void ShowPendingXfers (HWND hWndofApp) 
 
{ 
	TW_UINT16           twRC = TWRC_FAILURE; 
	TW_UINT16           ccRC = TWRC_FAILURE; 
	TW_PENDINGXFERS     twPendingXfers; 
	char                Details [255]; 
	char                Details2 [1024]; 
 
	memset(&twPendingXfers, 0, sizeof(TW_PENDINGXFERS)); 
	memset(Details, 0, sizeof(char[255])); 
	memset(Details2, 0, sizeof(char[1024])); 
 
	ASSERT(hWndofApp); 
 
	// Inquire Pending Xfers 
	twRC = CallDSMEntry(&appID, 
				&dsID,  
				DG_CONTROL, 
				DAT_PENDINGXFERS,  
				MSG_GET,  
				(TW_MEMREF)&twPendingXfers); 
 
	// Return Code from Operation 
	wsprintf(Details2, "%s %d\n", "RETURN CODE:", twRC); 
 
	switch (twRC) 
	{ 
		case TWRC_SUCCESS: 
			wsprintf (Details, "\n%s %d", "Count:", twPendingXfers.Count); 
			strcat(Details2, Details); 
			break; 
 
		case TWRC_FAILURE: 
		default: 
			// determine details of failure from SM 
 
			if (ccRC == TWRC_SUCCESS) 
			{ 
				wsprintf(Details, "\n%s %d", "Condition Code:", gGlobalStatus.ConditionCode); 
				strcat(Details2, Details); 
			} 
			else 
			{ 
				wsprintf(Details, "\n%s %d", "Condition Code:", gGlobalStatus.ConditionCode); 
				strcat(Details2, Details); 
			} 
			break; 
	} 
 
	ShowRC_CC(hWndofApp,0,0,0,Details2,"ADF Pending Transfers"); 
	return; 
}    
 
/////////////////////////////////////////////////////////////////////////// 
// function: ShowRC_CC --  
// Author: TWAIN Working Group 
// Input: 
//		hWndofApp - handle to window 
//		DisplayRC - 
//		ReturnCode -  
//		Dest -  
//		Text -  
//		Title -  
// Output: none 
// Comments: 
//		Main message notification routine.  Displays the failure, condition 
// codes and message associated with the problem.  Additionally, all log messages 
// pass thru this function. 
// 
void ShowRC_CC (HWND        hWndofApp, 
                TW_UINT16   DisplayRC,      //0-No, 1-Yes 
                TW_UINT16   uiReturnCode, 
                TW_UINT16   Dest,           //0-Source Manager or 1-Source  
                char *      Text,           //Additional Information         
                char *      Title)          //Triplet or Cap 
{ 
	char            Details[255]; 
	char            Details2[1024]; 
	char outstring[1024]; 
	char outtitle[255]; 
 
	memset(Details, 0, sizeof(char[255])); 
	memset(Details2, 0, sizeof(char[1024])); 
	memset(outstring, 0, sizeof(char[1024])); 
	memset(outtitle, 0, sizeof(char[255])); 
 
	ASSERT(Text); 
	ASSERT(Title); 
 
	strcpy(Details, ""); 
	strcpy(Details2, "");                          
 
	lstrcpy(outstring,Text); 
	lstrcpy(outtitle,Title); 
 
	// if display check and display condition code 
	if(DisplayRC == 1)   
	{ 
		//Get Return Code to be displayed, place in Details2 
		MatchTwainInt(ReturnCode, MAX_RETURNCODE, (TW_INT32)uiReturnCode,  
									Details2); 
 
		MatchTwainInt(ConditionCode,MAX_CONDITIONCODE,  
									(TW_INT32)gGlobalStatus.ConditionCode,  
									Details); 
 
		lstrcpy(outtitle,"Operation Status"); 
 
		lstrcpy(outstring,"Operation: "); 
		lstrcat(outstring,Title); 
		lstrcat(outstring,"\r\n"); 
		lstrcat(outstring,"Return Code: "); 
		lstrcat(outstring,Details2); 
		lstrcat(outstring,"\r\n"); 
		lstrcat(outstring,"Condition Code: "); 
		lstrcat(outstring,Details); 
	}    
 
	MessageBox (hWndofApp, outstring, outtitle, MB_OK); 
	return; 
}   
 
//////////////////////////////////////////////////////////////////////////// 
// FUNCTION: MessageLevel 
// 
// ARGS:    none 
// 
// RETURNS: current state of Source Manager (open/closed) 
// 
// NOTES:   Just a way to reduce the number of global vars 
// 
int MessageLevel (VOID) 
{ 
	return (MessageLevelVAR); 
} 
 
//////////////////////////////////////////////////////////////////////////// 
// FUNCTION: SetMessageLevel 
// 
// ARGS:    none 
// 
// RETURNS: current state of Source Manager (open/closed) 
// 
// NOTES:   Just a way to reduce the number of global vars 
// 
void SetMessageLevel (int Level) 
{ 
	MessageLevelVAR = Level; 
	return; 
} 
 
/* 
* Function: MsgQuerySupport  
* Author: TWAIN Working Group 
* Input: 
*		cap - 
*		type -  
*		ptwCapability 
* Output: 
*		TRUE is successful 
* Comments: 
* 
*/ 
BOOL MsgQuerySupport(TW_UINT16 cap,TW_UINT16 type, pTW_CAPABILITY ptwCapability) 
{ 
	TW_INT16 rc = TWRC_FAILURE; 
	char string[50]; 
 
	memset(string, 0, sizeof(char[50])); 
 
	ASSERT(ptwCapability); 
 
	/* 
	* Setup dsID for default Source                              
	*/ 
	if (!TWIsDSOpen()) 
	{ 
		dsID.Id = 0; 
		dsID.ProductName[0] = 0; 
		appID.Id = 0;	 
	} 
	/* 
	* Open DSM 
	*/ 
	if (TWOpenDSM() != TRUE) 
	{ 
		if (MessageLevel() >= ML_ERROR) 
		{ 
			ShowRC_CC(NULL, 0, 0, 0,"Failed to Open DSM","Capabilities"); 
		} 
		return(FALSE); 
	} 
	/* 
	* Open DS 
	*/ 
	if (TWOpenDS() != TRUE) 
		{ 
		if (MessageLevel() >= ML_ERROR) 
		{ 
			ShowRC_CC(NULL,0,0,0,"Failed to open DS","Capabilities"); 
		} 
		return(FALSE); 
	} 
 
	ptwCapability->Cap = cap; 
	ptwCapability->ConType = TWON_DONTCARE16; 
	ptwCapability->hContainer = NULL; 
 
	rc = CallDSMEntry(&appID, 
				&dsID, 
				DG_CONTROL, 
				DAT_CAPABILITY, 
				type, 
				(TW_MEMREF)ptwCapability); 
 
	if (rc == TWRC_SUCCESS) 
	{ 
		return(TRUE);     
	} 
	else 
	{       
		memset(string,'\0',sizeof(string)); 
		lstrcat(string,"DG_CONTROL/DAT_CAPABILITY/"); 
		if(type == MSG_QUERYSUPPORT) 
		{ 
			lstrcat(string, "MSG_QUERYSUPPORT"); 
		}     
 
		/* 
		* Error message using condition state of the Source 
		*/ 
		ShowRC_CC(g_hMainDlg,1,rc,1,"",string); 
		return(FALSE); 
	} 
} 
 
////////////////////////////////////////////////////////////////////////// 
// Function: MsgGetCapability --   
// Author: TWAIN Working Group 
// Input: 
//		cap - 
//		type -  
//		ptwCapability 
// Output: 
//		TRUE is successful 
// Comments: 
//		Sends one of the three GET triplets to the  
// source and returns the TW_CAPABILITY structure to the caller as a  
// parameter.  If the DSM_Entry call fails, FALSE is returned  
// 
BOOL MsgGetCapability(TW_UINT16 cap,TW_UINT16 type, pTW_CAPABILITY ptwCapability) 
{ 
	TW_INT16 rc = TWRC_FAILURE; 
	char string[50]; 
 
	memset(string, 0, sizeof(char[50])); 
 
	ASSERT(ptwCapability); 
 
	//	Setup dsID for default Source                              
	if (!TWIsDSOpen()) 
	{ 
		dsID.Id = 0; 
		dsID.ProductName[0] = 0; 
		appID.Id = 0;	 
	} 
	//	Open DSM 
	if (TWOpenDSM() != TRUE) 
	{ 
		if (MessageLevel() >= ML_ERROR) 
		{ 
			ShowRC_CC(NULL, 0, 0, 0,"Failed to Open DSM","Capabilities"); 
		} 
		return(FALSE); 
	} 
	//	Open DS 
	if (TWOpenDS() != TRUE) 
	{ 
		if (MessageLevel() >= ML_ERROR) 
		{ 
			ShowRC_CC(NULL,0,0,0,"Failed to open DS","Capabilities"); 
		} 
		return(FALSE); 
	} 
 
	ptwCapability->Cap = cap; 
	ptwCapability->ConType = TWON_DONTCARE16; 
	ptwCapability->hContainer = NULL; 
 
 
	rc = CallDSMEntry(&appID, 
				&dsID, 
				DG_CONTROL, 
				DAT_CAPABILITY, 
				type, 
				(TW_MEMREF)ptwCapability); 
 
	if (rc == TWRC_SUCCESS) 
	{ 
		return(TRUE);     
	} 
	else 
	{       
		memset(string,'\0',sizeof(string)); 
		lstrcat(string,"DG_CONTROL/DAT_CAPABILITY/"); 
		switch(type) 
		{ 
			case MSG_GET: 
				lstrcat(string,"MSG_GET"); 
				break; 
			case MSG_GETDEFAULT: 
				lstrcat(string,"MSG_GETDEFAULT"); 
				break; 
			case MSG_GETCURRENT:             
				lstrcat(string,"MSG_GETCURRENT"); 
				break; 
			default: 
				break; 
		}     
 
		// Error message using condition state of the Source 
		ShowRC_CC(g_hMainDlg,1,rc,1,"",string); 
		return(FALSE); 
	} 
} 
 
////////////////////////////////////////////////////////////////////////// 
// Function: MsgSetCapability --   
// Author: TWAIN Working Group 
// Input: 
//		cap - 
//		type -  
//		ptwCapability 
// Output: 
//		TRUE is successful 
// Comments: 
//		Sends one of the two SET triplets to the  
// source and returns the TW_CAPABILITY structure to the caller as a  
// parameter.  If the DSM_Entry call fails, FALSE is returned.  
// 
BOOL MsgSetCapability(TW_UINT16 cap,TW_UINT16 type, pTW_CAPABILITY ptwCapability) 
{ 
	TW_INT16 rc = TWRC_FAILURE; 
	char string[50]; 
 
	memset(string, 0, sizeof(char[50])); 
 
	ASSERT(ptwCapability); 
 
	//	Setup dsID for default Source                              
	if (!TWIsDSOpen()) 
	{ 
		dsID.Id = 0; 
		dsID.ProductName[0] = 0; 
		appID.Id = 0;	//Why do this? 
	} 
	//	Open DSM 
	if (TWOpenDSM() != TRUE) 
		{ 
		if (MessageLevel() >= ML_ERROR) 
		{ 
			ShowRC_CC(NULL, 0, 0, 0,"Failed to Open DSM","Capabilities"); 
		} 
		return(FALSE); 
	} 
	//	Open DS 
	if (TWOpenDS() != TRUE) 
	{ 
		if (MessageLevel() >= ML_ERROR) 
		{ 
			ShowRC_CC(NULL,0,0,0,"Failed to open DS","Capabilities"); 
		} 
		return(FALSE); 
	} 
 
	if (type == MSG_RESET) 
	{ 
		ptwCapability->Cap = cap; 
		ptwCapability->ConType = TWON_DONTCARE16; 
		ptwCapability->hContainer = NULL; 
	} 
 
	rc = CallDSMEntry(&appID, 
				&dsID, 
				DG_CONTROL, 
				DAT_CAPABILITY, 
				type, 
				(TW_MEMREF)ptwCapability); 
 
	if (rc == TWRC_SUCCESS) 
	{ 
		return(TRUE);     
	} 
	else 
	{       
		memset(string,'\0',sizeof(string)); 
		lstrcat(string,"DG_CONTROL/DAT_CAPABILITY/"); 
		switch(type) 
		{ 
			case MSG_SET: 
				lstrcat(string,"MSG_SET"); 
				break; 
			case MSG_RESET: 
				lstrcat(string,"MSG_RESET"); 
				break; 
			default: 
				break; 
		}     
 
		// Error message using condition state of the Source 
		ShowRC_CC(g_hMainDlg,1,rc,1,"",string); 
		return(FALSE); 
	} 
}