/** Opens a Data Source */ bool KSaneWidgetPrivate::OpenSource(const QString &source) { if (source.isEmpty()) { return false; } QStringList splited = source.split(';'); if (splited.size() != 3) { return false; } // go thorough the list and check if the source is available bool ret_ok = CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETFIRST, &m_Source); while (ret_ok) { //qDebug() << m_Source.Id << m_Source.Version.MajorNum << m_Source.Version.MinorNum; //qDebug() << m_Source.Manufacturer << m_Source.ProductFamily << m_Source.ProductName; if (QString(m_Source.ProductName) == splited[0]) break; ret_ok = CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETNEXT, &m_Source); } if (!ret_ok) { // CallTwainProc failed when reading beyond the last source return false; } // open the source if (m_hTwainDLL && m_pDSMProc && m_bDSMOpen) { m_bDSOpen = CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_OPENDS, (TW_MEMREF)&m_Source); //qDebug() << "OpenSource(qst..) m_bDSOpen" << m_bDSOpen; } SetImageCount(TWCPP_ANYCOUNT); return DSOpen(); }
/** 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 KSaneWidgetPrivate. */ QString KSaneWidgetPrivate::SelectSource() { TW_IDENTITY src; memset(&src, 0, sizeof(src)); // debug printouts bool ret_ok = CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETFIRST, &src); while (ret_ok) { ret_ok = CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETNEXT, &src); } // set the default entry selected CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT, &src); // now open the selection dialog if (!CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT, &src)) { return QString(); } QString source; source += src.ProductName; source += ';'; source += src.ProductFamily; source += ';'; source += src.Manufacturer; //qDebug()<< source; return source; }
/** Closes the Data Source */ void KSaneWidgetPrivate::CloseDS() { if(DSOpen()) { if(m_bSourceEnabled) { TW_USERINTERFACE twUI; if(CallTwainProc(&m_AppId, &m_Source, DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS, &twUI)) { m_bSourceEnabled = false; } } CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, (TW_MEMREF)&m_Source); m_bDSOpen = false; } }
/** 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 KSaneWidgetPrivate::ProcessMessage(MSG msg) { // TODO: don't really know why... if (msg.message == 528) return false; if (m_hMessageWnd == 0) return false; if(m_bSourceEnabled) { TW_UINT16 twRC = TWRC_NOTDSEVENT; TW_EVENT twEvent; twEvent.pEvent = (TW_MEMREF)&msg; //memset(&twEvent, 0, sizeof(TW_EVENT)); twEvent.TWMessage = MSG_NULL; CallTwainProc(&m_AppId, &m_Source, DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, (TW_MEMREF)&twEvent); if(m_returnCode != TWRC_NOTDSEVENT) { TranslateMessage(twEvent); } return (twRC==TWRC_DSEVENT); } return false; }
/* Calls TWAIN to actually get the image */ BOOL CTwain::GetImage(TW_IMAGEINFO& info) { HANDLE hBitmap; CallTwainProc(&m_AppId,&m_Source,DG_IMAGE,DAT_IMAGENATIVEXFER,MSG_GET,&hBitmap); switch(m_returnCode) { case TWRC_XFERDONE: TRACE("********** GetImage --> TWRC_XFERDONE ************\n"); CopyImage(hBitmap,info); break; case TWRC_CANCEL: TRACE("GetImage --> TWRC_CANCEL.\n"); break; case TWRC_FAILURE: TRACE("********** GetImage --> TWRC_FAILURE ************\n"); CancelTransfer(); return FALSE; default: TRACE("GetImage --> default.\n"); break; } GlobalFree(hBitmap); TRACE("********** GetImage --> done ************\n"); return EndTransfer(); }
/** Calls TWAIN to actually get the image */ bool KSaneWidgetPrivate::GetImage(TW_IMAGEINFO& info) { TW_MEMREF pdata; CallTwainProc(&m_AppId, &m_Source, DG_IMAGE, DAT_IMAGENATIVEXFER, MSG_GET, &pdata); switch(m_returnCode) { case TWRC_XFERDONE: //qDebug()<< "GetImage:TWRC_XFERDONE"; ImageData(pdata, info); break; case TWRC_CANCEL: //qDebug()<< "GetImage:TWRC_CANCEL"; break; case TWRC_FAILURE: //qDebug()<< "GetImage:TWRC_FAILURE"; CancelTransfer(); return false; break; } GlobalFree(pdata); return EndTransfer(); }
/* 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. */ BOOL CTwain::InitTwain(HWND hWnd) { char libName[512]; if(IsValidDriver()) { return TRUE; } memset(&m_AppId,0,sizeof(m_AppId)); if(!IsWindow(hWnd)) { return FALSE; } m_hMessageWnd = hWnd; strcpy(libName,"TWAIN_32.DLL"); m_hTwainDLL = LoadLibrary(libName); if(m_hTwainDLL != NULL) { if(!(m_pDSMProc = (DSMENTRYPROC)GetProcAddress(m_hTwainDLL,MAKEINTRESOURCE(1)))) { FreeLibrary(m_hTwainDLL); m_hTwainDLL = NULL; } } if(IsValidDriver()) { GetIdentity(); m_bDSMOpen= CallTwainProc(&m_AppId,NULL,DG_CONTROL,DAT_PARENT,MSG_OPENDSM,(TW_MEMREF)&m_hMessageWnd); return TRUE; } else { return FALSE; } }
/** 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 TwainIface::ProcessMessage(MSG msg) { if(SourceEnabled()) { TW_UINT16 twRC = TWRC_NOTDSEVENT; TW_EVENT twEvent; twEvent.pEvent = (TW_MEMREF)&msg; //memset(&twEvent, 0, sizeof(TW_EVENT)); twEvent.TWMessage = MSG_NULL; CallTwainProc(&m_AppId, &m_Source, DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, (TW_MEMREF)&twEvent); if(GetRC() != TWRC_NOTDSEVENT) { TranslateMessage(twEvent); } return (twRC==TWRC_DSEVENT); } return false; }
/** Sets the capability of the Twain Data Source */ bool KSaneWidgetPrivate::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 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; }
/* Gets Imageinfo for an image which is about to be transferred. */ BOOL CTwain::GetImageInfo(TW_IMAGEINFO& info) { if(SourceEnabled()) { return CallTwainProc(&m_AppId,&m_Source,DG_IMAGE,DAT_IMAGEINFO,MSG_GET,(TW_MEMREF)&info); } return FALSE; }
/** Gets Imageinfo for an image which is about to be transferred. */ bool KSaneWidgetPrivate::GetImageInfo(TW_IMAGEINFO& info) { if(m_bSourceEnabled) { return CallTwainProc(&m_AppId, &m_Source, DG_IMAGE, DAT_IMAGEINFO, MSG_GET, (TW_MEMREF)&info); } return false; }
/** Closes the Data Source Manager */ void KSaneWidgetPrivate::CloseDSM() { if(m_hTwainDLL && m_pDSMProc && m_bDSMOpen) { CloseDS(); CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, (TW_MEMREF)&m_hMessageWnd); m_bDSMOpen = false; } }
/* Closes the Data Source */ void CTwain::CloseDS() { if(DSOpen()) { DisableSource(); CallTwainProc(&m_AppId,NULL,DG_CONTROL,DAT_IDENTITY,MSG_CLOSEDS,(TW_MEMREF)&m_Source); m_bDSOpen = FALSE; } }
/** Gets Imageinfo for an image which is about to be transferred. */ bool TwainIface::GetImageInfo(TW_IMAGEINFO& info) { if(SourceEnabled()) { return CallTwainProc(&m_AppId, &m_Source, DG_IMAGE, DAT_IMAGEINFO, MSG_GET, (TW_MEMREF)&info); } return false; }
/* Closes the Data Source Manager */ void CTwain::CloseDSM() { if(DSMOpen()) { CloseDS(); CallTwainProc(&m_AppId,NULL,DG_CONTROL,DAT_PARENT,MSG_CLOSEDSM,(TW_MEMREF)&m_hMessageWnd); m_bDSMOpen = FALSE; } }
/* Ends the current transfer. Returns TRUE if the more images are pending */ BOOL CTwain::EndTransfer() { TW_PENDINGXFERS twPend; if(CallTwainProc(&m_AppId,&m_Source,DG_CONTROL,DAT_PENDINGXFERS,MSG_ENDXFER,(TW_MEMREF)&twPend)) { return twPend.Count != 0; } return FALSE; }
/** Ends the current transfer. Returns true if the more images are pending */ bool KSaneWidgetPrivate::EndTransfer() { TW_PENDINGXFERS twPend; if(CallTwainProc(&m_AppId, &m_Source, DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER, (TW_MEMREF)&twPend)) { return twPend.Count != 0; } return false; }
/* 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(SourceEnabled()) { #if 1 TW_UINT16 twRC = TWRC_NOTDSEVENT; TW_EVENT twEvent; memset(&twEvent, 0, sizeof(TW_EVENT)); // twEvent.TWMessage = MSG_NULL; twEvent.pEvent = (TW_MEMREF)&msg; twRC = CallDSMEntry(&m_AppId,&m_Source,DG_CONTROL,DAT_EVENT,MSG_PROCESSEVENT,(TW_MEMREF)&twEvent); // if (twRC != TWRC_DSEVENT) // return FALSE; // CallTwainProc(&m_AppId,&m_Source,DG_CONTROL,DAT_EVENT,MSG_PROCESSEVENT,(TW_MEMREF)&twEvent); // if(GetRC() != TWRC_NOTDSEVENT) // { if (!_bTwainContinue) { twEvent.TWMessage = MSG_CLOSEDSREQ; } TranslateMessage(twEvent); // } // tell the caller what happened return (twRC == TWRC_DSEVENT); // returns TRUE or FALSE // return TRUE; #else TW_EVENT twEvent; twEvent.pEvent = (TW_MEMREF)&msg; twEvent.TWMessage = MSG_NULL; CallTwainProc(&m_AppId,&m_Source,DG_CONTROL,DAT_EVENT,MSG_PROCESSEVENT,(TW_MEMREF)&twEvent); if(GetRC() != TWRC_NOTDSEVENT) { TRACE("********** ProcessMessage ************\n"); TranslateMessage(twEvent); } return FALSE; #endif } else { // TRACE("********** ProcessMessage SourceEnabled = false ************\n"); } return FALSE; }
/* Called to disable the source. */ BOOL CTwain::DisableSource() { if(SourceEnabled()) { if(CallTwainProc(&m_AppId,&m_Source,DG_CONTROL,DAT_USERINTERFACE,MSG_DISABLEDS,&twUI)) { m_bSourceEnabled = FALSE; return TRUE; } } return FALSE; }
/** 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 receive Twain messaged. Normally - this would be your main application window. */ bool KSaneWidgetPrivate::InitTwain() { char libName[512]; if((m_hTwainDLL && m_pDSMProc)) { return true; } memset(&m_AppId,0,sizeof(m_AppId)); if(!IsWindow(this->winId())) { return false; } m_hMessageWnd = this->winId(); strcpy(libName, "TWAIN_32.DLL"); m_hTwainDLL = LoadLibraryA(libName); if(m_hTwainDLL != NULL) { if(!(m_pDSMProc = (DSMENTRYPROC)GetProcAddress(m_hTwainDLL, (LPCSTR)MAKEINTRESOURCE(1)))) { FreeLibrary(m_hTwainDLL); m_hTwainDLL = NULL; } } if((m_hTwainDLL && m_pDSMProc)) { // Expects all the fields in m_AppId to be set except for the id field. m_AppId.Id = 0; // Initialize to 0 (Source Manager will assign real value) m_AppId.Version.MajorNum = 0; // Your app's version number m_AppId.Version.MinorNum = 2; m_AppId.Version.Language = TWLG_USA; m_AppId.Version.Country = TWCY_USA; strcpy(m_AppId.Version.Info, "libksane"); m_AppId.ProtocolMajor = TWON_PROTOCOLMAJOR; m_AppId.ProtocolMinor = TWON_PROTOCOLMINOR; m_AppId.SupportedGroups = DG_IMAGE | DG_CONTROL; strcpy(m_AppId.Manufacturer, "KDE"); strcpy(m_AppId.ProductFamily, "Generic"); strcpy(m_AppId.ProductName, "libksane"); m_bDSMOpen= CallTwainProc(&m_AppId, NULL, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, (TW_MEMREF)&m_hMessageWnd); return true; } else { return false; } }
/* 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. */ BOOL CTwain::SelectSource() { memset(&m_Source,0,sizeof(m_Source)); if(!SourceSelected()) { SelectDefaultSource(); } if(CallTwainProc(&m_AppId,NULL,DG_CONTROL,DAT_IDENTITY,MSG_USERSELECT,&m_Source)) { m_bSourceSelected = TRUE; } return m_bSourceSelected; }
/** Called to disable the source. */ bool TwainIface::DisableSource() { if(SourceEnabled()) { TW_USERINTERFACE twUI; if(CallTwainProc(&m_AppId, &m_Source, DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS, &twUI)) { m_bSourceEnabled = false; return true; } } return false; }
/* Queries the capability of the Twain Data Source */ BOOL CTwain::GetCapability(TW_CAPABILITY& twCap,TW_UINT16 cap,TW_UINT16 conType) { if(DSOpen()) { twCap.Cap = cap; twCap.ConType = conType; twCap.hContainer = NULL; 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 KSaneWidgetPrivate::GetCapability(TW_CAPABILITY& twCap, TW_UINT16 cap, TW_UINT16 conType) { if(DSOpen()) { twCap.Cap = cap; twCap.ConType = conType; twCap.hContainer = NULL; if(CallTwainProc(&m_AppId, &m_Source, DG_CONTROL, DAT_CAPABILITY, MSG_GET, (TW_MEMREF)&twCap)) { return true; } } return false; }
/* Opens a Data Source supplied as the input parameter */ BOOL CTwain::OpenSource(TW_IDENTITY *pSource) { if(pSource) { m_Source = *pSource; } if(DSMOpen()) { if(!SourceSelected()) { SelectDefaultSource(); } m_bDSOpen = CallTwainProc(&m_AppId,NULL,DG_CONTROL,DAT_IDENTITY,MSG_OPENDS,(TW_MEMREF)&m_Source); } return DSOpen(); }
/* Ends the current transfer. Returns TRUE if the more images are pending */ BOOL CTwain::EndTransfer() { TW_PENDINGXFERS twPend; if(CallTwainProc(&m_AppId,&m_Source,DG_CONTROL,DAT_PENDINGXFERS,MSG_ENDXFER,(TW_MEMREF)&twPend)) { if (twPend.Count == 0) { DisableSource(); _bHasNextPic = FALSE; } else _bHasNextPic = TRUE; TRACE("********** EndTransfer --> twPend.Count = %d ************\n", twPend.Count); return twPend.Count != 0; } return FALSE; }
/* 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(SourceEnabled()) { TW_EVENT twEvent; twEvent.pEvent = (TW_MEMREF)&msg; twEvent.TWMessage = MSG_NULL; CallTwainProc(&m_AppId,&m_Source,DG_CONTROL,DAT_EVENT,MSG_PROCESSEVENT,(TW_MEMREF)&twEvent); if(GetRC() != TWRC_NOTDSEVENT) { TranslateMessage(twEvent); } return FALSE; } return FALSE; }
/* Calls TWAIN to actually get the image */ BOOL CTwain::GetImage(TW_IMAGEINFO& info) { HANDLE hBitmap; CallTwainProc(&m_AppId,&m_Source,DG_IMAGE,DAT_IMAGENATIVEXFER,MSG_GET,&hBitmap); switch(m_returnCode) { case TWRC_XFERDONE: CopyImage(hBitmap,info); break; case TWRC_CANCEL: break; case TWRC_FAILURE: CancelTransfer(); return FALSE; } GlobalFree(hBitmap); return EndTransfer(); }
/* Called to enable the Twain Acquire Dialog. This too can be overridden but is a helluva job . */ BOOL CTwain::EnableSource(BOOL showUI) { if(DSOpen() && !SourceEnabled()) { twUI.ShowUI = showUI; //FALSE twUI.hParent = (TW_HANDLE)m_hMessageWnd; if(CallTwainProc(&m_AppId,&m_Source,DG_CONTROL,DAT_USERINTERFACE,MSG_ENABLEDS,(TW_MEMREF)&twUI)) { m_bSourceEnabled = TRUE; m_bModalUI = twUI.ModalUI; } else { m_bSourceEnabled = FALSE; m_bModalUI = TRUE; } return m_bSourceEnabled; } return FALSE; }