TWAIN.CPP
- include "twaincpp.h"
- #include <QtGlobal>
- #include <QDateTime>
- #include <QString>
- #pragma execution_character_set("utf-8");
- CTwain::CTwain(HWND hWnd)
- {
- m_hMessageWnd = nullptr;//消息窗口句柄
- m_hTwainDLL = nullptr;//是否已载入库
- m_pDSMProc = nullptr;//数据源管理器
- m_bSourceSelected = false;//是否已选择数据源
- m_bDSOpen = false;//是否已打开数据源
- m_bDSMOpen = false;//是否已打开数据源管理器
- m_bSourceEnabled = false;//数据源是否设为可用
- m_bModalUI = true;
- m_nImageCount = TWCPP_ANYCOUNT;
- if(hWnd)
- {
- qDebug()<<"在构造函数中安装Twain";
- InitTwain(hWnd);
- }
- }
- CTwain::~CTwain()
- {
- ReleaseTwain();
- }
- /*
- Initializes TWAIN interface . Is already called from the constructor.
- It should be called again if ReleaseTwain is called.
- hWnd is the window which has to subclassed in order to recieve
- Twain messaged. Normally - this would be your main application window.
- 初始化TWAIN接口。已经从构造函数调用。
- 如果调用ReleaseTwain,则应再次调用它。
- hWnd是必须进行子类化以便接收的窗口Twain消息。
- 通常 - 这将是您的主要应用程序窗口。
- */
- bool CTwain::InitTwain(HWND hWnd)
- {
- qDebug()<<"****************开始安装Twain****************";
- char libName[512];
- if(IsValidDriver())
- {
- return true;
- }
- memset(&m_AppId,0,sizeof(m_AppId));
- if(!IsWindow(hWnd))//确定给定的窗口句柄是否标识一个已存在的窗口
- {
- return false;
- }
- m_hMessageWnd = hWnd;//要传递消息的窗口
- strcpy_s(libName,"TWAIN_32.DLL");
- m_hTwainDLL = LoadLibraryA(libName);//载入库
- if(m_hTwainDLL != nullptr)
- {
- qDebug()<<"已载入有效扫描驱动";
- //获取数据源管理器入
- if(!(m_pDSMProc = (DSMENTRYPROC)GetProcAddress(m_hTwainDLL,(LPCSTR)MAKEINTRESOURCE(1))))
- {
- qDebug()<<"获取数据源管理器入口失败";
- FreeLibrary(m_hTwainDLL);
- m_hTwainDLL = nullptr;
- }
- else
- {
- qDebug()<<"获取数据源管理器入口成功";
- }
- }
- if(IsValidDriver())//成功载入驱动且获取了数据源管理器
- {
- GetIdentity();//设置应用程序信息
- //打开数据源管理器
- m_bDSMOpen = CallTwainProc(&m_AppId,nullptr,DG_CONTROL,DAT_PARENT,MSG_OPENDSM,(TW_MEMREF)&m_hMessageWnd);
- if(m_bDSMOpen)
- {
- qDebug()<<"初始化Twain接口:打开数据源管理器成功";
- get_source_list();
- qDebug()<<"****************结束安装Twain****************";
- return true;
- }
- else
- {
- qDebug()<<"初始化Twain接口:打开数据源管理器失败";
- qDebug()<<"****************结束安装Twain****************";
- return false;
- }
- }
- else
- {
- qDebug()<<"****************结束安装Twain****************";
- return false;
- }
- }
- /*
- Releases the twain interface . Need not be called unless you
- want to specifically shut it down.
- 释放twain接口。除非你想要特别关闭它。
- */
- void CTwain::ReleaseTwain()
- {
- qDebug()<<"****************开始析构Twain****************";
- if(IsValidDriver())//如果已加载有效的驱动程序且存在数据源管理器入口
- {
- CloseDSM();
- FreeLibrary(m_hTwainDLL);
- m_hTwainDLL = nullptr;
- m_pDSMProc = nullptr;
- sourcelist.clear();
- }
- qDebug()<<"****************结束析构Twain****************";
- }
- /*
- Returns true if a valid driver has been loaded
- 如果已加载有效的驱动程序且存在数据源管理器入口,则返回true
- */
- bool CTwain::IsValidDriver() const
- {
- return (m_hTwainDLL && m_pDSMProc);
- }
- /*
- Entry point into Twain. For a complete description of this
- routine please refer to the Twain specification 1.8
- 进入Twain的入口点。有关此的完整描述
- 例程请参考Twain规范1.8
- */
- bool CTwain::CallTwainProc(pTW_IDENTITY pOrigin,pTW_IDENTITY pDest,
- TW_UINT32 DG,TW_UINT16 DAT,TW_UINT16 MSG,
- TW_MEMREF pData)
- {
- // qDebug()<<"****************开始数据源管理器相关操作****************";
- if(IsValidDriver())//如果已加载有效的驱动程序且存在数据源管理器入口
- {
- USHORT ret_val;
- //数据源管理器相关操作
- ret_val = (*m_pDSMProc)(pOrigin,pDest,DG,DAT,MSG,pData);
- // qDebug()<<"数据源管理器相关操作结果"<<ret_val;
- m_returnCode = ret_val;
- /////////////////////吐血开始//////////////////
- // if(ret_val != TWRC_SUCCESS)
- // {
- // qDebug()<<"数据源管理器相关操作失败";
- // //初始化数据源管理器
- // (*m_pDSMProc)(pOrigin,pDest,DG_CONTROL,DAT_STATUS,MSG_GET,&m_Status);
- // }
- // else
- // {
- // qDebug()<<"数据源管理器相关操作成功";
- // }
- ////////////////////吐血结束/////////////////
- // qDebug()<<"****************结束数据源管理器相关操作****************A";
- return (ret_val == TWRC_SUCCESS);
- }
- else
- {
- m_returnCode = TWRC_FAILURE;
- // qDebug()<<"****************未加载有效的驱动程序或不存在数据源管理器入口****************";
- // qDebug()<<"****************结束数据源管理器相关操作****************B";
- return false;
- }
- }
- /*
- This function should ideally be overridden in the derived class . If only a
- few fields need to be updated , call CTawin::GetIdentity first in your
- derived class
- 理想情况下,应在派生类中重写此函数。 如果只有一个
- 几个字段需要更新,首先在你的电话中调用CTawin :: GetIdentity
- 派生类
- 设置应用程序信息
- */
- void CTwain::GetIdentity()
- {
- // Expects all the fields in m_AppId to be set except for the id field.
- //期望m_AppId中的所有字段都要设置,除了id字段。
- m_AppId.Id = 0; // Initialize to 0 Source Manager
- // will assign real value)
- m_AppId.Version.MajorNum = 1; //Your app's version number
- m_AppId.Version.MinorNum = 0;
- m_AppId.Version.Language = TWLG_USA;
- m_AppId.Version.Country = TWCY_USA;
- strcpy_s (m_AppId.Version.Info, "1.0");
- m_AppId.ProtocolMajor = TWON_PROTOCOLMAJOR;
- m_AppId.ProtocolMinor = TWON_PROTOCOLMINOR;
- m_AppId.SupportedGroups = DG_IMAGE | DG_CONTROL;
- strcpy_s (m_AppId.Manufacturer, "MICSS");
- strcpy_s (m_AppId.ProductFamily, "Generic");
- strcpy_s (m_AppId.ProductName, "jiandao Twain");
- }
- /*
- Called to display a dialog box to select the Twain source to use.
- This can be overridden if a list of all sources is available
- to the application. These sources can be enumerated by Twain.
- it is not yet supportted by CTwain.
- 调用以显示一个对话框以选择要使用的Twain源。
- 如果所有源列表都可用,则可以覆盖此项
- 到申请。这些来源可以由Twain列举。
- 它还没有得到CTwain的支持。
- //选择数据源
- MSG_USERSELECT的效果是弹出一个框让用户选择数据源
- */
- bool CTwain::SelectSource()
- {
- qDebug()<<"****************开始选择数据源****************";
- memset(&m_Source,0,sizeof(m_Source));
- if(!SourceSelected())//扫描时候未选择数据源,则设置数据源为默认的数据源
- {
- SelectDefaultSource();
- }
- if(CallTwainProc(&m_AppId,nullptr,DG_CONTROL,DAT_IDENTITY,MSG_USERSELECT,&m_Source))//MSG_OPENDS
- {
- m_bSourceSelected = true;
- qDebug()<<"成功应用所选的数据源";
- }
- else
- {
- m_bSourceSelected = false;
- qDebug()<<"应用所选的数据源失败";
- }
- qDebug()<<"****************结束选择数据源****************";
- return m_bSourceSelected;
- }
- //选择默认的数据源
- bool CTwain::SelectDefaultSource()
- {
- qDebug()<<"未选择数据源,使用默认的数据源";
- m_bSourceSelected = CallTwainProc(&m_AppId,nullptr,DG_CONTROL,DAT_IDENTITY,MSG_GETDEFAULT,&m_Source);
- if(m_bSourceSelected)
- {
- qDebug()<<"使用默认的数据源成功";
- }
- else
- {
- qDebug()<<"使用默认的数据源失败";
- }
- return m_bSourceSelected;
- }
- //关闭数据源 先禁用再关闭
- void CTwain::CloseDS()
- {
- qDebug()<<"****************开始关闭数据源****************";
- if(DSOpen())//数据源是打开的
- {
- DisableSource();
- qDebug()<<"关闭数据源";
- CallTwainProc(&m_AppId,nullptr,DG_CONTROL,DAT_IDENTITY,MSG_CLOSEDS,(TW_MEMREF)&m_Source);
- m_bDSOpen = false;
- }
- qDebug()<<"****************结束关闭数据源****************";
- }
- //关闭数据源管理器
- void CTwain::CloseDSM()
- {
- qDebug()<<"****************开始关闭数据源管理器****************";
- if(DSMOpen())//如果数据源管理器是打开的
- {
- CloseDS();//关闭数据源
- qDebug()<<"执行关闭数据源管理器";
- CallTwainProc(&m_AppId,nullptr,DG_CONTROL,DAT_PARENT,MSG_CLOSEDSM,(TW_MEMREF)&m_hMessageWnd);
- m_bDSMOpen = false;
- }
- qDebug()<<"****************结束关闭数据源管理器****************";
- }
- /*如果:
- 1、数据源是打开的
- 2、数据源管理器是打开的
- 3、数据源管理器入口存在
- 返回true
- */
- bool CTwain::DSMOpen() const
- {
- return IsValidDriver() && m_bDSMOpen;
- }
- /*如果:
- 1、数据源是打开的
- 2、数据源管理器是打开的
- 3、数据源管理器入口存在
- 4、已载入扫描驱动
- 返回true
- */
- bool CTwain::DSOpen() const
- {
- return IsValidDriver() && DSMOpen() && m_bDSOpen;
- }
- //打开作为输入参数提供的数据源
- bool CTwain::OpenSource(TW_IDENTITY *pSource)
- {
- if(pSource)
- {
- m_Source = *pSource;
- }
- if(DSMOpen())//如果此时数据源管理器是打开的
- {
- qDebug()<<"xxxxxxxxxxx";
- if(!SourceSelected())//此时未选中数据源
- {
- SelectDefaultSource();
- }
- //打开数据源
- m_bDSOpen = CallTwainProc(&m_AppId,nullptr,DG_CONTROL,DAT_IDENTITY,MSG_OPENDS,(TW_MEMREF)&m_Source);
- }
- return DSOpen();
- }
- /*
- Should be called from the main message loop of the application. Can always be called,
- it will not process the message unless a scan is in progress.
- 应该从应用程序的主消息循环调用。可以随时调用,
- 除非正在进行扫描,否则它不会处理消息。
- 消息事件
- */
- bool CTwain::ProcessMessage(MSG msg)
- {
- if (msg.message == 528) // don't really know why...
- {
- return false;
- }
- if (m_hMessageWnd == nullptr)
- {
- return false;
- }
- if(SourceEnabled() && m_pDSMProc)//如果数据源可用
- {
- TW_EVENT twEvent;
- twEvent.pEvent = (TW_MEMREF)&msg;
- twEvent.TWMessage = MSG_NULL;
- TW_UINT16 twRC = TWRC_NOTDSEVENT;
- //从扫描仪中获取事件
- twRC = CallTwainProc(&m_AppId,&m_Source,DG_CONTROL,DAT_EVENT,MSG_PROCESSEVENT,(TW_MEMREF)&twEvent);
- if(twRC != TWRC_NOTDSEVENT)
- {
- switch(twEvent.TWMessage)
- {
- case MSG_XFERREADY:
- TransferImage();//传输图像或取消传输
- break;
- case MSG_CLOSEDSREQ://关闭数据源
- CloseDS();
- break;
- case MSG_CLOSEDSOK:
- break;
- case MSG_DEVICEEVENT:
- break;
- default: ;
- //qDebug()<<"都不是";
- }
- }
- else
- {
- qDebug()<<"无法获取事件";
- }
- return false;
- }
- else
- {
- // qDebug()<<"数据源不可用";
- }
- return false;
- }
- /*
- Queries the capability of the Twain Data Source
- 查询twain数据源的功能
- */
- bool CTwain::GetCapability(TW_CAPABILITY& twCap,TW_UINT16 cap,TW_UINT16 conType)
- {
- if(DSOpen())
- {
- twCap.Cap = cap;
- twCap.ConType = conType;
- twCap.hContainer = nullptr;
- if(CallTwainProc(&m_AppId,&m_Source,DG_CONTROL,DAT_CAPABILITY,MSG_GET,(TW_MEMREF)&twCap))
- {
- return true;
- }
- }
- return false;
- }
- /*
- Queries the capability of the Twain Data Source
- 同上 重载函数
- */
- bool CTwain::GetCapability(TW_UINT16 cap,TW_UINT32& value)
- {
- TW_CAPABILITY twCap;
- if(GetCapability(twCap,cap))
- {
- pTW_ONEVALUE pVal;
- pVal = (pTW_ONEVALUE )GlobalLock(twCap.hContainer);
- if(pVal)
- {
- value = pVal->Item;
- GlobalUnlock(pVal);
- GlobalFree(twCap.hContainer);
- return true;
- }
- }
- return false;
- }
- /*
- Sets the capability of the Twain Data Source
- 设置twain数据源的功能
- */
- bool CTwain::SetCapability(TW_UINT16 cap,TW_UINT16 value,bool sign)
- {
- if(DSOpen())
- {
- TW_CAPABILITY twCap;
- pTW_ONEVALUE pVal;
- bool ret_value = false;
- twCap.Cap = cap;
- twCap.ConType = TWON_ONEVALUE;
- twCap.hContainer = GlobalAlloc(GHND,sizeof(TW_ONEVALUE));
- if(twCap.hContainer)
- {
- pVal = (pTW_ONEVALUE)GlobalLock(twCap.hContainer);
- pVal->ItemType = sign ? TWTY_INT16 : TWTY_UINT16;
- pVal->Item = (TW_UINT32)value;
- GlobalUnlock(twCap.hContainer);
- ret_value = SetCapability(twCap);
- GlobalFree(twCap.hContainer);
- }
- return ret_value;
- }
- return false;
- }
- bool CTwain::SetResolution(TW_UINT16 cap,TW_UINT32 value)
- {
- if(DSOpen())
- {
- TW_CAPABILITY twCap;
- pTW_ONEVALUE pVal;
- BOOL ret_value = FALSE;
- twCap.Cap = cap;
- twCap.ConType = TWON_ONEVALUE;
- twCap.hContainer = GlobalAlloc(GHND,sizeof(TW_ONEVALUE));
- if(twCap.hContainer)
- {
- pVal = (pTW_ONEVALUE)GlobalLock(twCap.hContainer);
- pVal->ItemType = TWTY_FIX32;
- pVal->Item = (TW_UINT32)value;
- GlobalUnlock(twCap.hContainer);
- ret_value = SetCapability(twCap);
- GlobalFree(twCap.hContainer);
- }
- return ret_value;
- }
- return FALSE;
- }
- /*
- Sets the capability of the Twain Data Source
- 同上 重载函数
- */
- bool CTwain::SetCapability(TW_CAPABILITY& cap)
- {
- if(DSOpen())
- {
- return CallTwainProc(&m_AppId,&m_Source,DG_CONTROL,DAT_CAPABILITY,MSG_SET,(TW_MEMREF)&cap);
- }
- return false;
- }
- /*
- Sets the number of images which can be accpeted by the application at one time
- 设置应用程序一次可接收的图像数
- */
- bool CTwain::SetImageCount(TW_INT16 nCount)
- {
- if(SetCapability(CAP_XFERCOUNT,(TW_UINT16)nCount,true))
- {
- m_nImageCount = nCount;
- return true;
- }
- else
- {
- if(GetRC() == TWRC_CHECKSTATUS)
- {
- TW_UINT32 count;
- if(GetCapability(CAP_XFERCOUNT,count))
- {
- nCount = (TW_INT16)count;
- if(SetCapability(CAP_XFERCOUNT,nCount))
- {
- m_nImageCount = nCount;
- return true;
- }
- }
- }
- }
- return false;
- }
- /*
- Called to enable the Twain Acquire Dialog. This too can be
- overridden but is a helluva job .
- 调用以启用TWAIN获取对话框。这也可以
- 被重写,但这是一个地狱般的工作。
- 使数据源可用
- */
- bool CTwain::EnableSource(bool showUI)
- {
- qDebug()<<"****************开始使数据源可用****************";
- if(DSOpen() && !SourceEnabled())//数据源打开了且数据源不可用
- {
- twUI.ShowUI = false/*showUIfalse*/;//是否打开默认的UI 111111111111111111111111111111111这里不设为false会报错 看看
- twUI.hParent = (TW_HANDLE)m_hMessageWnd;//消息窗口作为默认ui的主窗口
- //启用数据源
- if(CallTwainProc(&m_AppId,&m_Source,DG_CONTROL,DAT_USERINTERFACE,MSG_ENABLEDS,(TW_MEMREF)&twUI))
- {
- m_bSourceEnabled = true;
- m_bModalUI = twUI.ModalUI;
- qDebug()<<"启用数据源成功 EnableSource";
- }
- else
- {
- m_bSourceEnabled = false;
- m_bModalUI = true;
- qDebug()<<"启用数据源失败 EnableSource";
- }
- return m_bSourceEnabled;
- }
- return false;
- }
- /*
- Called to acquire images from the source. parameter numImages i the
- numberof images that you an handle concurrently
- 调用以从源获取图像。参数numImages i
- 同时处理的图像数
- */
- bool CTwain::Acquire(int numImages,TW_UINT16 duplex,TW_UINT16 size,TW_UINT16 pixel,TW_UINT16 resolution)
- {
- qDebug()<<"****************开始启动扫描****************";
- if(DSOpen() || OpenSource())//数据源是打开可用的
- {
- BOOL ret_value = SetCapability(CAP_DUPLEXENABLED,duplex,TRUE);
- ret_value = SetCapability(ICAP_SUPPORTEDSIZES,size,TRUE);
- ret_value = SetCapability(ICAP_PIXELTYPE,pixel,TRUE);
- ret_value = SetResolution(ICAP_XRESOLUTION,resolution);
- ret_value = SetResolution(ICAP_YRESOLUTION,resolution);
- // lqh - 设置传输模式为文件
- ret_value = SetCapability(ICAP_XFERMECH,TWSX_FILE,TRUE);
- //设置扫描的最大张数
- if(SetImageCount(numImages))
- {
- if(EnableSource())
- {
- return true;
- }
- else
- {
- qDebug()<<"启用扫描源失败";
- return false;
- }
- }
- }
- return false;
- }
- //禁用数据源
- bool CTwain::DisableSource()
- {
- qDebug()<<"****************开始禁用数据源****************";
- if(SourceEnabled())//数据源目前的状态是:可用
- {
- //禁用数据源
- if(CallTwainProc(&m_AppId,&m_Source,DG_CONTROL,DAT_USERINTERFACE,MSG_DISABLEDS,&twUI))
- {
- m_bSourceEnabled = false;
- qDebug()<<"禁用数据源成功";
- return true;
- }
- else
- {
- qDebug()<<"禁用数据源失败";
- return false;
- }
- }
- else
- {
- qDebug()<<"数据源目前的状态是不可用,不用再次禁用";
- }
- return false;
- }
- /*
- Gets Imageinfo for an image which is about to be transferred.
- 获取即将传输的图像的ImageInfo
- */
- bool CTwain::GetImageInfo(TW_IMAGEINFO& info)
- {
- qDebug()<<"****************开始获取图片信息****************";
- if(SourceEnabled())//如果数据源是可用的
- {
- bool b = CallTwainProc(&m_AppId,&m_Source,DG_IMAGE,DAT_IMAGEINFO,MSG_GET,(TW_MEMREF)&info);
- if(b == true)
- {
- qDebug()<<"成功获取即将传输的图片信息";
- }
- else
- {
- qDebug()<<"获取即将传输的图片信息失败";
- }
- return b;
- }
- return false;
- }
- /*
- Trasnfers the image or cancels the transfer depending on the state of the
- TWAIN system
- 根据图像的状态传输图像或取消传输
- */
- void CTwain::TransferImage()
- {
- qDebug()<<"****************根据图像的状态传输图像或取消传输****************";
- TW_IMAGEINFO info;//图片信息
- bool bContinue = true;
- while(bContinue)
- {
- if(GetImageInfo(info))//获取图片信息
- {
- /* lqh start */
- TW_SETUPFILEXFER filexfer;
- memset(&filexfer, 0, sizeof(filexfer));
- QString file = "C:\\SCANFILES\\scan_" + QDateTime::currentDateTime().toString("yyyyMMddHHmmsszzz") +".bmp";
- qDebug() << "scan file = " << file ;
- filexfer.Format = TWFF_BMP/*TWFF_BMP*/;
- strcpy(filexfer.FileName,file.toLatin1().data());
- CallTwainProc(&m_AppId,&m_Source,DG_CONTROL, DAT_SETUPFILEXFER, MSG_SET, (TW_MEMREF)&(filexfer));
- /* lqh end */
- int permission;
- permission = ShouldTransfer(info);
- qDebug()<<"执行到这";
- switch(permission)
- {
- case TWCPP_CANCELTHIS:
- qDebug()<<"执行到这01";
- bContinue = EndTransfer();//结束当前的传输
- break;
- case TWCPP_CANCELALL:
- qDebug()<<"执行到这02";
- CancelTransfer();//中止所有传输
- bContinue = false;
- break;
- case TWCPP_DOTRANSFER:
- qDebug()<<"执行到这03";
- bContinue = GetImage(info);//获取图片
- break;
- }
- }
- }
- }
- /*
- Ends the current transfer.
- Returns true if the more images are pending
- 结束当前传输。
- 如果有更多图像挂起,则返回true
- */
- bool CTwain::EndTransfer()
- {
- qDebug()<<"****************执行结束当前传输****************";
- TW_PENDINGXFERS twPend;
- if(CallTwainProc(&m_AppId,&m_Source,DG_CONTROL,DAT_PENDINGXFERS,MSG_ENDXFER,(TW_MEMREF)&twPend))
- {
- if (twPend.Count==0)
- {
- DisableSource();
- }
- return twPend.Count != 0;
- }
- return false;
- }
- /*
- Aborts all transfers
- 中止所有传输
- */
- void CTwain::CancelTransfer()
- {
- qDebug()<<"****************执行终止所有传输****************";
- TW_PENDINGXFERS twPend;
- CallTwainProc(&m_AppId,&m_Source,DG_CONTROL,DAT_PENDINGXFERS,MSG_RESET,(TW_MEMREF)&twPend);
- }
- /*
- Calls TWAIN to actually get the image
- 调用twain以实际获取图像
- */
- bool CTwain::GetImage(TW_IMAGEINFO& info)
- {
- qDebug()<<"****************获得图片****************";
- HANDLE hBitmap;
- // CallTwainProc(&m_AppId,&m_Source,DG_IMAGE,DAT_IMAGENATIVEXFER,MSG_GET,&hBitmap);
- //这里失败了
- CallTwainProc(&m_AppId,&m_Source,DG_IMAGE, DAT_IMAGEFILEXFER, MSG_GET, NULL);
- qDebug()<<"m_returnCode "<<m_returnCode;
- switch(m_returnCode)
- {
- case TWRC_XFERDONE:
- qDebug()<<"01";
- CopyImage(hBitmap,info);//本类的虚函数 子类实现获取图片后的操作
- break;
- case TWRC_CANCEL:
- qDebug()<<"02";
- break;
- case TWRC_FAILURE:
- break;
- CancelTransfer();//终止传输
- return false;
- }
- GlobalFree(hBitmap);//释放图片内存
- return EndTransfer();
- }
- //获取数据源列表
- void CTwain::get_source_list()
- {
- if(!sourcelist.isEmpty())
- {
- sourcelist.clear();
- }
- if (CallTwainProc(&m_AppId,nullptr,DG_CONTROL,DAT_IDENTITY,MSG_GETFIRST,&m_Source))
- {
- TW_IDENTITY temp_Source = m_Source;
- sourcelist.append(temp_Source);//添加到链表
- // qDebug()<<"可用扫描仪:"<<temp_Source.ProductName;
- while(CallTwainProc(&m_AppId,nullptr,DG_CONTROL,DAT_IDENTITY,MSG_GETNEXT,&m_Source))
- {
- TW_IDENTITY temp_Source = m_Source;
- sourcelist.append(temp_Source);//添加到链表
- // qDebug()<<"可用扫描仪:"<<temp_Source.ProductName;
- }
- m_Source = sourcelist.value(0);//第一个可用的扫描源
- m_bSourceSelected = TRUE;
- }
- else
- {
- qDebug()<<"没有可用的扫描仪";
- m_bSourceSelected = FALSE;
- }
- }
TWAIN.CPP的更多相关文章
- 使用“Cocos引擎”创建的cpp工程如何在VS中调试Cocos2d-x源码
前段时间Cocos2d-x更新了一个Cocos引擎,这是一个集合源码,IDE,Studio这一家老小的整合包,我们可以使用这个Cocos引擎来创建我们的项目. 在Cocos2d-x被整合到Cocos引 ...
- Json CPP 中文支持与入门示例
在每一个Json Cpp自带*.cpp文件头加上: #include "stdafx.h" 将Json Cpp对自带的头文件的引用修改为单引号方式,例如json_reader.cp ...
- cpp 调用python
在用cpp调用python时, 出现致命错误: no module named site , 原因解释器在搜索路径下没有找到python库.可以在调用Py_Initialize前,调用 Py_Se ...
- nginx+fastcgi+c/cpp
参考:http://github.tiankonguse.com/blog/2015/01/19/cgi-nginx-three/ 跟着做了一遍,然后根据记忆写的,不清楚有没错漏步骤,希望多多评论多多 ...
- APM程序分析-ArduCopter.cpp
该文件是APM的主文件. #define SCHED_TASK(func, rate_hz, max_time_micros) SCHED_TASK_CLASS(Copter, &copter ...
- APM程序分析-AC_WPNav.cpp
APM程序分析 主程序在ArduCopter.cpp的loop()函数. /// advance_wp_target_along_track - move target location along ...
- Dev Cpp 输出中文字符问题
最近 c++ 上机作业,vc++6.0 挂了没法用,只好用 Dev Cpp 先顶替一下,然而在遇到输出中文字符的时候出现了乱码的情况,但这种情况又非常诡异.于是简单了解了一下写成此博客. [写在前面] ...
- 扫描仪API接入大全:Twain, WIA 或 两者不具有.[换个思路 春暖花开]
最近做和扫描仪接入的扫描应用程序,深深感觉到了来自底层设备和WINDOWS协议的恶意.软件专业,对计算机深层次通知机制和协议,以及与之相连接的机器的接入协议和一些参数,当时并木有认真学习和了解,前一阵 ...
- 【安卓】aidl.exe E 10744 10584 io_delegate.cpp:102] Error while creating directories: Invalid argument
这几天在使用.aidl文件的时候eclipse的控制台总是爆出如下提示: aidl.exe E 10744 10584 io_delegate.cpp:102] Error while creatin ...
随机推荐
- GO语言复合类型02---数组
package main import "fmt" /* 固定长度.固定类型的数据容器 */ /*数组的声明*/ func main031() { //var array [5]i ...
- Python+Selenium - Alert弹框
上面三种弹窗可以在浏览器的控制台做出效果,如下图 上面三种弹窗可以用alert方法处理 示例: #出现弹窗的操作xxxx# 切换al = driver.switch_to.alert# print(a ...
- Python+Selenium+Appium+API学习使用过的命令
adb devices 查看连接电脑的手机设备 weditor 启动uiautomatorviewer2元素定位工具 以下2个命令作用一样 adb shell dumpsys activity | f ...
- springboot项目添加swagger2
1.pom中添加swagger依赖 <!-- swagger-ui --> <dependency> <groupId>io.springfox</group ...
- 适用于AMD ROC GPU的Numba概述
适用于AMD ROC GPU的Numba概述 Numba通过按照HSA执行模型将Python代码的受限子集直接编译到HSA内核和设备功能中,从而支持AMD ROC GPU编程.用Numba编写的内核似 ...
- TensorRT 7.2.1 开发概要(上)
TensorRT 7.2.1 开发概要(上) Abstract 这个TysRR7.2.1开发者指南演示了如何使用C++和Python API来实现最常用的深层学习层.它展示了如何使用深度学习框架构建现 ...
- 如何查看app启动的activity
adb 查看 使用adb shell 进入安卓的linux系统 拿QQ做例子: monkey -p com.tencent.mobileqq -v -v 1 #启动一次 启动页面为:com.tence ...
- .Net RabbitMQ实战指南——HTTP API接口调用
RabbitMQ Management插件还提供了基于RESTful风格的HTTP API接口来方便调用.一共涉及4种HTTP方法:GET.PUT.DELETE和POST.GET方法一般用来获取如集群 ...
- docker基本底层原理
docker是怎么工作的 Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过Socket客户端进行访问 DockerServer接收到DockerClie ...
- Java-Lambda相关使用介绍
频繁使用的语句 Lambda又涉及到comparator和comparable区别(Comparable是实现comparable接口,实现后可以使用Collections.sort或Arrays ...