TWAIN协议(Toolkit Without An Interesting Name)
TWAIN指TWAIN协议,是应用 软件从计算机外设获取静态图像的国际标准。 TWAIN是一项重要的接口标准,为软件开发商和硬件设备生产厂商之间提供了一个统一的规范,以有效地避免系统及设备之间的不兼容问题。TWAIN协议为 操作系统提供了软件支持,使得符合TWAIN协议的软件通过调用TWAIN协议接口就能从兼容TWAIN协议的外设上获取静态图像,而不必考虑外设的功能差别。 比如,Photoshop是一款符合TWAIN协议要求的软件。在Photoshop中,通过点击菜单File|Select...可以选择不同的外设,然后点击菜单File|Acquire...弹出相应外设的TWAIN界面对话框,通过这个对话框可以设置图像的各种参数并获取图像。 目前TWAIN协议覆盖的外设范围包括扫描仪、数码相机、数字音频和图像数据库(作为虚拟外设)等,TWAIN协议是一个开放协议,符合TWAIN协议的设备都可以向调用TWAIN接口的软件提供数据。 TWAIN协议全称Toolkit Without An Interesting Name,无注名工具包协议,由TWAIN工作组负责开发,目前版本是2.1。支持win7 32位及64位系统,支持Linux/Unix系统。 有关符合TWAIN协议软件和硬件开发请访问TWAIN工作组网站(www.twain.org)。
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<
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);
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
