32位Windows下TWAIN协议软件接口模块是twain_32.dll,由Windows操作系统自带,并且可以随兼容TWAIN的软件和硬件驱动自由分发。
//对话框程序,稍微修改就可以用的代码
//#include "twain.h"
/************************************************************************/
/* STATE 1 to 2: Load the Source manager and Get the DSM_Entry */
/************************************************************************/
//加载动态库
HMODULE hDLL;
hDLL = LoadLibrary(_T("twain_32.dll"));
if (hDLL == NULL)
return;
//获取函数指针
DSMENTRYPROC fnDSMEntry;
fnDSMEntry = (DSMENTRYPROC)GetProcAddress(hDLL,"DSM_Entry");
//如果指针为空,释放掉句柄
if (fnDSMEntry == NULL)
{
FreeLibrary(hDLL);
return;
}
/************************************************************************/
/* STATE 2 TO 3 :Open the Source Manager */
/************************************************************************/
TW_IDENTITY twApp;
TW_UINT16 nRet;
//获取窗口句柄
TW_INT32 nParent = (TW_INT32)GetSafeHwnd();
twApp.Id = 0;
strcpy_s(twApp.Manufacturer,sizeof(TW_STR32),"Avision");
strcpy_s(twApp.ProductFamily,sizeof(TW_STR32),"Demo");
strcpy_s(twApp.ProductName,sizeof(TW_STR32),"TwainTest");
twApp.ProtocolMajor = TWON_PROTOCOLMAJOR;
twApp.ProtocolMinor = TWON_PROTOCOLMINOR;
twApp.SupportedGroups = DG_IMAGE | DG_CONTROL;
twApp.Version.Country = TWCY_CHINA;
twApp.Version.Language = TWLG_CHINESE;
twApp.Version.MajorNum = 0;
twApp.Version.MinorNum = 0;
strcpy_s(twApp.Version.Info,sizeof(TW_STR32),"TwainDemo Info");
nRet = fnDSMEntry(&twApp,NULL,DG_CONTROL,DAT_PARENT,MSG_OPENDSM,&nParent);
// If success then goto state 3
if (nRet == TWRC_SUCCESS)
{
TW_IDENTITY twDest;
twDest.Id = 0;
/************************************************************************/
/* STATE 3 :Select the Source */
/************************************************************************/
nRet = fnDSMEntry(&twApp,NULL,DG_CONTROL,DAT_IDENTITY,MSG_USERSELECT,&twDest);
// nRet = fnDSMEntry(&twApp,NULL,DG_CONTROL,DAT_IDENTITY,MSG_GETDEFAULT,&twDest);
/************************************************************************/
/* STATE 3 to 4 :Open the Source */
/************************************************************************/
nRet = fnDSMEntry(&twApp,NULL,DG_CONTROL,DAT_IDENTITY,MSG_OPENDS,&twDest);
if (nRet == TWRC_SUCCESS)
{
/************************************************************************/
/* STATE 4 */
/************************************************************************/
TW_CAPABILITY twCap;
twCap.Cap = ICAP_XFERMECH;
twCap.ConType = TWON_ONEVALUE;
twCap.hContainer = GlobalAlloc(GHND,sizeof(TW_ONEVALUE));
pTW_ONEVALUE pValue = (pTW_ONEVALUE)GlobalLock(twCap.hContainer);
pValue->Item = TWTY_UINT16;
pValue->ItemType = TWSX_NATIVE;
GlobalUnlock(twCap.hContainer);
nRet = fnDSMEntry(&twApp,&twDest,DG_CONTROL,DAT_CAPABILITY,MSG_SET,&twCap);
GlobalFree(twCap.hContainer);
/************************************************************************/
/* STATE 4 to 5 */
/************************************************************************/
TW_USERINTERFACE twUI;
twUI.hParent = GetSafeHwnd();
twUI.ModalUI = 0;
twUI.ShowUI = TRUE;
nRet = fnDSMEntry(&twApp,&twDest,DG_CONTROL,DAT_USERINTERFACE,MSG_ENABLEDS,&twUI);
/************************************************************************/
/* STATE 5 to 6 */
/************************************************************************/
if (nRet == TWRC_SUCCESS)
{
TW_EVENT twEvent;
MSG msg;
BOOL bLoop = TRUE;
while (bLoop&&GetMessage(&msg,NULL,0,0))
{
twEvent.pEvent = &msg;
twEvent.TWMessage = MSG_NULL;
nRet = fnDSMEntry(&twApp,&twDest,DG_CONTROL,DAT_EVENT,MSG_PROCESSEVENT,&twEvent);
if (nRet == TWRC_DSEVENT)
{
switch(twEvent.TWMessage)
{
case MSG_XFERREADY:
{
/************************************************************************/
/* STATE 6 to 7 */
/************************************************************************/
HBITMAP hBitmap;
int count = 0;
TCHAR szFilename[_MAX_PATH];
CFile szFile;
TW_PENDINGXFERS twPx;
while (TRUE)
{
count++;
nRet = fnDSMEntry(&twApp,&twDest,DG_IMAGE,DAT_IMAGENATIVEXFER,MSG_GET,&hBitmap);
{
_stprintf_s(szFilename,_MAX_PATH,_T("D:\\temp\\%04d.bmp"),count);
if (szFile.Open(szFilename,CFile::modeCreate|CFile::modeWrite))
{
int nHeight,nWidth;
int nBPP;
LPBITMAPINFO pBMP;
LPBYTE pData = (LPBYTE)GlobalLock(hBitmap);
pBMP = (LPBITMAPINFO)pData;
nHeight = pBMP->bmiHeader.biHeight;
nWidth = pBMP->bmiHeader.biWidth;
nBPP = pBMP->bmiHeader.biBitCount;
int nColor = (nBPP>8)?0:(1<<nBPP);
int nBytePerline = (nWidth*nBPP+31)/32*4;
int nImageSize = nBytePerline*nHeight;
BITMAPFILEHEADER bh;
bh.bfType = 0x4d42;
bh.bfReserved1 = 0;
bh.bfReserved2 = 0;
bh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nColor*sizeof(RGBQUAD);
bh.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nColor*sizeof(RGBQUAD)+nImageSize;
szFile.Write(&bh,sizeof(BITMAPFILEHEADER));
szFile.Write(pData,sizeof(BITMAPINFOHEADER)+nColor*sizeof(RGBQUAD)+nImageSize);
szFile.Close();
}
}
GlobalFree(hBitmap);
/************************************************************************/
/* STATE 7 to 6 to 5 */
/************************************************************************/
nRet = fnDSMEntry(&twApp,&twDest,DG_CONTROL,DAT_PENDINGXFERS,MSG_ENDXFER,&twPx);
if (nRet != TWRC_SUCCESS)
break;
if(twPx.Count == 0)
break;
}
bLoop = FALSE;
break;
}
case MSG_CLOSEDSOK:
case MSG_CLOSEDSREQ:
bLoop = FALSE;
break;
default:
TranslateMessage(&msg);
DispatchMessage(&msg);
break;
}
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
//State 5 to 4
fnDSMEntry(&twApp,&twDest,DG_CONTROL,DAT_USERINTERFACE,MSG_DISABLEDS,&twUI);;
}
//State 4 to 3
fnDSMEntry(&twApp,NULL,DG_CONTROL,DAT_IDENTITY,MSG_CLOSEDS,&twDest);
}
//失败了,获取状态
else if(nRet ==TWRC_FAILURE)
{
TW_STATUS twStatus;
nRet = fnDSMEntry(&twApp,NULL,DG_CONTROL,DAT_IDENTITY,MSG_GET,&twStatus);
}
//State 3 to 2
// Close the DMS
nRet = fnDSMEntry(&twApp,NULL,DG_CONTROL,DAT_PARENT,MSG_CLOSEDSM,&nParent);
}
//State 2 to 1
FreeLibrary(hDLL);