⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eztwain.c

📁 扫描仪设置
💻 C
📖 第 1 页 / 共 4 页
字号:
// EZTWAIN.C - Easy TWAIN DLL main module
//
// 	05/11/94	spike	initial version
// 1.00	06/17/94	spike
// 1.01	07/27/94	spike - added XferCount negotiation
// 1.02 10/26/94	spike - fixed bug in ModalEventLoop (thanks to Bill DeVoe of HP)
//							replaced random flags with state tracking
// 1.03 02/06/95	spike - fixed gross omissions in WriteDibToFile
// 1.04 04/05/95	spike - added WriteNativeToFile, WriteNativeToFilename, FreeNative
//							added Get/SetCurrentUnits, SetCurrentPixelType
//							added SetCurrentResolution, SetCapOneValue
//							corrected bug in SelectImageSource
// 1.05 04/02/97	spike - 32-bit version.
//							Correction to MessageHook, for thunking DSM.
//							Bugfix: 32-bit version of TWAIN_WriteDibToFile
// 1.06 08/21/97	spike
//							Yet another correction to MessageHook.
//							Figured out how to export names 'as is' in 32-bit version.

#define VERSION 106		// version number, times 100.

//------------ Includes

//#include <assert.h>
//#include <memory.h>		// memset, memcpy

#include "windows.h"
#include "commdlg.h"

#ifdef _WIN32
#ifndef _INC_VFW
#include <vfw.h>
#endif
#else
#include "commdlg.h"
#endif

#include "twain.h"

#ifdef _WIN32
  #define EZTAPI WINAPI
#else
  #define EZTAPI __export FAR PASCAL
#endif

#include "eztwain.h"

//------------ Constants and Macros

#define STATIC static
#ifdef __BORLANDC__
#define _WIN32
#endif

#ifdef _WIN32
  #define INT32 int
  #define DATAGROUP unsigned
  #define DSM_FILENAME "TWAIN_32.DLL"
  #define DSM_ENTRYPOINT "DSM_Entry"
  #define IsValidHandle(h) (h!=NULL)
  #define HUGEWRITE(fh, pb, bc) ((INT32)_lwrite(fh, pb, bc))
  #define FMEMSET(p, v, n) memset(p, v, n);
  #define FMEMCPY(p, q, n) memcpy(p, q, n);
#else
  #define INT32 long
  #define DATAGROUP unsigned long
  #define DSM_FILENAME "TWAIN.DLL"
  #define DSM_ENTRYPOINT "DSM_ENTRY"
  #define VALID_HANDLE 32
  #define IsValidHandle(h) ((h!=0) && ((h) >= 32))
  #define HUGEWRITE(fh, pb, bc) _hwrite(fh, pb, bc)
  #define FMEMSET(p, v, n) _fmemset(p, v, n);
  #define FMEMCPY(p, q, n) _fmemcpy(p, q, n);
#endif

#define MAX_IMAGES 999
#define TW_CALLBACK_REGISTERED 0xf0f0f

typedef enum {
	ED_NONE,
	ED_START_TRIPLET_ERRS,
	ED_CAP_GET,				// MSG_GET triplet on a capability failed
	ED_CAP_SET,				// MSG_SET triplet on capability failed
	ED_DSM_FAILURE,			// TWAIN DSM returned TWRC_FAILURE
	ED_DS_FAILURE,			// source returned TWRC_FAILURE
	ED_END_TRIPLET_ERRS,
	ED_NOT_STATE_4,			// operation invoked in wrong state
	ED_NULL_HCON,			// MSG_GET returned a null container handle
	ED_BAD_HCON,			// MSG_GET returned an invalid/unlockable container handle
	ED_BAD_CONTYPE,			// returned container ConType is not valid.
	ED_BAD_ITEMTYPE,		// returned container ItemType is not valid.
	ED_CAP_GET_EMPTY,		// returned container has 0 items.
	ED_CAP_SET_EMPTY,		// trying to restrict a cap to empty set
} ErrorDetail;

const char *pszErrDescrip[] =
	{	"[no details available]",
		"",
		"DAT_CAPABILITY/MSG_GET failed",
		"DAT_CAPABILITY/MSG_SET failed",
		"Source Manager operation failed",
		"DataSource operation failed",
		"",
		"TWAIN session not in State 4 (Source Open)",
		"MSG_GET returned a NULL container handle",
		"MSG_GET returned an invalid container handle",
		"Returned container is not valid type",
		"Returned container has invalid ItemType",
		"Returned container is empty",
		"App and source found NO values in common",
	};

const char *pszRC[] = {
	"TWRC_SUCCESS",
	"TWRC_FAILURE",
	"TWRC_CHECKSTATUS ('tried hard')",
	"TWRC_CANCEL",
	"TWRC_DSEVENT",
	"TWRC_NOTDSEVENT",
	"TWRC_XFERDONE",
	"TWRC_ENDOFLIST",
};

