?? eztwain.c
字號:
// 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
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -