TWAIN协议(Toolkit Without An Interesting Name)

来源:互联网 发布:淘宝如何入驻全球购 编辑:程序博客网 时间:2024/04/27 20:51
 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<<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);

 

原创粉丝点击