const char *pszCC[] = {
	"TWCC_SUCCESS",
	"TWCC_BUMMER (Failure due to unknown causes)",
	"TWCC_LOWMEMORY",
	"TWCC_NODS (No Data Source)",
	"TWCC_MAXCONNECTIONS (DS is connected to max possible apps)",
	"TWCC_OPERATIONERROR (DS or DSM reported error, app shouldn't)",
	"TWCC_BADCAP (Unknown capability)",
	"7 (undefined)",
	"8 (undefined)",
	"TWCC_BADPROTOCOL (Unrecognized triplet)",
	"TWCC_BADVALUE (Data parameter out of range)",
	"TWCC_SEQERROR (Triplet out of sequence)",
	"TWCC_BADDEST (Unknown dest. App/Src in DSM_Entry)",
};

//------------ Global variables

STATIC int			iAvailable;			// TWAIN available: 0:unknown, -1:No, 1:Yes
STATIC int			nState = 1;			// TWAIN state (per the standard)
STATIC int			nErrDetail;			// detailed error code
STATIC unsigned		nErrRC, nErrCC;		// result code and condition code for last error
STATIC char			szMsg[256];			// scratch buffer for messages
STATIC DSMENTRYPROC	pDSM_Entry;			// entry point of Data Source Manager (TWAIN.DLL)
STATIC HANDLE		hDSMLib;			// handle of DSM
STATIC TW_IDENTITY	AppId = {			// application identity structure
	0,									// Id, filled in by DSM
	{ 1, 0, TWLG_USA, TWCY_USA, "<?>"},	// Version
	 TWON_PROTOCOLMAJOR,
	 TWON_PROTOCOLMINOR,
	 DG_IMAGE | DG_CONTROL,
	 "<?>",								// Mfg
	 "<?>",								// Family
	 "<?>"								// Product
	 };
STATIC TW_IDENTITY	SourceId;			// source identity structure
STATIC BOOL			bHideUI;			// allow source u/i to be hidden
STATIC TW_USERINTERFACE twUI;
STATIC TW_PENDINGXFERS pendingXfers;
STATIC HANDLE		hDib;				// bitmap returned by native transfer
STATIC TW_INT16		rc;					// result code
STATIC HINSTANCE	hinstLib;			// instance handle for this DLL

STATIC HANDLE hDibList[MAX_IMAGES];
STATIC TW_INT32 nDibs;
STATIC HDIBCALLBACKPROC lpfnDibCallback;
STATIC int hDibCallback_registered = 0;

const char szInsuffMem[] = "Insufficient Memory";	// error message
STATIC int bTrace = 0;  // debugging helper

//------------ Forward declarations

void TWAIN_NativeXferReady(LPMSG pmsg);
HWND CreateProxyWindow(void);
unsigned Intersect16(unsigned wMask, unsigned nItems, TW_UINT16 far *pItem);
unsigned BitCount(unsigned W);
void TWAIN_ErrorBox(const char *szMsg);
int RecordError(ErrorDetail ed);
void ClearError(void);
void TWAIN_ReportLastError(LPSTR lpzGeneral);
// TW_UINT32 ToFix32(double r);
// double Fix32ToFloat(TW_FIX32 fix);
// above functions implemented on the Delphi side to avoid need for floating
// point library functions --DSN 7/98
void assert(int);

//------------ Public functions
// the two functions below are implemented by hand vs. the C RTL so that the
// resultant OBJ can be neatly linked into a Delphi DCU.
void assert(int a)
{
  if (a == 0)
	  MessageBox(NULL, "Assertion failed", "EZTWAIN", MB_OK);
}

void *memset(void *s, int c, size_t n)
{
	size_t j;
	char *p;
	p = (char *) s;

	for (j = 0; j < n; j++)
		p[j] = (char) c;

	return s;
}

void *memcpy(void *dest, const void *src, size_t n)
{
	size_t j;
	char *pdest, *psrc;
	pdest = (char *) dest;
	psrc = (char *)src;
	for (j = 0; j < n; j++)
		pdest[j] = psrc[j];

	return dest;
}

#ifdef _WIN32

// Win32 DLL main
/*BOOL WINAPI DllMain(HANDLE hModule,
						  ULONG  ulEvent,
						  LPVOID lpReserved)
{
	return 1;
}*/

#else

// Win16 DLL initialization and termination routines
int CALLBACK __export LibMain(HINSTANCE hinst, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
{
	wDataSeg = wDataSeg; cbHeapSize = cbHeapSize; lpszCmdLine = lpszCmdLine;

	hinstLib = hinst;
	return 1;		// indicate success
} // LibMain


int FAR PASCAL __export _WEP(int x)
{
	x = x;				// suppress 'is never used' warning
	return 1;
} // _WEP


#endif


void EZTAPI TWAIN_RegisterApp(	// record application information
	int		nMajorNum, int nMinorNum,	// major and incremental revision of application. E.g.
										// for version 2.1, nMajorNum == 2 and nMinorNum == 1
	int		nLanguage,					// language of this version (use TWLG_xxx from TWAIN.H)
	int		nCountry,					// country of this version (use TWCY_xxx from TWAIN.H)
	LPSTR	lpszVersion,				// version info string e.g. "1.0b3 Beta release"
	LPSTR	lpszMfg,					// name of manufacturer/developer e.g. "Crazbat Software"
	LPSTR	lpszFamily,					// product family e.g. "BitStomper"
	LPSTR	lpszProduct)				// specific product e.g. "BitStomper Deluxe Pro"
{
	 AppId.Id = 0;						// init to 0, but Source Manager will assign real value
    AppId.Version.MajorNum = nMajorNum;
    AppId.Version.MinorNum = nMinorNum;
    AppId.Version.Language = nLanguage;
    AppId.Version.Country  = nCountry;
    lstrcpy (AppId.Version.Info,  lpszVersion);

    AppId.ProtocolMajor =    TWON_PROTOCOLMAJOR;
	 AppId.ProtocolMinor =    TWON_PROTOCOLMINOR;
	 AppId.SupportedGroups =  DG_IMAGE | DG_CONTROL;
    lstrcpy (AppId.Manufacturer,  lpszMfg);
    lstrcpy (AppId.ProductFamily, lpszFamily);
    lstrcpy (AppId.ProductName,   lpszProduct);

} // TWAIN_RegisterApp


int EZTAPI TWAIN_SelectImageSource(HWND hwnd)
{

	int fSuccess = FALSE;
	int fProxyWindow = FALSE;

	if (!IsWindow(hwnd)) {
		if (hwnd != NULL) {
			TWAIN_ErrorBox("TWAIN_SelectImageSource: window handle is invalid");
			return FALSE;
		}
		hwnd = CreateProxyWindow();
		if (!IsWindow(hwnd)) {
			TWAIN_ErrorBox("TWAIN_SelectImageSource: Unable to create proxy window");
			return FALSE;
		}
		fProxyWindow = TRUE;
	}
	if (TWAIN_LoadSourceManager()) {
		if (TWAIN_OpenSourceManager(hwnd)) {
			TW_IDENTITY	NewSourceId;
#ifdef _WIN32
			FMEMSET(&NewSourceId, 0, sizeof NewSourceId);
#else
			// I will settle for the system default.  Shouldn't I get a highlight
			// on system default without this call?
			TWAIN_Mgr(DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT, &NewSourceId);
#endif
			// Post the Select Source dialog
			fSuccess = TWAIN_Mgr(DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT, &NewSourceId);
			 TWAIN_CloseSourceManager(hwnd);
		 } else {
			TWAIN_ErrorBox("Unable to open Source Manager (" DSM_FILENAME ")");
		 }
		 TWAIN_UnloadSourceManager();
	} else {
		TWAIN_ErrorBox("Unable to load Source Manager (" DSM_FILENAME ")");
	}
	 if (fProxyWindow) DestroyWindow(hwnd);

	return fSuccess;
} // TWAIN_SelectImageSource


HANDLE EZTAPI TWAIN_AcquireNative(HWND hwnd, unsigned wPixTypes)
{
	int fProxyWindow = FALSE;
	hDib = NULL;
	ClearError();			// clear error detail
	TWAIN_ClearDibList();

	if (!IsWindow(hwnd)) {
		// hwnd isn't a valid window handle - most likely NULL
		hwnd = CreateProxyWindow();
		if (hwnd) fProxyWindow = TRUE;
	}
	if (!IsWindow(hwnd)) {
		TWAIN_ErrorBox("Unable to create proxy window");
	} else if (!TWAIN_LoadSourceManager()) {
		TWAIN_ErrorBox("Unable to load Source Manager (" DSM_FILENAME ")");
	} else if (!TWAIN_OpenSourceManager(hwnd)) {
		TWAIN_ErrorBox("Unable to open Source Manager (" DSM_FILENAME ")");
	 } else if (!TWAIN_OpenDefaultSource()) {
		TWAIN_ReportLastError("Unable to open default Data Source.");
	} else if (!TWAIN_NegotiatePixelTypes(wPixTypes)) {
		TWAIN_ReportLastError("Failed to negotiate Pixel Type.");
	} else if (!TWAIN_EnableSource(hwnd)) {
		TWAIN_ReportLastError("Failed to enable Data Source.");
	} else {
		EnableWindow(hwnd, FALSE);
		// source is enabled, wait for transfer or source closed
		TWAIN_ModalEventLoop();

		EnableWindow(hwnd, TRUE);
	}

	// shut everything down in the right sequence
	// these routines do nothing if the corresponding 'open' failed
	TWAIN_DisableSource();
	TWAIN_CloseSource();
	 TWAIN_CloseSourceManager(hwnd);
	 TWAIN_UnloadSourceManager();

	 if (fProxyWindow) {
		DestroyWindow(hwnd);
	 }

	return hDib;
} // TWAIN_AcquireNative


void EZTAPI TWAIN_FreeNative(HANDLE hdib)
// Release the memory allocated to a native format image, as returned by TWAIN_AcquireNative.
// (For those coding in C or C++, this is just a call to GlobalFree.)
{
	if (hdib) GlobalFree(hdib);
} // TWAIN_FreeNative



int EZTAPI TWAIN_AcquireToClipboard(HWND hwndApp, unsigned wPixTypes)
// Like AcquireNative, but puts the resulting image, if any, into the system clipboard.
// Useful for environments like Visual Basic where it is hard to make direct use of a DIB handle.
// A return value of 1 indicates success, 0 indicates failure.
{
	int fOk = FALSE;
	HANDLE hDib = TWAIN_AcquireNative(hwndApp, wPixTypes);
	if (hDib) {
		if (OpenClipboard(hwndApp)) {
			if (EmptyClipboard()) {
				SetClipboardData(CF_DIB, hDib);
				fOk = TRUE;
				hDib = NULL;
			}
			CloseClipboard();
		}
		if (hDib) {
			// something went wrong, recycle the image
			GlobalFree(hDib);
		}
	}
	return fOk;		// failed
} // TWAIN_AcquireToClipboard


int EZTAPI TWAIN_AcquireToFilename(HWND hwndApp, char *pszFile)
// Adapted from a routine by David D. Henseler (ddh) of SOLUTIONS GmbH
{
	int result = -1;
	HANDLE	hDib = TWAIN_AcquireNative(hwndApp, TWAIN_ANYTYPE);
	if (hDib) {
		result = TWAIN_WriteNativeToFilename(hDib, pszFile);
		TWAIN_FreeNative(hDib);
	}
	return result;
} // TWAIN_AcquireToFile

//--------- Callback mechanism -------------
// These routines, added by DSN 7/98, allow the user to specify an
// optional callback function to be called each time a new image comes
// in.  This can be a potentially powerful way to increase the primary
// application's efficiency, because upon receipt of an hdib the app
// could start a background thread to begin processing the images as
// needed.  Why bother with this?  Because on my Pentium 150, the Windows
// NT task monitor indicates that when I download images at 112kbps that
// I'm only using 15% of the processor's power, and the remaining 85% of
// the time it is idle!  It's silly to wait to begin processing because
// there's so much untapped processing capacity here.

void EZTAPI TWAIN_RegisterCallback(HDIBCALLBACKPROC *fxn)
{
	  lpfnDibCallback = fxn;
	  hDibCallback_registered = TW_CALLBACK_REGISTERED;  // our signature, because I don't trust
													 // the supposed initialization to zero
													 // by the compiler
}

void EZTAPI TWAIN_UnRegisterCallback()
{
	  lpfnDibCallback = NULL;
	  hDibCallback_registered = TW_CALLBACK_REGISTERED;
}

///////////////////////////////////////////////////////////////////////
// DIB utilities

void EZTAPI TWAIN_ClearDibList()
/// new; added by DSN
/// note: user is responsible for calling TWAIN_FreeNative *before*
/// calling this function!

{
	  int i;
	  for (i = 0; i < MAX_IMAGES; i++)
			 hDibList[i] = 0;
	  nDibs = 0;
}

int EZTAPI TWAIN_GetNumDibs()
{
	  return nDibs;
}

HANDLE EZTAPI TWAIN_GetDib(int n)
{
	  return hDibList[n];
}
int EZTAPI TWAIN_DibDepth(HANDLE hdib)
{
	LPBITMAPINFOHEADER pbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
	int D = pbi->biBitCount;
	GlobalUnlock(hdib);
	return D;
} // TWAIN_DibDepth

int EZTAPI TWAIN_DibWidth(HANDLE hdib)
{
	LPBITMAPINFOHEADER pbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
	int W = (int)pbi->biWidth;
	GlobalUnlock(hdib);
	return W;
} // TWAIN_DibWidth


int EZTAPI TWAIN_DibHeight(HANDLE hdib)
{
	LPBITMAPINFOHEADER pbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
	int H = (int)pbi->biHeight;
	GlobalUnlock(hdib);
	return H;
} // TWAIN_DibHeight

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -