// TwnConfig.cpp : Defines the class behaviors for the application. // #include "stdafx.h" #include "TwnConfig.h" #include "MainFrm.h" #include "TwnConfigDoc.h" #include "TwnConfigView.h" #include "Options.h" #include "Configs.h" #include "LogFile.h" #include "ConfigRes.h" #include "ScanRes.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define MAX_CONFIG_COUNT 10 ///////////////////////////////////////////////////////////////////////////// // CTwainConfigApp BEGIN_MESSAGE_MAP(CTwainConfigApp, CWinApp) //{{AFX_MSG_MAP(CTwainConfigApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) ON_COMMAND(ID_CONFIGURATION_AUTOSCAN, OnConfigurationAutoScan) ON_COMMAND(ID_CONFIGURATION_MANUALSCAN, OnConfigurationManualScan) ON_COMMAND(ID_CONFIGURATION_CONTINUESTOPPEDSCAN, OnConfigurationContinueStoppedScan) ON_COMMAND(ID_CONFIGURATION_OPTIONS, OnConfigurationOptions) ON_UPDATE_COMMAND_UI(ID_CONFIGURATION_AUTOSCAN, OnUpdateConfigurationAutoscan) ON_UPDATE_COMMAND_UI(ID_CONFIGURATION_MANUALSCAN, OnUpdateConfigurationManualscan) ON_COMMAND(ID_HELP_UTILITYINSTRUCTIONS, OnHelpUtilityInstructions) ON_COMMAND(ID_TOOLS_UPLOADDATCFILE, OnToolsUploadDATCFile) ON_UPDATE_COMMAND_UI(ID_TOOLS_UPLOADDATCFILE, OnUpdateToolsUploadDATCFile) ON_UPDATE_COMMAND_UI(ID_CONFIGURATION_CONTINUESTOPPEDSCAN, OnUpdateConfigurationContinuestoppedscan) ON_UPDATE_COMMAND_UI(ID_CONFIGURATION_OPTIONS, OnUpdateConfigurationOptions) ON_UPDATE_COMMAND_UI(ID_APP_EXIT, OnUpdateAppExit) //}}AFX_MSG_MAP // Standard file based document commands ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) // Standard print setup command ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup) END_MESSAGE_MAP() L_INT EXT_CALLBACK FastConfigCB(HTWAINSESSION hSession, pFASTCONFIG pResConfig, L_VOID *pUserData); ///////////////////////////////////////////////////////////////////////////// // CTwainConfigApp construction CTwainConfigApp::CTwainConfigApp() { m_hSession = NULL; m_bStartNegs = FALSE; m_bSetConfigs = FALSE; m_bUseThreadMode = FALSE; m_bUseAllBPP = FALSE; m_nBPP = 1; m_nBufferIter = 10; m_bUseThreadMode = TRUE; m_bUseAllBPP = TRUE; m_csDatFileName.Empty(); m_csLogFileName.Empty(); m_csWorkingFolder.Empty(); m_csDatFileNameNum.Empty(); m_pInFastConfigs = NULL; m_nInFastConfigsCount = 0; m_pStdFile = NULL; m_pDatStdFile = NULL; m_nTestConfigCount = 0; memset(&m_BestConfig, 0, sizeof(FASTCONFIG)); m_BestConfig.uTime = -1; m_nAllBPPCount = 0; m_pnBPP = NULL; m_csTwnSourceName.Empty(); m_csTwnFamilyName.Empty(); m_csTwnManufacturerName.Empty(); m_bFillDATC = FALSE; m_bScanConfigs = FALSE; m_uFlags = 0; m_nScannedPageCount = 0; m_dwStartTickCount = 0; m_dwEndTickCount = 0; m_pTime = NULL; m_nTimeLen = 0; } ///////////////////////////////////////////////////////////////////////////// // The one and only CTwainConfigApp object CTwainConfigApp theApp; ///////////////////////////////////////////////////////////////////////////// // CTwainConfigApp initialization BOOL CTwainConfigApp::InitInstance() { AfxEnableControlContainer(); // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif // Change the registry key under which our settings are stored. // You should modify this string to be something appropriate // such as the name of your company or organization. SetRegistryKey(_T("Local AppWizard-Generated Applications")); LoadStdProfileSettings(0); // Load standard INI file options (including MRU) // Register the application's document templates. Document templates // serve as the connection between documents, frame windows and views. CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CTwainConfigDoc), RUNTIME_CLASS(CMainFrame), // main SDI frame window RUNTIME_CLASS(CTwainConfigView)); AddDocTemplate(pDocTemplate); // Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // Dispatch commands specified on the command line if (!ProcessShellCommand(cmdInfo)) return FALSE; // The one and only window has been initialized, so show and update it. m_pMainWnd->ShowWindow(SW_SHOW); m_pMainWnd->UpdateWindow(); /************************* Start TWAIN Session *************************/ APPLICATIONDATA AppData; AppData.hWnd = m_pMainWnd->GetSafeHwnd(); // Window handle of an application, may not be NULL lstrcpy (AppData.szManufacturerName, _T("LEAD Technologies, Inc.")); // Application manufacturer name lstrcpy (AppData.szAppProductFamily, _T("LEAD Test Applications")); // Application product family lstrcpy (AppData.szVersionInfo, _T("Version 13.0")); // Application version info lstrcpy (AppData.szAppName, _T("TWAIN Utility Application")); // Application Name AppData.uStructSize = sizeof(APPLICATIONDATA); // initialize the twain session to use other lead twain functions L_INT nRet = L_TwainInitSession (&m_hSession, &AppData); if (nRet != SUCCESS) return FALSE; L_UnlockSupport(L_SUPPORT_DOCUMENT, L_KEY_DOCUMENT); // /////////////////////////////////////////////////////////// // HKEY hKey= HKEY_LOCAL_MACHINE; // LONG ret = ERROR_SUCCESS; // // L_TCHAR szSubKey[MAX_PATH]; // memset(szSubKey, 0, sizeof(szSubKey)); // // strcpy(szSubKey, "SOFTWARE\\LEAD Technologies, Inc."); // nRet = RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hKey); // if (nRet == 0) // { // DWORD lpType; // BYTE data[MAX_PATH]; // DWORD sizeData = MAX_PATH; // // memset(data,0,sizeof(data)); // nRet = RegQueryValueEx(hKey, "HelpDir", NULL, &lpType, data, &sizeData); // if (nRet == 0) // m_csTutorialPath.Format("%s%s", (L_TCHAR *)&data, "\\LTTwnUtil.htm"); // // RegCloseKey(hKey); // } // /////////////////////////////////////////////////////////// TCHAR path[_MAX_PATH]=_T(""); TCHAR drive[_MAX_DRIVE]; TCHAR dir[_MAX_DIR]; GetModuleFileName(NULL, path, _MAX_PATH); _tsplitpath(path, drive, dir, NULL, NULL); m_csTutorialPath.Format(_T("%s%s%s"), drive, dir, _T("..\\Help\\LTTwnUtil.htm")); LPTSTR lptstrPath = m_csWorkingFolder.GetBuffer(MAX_PATH); GetTempPath(MAX_PATH, lptstrPath); m_csWorkingFolder.ReleaseBuffer(); m_csLogFileName.Format(_T("%sTWAINCONFIG.LOG"), m_csWorkingFolder); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) virtual BOOL OnInitDialog(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) //}}AFX_MSG_MAP END_MESSAGE_MAP() // App command to run the dialog void CTwainConfigApp::OnAppAbout() { CAboutDlg aboutDlg; aboutDlg.DoModal(); } BOOL CAboutDlg::OnInitDialog() { CDialog::OnInitDialog(); VERSIONINFO VerInfo; L_TCHAR szBuffer[1024]; L_VersionInfo (&VerInfo,sizeof(VerInfo)); wsprintf(szBuffer, _T("LEAD Product: %hs\nVersion %d.%d\nDate: %hs\nTime: %hs"), (L_TCHAR L_FAR *)VerInfo.Product, VerInfo.MajorNumber, VerInfo.MinorNumber, (L_TCHAR L_FAR *)VerInfo.Date, (L_TCHAR L_FAR *)VerInfo.Time); GetDlgItem(IDC_STATIC_VERSIONINFO)->SetWindowText(szBuffer); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } ///////////////////////////////////////////////////////////////////////////// // CTwainConfigApp commands int CTwainConfigApp::ExitInstance() { if (m_pTime) GlobalFreePtr(m_pTime); if (m_pInFastConfigs) GlobalFreePtr(m_pInFastConfigs); if (m_hSession) L_TwainEndSession(&m_hSession); return CWinApp::ExitInstance(); } L_BOOL CTwainConfigApp::OpenLogFile(CString csFileName) { CString csBuffer; if (m_pStdFile) return FALSE; TRY { m_pStdFile = new CStdioFile(csFileName, CFile::modeCreate | CFile::modeWrite | CFile::typeText); } CATCH (CFileException, pEx) { csBuffer.Format(_T("Not able to open the Log File.")); ::MessageBox(NULL, csBuffer, _T("Error!"), MB_OK); m_pStdFile = NULL; return FALSE; } END_CATCH return TRUE; } void CTwainConfigApp::StartLogFile(CString csFileName) { CString csBuffer; BOOL bRet; bRet = OpenLogFile(csFileName); if (!bRet) return; GetSelectScannerName(); csBuffer.Format(_T("======================\nScanner Configuration:\n======================\n\n\n")); m_pStdFile->WriteString(csBuffer); csBuffer.Empty(); csBuffer.Format(_T("Scanner Driver Name: %s\n"), m_csTwnSourceName); m_pStdFile->WriteString(csBuffer); csBuffer.Empty(); csBuffer.Format(_T("Scanner Family Name: %s\n"), m_csTwnFamilyName); m_pStdFile->WriteString(csBuffer); csBuffer.Empty(); csBuffer.Format(_T("Scanner Manufacturer Name: %s\n"), m_csTwnManufacturerName); m_pStdFile->WriteString(csBuffer); csBuffer.Empty(); csBuffer.Format(_T("----------------------------------------------------------------\n")); m_pStdFile->WriteString(csBuffer); csBuffer.Empty(); csBuffer.Empty(); csBuffer.Format(_T("---------------------------------\nHere are all tested configurations:\n---------------------------------\n")); m_pStdFile->WriteString(csBuffer); } void CTwainConfigApp::EndLogFile(pFASTCONFIG pBestConfig) { if (pBestConfig) { CString csBuffer; csBuffer.Format(_T("The following is the recommended configuration for your scanner:\n")); m_pStdFile->WriteString(csBuffer); csBuffer.Empty(); csBuffer.Format(_T("----------------------------------------------------------------\n")); m_pStdFile->WriteString(csBuffer); WriteConfig(pBestConfig, TRUE); csBuffer.Format(_T("=======================\n End\n=======================\n\n\n")); m_pStdFile->WriteString(csBuffer); } m_pStdFile->Close(); delete m_pStdFile; m_pStdFile = NULL; } void CTwainConfigApp::WriteConfig(pFASTCONFIG pConfigs, L_BOOL bBest /* = FALSE*/) { CString csBuffer; CString csFormatName; CString csTransferName; if (!bBest) { csBuffer.Empty(); csBuffer.Format(_T("Configuration # %d is:\n"), m_nTestConfigCount); m_pStdFile->WriteString(csBuffer); } GetTransferName(pConfigs, csTransferName); GetFormatName(pConfigs, csFormatName); csBuffer.Empty(); csBuffer.Format(_T("Transfer Mode = %s\nFile Format = %s\nBuffer Size = %d\nRequired Time = %d ms\nBits Per Pixel = %d\n"), csTransferName, csFormatName, pConfigs->ulBufferSize, pConfigs->uTime, pConfigs->nBitsPerPixel); m_pStdFile->WriteString(csBuffer); csBuffer.Empty(); csBuffer.Format(_T("+++++++++++++++++++++++++++++++++\n")); m_pStdFile->WriteString(csBuffer); } void CTwainConfigApp::ShowConfigsResult(pFASTCONFIG pConfigs, L_INT nConfigsCount, pFASTCONFIG pBestConfig) { CConfigResult cfgResDlg(pBestConfig, pConfigs, nConfigsCount); cfgResDlg.DoModal(); } void CTwainConfigApp::OnConfigurationAutoScan() { L_INT nRet = SUCCESS; pFASTCONFIG pTestConfigs = NULL; L_INT nTestConfigsCount = 0; FASTCONFIG BestConfig; memset(&BestConfig, 0, sizeof(FASTCONFIG)); if (!GetWorkingConfigs(m_csDatFileName, TRUE)) return; StartLogFile(m_csLogFileName); if (!m_pStdFile) return; m_bScanConfigs = TRUE; m_uFlags = LTWAIN_SHOW_USER_INTERFACE; m_uFlags = m_uFlags | ((m_bUseThreadMode) ? LTWAIN_USE_THREAD_MODE : 0) | ((m_bUseAllBPP) ? LTWAIN_CHECK_ALL_DEFAULT_BPP : 0); m_nTestConfigCount = 0; memset(&m_BestConfig, 0, sizeof(FASTCONFIG)); m_BestConfig.uTime = -1; nRet = L_TwainFindFastConfig(m_hSession, (L_TCHAR L_FAR *)(LPCTSTR)m_csWorkingFolder, m_uFlags, m_nBPP, m_nBufferIter, NULL, 0, &pTestConfigs, &nTestConfigsCount, &BestConfig, sizeof(FASTCONFIG), FastConfigCB, this); pFASTCONFIG pBestCfg = NULL; if (nRet == SUCCESS) { pBestCfg = &BestConfig; if (m_BestConfig.uTime < BestConfig.uTime) pBestCfg = &m_BestConfig; } if (nRet == SUCCESS && pBestCfg->bSuccess) { ShowConfigsResult(pTestConfigs, nTestConfigsCount, pBestCfg); TestFastConfig(); } else if (nRet != TWAIN_SUCCESS_ABORT) ErrorMsgBox(nRet); EndLogFile(pBestCfg); m_bScanConfigs = FALSE; } void CTwainConfigApp::OnUpdateConfigurationAutoscan(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bSetConfigs && !m_bScanConfigs); } void CTwainConfigApp::OnConfigurationManualScan() { if (!GetWorkingConfigs(m_csDatFileName, FALSE)) return; L_BOOL bRet = OpenDatFile(m_csDatFileName); if (!bRet) return; m_bScanConfigs = TRUE; WriteConfigsToDatFile(m_pInFastConfigs, m_nInFastConfigsCount); CloseDatFile(); TestManualConfiguration(); m_bScanConfigs = FALSE; } void CTwainConfigApp::OnUpdateConfigurationManualscan(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bSetConfigs && !m_bScanConfigs); } L_INT CTwainConfigApp::TestManualConfiguration() { L_INT nRet = SUCCESS; pFASTCONFIG pTestConfigs = NULL; L_INT nTestConfigsCount = 0; FASTCONFIG BestConfig; StartLogFile(m_csLogFileName); if (!m_pStdFile) return FAILURE; m_uFlags = LTWAIN_SHOW_USER_INTERFACE; m_uFlags = m_uFlags | ((m_bUseThreadMode) ? LTWAIN_USE_THREAD_MODE : 0) | ((m_bUseAllBPP) ? LTWAIN_CHECK_ALL_DEFAULT_BPP : 0); m_nTestConfigCount = 0; memset(&m_BestConfig, 0, sizeof(FASTCONFIG)); m_BestConfig.uTime = -1; nRet = L_TwainFindFastConfig(m_hSession, (L_TCHAR L_FAR *)(LPCTSTR)m_csWorkingFolder, m_uFlags, m_nBPP, m_nBufferIter, m_pInFastConfigs, m_nInFastConfigsCount, &pTestConfigs, &nTestConfigsCount, &BestConfig, sizeof(FASTCONFIG), FastConfigCB, this); pFASTCONFIG pBestCfg = NULL; if (nRet == SUCCESS) { pBestCfg = &BestConfig; if (m_BestConfig.uTime < BestConfig.uTime) pBestCfg = &m_BestConfig; } if (nRet == SUCCESS && pBestCfg->bSuccess) { ShowConfigsResult(pTestConfigs, nTestConfigsCount, pBestCfg); TestFastConfig(); } else if (nRet != TWAIN_SUCCESS_ABORT) ErrorMsgBox(nRet); EndLogFile(pBestCfg); return nRet; } void CTwainConfigApp::OnConfigurationContinueStoppedScan() { if (m_pInFastConfigs) { GlobalFreePtr(m_pInFastConfigs); m_pInFastConfigs = NULL; m_nInFastConfigsCount = 0; } CLogFile SelLogFile; if (SelLogFile.DoModal() == IDOK) { m_csLogFileName = SelLogFile.m_csFileName; m_csDatFileName = SelLogFile.m_csDatFile; m_csDatFileNameNum = SelLogFile.m_csDatFileNum; L_BOOL bRet = ReadFileConfigs(m_csDatFileName, m_csDatFileNameNum); if (!bRet) return; if (m_nInFastConfigsCount == 0) { AfxMessageBox(_T("All Scan Configurations was completed!!!")); return; } SkipConfiguration(); if (m_nInFastConfigsCount == 0 && m_pInFastConfigs == NULL) return; m_nTestConfigCount = 0; m_bFillDATC = FALSE; if (!WriteDATCFile()) return; m_bFillDATC = TRUE; bRet = OpenDatFile(m_csDatFileName); if (!bRet) return; WriteConfigsToDatFile(m_pInFastConfigs, m_nInFastConfigsCount); CloseDatFile(); m_bScanConfigs = TRUE; TestManualConfiguration(); m_bScanConfigs = FALSE; } } void CTwainConfigApp::OnConfigurationOptions() { COptions Opt(m_hSession, m_csLogFileName, m_nBPP, m_nBufferIter, m_bUseThreadMode, m_bUseAllBPP); if (Opt.DoModal() == IDOK) { m_csLogFileName = Opt.m_csFileName; m_csDatFileName = Opt.m_csDatFile; m_csDatFileNameNum= Opt.m_csDatFileNum; m_nBPP = Opt.m_nBPP; m_nBufferIter = Opt.m_nBuffIter; m_csWorkingFolder = Opt.m_csFilePath; m_bUseThreadMode = Opt.m_bUseThreadMode; m_bUseAllBPP = Opt.m_bUseAllBPP; m_bSetConfigs = TRUE; } } L_INT EXT_CALLBACK FastConfigCB(HTWAINSESSION hSession, pFASTCONFIG pResConfig, L_VOID *pUserData) { CTwainConfigApp *pTheApp = (CTwainConfigApp *)pUserData; pTheApp->m_nTestConfigCount++; if (pResConfig->bSuccess && pResConfig->uTime > 0) { pTheApp->WriteConfig(pResConfig); if (pResConfig->uTime < pTheApp->m_BestConfig.uTime) { pTheApp->m_BestConfig.uTransferMode = pResConfig->uTransferMode; pTheApp->m_BestConfig.nFileFormat = pResConfig->nFileFormat; pTheApp->m_BestConfig.ulBufferSize = pResConfig->ulBufferSize; pTheApp->m_BestConfig.uTime = pResConfig->uTime; pTheApp->m_BestConfig.nBitsPerPixel = pResConfig->nBitsPerPixel; } } pTheApp->m_bFillDATC = FALSE; if (!pTheApp->WriteDATCFile()) return FALSE; pTheApp->m_bFillDATC = TRUE; return SUCCESS; } L_BOOL CTwainConfigApp::OpenDatFile(CString csFileName) { CString csBuffer; if (m_pDatStdFile) return FALSE; TRY { m_pDatStdFile = new CStdioFile(csFileName, CFile::modeCreate | CFile::modeWrite | CFile::typeText); } CATCH (CFileException, pEx) { csBuffer.Format(_T("Not able to open the Log File.")); ::MessageBox(NULL, csBuffer, _T("Error!"), MB_OK); m_pDatStdFile = NULL; return FALSE; } END_CATCH csBuffer.Format(_T("LEAD TWAIN Configuration\n")); m_pDatStdFile->WriteString(csBuffer); GetSelectScannerName(); csBuffer.Format(_T("Driver Name: %s\n"), m_csTwnSourceName); m_pDatStdFile->WriteString(csBuffer); csBuffer.Empty(); csBuffer.Format(_T("Family Name: %s\n"), m_csTwnFamilyName); m_pDatStdFile->WriteString(csBuffer); csBuffer.Empty(); csBuffer.Format(_T("Manufacturer Name: %s\n"), m_csTwnManufacturerName); m_pDatStdFile->WriteString(csBuffer); csBuffer.Empty(); return TRUE; } void CTwainConfigApp::CloseDatFile() { CString csBuffer; csBuffer.Format(_T("End LEAD TWAIN Configuration")); m_pDatStdFile->WriteString(csBuffer); m_pDatStdFile->Close(); delete m_pDatStdFile; m_pDatStdFile= NULL; } void CTwainConfigApp::WriteConfigsToDatFile(pFASTCONFIG pConfigs, L_INT nConfigsCount) { CString csBuffer; for (int i=0; iWriteString(csBuffer); } } L_BOOL CTwainConfigApp::GetScannerBPP() { L_BOOL bRet=TRUE; TW_CAPABILITY twCap; pTW_ONEVALUE pOneVal=NULL; pTW_ENUMERATION pEnum =NULL; TW_UINT16 * pValue = NULL; L_INT nRet = L_TwainStartCapsNeg(m_hSession); if (nRet != SUCCESS) return FALSE; m_bStartNegs = TRUE; if (m_pnBPP) { GlobalFreePtr(m_pnBPP); m_pnBPP = NULL; m_nAllBPPCount = 0; } // Get the available supported Bits Per Pixel twCap.Cap = ICAP_BITDEPTH; twCap.ConType = TWON_ENUMERATION; twCap.hContainer = NULL; nRet = L_TwainGetCapability(m_hSession, &twCap, LTWAIN_CAPABILITY_GETVALUES); if (nRet != TWAIN_SUCCESS) return FALSE; switch (twCap.ConType) { case TWON_ONEVALUE: if (twCap.hContainer) { pOneVal = (TW_ONEVALUE *)GlobalLock(twCap.hContainer); if (pOneVal && (pOneVal->ItemType == TWTY_UINT16 || pOneVal->ItemType == TWTY_INT16)) { pValue = (TW_UINT16 *)&pOneVal->Item; m_nAllBPPCount = 1; } else bRet = FALSE; } else bRet = FALSE; break; case TWON_ENUMERATION: if (twCap.hContainer) { pEnum = (TW_ENUMERATION *)GlobalLock(twCap.hContainer); if (pEnum && (pEnum->ItemType == TWTY_UINT16 || pEnum->ItemType == TWTY_INT16)) { pValue = (TW_UINT16 *)pEnum->ItemList; m_nAllBPPCount = pEnum->NumItems; } else bRet = FALSE; } else bRet = FALSE; } if (bRet) { m_pnBPP = (L_INT *)GlobalAllocPtr(GHND, sizeof(L_INT) * m_nAllBPPCount); if (m_pnBPP) { for(int i=0; iReadString(csBuffer); pStdFile->Close(); delete pStdFile; pStdFile = NULL; ParseBestConfig((L_TCHAR *)(LPCTSTR)csBuffer, &nTestConfigsCount); } else nTestConfigsCount = 0; /***************************************************************/ //////////////////// Read all configurations //////////////////// /***************************************************************/ TRY { pStdFile = new CStdioFile(csDatFileName, CFile::modeRead | CFile::typeText); } CATCH (CFileException, pEx) { csBuffer.Format(_T("Not able to open the Log File.")); ::MessageBox(NULL, csBuffer, _T("Error!"), MB_OK); pStdFile = NULL; return FALSE; } END_CATCH // Do the parsing operation to get all configuration... ParseBuffer(pStdFile, lptstrBuff, &pConfigs, &nConfigsCount); if (pConfigs && nConfigsCount) { m_nInFastConfigsCount = nConfigsCount - nTestConfigsCount; if (m_nInFastConfigsCount > 0) { m_pInFastConfigs = (pFASTCONFIG)GlobalAllocPtr(GHND, sizeof(FASTCONFIG) * m_nInFastConfigsCount); if (m_pInFastConfigs) CopyConfigurations(m_pInFastConfigs, pConfigs, nConfigsCount, nTestConfigsCount); else bRet = FALSE; } GlobalFreePtr(pConfigs); pConfigs = NULL; nConfigsCount = 0; } csBuffer.ReleaseBuffer(); pStdFile->Close(); delete pStdFile; pStdFile = NULL; return bRet; } void CTwainConfigApp::CopyConfigurations(pFASTCONFIG pDstConfigs, pFASTCONFIG pSrcConfigs, L_INT nSrcConfigsCount, L_INT nIgnoreConfigsCount) { int i, j; int nDstConfigsCount = nSrcConfigsCount - nIgnoreConfigsCount; j = nIgnoreConfigsCount; for(i=0; iReadString(csBuffer); nMaxCfgCount = MAX_CONFIG_COUNT; while (!csBuffer.IsEmpty()) { /* Get the Configuration information from that line */ bRet = GetConfiguration((TCHAR *)(LPCTSTR)csBuffer, &(*ppConfigs)[nRCfgCount]); if (bRet) nRCfgCount++; if (nRCfgCount >= nMaxCfgCount) { *ppConfigs = (pFASTCONFIG)GlobalReAllocPtr(*ppConfigs, sizeof(FASTCONFIG) * (MAX_CONFIG_COUNT + nRCfgCount), GHND); if (!*ppConfigs) break; else nMaxCfgCount += MAX_CONFIG_COUNT; } pStdFile->ReadString(csBuffer); } *pnConfigsCount = nRCfgCount; } L_BOOL CTwainConfigApp::GetConfiguration(L_TCHAR * pszLine, pFASTCONFIG pConfig) { L_TCHAR * pszToken=NULL; L_TCHAR chDelimit[]=_T("#"); L_INT nTokCount=0; L_UINT uTransferMode; L_INT nFormat; L_UINT32 ulBufSize; L_UINT uTime; L_INT nBPP; L_BOOL bReadOk = FALSE; pszToken = _tcstok(pszLine, chDelimit); if (!pszToken) return FALSE; while (pszToken) { switch (nTokCount) { case 0: /* Transfer Mode */ uTransferMode = _ttoi(pszToken); break; case 1: /* File Format */ nFormat = _ttoi(pszToken); break; case 2: /* Buffer Size */ ulBufSize = _ttoi(pszToken); break; case 3: /* Required Time */ uTime = _ttoi(pszToken); break; case 4: /* Bits Per Pixel */ nBPP = _ttoi(pszToken); bReadOk = TRUE; break; } nTokCount++; pszToken = _tcstok(NULL, chDelimit); } if (bReadOk) { pConfig->uTransferMode = uTransferMode; pConfig->nFileFormat = nFormat; pConfig->ulBufferSize = ulBufSize; pConfig->uTime = uTime; pConfig->nBitsPerPixel = nBPP; return TRUE; } return FALSE; } void CTwainConfigApp::ParseBestConfig(L_TCHAR * pszBuffer, L_INT * pnTestConfigsCount) { L_TCHAR *pszToken=NULL; L_TCHAR chDelimit[]=_T(";"); L_INT nTokCount=0; pszToken = _tcstok(pszBuffer, chDelimit); if (!pszToken) return; while (pszToken) { switch (nTokCount) { case 0: /* Number of test configuration */ *pnTestConfigsCount = _ttoi(pszToken); break; case 1: /* Transfer Mode */ m_BestConfig.uTransferMode = _ttoi(pszToken); break; case 2: /* File Format */ m_BestConfig.nFileFormat = _ttoi(pszToken); break; case 3: /* Buffer Size */ m_BestConfig.ulBufferSize = _ttoi(pszToken); break; case 4: /* Required Time */ m_BestConfig.uTime = _ttoi(pszToken); break; case 5: /* Bits Per Pixel */ m_BestConfig.nBitsPerPixel = _ttoi(pszToken); break; } nTokCount++; pszToken = _tcstok(NULL, chDelimit); } } void CTwainConfigApp::GetTransferName(pFASTCONFIG pConfig, CString & csName) { switch (pConfig->uTransferMode) { case LTWAIN_FILE_MODE: csName = "FILE"; break; case LTWAIN_BUFFER_MODE: csName = "MEMORY"; break; case LTWAIN_NATIVE_MODE: csName = "NATIVE"; break; } } void CTwainConfigApp::GetFormatName(pFASTCONFIG pConfig, CString & csName) { switch (pConfig->uTransferMode) { case LTWAIN_FILE_MODE: switch (pConfig->nFileFormat) { case TWFF_TIFF: case TWFF_TIFFMULTI: csName = "TIF"; break; case TWFF_PICT: csName = "PICT"; break; case TWFF_BMP: csName = "BMP"; break; case TWFF_XBM: csName = "XBM"; break; case TWFF_JFIF: csName = "JPEG"; break; case TWFF_FPX: csName = "FPX"; break; case TWFF_PNG: csName = "PNG"; break; case TWFF_SPIFF: csName = "SPIFF"; break; case TWFF_EXIF: csName = "EXIF"; break; } break; case LTWAIN_BUFFER_MODE: case LTWAIN_NATIVE_MODE: switch (pConfig->nFileFormat) { case FILE_FAX_G4: csName = "FAX G4"; break; case FILE_FAX_G3_2D: csName = "FAX G32D"; break; case FILE_FAX_G3_1D: csName = "FAX G31D"; break; case FILE_CCITT_GROUP4: csName = "CCITT G4"; break; case FILE_CCITT_GROUP3_2DIM: csName = "CCITT G32D"; break; case FILE_FAX_G3_1D_NOEOL: csName = "FAX G31D NO EOL"; break; case FILE_CCITT_GROUP3_1DIM: csName = "CCITT G31D"; break; case FILE_BMP: csName = "BMP"; break; case FILE_JBIG: csName = "JBIG"; break; case FILE_TIF_JPEG: csName = "TIF JPEG"; break; case FILE_TIF: csName = "TIF"; break; case FILE_JPEG: csName = "JPEG"; break; case FILE_JPEG_411: csName = "JPEG 411"; break; case FILE_JPEG_422: csName = "JPEG 422"; break; } break; } } void CTwainConfigApp::ErrorMsgBox(L_INT nErrorCode) { CString csText; csText.Format(_T("L_TwainFindFastConfig failed: Error = %d"), nErrorCode); AfxMessageBox(csText); } L_INT EXT_CALLBACK TwnSourcesCB(HTWAINSESSION hSession, pLTWAINSOURCEINFO pSource, L_VOID * pUserData) { CTwainConfigApp * pApp = (CTwainConfigApp *)pUserData; pApp->m_csTwnSourceName = pSource->pszTwnSourceName; pApp->m_csTwnFamilyName = pSource->pszTwnProductFamily; pApp->m_csTwnManufacturerName = pSource->pszTwnManufacturer; return TWAIN_SUCCESS; } void CTwainConfigApp::GetSelectScannerName() { L_INT nRet = L_TwainGetSources(m_hSession, TwnSourcesCB, sizeof(LTWAINSOURCEINFO), LTWAIN_SOURCE_ENUMERATE_DEFAULT, this); if (nRet != TWAIN_SUCCESS) { m_csTwnSourceName.Empty(); m_csTwnFamilyName.Empty(); m_csTwnManufacturerName.Empty(); } } void CTwainConfigApp::OnHelpUtilityInstructions() { ShellExecute(m_pMainWnd->m_hWnd, _T("open"), _T("IEXPLORE"), m_csTutorialPath, NULL, SW_SHOW); } void CTwainConfigApp::OnToolsUploadDATCFile() { ShellExecute(m_pMainWnd->m_hWnd, _T("open"), _T("IEXPLORE"), _T("http://www.leadtools.com/sdk/twain/uploadSettings.asp"), NULL, SW_SHOW); } void CTwainConfigApp::OnUpdateToolsUploadDATCFile(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bFillDATC && !m_bScanConfigs); } L_BOOL CTwainConfigApp::WriteDATCFile() { CStdioFile *pStdFile; CString csBuffer; TRY { pStdFile = new CStdioFile(m_csDatFileNameNum, CFile::modeCreate | CFile::modeWrite | CFile::typeText); } CATCH (CFileException, pEx) { csBuffer.Format(_T("Not able to open the Log File.")); ::MessageBox(NULL, csBuffer, _T("Error!"), MB_OK); pStdFile = NULL; m_bFillDATC = FALSE; return FALSE; } END_CATCH csBuffer.Format(_T("%d;%d;%d;%d;%d;%d\n"), m_nTestConfigCount, m_BestConfig.uTransferMode, m_BestConfig.nFileFormat, m_BestConfig.ulBufferSize, m_BestConfig.uTime, m_BestConfig.nBitsPerPixel); pStdFile->WriteString(csBuffer); GetSelectScannerName(); csBuffer.Format(_T("Scanner Driver Name is %s\n"), m_csTwnSourceName); pStdFile->WriteString(csBuffer); csBuffer.Empty(); csBuffer.Format(_T("Scanner Family Name: %s\n"), m_csTwnFamilyName); pStdFile->WriteString(csBuffer); csBuffer.Empty(); csBuffer.Format(_T("Scanner Manufacturer Name: %s\n"), m_csTwnManufacturerName); pStdFile->WriteString(csBuffer); csBuffer.Empty(); pStdFile->Close(); delete pStdFile; return TRUE; } void CTwainConfigApp::SkipConfiguration() { if (MessageBox(m_pMainWnd->m_hWnd, _T("Did the configuration test end normally?"), _T("Skip Configuration"), MB_YESNO) == IDNO) return; if (m_nInFastConfigsCount-1 == 0) { AfxMessageBox(_T("You ignored the last configuration\nAnd all Scan Configurations was completed")); m_nInFastConfigsCount = 0; GlobalFreePtr(m_pInFastConfigs); m_pInFastConfigs = NULL; return; } for(int i=0; iEnable(!m_bScanConfigs); } void CTwainConfigApp::OnUpdateConfigurationOptions(CCmdUI* pCmdUI) { pCmdUI->Enable(!m_bScanConfigs); } void CTwainConfigApp::OnUpdateAppExit(CCmdUI* pCmdUI) { pCmdUI->Enable(!m_bScanConfigs); } L_VOID EXT_CALLBACK TwnAcquireMulti(HTWAINSESSION hSession, L_INT nPage, L_TCHAR L_FAR * pszFileName, L_BOOL bFinishScan, L_VOID *pUserData) { CTwainConfigApp * pApp = (CTwainConfigApp *)pUserData; if (pApp->m_nTimeLen == 0) { pApp->m_pTime = (L_UINT *)GlobalAllocPtr(GHND, sizeof(L_UINT) * MAX_SCAN_PAGES); if (pApp->m_pTime) pApp->m_nTimeLen = MAX_SCAN_PAGES; } else if (pApp->m_nScannedPageCount >= pApp->m_nTimeLen) { pApp->m_pTime = (L_UINT *)GlobalReAllocPtr(pApp->m_pTime, sizeof(L_UINT) * (pApp->m_nTimeLen + MAX_SCAN_PAGES), GHND); if (pApp->m_pTime) pApp->m_nTimeLen += MAX_SCAN_PAGES; } if (!pApp->m_pTime) { pApp->m_nTimeLen = 0; return; } if (bFinishScan) { pApp->m_dwEndTickCount = GetTickCount(); pApp->m_pTime[pApp->m_nScannedPageCount] = pApp->m_dwEndTickCount - pApp->m_dwStartTickCount; pApp->m_nScannedPageCount++; } else pApp->m_dwStartTickCount = GetTickCount(); } void CTwainConfigApp::TestFastConfig() { CString csMsg; csMsg.Format(_T("Would you like to try a test scan using the Fastest Configuration?")); L_INT nRet = MessageBox(m_pMainWnd->m_hWnd, csMsg, _T("Fast Configuration"), MB_YESNO); if (nRet == IDNO) return; CString csFileName; CLogFile SelFileName(FALSE); if (SelFileName.DoModal() == IDOK) csFileName = SelFileName.m_csFileName; else return; csMsg.Format(_T("Please, insert the pages into your feeder\nor put the page into the flatbed...\nand then press OK")); MessageBox(m_pMainWnd->m_hWnd, csMsg, _T("Fast Configuration"), MB_OK); m_nScannedPageCount = 0; m_dwStartTickCount = 0; m_dwEndTickCount = 0; if (m_pTime) { GlobalFreePtr(m_pTime); m_pTime = NULL; m_nTimeLen = 0; } nRet = L_TwainAcquireMulti(m_hSession, (L_TCHAR *)(LPCTSTR)csFileName, m_uFlags, m_BestConfig.uTransferMode, m_BestConfig.nFileFormat, m_BestConfig.nBitsPerPixel, TRUE, m_BestConfig.ulBufferSize, TRUE, TwnAcquireMulti, this); if (nRet == SUCCESS) { CScanRes scanDlg; scanDlg.DoModal(); } }