📄 eztwain.c
字号:
}
return (nState == 4);
} // TWAIN_OpenDefaultSource
int EZTAPI TWAIN_EnableSource(HWND hwnd)
{
if (nState != 4) return FALSE;
twUI.ShowUI = !bHideUI;
twUI.hParent = (TW_HANDLE)hwnd;
TWAIN_DS(DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS, &twUI);
if (rc == TWRC_FAILURE) {
RecordError(ED_DS_FAILURE);
} else {
// rc could be either SUCCESS or CHECKSTATUS
nState = 5;
// note, source will set twUI.ModalUI.
}
return (nState == 5);
} // TWAIN_EnableSource
int EZTAPI TWAIN_DisableSource(void)
{
if (nState == 5 &&
TWAIN_DS(DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS, &twUI)) {
nState = 4;
}
return (nState <= 4);
} // TWAIN_DisableSource
int EZTAPI TWAIN_CloseSource(void)
{
rc = TWRC_SUCCESS;
if (nState == 5) TWAIN_DisableSource();
if (nState == 4 &&
TWAIN_Mgr(DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, &SourceId)) {
nState = 3;
}
return (nState <= 3);
} // TWAIN_CloseSource
int EZTAPI TWAIN_CloseSourceManager(HWND hwnd)
{
TW_INT32 hwnd32 = (TW_INT32)hwnd;
rc = TWRC_SUCCESS;
if (TWAIN_CloseSource() &&
TWAIN_Mgr(DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, &hwnd32)) {
nState = 2;
}
return (nState <= 2);
} // TWAIN_CloseSourceManager
int EZTAPI TWAIN_UnloadSourceManager(void)
{
if (nState == 2) {
if (hDSMLib) {
FreeLibrary(hDSMLib);
hDSMLib = NULL;
}
pDSM_Entry = NULL;
nState = 1;
}
return (nState == 1);
} // TWAIN_UnloadSourceManager
void EZTAPI TWAIN_ModalEventLoop(void)
{
MSG msg;
while ((nState >= 5) && !hDib && GetMessage((LPMSG)&msg, NULL, 0, 0)) {
if (!TWAIN_MessageHook ((LPMSG)&msg)) {
TranslateMessage ((LPMSG)&msg);
DispatchMessage ((LPMSG)&msg);
}
} // while
} // TWAIN_ModalEventLoop
int EZTAPI TWAIN_MessageHook(LPMSG lpmsg)
// returns TRUE if msg processed by TWAIN (source)
{
int bProcessed = FALSE;
if (nState >= 5) {
// source enabled
TW_EVENT twEvent;
twEvent.pEvent = (TW_MEMREF)lpmsg;
twEvent.TWMessage = MSG_NULL;
// see if source wants to process (eat) the message
TWAIN_DS(DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, &twEvent);
bProcessed = (rc == TWRC_DSEVENT);
switch (twEvent.TWMessage) {
case MSG_XFERREADY:
nState = 6;
// TWAIN_NativeXferReady(lpmsg); Spike's original code
TWAIN_NativeXferGetAll(lpmsg); // replace with this -- DSN 07/98
break;
case MSG_CLOSEDSREQ:
TWAIN_DisableSource();
break;
case MSG_NULL:
// no message returned from DS
break;
} // switch
}
return bProcessed;
} // TWAIN_MessageHook
void TWAIN_NativeXferReady(LPMSG pmsg)
// Spike's original code. Note that it doesn't get called any more; instead,
// Message_Hook calls NativeXferGetAll, which supports multiple image
// acquisition. -- DSN 7/13/98
{
TW_UINT32 hNative;
pmsg = pmsg; // suppress warning
assert(nState == 6);
TWAIN_DS(DG_IMAGE, DAT_IMAGENATIVEXFER, MSG_GET, &hNative);
if (rc != TWRC_XFERDONE) hDib = NULL;
switch (rc) {
case TWRC_XFERDONE:
// hNative contains a valid native image (handle)
// application is responsible for de-allocating.
nState = 7;
// Need to acknowledge the end of the transfer
hDib = (HANDLE)hNative;
// above line added by DSN: add to list of hdibs and advance counter
break;
case TWRC_CANCEL:
// user cancelled the transfer
// hNative is invalid
nState = 7;
// acknowledge the end of the transfer
break;
case TWRC_FAILURE:
default:
// the transfer failed (e.g. insufficient memory)
// hNative is invalid
// check condition code for more info
nState = 6;
// state transition failed
// image data is still pending
break;
} // switch
assert(nState >= 6);
TWAIN_AbortAllPendingXfers(); // state 7 or 6 -> state 5
} // TWAIN_NativeXferReady
int EZTAPI TWAIN_AbortAllPendingXfers(void)
// Not used any more because its only caller was TWAIN_NativeXferReady, which
// is now ignored in favor or TWAIN_NativeXferGetAll. -- DSN 7/13/98
{
if (nState == 7 &&
TWAIN_DS(DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER, &pendingXfers)) {
nState = pendingXfers.Count ? 6 : 5;
}
if (nState == 6 &&
TWAIN_DS(DG_CONTROL, DAT_PENDINGXFERS, MSG_RESET, &pendingXfers)) {
nState = 5;
}
return (nState <= 5);
} // TWAIN_AbortAllPendingXfers
void EZTAPI TWAIN_NativeXferGetAll(LPMSG pmsg)
// A modified version of Spike's original code that loops through until
// no more images are left. -- DSN 7/98
{
TW_UINT32 hNative;
pmsg = pmsg; // suppress warning; (sic) -- does this do anything? DSN
assert(nState == 6);
do {
TWAIN_DS(DG_IMAGE, DAT_IMAGENATIVEXFER, MSG_GET, &hNative);
if (rc != TWRC_XFERDONE) hDib = NULL;
switch (rc) {
case TWRC_XFERDONE:
// hNative contains a valid native image (handle)
// application is responsible for de-allocating.
nState = 7;
// Need to acknowledge the end of the transfer
hDib = (HANDLE)hNative; // thus hDib represents MOST RECENT image!
hDibList[nDibs] = hDib;
// added by DSN: add to list of hdibs and advance counter
if (hDibCallback_registered == TW_CALLBACK_REGISTERED) // user may specify callback
(*lpfnDibCallback)(hDibList[nDibs], nDibs); // great for multithreading!
nDibs++;
break;
case TWRC_CANCEL:
// user cancelled the transfer
// hNative is invalid
nState = 7;
// acknowledge the end of the transfer
break;
case TWRC_FAILURE:
default:
// the transfer failed (e.g. insufficient memory)
// hNative is invalid
// check condition code for more info
nState = 6;
// state transition failed
// image data is still pending
break;
} // switch
assert(nState >= 6);
if (nState == 7 && TWAIN_DS(DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER, &pendingXfers))
nState = pendingXfers.Count ? 6 : 5;
} while (nState == 6);
// TWAIN_AbortAllPendingXfers(); // state 7 or 6 -> state 5
// Commented out the above; we want to get all xfers!!
} // TWAIN_NativeXferReady
///////////////////////////////////////////////////////////////////////
// DIB/BMP File I/O
int EZTAPI TWAIN_WriteNativeToFilename(HANDLE hdib, LPCSTR pszFile)
// Writes a DIB handle to a .BMP file
//
// hdib = DIB handle, as returned by TWAIN_AcquireNative
// pszFile = far pointer to NUL-terminated filename
// If pszFile is NULL or points to a null string, prompts the user
// for the filename with a standard file-save dialog.
//
// Return values:
// 0 success
// -1 user cancelled File Save dialog
// -2 file open error (invalid path or name, or access denied)
// -3 (weird) unable to lock DIB - probably an invalid handle.
// -4 writing BMP data failed, possibly output device is full
{
int result;
char szFile[256];
HFILE fh;
OFSTRUCT ofs;
if (!pszFile || !*pszFile) {
// prompt for filename
OPENFILENAME ofn;
int nExt;
FMEMSET(&ofn, 0, sizeof ofn);
szFile[0] = '\0';
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = "Windows Bitmap (*.bmp)\0*.bmp\0\0";
ofn.lpstrFile= szFile;
ofn.nMaxFile = sizeof(szFile) - 5;
ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
OFN_NOREADONLYRETURN;
if (!GetSaveFileName(&ofn)) {
return -1; // user cancelled dialog
}
// supply default extension - GetSaveFileName doesn't seem to do it!
nExt = ofn.nFileExtension;
if (nExt && !szFile[nExt]) {
// no extension
lstrcat(szFile, ".bmp");
}
pszFile = szFile;
}
result = -2;
fh = OpenFile(pszFile , &ofs, OF_CREATE | OF_WRITE | OF_SHARE_EXCLUSIVE);
if (fh != HFILE_ERROR) {
result = TWAIN_WriteNativeToFile(hdib, fh);
_lclose(fh);
}
return result;
} // TWAIN_WriteNativeToFilename
int EZTAPI TWAIN_WriteNativeToFile(HANDLE hdib, HFILE fh)
// Writes a DIB to a file in .BMP format.
//
// hdib = DIB handle, as returned by TWAIN_AcquireNative
// fh = file handle, as returned by C _open or Windows _lopen or OpenFile
//
// Return value as for TWAIN_WriteNativeToFilename
{
int result = -3;
LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
if (lpbmi) {
result = -4;
if (TWAIN_WriteDibToFile(lpbmi, fh)) {
result = 0; // success
}
GlobalUnlock(hdib);
}
return result;
} // TWAIN_WriteNativeToFile
int EZTAPI TWAIN_WriteDibToFile(LPBITMAPINFOHEADER lpDIB, HFILE fh)
{
BITMAPFILEHEADER bfh;
int fOk = FALSE;
int nBPP = lpDIB->biBitCount;
int nColors = (int)lpDIB->biClrUsed;
// figure out actual size of color table
if (nColors == 0 && nBPP <= 8) {
nColors = (1 << nBPP);
}
if (lpDIB->biCompression == BI_RGB) {
// uncompressed bitmap, image size might not be set
DWORD dwBytesPerRow = (((lpDIB->biWidth * nBPP) + 31) / 32) * 4;
lpDIB->biSizeImage = dwBytesPerRow * lpDIB->biHeight;
} else if (lpDIB->biSizeImage == 0) {
// compressed bitmap, image size had damn well better be set!
return FALSE;
// This could be hacked around with something like this:
//lpDIB->biSizeImage = GlobalSize((HANDLE)GlobalHandle(HIWORD(lpDIB)));
}
// Set up BMP header.
bfh.bfType = 0x4d42; // "BM"
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) +
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * nColors;
bfh.bfSize = bfh.bfOffBits + lpDIB->biSizeImage;
if (_lwrite(fh, (LPCSTR)&bfh, sizeof bfh) == sizeof bfh) {
INT32 towrite = bfh.bfSize - (INT32)sizeof bfh;
if (HUGEWRITE(fh, (LPCSTR)lpDIB, towrite) == towrite) {
fOk = TRUE;
}
}
return fOk;
} // TWAIN_WriteDibToFile
HANDLE EZTAPI TWAIN_LoadNativeFromFilename(LPCSTR pszFile)
// Load a .BMP file and return a DIB handle (as from AcquireNative.)
//
// pszFile = far pointer to NUL-terminated filename
// If pszFile is NULL or points to a null string, prompts the user
// for the filename with a standard file-open dialog.
//
// Return value:
// handle to a DIB if successful, otherwise NULL (0).
{
HANDLE hdib = NULL;
char szFile[256];
HFILE fh;
OFSTRUCT ofs;
if (!pszFile || !*pszFile) {
// prompt for filename
OPENFILENAME ofn;
int nExt;
FMEMSET(&ofn, 0, sizeof ofn);
szFile[0] = '\0';
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = "Windows Bitmaps (*.bmp)\0*.bmp\0\0";
ofn.lpstrFile= szFile;
ofn.nMaxFile = sizeof(szFile) - 5;
ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY |
OFN_NOREADONLYRETURN;
if (!GetOpenFileName(&ofn)) {
return NULL; // user cancelled dialog
}
// supply default extension - GetOpenFileName doesn't seem to do it!
nExt = ofn.nFileExtension;
if (nExt && !szFile[nExt]) {
// no extension
lstrcat(szFile, ".bmp");
}
pszFile = szFile;
}
fh = OpenFile(pszFile, &ofs, OF_READ | OF_SHARE_DENY_WRITE);
if (fh != HFILE_ERROR) {
hdib = TWAIN_LoadNativeFromFile(fh);
_lclose(fh);
}
return hdib;
} // TWAIN_LoadNativeFromFilename
HANDLE EZTAPI TWAIN_LoadNativeFromFile(HFILE fh)
// Like LoadNativeFromFilename, but takes an already open file handle.
{
HANDLE hdib;
LPBYTE pbi;
BITMAPFILEHEADER bmh;
INT32 dibSize;
// Read BMP file header and validate
if (_lread(fh, &bmh, sizeof bmh) != sizeof bmh ||
bmh.bfType != 0x4d42) {
return NULL;
}
// Allocate global block for DIB
dibSize = bmh.bfSize - sizeof bmh;
hdib = GlobalAlloc(0, dibSize);
pbi = (LPBYTE)GlobalLock(hdib);
if (!hdib || !pbi) {
return NULL;
}
// Read DIB from file
if (_hread(fh, pbi, dibSize) != dibSize) {
GlobalUnlock(hdib);
GlobalFree(hdib);
return NULL;
}
GlobalUnlock(hdib);
return hdib;
} // TWAIN_LoadNativeFromFile
///////////////////////////////////////////////////////////////////////
// TWAIN State 4 Negotiation Functions
int EZTAPI TWAIN_NegotiateXferCount(int nXfers)
{
return TWAIN_SetCapOneValue(CAP_XFERCOUNT, TWTY_INT16, nXfers);
} // TWAIN_NegotiateXferCount
int EZTAPI TWAIN_NegotiatePixelTypes(unsigned wPixTypes)
{
TW_CAPABILITY cap;
void far * pv;
int fSuccess = FALSE;
if (nState != TWAIN_SOURCE_OPEN) {
return RecordError(ED_NOT_STATE_4);
}
if (TWAIN_ANYTYPE == wPixTypes) {
return TRUE; // that was easy!
}
// Fill in capability structure
cap.Cap = ICAP_PIXELTYPE; // capability id
cap.ConType = TWON_ENUMERATION; // favorite type of container (should be ignored...)
if (!TWAIN_DS(DG_CONTROL, DAT_CAPABILITY, MSG_GET, (TW_MEMREF)&cap)) {
return RecordError(ED_CAP_GET);
}
if (!cap.hContainer) {
return RecordError(ED_NULL_HCON);
}
if (!(pv = GlobalLock(cap.hContainer))) {
// this source is invalid, further negotiation is unlikely to succeed
return RecordError(ED_BAD_HCON);
}
switch (cap.ConType) {
case TWON_ENUMERATION: {
TW_ENUMERATION far *pcon = (TW_ENUMERATION far *)pv;
if (pcon->NumItems < 1) {
RecordError(ED_CAP_GET_EMPTY);
} else if (pcon->ItemType != TWTY_UINT16 && pcon->ItemType != TWTY_INT16) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -