📄 twain.c
字号:
// UNISCAN windows scanning program
// Tsinghua Unisplendour Group
// Programmed in MS VC/C++
// Daohong Kan, Aug.23, 1996
#include "windows.h"
#include "stdio.h"
#include "string.h"
#include "scan.h"
#include "twain.h"
extern HWND hWnd;
DSMENTRYPROC pDSMEntry;
HANDLE hDSMLib;
TW_IDENTITY AppID, ScannerID;
char dsmOpened = 'N', dsOpened = 'N';
extern void UNMessageBox(char *);
UNTwainError(char*, TW_UINT16);
UNLoadDSM(void) // State 1 to 2, 3
{
char TwainDir[MAX_FILENAME];
OFSTRUCT of;
TW_UINT16 rc;
// State 1 to 2, Load DSM
GetWindowsDirectory(TwainDir, MAX_FILENAME);
lstrcat(TwainDir, "\\TWAIN_32.DLL");
if (OpenFile(TwainDir, &of, OF_EXIST) != -1)
hDSMLib = LoadLibrary(TwainDir);
else
hDSMLib = NULL;
if (!hDSMLib)
pDSMEntry = NULL;
else
{
pDSMEntry = (DSMENTRYPROC)GetProcAddress(hDSMLib, MAKEINTRESOURCE(1));
if (!pDSMEntry)
FreeLibrary(hDSMLib);
}
if (pDSMEntry == NULL)
{
UNMessageBox("No TWAIN DSM");
return(UN_ERROR);
}
// State 2 to 3, Open DSM
AppID.Id = 0;
AppID.Version.MajorNum = 1;
AppID.Version.MinorNum = 5;
AppID.Version.Language = TWLG_USA;
AppID.Version.Country = TWCY_USA;
lstrcpy(AppID.Version.Info, "Uniscan V1.0");
AppID.ProtocolMajor = TWON_PROTOCOLMAJOR;
AppID.ProtocolMinor = TWON_PROTOCOLMINOR;
AppID.SupportedGroups = DG_IMAGE | DG_CONTROL;
lstrcpy(AppID.Manufacturer, "Tsinghua Unisplendour Group Company");
lstrcpy(AppID.ProductFamily, "Uniscan Application");
lstrcpy(AppID.ProductName, "Uniscan");
rc = (*pDSMEntry)(&AppID, NULL, DG_CONTROL, DAT_PARENT, MSG_OPENDSM,
(TW_MEMREF)&hWnd);
if (UNTwainError("Open DSM", rc) == UN_OK)
{
dsmOpened = 'Y';
// State 3, Get default DS
rc = (*pDSMEntry)(&AppID, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT,
(TW_MEMREF)&ScannerID);
UNTwainError("DefaultDS", rc);
}
return(UN_OK);
}
UNSelectSource(void) // State 3
{
TW_UINT16 rc;
ScannerID.Id = 0;
ScannerID.ProductName[0] = '\0';
rc = (*pDSMEntry)(&AppID, NULL, DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT,
(TW_MEMREF)&ScannerID);
UNTwainError("Select Source", rc);
return (UN_OK);
}
UNOpenDS(void) // State 3 to 4
{
TW_UINT16 rc;
rc = (*pDSMEntry)(&AppID, NULL, DG_CONTROL, DAT_IDENTITY, MSG_OPENDS,
(TW_MEMREF)&ScannerID);
if (UNTwainError("Open DS", rc) == UN_OK)
dsOpened = 'Y';
return (UN_OK);
}
UNNegotiateCap(void) // State 4
{
TW_UINT16 rc;
TW_CAPABILITY twCap;
pTW_ONEVALUE pval;
twCap.hContainer = GlobalAlloc(GHND, sizeof(TW_ONEVALUE));
pval = (pTW_ONEVALUE)GlobalLock(twCap.hContainer);
/* The following is for ADF only, can be deleted
// Set ADF
twCap.Cap = CAP_FEEDERENABLED;
twCap.ConType = TWON_ONEVALUE;
pval->ItemType = TWTY_UINT16;
pval->Item = FALSE;
rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_CAPABILITY, MSG_SET,
(TW_MEMREF)&twCap);
if (UNTwainError("Negotiate FEEDERENABLED", rc) == UN_OK)
{
// Set paper autofeeding
twCap.Cap = CAP_AUTOFEED;
twCap.ConType = TWON_ONEVALUE;
pval->ItemType = TWTY_UINT16;
pval->Item = TRUE;
rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_CAPABILITY, MSG_SET,
(TW_MEMREF)&twCap);
UNTwainError("Negotiate AUTOFEED", rc);
}
*/
// Set multi-image transfer
twCap.Cap = CAP_XFERCOUNT;
twCap.ConType = TWON_ONEVALUE;
pval->ItemType = TWTY_UINT16;
pval->Item = (TW_UINT32)-1;
rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_CAPABILITY, MSG_SET,
(TW_MEMREF)&twCap);
UNTwainError("Negotiate XFERCOUNT", rc);
// Set buffer memory transfer
twCap.Cap = ICAP_XFERMECH;
twCap.ConType = TWON_ONEVALUE;
pval->ItemType = TWTY_UINT16;
pval->Item = TWSX_MEMORY;
rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_CAPABILITY, MSG_SET,
(TW_MEMREF)&twCap);
UNTwainError("Negotiate XFERMECH", rc);
// Set pixel flavor
twCap.Cap = ICAP_PIXELFLAVOR;
twCap.ConType = TWON_ONEVALUE;
pval->ItemType = TWTY_UINT16;
pval->Item = TWPF_CHOCOLATE;
rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_CAPABILITY, MSG_SET,
(TW_MEMREF)&twCap);
UNTwainError("Negotiate PIXELFLAVOR", rc);
GlobalUnlock(twCap.hContainer);
GlobalFree(twCap.hContainer);
return (UN_OK);
}
UNEnableDS(void) // State 4 to 5
{
TW_UINT16 rc;
TW_USERINTERFACE ui;
ui.ShowUI = TRUE;
ui.ModalUI = FALSE;
ui.hParent = hWnd;
rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS,
(TW_MEMREF)&ui);
UNTwainError("Enable DS", rc);
return (UN_OK);
}
UNGetImage() // State 6 to 7, 7 to 6
{
TW_UINT16 rc;
TW_IMAGEINFO iInfo;
TW_IMAGELAYOUT iLay;
TW_SETUPMEMXFER iMem;
TW_IMAGEMEMXFER iBuf;
TW_PENDINGXFERS iEnd;
HANDLE hBuf;
char hasNextBuf, str[256];
unsigned char TW_HUGE *buf;
HFILE hFile;
OFSTRUCT of;
iEnd.Count = 1;
while (iEnd.Count != 0)
{
// Get image information
rc = (*pDSMEntry)(&AppID, &ScannerID, DG_IMAGE, DAT_IMAGEINFO, MSG_GET,
(TW_MEMREF)&iInfo);
sprintf(str, "xRes=%d yRes=%d\nWidth=%ld Height=%ld\nSamp=%d Bits=%d",
iInfo.XResolution.Whole, iInfo.YResolution.Whole,
iInfo.ImageWidth, iInfo.ImageLength,
iInfo.SamplesPerPixel, iInfo.BitsPerPixel);
switch (iInfo.PixelType)
{
case TWPT_BW : lstrcat(str, "\nType=BW"); break;
case TWPT_GRAY: lstrcat(str, "\nType=GRAY"); break;
case TWPT_RGB : lstrcat(str, "\nType=RGB"); break;
default: // Not accepted by application, such as TWPT_CMYK, TWPT_YUV
lstrcat(str, "\nType=Error"); break;
}
UNMessageBox(str);
// Get image layout
rc = (*pDSMEntry)(&AppID, &ScannerID, DG_IMAGE, DAT_IMAGELAYOUT, MSG_GET,
(TW_MEMREF)&iLay);
sprintf(str, "L=%d T=%d R=%d B=%d\nDNo=%ld PNo=%ld FNo=%ld",
iLay.Frame.Left.Whole, iLay.Frame.Top.Whole,
iLay.Frame.Right.Whole, iLay.Frame.Bottom.Whole,
iLay.DocumentNumber, iLay.PageNumber, iLay.FrameNumber);
UNMessageBox(str);
// Get memory preferred
rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_SETUPMEMXFER, MSG_GET,
(TW_MEMREF)&iMem);
//sprintf(str, "Min=%ld Max=%ld Pre=%ld",
// iMem.MinBufSize, iMem.MaxBufSize, iMem.Preferred);
//UNMessageBox(str);
hBuf = GlobalAlloc(GHND, iMem.Preferred);
buf = (unsigned char TW_HUGE *)GlobalLock(hBuf);
iBuf.Memory.Flags = TWMF_APPOWNS | TWMF_POINTER;
iBuf.Memory.Length = iMem.Preferred;
iBuf.Memory.TheMem = buf;
iBuf.Compression = TWON_DONTCARE16;
iBuf.BytesPerRow = TWON_DONTCARE32;
iBuf.Columns = TWON_DONTCARE32;
iBuf.Rows = TWON_DONTCARE32;
iBuf.XOffset = TWON_DONTCARE32;
iBuf.YOffset = TWON_DONTCARE32;
iBuf.BytesWritten = TWON_DONTCARE32;
hasNextBuf = 'Y';
hFile = OpenFile("IMAGE.DAT", &of, OF_CREATE);
_lwrite(hFile, (const char*)&iInfo.ImageWidth, 4);
_lwrite(hFile, (const char*)&iInfo.ImageLength, 4);
while (hasNextBuf == 'Y')
{
rc = (*pDSMEntry)(&AppID, &ScannerID,
DG_IMAGE, DAT_IMAGEMEMXFER, MSG_GET,
(TW_MEMREF)&iBuf);
switch (rc)
{
case TWRC_SUCCESS:
sprintf(str, "Byte/Row=%ld Columns=%ld\nRows=%ld Bytes=%ld",
iBuf.BytesPerRow, iBuf.Columns, iBuf.Rows, iBuf.BytesWritten);
UNMessageBox(str);
// Here to process or save image data in buf
_lwrite(hFile, buf, (UINT)iBuf.BytesWritten);
iBuf.Memory.TheMem = buf;
//_fmemset(buf, 0, (size_t)iMem.Preferred);
break;
case TWRC_XFERDONE:
sprintf(str, "Byte/Row=%ld Columns=%ld\nRows=%ld Bytes=%ld",
iBuf.BytesPerRow, iBuf.Columns, iBuf.Rows, iBuf.BytesWritten);
UNMessageBox(str);
// Here to process or save image data in buf
_lwrite(hFile, buf, (UINT)iBuf.BytesWritten);
_lclose(hFile);
hasNextBuf = 'N';
GlobalUnlock(hBuf);
GlobalFree(hBuf);
rc = (*pDSMEntry)(&AppID, &ScannerID,
DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER,
(TW_MEMREF)&iEnd);
SendMessage(hWnd, UN_XFERDONE, 0, 0);
break;
case TWRC_CANCEL:
case TWRC_FAILURE:
default:
_lclose(hFile);
hasNextBuf = 'N';
GlobalUnlock(hBuf);
GlobalFree(hBuf);
rc = (*pDSMEntry)(&AppID, &ScannerID,
DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER,
(TW_MEMREF)&iEnd);
SendMessage(hWnd, UN_XFERDONE, 0, 0);
break;
}
}
sprintf(str, "Image Ready=%d", iEnd.Count);
UNMessageBox(str);
}
return(UN_OK);
}
UNCloseDS(void) // State 5 to 3
{
TW_UINT16 rc;
TW_USERINTERFACE ui;
ui.ShowUI = TRUE;
ui.ModalUI = TRUE;
ui.hParent = hWnd;
rc = (*pDSMEntry)(&AppID, &ScannerID, DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS,
(TW_MEMREF)&ui);
rc = (*pDSMEntry)(&AppID, NULL, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS,
(TW_MEMREF)&ScannerID);
dsOpened = 'N';
return (UN_OK);
}
UNCloseDSM(void) // State 3 to 1
{
TW_UINT16 rc;
rc = (*pDSMEntry)(&AppID, NULL, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM,
(TW_MEMREF)&hWnd);
FreeLibrary(hDSMLib);
dsmOpened = 'N';
return (UN_OK);
}
UNTwainError(char *act, TW_UINT16 rc)
{
char str[256];
lstrcpy(str, act);
switch(rc)
{
case TWRC_SUCCESS:
lstrcat(str, ": Success");
//UNMessageBox(str);
return(UN_OK);
break;
case TWRC_FAILURE:
default:
lstrcat(str, ": Failure");
UNMessageBox(str);
return(UN_ERROR);
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -