diff --git a/app/twaintest/HGUIGlobal.cpp b/app/twaintest/HGUIGlobal.cpp new file mode 100644 index 00000000..fd3dbbf1 --- /dev/null +++ b/app/twaintest/HGUIGlobal.cpp @@ -0,0 +1,20 @@ +#include "HGUIGlobal.h" +#include "base/HGDef.h" +#include "base/HGInc.h" +#include "base/HGUtility.h" + +QString getStdFileName(const QString &fileName) +{ + char result[512] = {0}; + HGBase_StandardiseFileName(fileName.toStdString().c_str(), result, 512); + return result; +} + +std::string getStdString(const QString &str) +{ +#ifdef HG_CMP_MSC + return str.toLocal8Bit().data(); +#else + return str.toStdString(); +#endif +} diff --git a/app/twaintest/HGUIGlobal.h b/app/twaintest/HGUIGlobal.h new file mode 100644 index 00000000..d1da4d16 --- /dev/null +++ b/app/twaintest/HGUIGlobal.h @@ -0,0 +1,10 @@ +#ifndef __HGUIGLOBAL_H__ +#define __HGUIGLOBAL_H__ + +#include + +QString getStdFileName(const QString &fileName); + +std::string getStdString(const QString &str); + +#endif /* __HGUIGLOBAL_H__ */ diff --git a/app/twaintest/main.cpp b/app/twaintest/main.cpp new file mode 100644 index 00000000..fd3e5334 --- /dev/null +++ b/app/twaintest/main.cpp @@ -0,0 +1,11 @@ +#include "mainwindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/app/twaintest/mainwindow.cpp b/app/twaintest/mainwindow.cpp new file mode 100644 index 00000000..0d504eef --- /dev/null +++ b/app/twaintest/mainwindow.cpp @@ -0,0 +1,188 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" + +#include +#include +#include "base/HGUtility.h" +#include "imgfmt/HGImgFmt.h" +#include "HGUIGlobal.h" +#include "HGString.h" + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) + , m_twainDSM(nullptr) + , m_twainDS(nullptr) + , m_cacheUuid("") +{ + ui->setupUi(this); + + HGChar cacheUuid[256] = { 0 }; + HGBase_GetUuid(cacheUuid, 256); + m_cacheUuid = cacheUuid; + + QStringList capTypes = { "TWTY_INT8", "TWTY_UINT8", "TWTY_INT16", "TWTY_UINT16", "TWTY_INT32", "TWTY_UINT32", "TWTY_BOOL","TWTY_FIX32", + "TWTY_STR32", "TWTY_STR64", "TWTY_STR128", "TWTY_STR255" }; + + ui->comboBox_capType->addItems(capTypes); + ui->comboBox_capType->setCurrentIndex(0); + ui->comboBox_capType->setEditable(true); + ui->label_deviceStatus->setText(tr("No device connected")); + + HGTwain_CreateDSM((HWND)this->winId(), &m_twainDSM); + + connect(this, SIGNAL(newImage(void*)), this, SLOT(on_newImage(void*)), Qt::DirectConnection); + connect(this, SIGNAL(clearRes()), this, SLOT(on_clearRes()), Qt::QueuedConnection); +} + +MainWindow::~MainWindow() +{ + QString cachePath = getCachePath() + m_cacheUuid + "/"; + QDir dir = QDir(cachePath); + if (dir.exists()) + dir.removeRecursively(); + + if (m_twainDSM != nullptr) + { + HGTwain_DestroyDSM(m_twainDSM); + m_twainDSM = nullptr; + } + + if (m_twainDS != nullptr) + { + HGTwain_CloseDS(m_twainDS); + HGTwain_DestroyDS(m_twainDS); + m_twainDS = nullptr; + } + + delete ui; +} + +void MainWindow::on_act_selectDevice_triggered() +{ + ui->label_deviceStatus->setText(tr("No device connected")); + + if (m_twainDS != nullptr) + { + HGTwain_CloseDS(m_twainDS); + HGTwain_DestroyDS(m_twainDS); + m_twainDS = nullptr; + } + + HGResult ret = HGTwain_CreateSelectedDSEx(m_twainDSM, &m_twainDS); + if (nullptr != m_twainDS) + { + HGResult ret = HGTwain_OpenDS(m_twainDS); + if (ret == HGBASE_ERR_OK) + { + HGTwain_LoginDS(m_twainDS, "user", "huagoscan"); + ui->label_deviceStatus->setText(tr("Device %1 is open").arg(getDeviceName())); + } + } + else + { + if (HGTWAIN_ERR_CANCELUI != ret) + { + QMessageBox::information(this, tr("Prompt"), tr("Device source not found!")); + } + } +} + +void MainWindow::on_pushButton_SetCap_clicked() +{ + QString capCode = ui->lineEdit_setCap->text(); + bool ok = false; + HGUShort cap = capCode.toInt(&ok, 16); + + HGCapValue value; + QString capType = ui->comboBox_capType->currentText(); + if (capType == "TWTY_BOOL") + { + value.type = HGCAPVALUE_TYPE_BOOL; + value.valueBool = ui->lineEdit_setCapContent->text().toInt(); + } + + HGResult ret = HGTwain_SetCapbility(m_twainDS, cap, &value, ui->checkBox_resetCap->isChecked()); + if (ret == HGBASE_ERR_OK) + { + QMessageBox::information(this, tr("Prompt"), tr("Set successfully")); + } + else + { + QMessageBox::information(this, tr("Prompt"), tr("Set failed")); + } +} + +void MainWindow::on_pushButton_scan_clicked() +{ + HGResult ret = HGTwain_EnableDS(m_twainDS, HGFALSE, (HWND)this->winId(), DSEventFunc, this, DSImageFunc, this); +} + +void MainWindow::on_newImage(void *image) +{ + HGImage img = nullptr; + HGBase_CloneImage((HGImage)image, 0, 0, &img); + QString scanFileName = getCacheFileName((HGImage)image); + HGImgFmtSaveInfo info; + info.jpegQuality = 100; + info.tiffCompression = HGIMGFMT_TIFFCOMP_LZW; + info.tiffJpegQuality = 0; + HGResult ret = HGImgFmt_SaveImage((HGImage)image, 0, &info, getStdString(scanFileName).c_str()); +} + +void MainWindow::on_clearRes() +{ + HGTwain_DisableDS(m_twainDS); +} + +void MainWindow::DSEventFunc(HGTwainDS ds, HGUInt event, HGPointer param) +{ + MainWindow* p = (MainWindow*)param; + if (HGTWAIN_EVENT_TYPE_SCANFINISHED == event || HGTWAIN_EVENT_TYPE_CLOSEDSREQ == event) + { + emit p->clearRes(); + } +} + +HGUInt MainWindow::DSImageFunc(HGTwainDS ds, HGImage image, HGUInt type, HGPointer param) +{ + MainWindow* p = (MainWindow*)param; + emit p->newImage(image); + return HGBASE_ERR_OK; +} + +QString MainWindow::getDeviceName() +{ + HGChar devName[256] = {0}; + HGTwain_GetDSDeviceName(m_twainDS, devName, 256); + return QString(devName); +} + +QString MainWindow::getCachePath() +{ + HGChar cachePath[512]; + HGBase_GetDocumentsPath(cachePath, 512); + HGChar procName[512]; + HGBase_GetProcessName(procName, 512); + strcat(cachePath, procName); + strcat(cachePath, "/Cache/"); + + return getStdFileName(StdStringToUtf8(cachePath).c_str()); +} + +QString MainWindow::getCacheFileName(HGImage img) +{ + assert(nullptr != img); + + HGImageInfo imgInfo; + HGBase_GetImageInfo(img, &imgInfo); + + QString cachePath = getCachePath() + m_cacheUuid + "/"; + HGBase_CreateDir(getStdString(cachePath).c_str()); + + char uuid[256] = {0}; + HGBase_GetUuid(uuid, 256); + QString suffix = (HGBASE_IMGTYPE_BINARY == imgInfo.type) ? ".bmp" : ".jpg"; + QString fileName = getStdFileName(cachePath + uuid + suffix); + return fileName; +} diff --git a/app/twaintest/mainwindow.h b/app/twaintest/mainwindow.h new file mode 100644 index 00000000..de8eda19 --- /dev/null +++ b/app/twaintest/mainwindow.h @@ -0,0 +1,50 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include "base/HGDef.h" +#include "twain_user/HGTwain.h" + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +private slots: + void on_act_selectDevice_triggered(); + + void on_pushButton_SetCap_clicked(); + + void on_pushButton_scan_clicked(); + +signals: + void newImage(void *image); + void clearRes(); + +private slots: + void on_newImage(void *image); + void on_clearRes(); + +private: + static void HGAPI DSEventFunc(HGTwainDS ds, HGUInt event, HGPointer param); + static HGUInt HGAPI DSImageFunc(HGTwainDS ds, HGImage image, HGUInt type, HGPointer param); + + QString getDeviceName(); + QString getCachePath(); + QString getCacheFileName(HGImage img); + +private: + Ui::MainWindow *ui; + HGTwainDSM m_twainDSM; + HGTwainDS m_twainDS; + + QString m_cacheUuid; +}; +#endif // MAINWINDOW_H diff --git a/app/twaintest/mainwindow.ui b/app/twaintest/mainwindow.ui new file mode 100644 index 00000000..8f21ed2f --- /dev/null +++ b/app/twaintest/mainwindow.ui @@ -0,0 +1,211 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + 30 + 80 + 91 + 16 + + + + Set Capbility: + + + + + + 130 + 70 + 161 + 31 + + + + + + + 310 + 450 + 101 + 41 + + + + Scan + + + + + + 240 + 200 + 111 + 41 + + + + Set Cap + + + + + + 30 + 30 + 331 + 16 + + + + Device Status: + + + + + + 130 + 130 + 161 + 31 + + + + + + + 20 + 130 + 101 + 16 + + + + Capbility Type: + + + + + + 370 + 210 + 121 + 16 + + + + Reset Capbility + + + + + + 410 + 70 + 231 + 31 + + + + + + + 330 + 80 + 71 + 16 + + + + Content: + + + + + + 20 + 320 + 91 + 16 + + + + Get Capbility: + + + + + + 130 + 310 + 161 + 31 + + + + + + + 330 + 320 + 71 + 16 + + + + Content: + + + + + + 410 + 310 + 231 + 31 + + + + + + + + 0 + 0 + 800 + 22 + + + + + act_scan + + + + + + + + + act_selectDevice + + + + + + diff --git a/build2/qt/HGSolutionWin.pro b/build2/qt/HGSolutionWin.pro index fa2e38cd..766dd0d7 100644 --- a/build2/qt/HGSolutionWin.pro +++ b/build2/qt/HGSolutionWin.pro @@ -6,6 +6,7 @@ SUBDIRS += \ HGImgProc \ HGTwainUI \ HGTwainUser \ + HGTwainTest \ HGVersion \ HGScannerLib \ HGWebService \ @@ -27,6 +28,9 @@ HGTwainUser.depends = \ HGBase \ HGTwainUI +HGTwainTest.depends = \ + HGTwainUser + HGVersion.depends = \ HGBase diff --git a/build2/qt/HGTwainTest/HGTwainTest.pro b/build2/qt/HGTwainTest/HGTwainTest.pro new file mode 100644 index 00000000..28f7eae9 --- /dev/null +++ b/build2/qt/HGTwainTest/HGTwainTest.pro @@ -0,0 +1,108 @@ +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TEMPLATE = app +DEFINES += UNTITLED_LIBRARY + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS +DEFINES += QT_NO_VERSION_TAGGING + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +include($$PWD/../HGOEM.pri) + +CONFIG(debug, debug|release) { + MY_CONFIGURE = Debug +} +CONFIG(release, debug|release) { + MY_CONFIGURE = Release +} + +win32 { + + MY_OS = windows + TARGET = $${OEM_PREFIX}TwainTestApp + + contains(QT_ARCH, i386) { + MY_ARCH = x86 + } + contains(QT_ARCH, x86_64) { + MY_ARCH = x64 + } + + CONFIG(release, debug|release) { + QMAKE_LFLAGS_RELEASE += /MAP + QMAKE_CFLAGS_RELEASE += /Zi + QMAKE_LFLAGS_RELEASE += /debug /opt:ref + } + + LIBS += -lgdi32 -lgdiplus -ldbghelp -luser32 -ladvapi32 + LIBS += -L$$PWD/../../build/$${MY_OS}/$${OEM_NAME}/$${MY_ARCH}/$${MY_CONFIGURE} -l$${OEM_PREFIX}Base -l$${OEM_PREFIX}ImgFmt -l$${OEM_PREFIX}TwainUser + + LIBS += -L$$PWD/../../../../release/win/$${MY_ARCH}/OEM/$${OEM_NAME} +} + +INCLUDEPATH += $$PWD/../../../modules +INCLUDEPATH += $$PWD/../../../utility + +DESTDIR = $$PWD/../../build/$${MY_OS}/$${OEM_NAME}/$${MY_ARCH}/$${MY_CONFIGURE} +UI_DIR = $$PWD/../../temp/$${MY_OS}/$${OEM_NAME}/$${MY_ARCH}/$${MY_CONFIGURE}/$${TARGET} +MOC_DIR = $$PWD/../../temp/$${MY_OS}/$${OEM_NAME}/$${MY_ARCH}/$${MY_CONFIGURE}/$${TARGET} +OBJECTS_DIR = $$PWD/../../temp/$${MY_OS}/$${OEM_NAME}/$${MY_ARCH}/$${MY_CONFIGURE}/$${TARGET} +RCC_DIR = $$PWD/../../temp/$${MY_OS}/$${OEM_NAME}/$${MY_ARCH}/$${MY_CONFIGURE}/$${TARGET} + +message(MY_OS: $$MY_OS) +message(MY_ARCH: $$MY_ARCH) +message(OEM_PREFIX: $$OEM_PREFIX) +message(OEM_PREFIX2: $$OEM_PREFIX2) +message(OEM_NAME: $$OEM_NAME) +message(MY_CONFIGURE: $$MY_CONFIGURE) +message(TARGET: $$TARGET) +message(DESTDIR: $$DESTDIR) +message(UI_DIR: $$UI_DIR) +message(MOC_DIR: $$MOC_DIR) +message(OBJECTS_DIR: $$OBJECTS_DIR) +message(RCC_DIR: $$RCC_DIR) + +win32 { + + CONFIG(release, debug|release) { + DESTEXE_PATH = $${PWD}/../../../../release/win/$${MY_ARCH}/$${MY_CONFIGURE}/ + DESTEXE_PATH = $$replace(DESTEXE_PATH, /, \\) + message(DESTEXE_PATH: $$DESTEXE_PATH) + + SRCEXE_FILE = $${DESTDIR}/$${TARGET}.exe + SRCEXE_FILE = $$replace(SRCEXE_FILE, /, \\) + message(SRCEXE_FILE: $$SRCEXE_FILE) + SRCPDB_FILE = $${DESTDIR}/$${TARGET}.pdb + SRCPDB_FILE = $$replace(SRCPDB_FILE, /, \\) + message(SRCPDB_FILE: $$SRCPDB_FILE) + + QMAKE_POST_LINK += xcopy /y $$SRCEXE_FILE $$DESTEXE_PATH && xcopy /y $$SRCPDB_FILE $$DESTEXE_PATH + } +} + +SOURCES += \ + ../../../app/twaintest/main.cpp \ + ../../../app/twaintest/mainwindow.cpp \ + ../../../app/twaintest/HGUIGlobal.cpp \ + ../../../utility/HGString.cpp + + +HEADERS += \ + ../../../app/twaintest/mainwindow.h \ + ../../../app/twaintest/HGUIGlobal.h \ + ../../../utility/HGString.h + +FORMS += \ + ../../../app/twaintest/mainwindow.ui