调整usb readbulk超时时间 增加固件兼容性

This commit is contained in:
masayume 2022-08-10 11:10:20 +08:00
parent 0aa4e0e025
commit e964c60148
17 changed files with 810 additions and 52 deletions

View File

@ -55,4 +55,10 @@
13.添加画质优先与速度优先模式 13.添加画质优先与速度优先模式
14.调整互斥锁不同设备能在同一台pc上使用 14.调整互斥锁不同设备能在同一台pc上使用
15.调整速度优先600 dpi 按照真实300dpi 缩放 15.调整速度优先600 dpi 按照真实300dpi 缩放
16.协议问题排查 16.协议问题排查
17.完成安卓3399适配
18.取消UI置顶
2020年8月10日
版本3.3.5.9
1.调整usb通信加长readbulk超时时间
2.屏蔽3288 自适应幅面功能

View File

@ -59,6 +59,7 @@ CImageProcPage::~CImageProcPage()
void CImageProcPage::ImageProcPageUpdate(int val,int twss, int cmduplexsel,bool is_Crop,int dpi) void CImageProcPage::ImageProcPageUpdate(int val,int twss, int cmduplexsel,bool is_Crop,int dpi)
{ {
this->colormode_index = val;
this->dpi = dpi; this->dpi = dpi;
this->twss = twss; this->twss = twss;
this->cmduplexsel = cmduplexsel; this->cmduplexsel = cmduplexsel;
@ -88,6 +89,7 @@ void CImageProcPage::ImageProcPageUpdate(int val,int twss, int cmduplexsel,bool
GetDlgItem(IDC_CHMULTIPUT)->EnableWindow(TRUE); GetDlgItem(IDC_CHMULTIPUT)->EnableWindow(TRUE);
GetDlgItem(IDC_CMBMULTIOUT)->EnableWindow(((CButton*)GetDlgItem(IDC_CHMULTIPUT))->GetCheck()); GetDlgItem(IDC_CMBMULTIOUT)->EnableWindow(((CButton*)GetDlgItem(IDC_CHMULTIPUT))->GetCheck());
} }
t_chMultiOutput->EnableWindow(TRUE);
} }
else { else {
GetDlgItem(IDC_CKHSVCORRECT)->EnableWindow(FALSE); GetDlgItem(IDC_CKHSVCORRECT)->EnableWindow(FALSE);
@ -98,21 +100,22 @@ void CImageProcPage::ImageProcPageUpdate(int val,int twss, int cmduplexsel,bool
((CButton*)GetDlgItem(IDC_CHMULTIPUT))->SetCheck(FALSE); ((CButton*)GetDlgItem(IDC_CHMULTIPUT))->SetCheck(FALSE);
GetDlgItem(IDC_CMBMULTIOUT)->EnableWindow(FALSE); GetDlgItem(IDC_CMBMULTIOUT)->EnableWindow(FALSE);
((CButton*)GetDlgItem(IDC_CMBMULTIOUT))->SetCheck(FALSE); ((CButton*)GetDlgItem(IDC_CMBMULTIOUT))->SetCheck(FALSE);
t_chMultiOutput->SetCheck(FALSE);
t_chMultiOutput->EnableWindow(FALSE);
} }
if (0 == val||val==3)//彩色 if (0 == val||val==3)//彩色
{ {
m_temp->SetCurSel(0); m_temp->SetCurSel(0);
m_temp->EnableWindow(FALSE); m_temp->EnableWindow(FALSE);
//t_chMultiOutput->SetCheck(TRUE); //t_chMultiOutput->SetCheck(TRUE);
t_chMultiOutput->EnableWindow(TRUE);
} }
else else
{ {
m_temp->EnableWindow(TRUE); m_temp->EnableWindow(TRUE);
t_chMultiOutput->SetCheck(FALSE);
t_chMultiOutput->EnableWindow(FALSE);
GetDlgItem(IDC_CKBACKGROUNDSMOOTH)->EnableWindow(FALSE); GetDlgItem(IDC_CKBACKGROUNDSMOOTH)->EnableWindow(FALSE);
} }
if (val == 2) if (val == 2)
{ {
((CButton*)GetDlgItem(IDC_CHECKDETACHNOISE))->EnableWindow(true); ((CButton*)GetDlgItem(IDC_CHECKDETACHNOISE))->EnableWindow(true);
@ -234,8 +237,10 @@ void CImageProcPage::SetMultiOutputEnable(int pixtype, bool enable)
switch (pixtype) switch (pixtype)
{ {
case 2://彩色 case 2://彩色
((CButton*)GetDlgItem(IDC_CKMULTIOUTPUT))->SetCheck(enable); if (colormode_index == 0) {
((CButton*)GetDlgItem(IDC_CKMULTIOUTPUT))->EnableWindow(TRUE); ((CButton*)GetDlgItem(IDC_CKMULTIOUTPUT))->SetCheck(enable);
((CButton*)GetDlgItem(IDC_CKMULTIOUTPUT))->EnableWindow(TRUE);
}
break; break;
case 0://灰度 黑白 case 0://灰度 黑白
case 1: case 1:
@ -350,7 +355,10 @@ void CImageProcPage::OnBnClickedChmultiput()
{ {
GetDlgItem(IDC_CMBMULTIOUT)->EnableWindow(FALSE); GetDlgItem(IDC_CMBMULTIOUT)->EnableWindow(FALSE);
((CComboBox*)GetDlgItem(IDC_CMBMULTIOUT))->SetCurSel(0); ((CComboBox*)GetDlgItem(IDC_CMBMULTIOUT))->SetCurSel(0);
GetDlgItem(IDC_CKMULTIOUTPUT)->EnableWindow(TRUE); if (colormode_index == 0)
{
GetDlgItem(IDC_CKMULTIOUTPUT)->EnableWindow(TRUE);
}
} }
} }

View File

@ -42,6 +42,7 @@ public:
int twss; int twss;
int cmduplexsel; int cmduplexsel;
int dpi; int dpi;
int colormode_index;
bool is_convex; bool is_convex;
bool is_crop; bool is_crop;
bool is_bw; bool is_bw;

View File

@ -0,0 +1,605 @@
#include "GScan439Android.h"
#include "IUsb.h"
#include "UsbScanEx.h"
#include <iostream>
using namespace std;
static std::mutex mx_ctrl;
#define m_max(a, b) (((a) > (b)) ? (a) : (b))
#define m_min(a, b) (((a) < (b)) ? (a) : (b))
static int read_reg(std::shared_ptr<IUsb>& usb, int addr)
{
std::lock_guard<std::mutex> lck(mx_ctrl);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
if (usb.get() && usb->is_connected()) {
int val = 0;
usb->control_msg(0xc0, USB_REQ_GET_DEV_REGS, addr, 0, 4, &val);
return val;
}
else
FileTools::writelog(log_ERROR, " read_reg error usb disconnect");
return 0;
}
static void write_reg(std::shared_ptr<IUsb>& usb, int addr, int val)
{
std::lock_guard<std::mutex> lck(mx_ctrl);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
if (usb.get() && usb->is_connected())
{
usb->control_msg(0x40, USB_REQ_SET_DEV_REGS, addr, 0, 4, &val);
}
else
FileTools::writelog(log_ERROR, " write_reg error usb disconnect");
}
static void scanner_control(std::shared_ptr<IUsb>& usb, int cmd)
{
write_reg(usb, 0, cmd);
}
GScan439Android::GScan439Android():m_readimgpool(1)
{
im_data.reset(new std::vector<char>());
m_status = -1;
m_pImages.reset(new ImageMatQueue());
}
GScan439Android::~GScan439Android()
{
if (m_usbthread.get() && m_usbthread->joinable())
{
b_usbthread = false;
m_usbthread->join();
m_usbthread.reset();
}
imgs.ShutDown();
m_imagedata.ShutDown();
}
void GScan439Android::open(int vid, int pid)
{
if (m_usb.get() && m_usb->is_connected())
return;
auto lsusb = UsbScan_List::find_vid_pid(vid, pid);
if (!lsusb.empty())
{
m_usb = *lsusb.begin();
m_usb->open();
if (m_usb->is_open())
m_usb->set_usbhotplug_callback(usbhotplug_callback, this);
}
}
void GScan439Android::regist_deviceevent_callback(deviceevent_callback callback, void* usrdata)
{
huagods = usrdata;
dev_callback = callback;
}
void GScan439Android::DogEar_callback(std::function<void(int)> fun)
{
}
int GScan439Android::aquire_bmpdata(std::vector<unsigned char>& bmpdata)
{
FileTools::writelog(log_lv::log_DEBUG, " aquire_bmpdata start");
StopWatch sw;
while (true)
{
if (m_pImages->empty()) {
DoEvents();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
if (sw.elapsed_s() > 30.00)
{
if (m_usbthread.get() && m_usbthread->joinable()) {
m_status = DEV_STOP;
m_usbthread->join();
m_usbthread.reset();
}
Stop_scan();//ֹͣɨ<D6B9><C9A8>
ResetScanner();
auto rollernew = Get_Roller_num();
set_scannum(abs(rollernew - roller_num));
FileTools::writelog(log_lv::log_DEBUG, " aquire_bmpdata timeout");
return HARDWARE_ERROR;
}
if (!is_scan()) {
auto rollernew = Get_Roller_num();
set_scannum(abs(rollernew - roller_num));
FileTools::writelog(log_lv::log_DEBUG, " aquire_bmpdata stop");
if (m_status == DEV_WRONG) {
return get_ErrorCode();
}
return -1;
}
}
else {
if (m_pImages->valid()) {
bmpdata = *(m_pImages->popBmpdata());
UpdateScanInfo(get_imgnReaded(), countNTransfered());
FileTools::writelog(log_lv::log_DEBUG, " aquire_bmpdata quit");
return 0;
}
DoEvents();
std::this_thread::sleep_for(std::chrono::milliseconds(2));
}
}
}
BOOL GScan439Android::IsConnected()
{
return m_usb.get() && m_usb->is_connected();
}
std::string GScan439Android::GetFWVersion()
{
static std::string fw;// = "12312312";
if (m_usb.get() && m_usb->is_connected() && fw.empty())
{
write_reg(m_usb, SR_GET_FWVERSION, 0);
fw.resize(512);
m_usb->read_bulk(&fw[0], 512);
//read_data(&fw[0], fw.length(), 100);
}
return fw;
}
std::string GScan439Android::GetSerialNum()
{
static std::string sn;// = "12333123123123";
if (m_usb.get() && m_usb->is_connected() && sn.empty())
{
write_reg(m_usb, SR_GET_SERIALNUM, 0);
sn.resize(512);
m_usb->read_bulk(&sn[0], 512);
//read_data(&sn[0], sn.length(), 100);
}
return sn;
}
std::string GScan439Android::GetMacAdder()
{
return std::string();
}
std::uint32_t GScan439Android::GetMotorFPGA()
{
return std::uint32_t();
}
std::uint32_t GScan439Android::GetScanFPGA()
{
return std::uint32_t();
}
bool GScan439Android::is_scan()
{
return m_status == DEV_ISRUNNING || (m_imagedata.Size() > 0);
}
BOOL GScan439Android::Get_Scanner_PaperOn()
{
return read_reg(m_usb, SR_GET_PAPERON);
}
int GScan439Android::Get_Roller_num()
{
return read_reg(m_usb, SR_GET_ROLLER_NUM);
}
void GScan439Android::config_params(GScanCap& param)
{
m_param = param;
HGScanConfig cfg;
cfg.value = 0;
PaperStatus ps = { param.papertype,param.paperAlign };
cfg.g200params.paper = SupPaperTyps.count(ps) > 0 ? SupPaperTyps[ps] : 0;
if (param.filter != 3 || param.enhance_color != 0 || param.hsvcorrect)
cfg.g200params.color = 1;//color
else
{
cfg.g200params.color = SupPixelTypes.count(param.pixtype) > 0 ? SupPixelTypes[param.pixtype] : 2;
}
cfg.g200params.dpi = param.resolution_dst >=300 ? 2 : 1;// SupResolutions.count(param.resolution_native) > 0 ? SupResolutions[param.resolution_native] : 1;
param.resolution_native = param.resolution_dst >= 300 ? 300 : 200;
cfg.g200params.double_feed_enbale = (unsigned int)param.hardwarecaps.en_doublefeed;
//cfg.g200params.stable_enbale = 0;
cfg.g200params.stable_enbale = (unsigned int)param.hardwarecaps.en_stapledetect;
cfg.g200params.screw_detect_enable = (unsigned int)param.hardwarecaps.en_skrewdetect;
cfg.g200params.screw_detect_level = (unsigned int)cfg.g200params.screw_detect_enable ? secrewMaps[param.hardwarecaps.skrewdetectlevel] : 0;
cfg.g200params.enable_sizecheck = param.en_sizecheck == 1 ? 1 : 0;
write_reg(m_usb, SR_CONFIG_SCAN_PARAM, cfg.value);
m_pImages->setparam(param);
}
void GScan439Android::Scanner_StartScan(UINT16 count)
{
error_index = 0;
roller_num = read_reg(m_usb, SR_GET_ROLLER_NUM);
Set_ErrorCode(0);
getimgnum = 0;
aquirenum = 0;
imagecount = 0;
reset();
m_status = DEV_ISRUNNING;
//if (read_reg(m_usb, SR_GET_SLEEP_STAUTUS) != 1)
//{
// m_status = DEV_WRONG;
// Set_ErrorCode(SLEEPING);
// scanflag = false;
// return;
//}
if (!Get_Scanner_PaperOn())
{
m_status = DEV_WRONG;
Set_ErrorCode(NO_FEED);
scanflag = false;
return;
}
int state = read_reg(m_usb, SR_GET_ANDROID_STATE);
if (state != 0)
{
if (state == 1) Set_ErrorCode(OPEN_COVER);
else if (state == 2) Set_ErrorCode(PAPER_JAM);
else if (state == 3) Set_ErrorCode(NO_FEED);
else Set_ErrorCode(HARDWARE_ERROR);
scanflag = false;
m_status = DEV_WRONG;
return;
}
write_reg(m_usb, 0x1000, m_param.is_duplex ? m_param.scannum /2 : m_param.scannum);
scanner_control(m_usb, SC_START);
if (!m_usbthread.get()) {
b_usbthread = true;
m_usbthread.reset(new thread(&GScan439Android::usbmainloop, this));
}
m_pImages->setscanflags(true);
m_pImages->run();
}
void GScan439Android::Stop_scan()
{
scanner_control(m_usb, SC_STOP);
if ((m_status == DEV_WRONG) || (m_status == DEV_STOP))
return;
m_status = DEV_STOP;
}
int GScan439Android::notifyscan()
{
return 1;
}
void GScan439Android::ResetScanner()
{
}
bool GScan439Android::Get_IsImageQueueEmpty()
{
return m_pImages->empty() && m_status == DEV_STOP;
}
void GScan439Android::reset()
{
m_status = DEV_STOP;
m_pImages->clear();
//scanner_control(m_usb, SC_INIT);
}
void GScan439Android::clear_hwerror()
{
//scanner_control(m_usb, SC_INIT);
}
UINT32 GScan439Android::get_ErrorCode()
{
return Error_Code;
}
void GScan439Android::Set_ErrorCode(UINT32 value)
{
Error_Code = value;
}
int GScan439Android::get_scanned_num()
{
return 0;
}
void GScan439Android::set_sleep_time(int mode)
{
}
bool GScan439Android::set_scannercode(std::string str)
{
return false;
}
std::string GScan439Android::get_scannercode()
{
return std::string();
}
void GScan439Android::usbhotplug_callback(bool isconnect, void* userdata)
{
GScan439Android* This = (GScan439Android*)userdata;
This->usbhotplug(isconnect);
}
void GScan439Android::usbhotplug(bool isleft)
{
FileTools::writelog(log_ERROR, "enable usb callback ");
if (isleft) {
m_status = DEV_WRONG;
Error_Code = USB_DISCONNECTED;
m_pImages->setscanflags(false);
scanflag = false;
if (m_usb.get())
m_usb.reset();
if (huagods)
dev_callback(USB_DISCONNECTED, huagods);
}
}
int GScan439Android::read_data(void* data, int length, int timeout)
{
if (!m_usb.get() && !m_usb->is_connected())
{
FileTools::writelog(log_INFO, "if (!m_usb.get() && !m_usb->is_connected())");
return 0;
}
timeout = std::max(1000, timeout);
int readed = 0;
int reading = 0;
const int buffer_size = 512 * 1024;
StopWatch sw;
FileTools::writelog(log_INFO, "read_data timeout =" + to_string(timeout));
while (readed < length) {
if (sw.elapsed_ms() < timeout && m_usb.get())
{
reading = std::max(0, std::min(length - readed, buffer_size));
reading = m_usb->read_bulk((unsigned char*)data + readed, reading);
if (reading > 0) {
readed += reading;
sw.reset();
}
}
else
{
FileTools::writelog(log_INFO, "read usb image data time out ,time = " + std::to_string(sw.elapsed_ms()));
break;
}
}
return readed;
}
void GScan439Android::usbmainloop()
{
unsigned char buff[32];
while (b_usbthread)
{
if (!m_usb.get() || !m_usb->is_connected())
{
this_thread::sleep_for(chrono::milliseconds(20));
continue;
}
memset(buff, 0, sizeof(buff));
auto length = m_usb->read_int(buff, sizeof(buff));
if (((length) == sizeof(buff)))//|| im_dev_count()
{
HGEIntInfo info = *(HGEIntInfo*)&buff;
if (codeconvter(info) > 0 && get_ErrorCode() == 0)
{
Set_ErrorCode(codeconvter(info));
}
if (codeconvter(info) == -1)
{
m_readimgpool.enqueue([this] {
StopWatch stoptime;
while (stoptime.elapsed_s() < 3) {
if (read_reg(m_usb, SR_IM_COUNT) > 0)
{
readimg();
stoptime.reset();
}
this_thread::sleep_for(chrono::milliseconds(200));
}
m_status = get_ErrorCode() == 0 ? DEV_STOP : DEV_WRONG;
m_pImages->setscanflags(false); });
}
switch (info.From)
{
case IMG:
m_readimgpool.enqueue([this] {
if (read_reg(m_usb, SR_IM_COUNT) > 0)
readimg();
});
break;
case MtBoard:
FileTools::writelog(log_ERROR, "Got MotorBoard error code = " + to_string(info.Code));
break;
case FPGA:
FileTools::writelog(log_ERROR, "Got FPGA Error code = " + to_string(info.Code));
break;
case V4L2:
FileTools::writelog(log_ERROR, "Got V4L2 Error code = " + to_string(info.Code));
scanner_control(m_usb, SC_STOP);
break;
case STOPSCAN:
FileTools::writelog(log_INFO, "StopScan");
break;
default:
FileTools::writelog(log_ERROR, "Got Unkown error code ! From =" + to_string(info.From) + " Code = " + to_string(info.Code));
break;
}
//this_thread::sleep_for(chrono::microseconds(10));
}
}
}
void GScan439Android::readimg()
{
if (read_reg(m_usb, SR_IM_TXING))
{
FileTools::writelog(log_ERROR, "Read image TXING");
return;
}
if (read_reg(m_usb, SR_IM_COUNT) > 0 && getStatus())
{
unsigned int len = read_reg(m_usb, SR_IM_FRONT_SIZE);
if (len > 0)
{
write_reg(m_usb, SR_IM_TX, 1);
im_data->resize(len);
static int indeximg = 0;
auto nreaded = tranxferimg(len, im_data);
if (nreaded == len)
{
m_pImages->pushMat(std::shared_ptr<IDecode>(new G400Decode(im_data)));
this_thread::sleep_for(chrono::milliseconds(10));
write_reg(m_usb, SR_IM_POP, 1);
FileTools::writelog(log_ERROR, "Enqueue image " + to_string(++indeximg) + "size " + to_string(nreaded));
UpdateScanInfo(countNReaded(), get_imgTransfered());
}
else
{
FileTools::writelog(log_ERROR, "error :read image data len error");
}
}
else
FileTools::writelog(log_ERROR, "error :Get front image data len ZERO" );
}
else
FileTools::writelog(log_ERROR, "image queue empty or not scanning" );
}
int GScan439Android::tranxferimg(unsigned int datalen, std::shared_ptr<std::vector<char>> data)
{
unsigned int timeout = 3000;
unsigned int readed = 0;
unsigned int reading = 0;
const int buffer_size = 512 * 1024;
StopWatch sw;
while (readed < datalen)
{
if (sw.elapsed_ms() < timeout && m_usb.get())
{
reading = m_max(0, m_min(datalen - readed, buffer_size));
reading = m_usb->read_bulk((unsigned char*)data->data() + readed, reading);
if (reading > 0)
{
readed += reading;
sw.reset();
}
else
FileTools::writelog(log_ERROR, "Read Image size zero");
}
else
{
FileTools::writelog(log_ERROR, "Read Image timeout" );
break;
}
}
return readed;
}
int GScan439Android::codeconvter(HGEIntInfo code)
{
if (code.From == HGType::FPGA)
{
switch (code.Code)
{
default:
break;
}
}
if (code.From == HGType::MtBoard)
{
switch (code.Code)
{
case 0x00002:
return NO_FEED;
case 0x00004:
return OPEN_COVER;
case 0x00008:
return FEED_IN_ERROR;
case 0x00010:
return PAPER_JAM;
case 0x00020:
return DETECT_DOUBLE_FEED;
case 0x00040:
return DETECT_STAPLE;
case 0x00080:
return PAPER_SKEW;
case 0x10000:
return AQUIRE_IMAGE_TIMEOUT;
case 0x20000:
return SIZE_ERROR;
case 0x40000:
return PAPER_HOLE;
case 0x80000:
return MLTOP_TIMEOUT;
default:
break;
}
}
if (code.From == HGType::V4L2)
{
switch (code.Code)
{
case 0:
return V4L2_AQULRE_ERROR;
case 1:
return V4L2_IMAGE_EMPTY;
default:
break;
}
}
if (code.From == HGType::STOPSCAN)
{
switch (code.Code)
{
case 0:
return -1;
case 1:
if (m_status == DEV_ISRUNNING)
m_status = DEV_STOP;
return 0;
default:
break;
}
}
return 0;
}
bool GScan439Android::getStatus()
{
return 1;
int val = read_reg(m_usb, SR_STATUS) & 0x3;
bool ret = (val > 0) && (val < 4);
return ret;
}

View File

@ -0,0 +1,76 @@
#pragma once
#include "stdafx.h"
#include "GScan.h"
#include "IConfig.h"
#include "G400ScanConfig.h"
#include <memory>
#include <future>
#include <functional>
#include "ThreadPool.h"
#include "StopWatch.h"
#include "ImageMatQueue.h"
#include "opencv2/opencv.hpp"
class GScan439Android :
public IScanner
{
public:
GScan439Android();
virtual ~GScan439Android();
virtual void open(int vid, int pid) override;
virtual void regist_deviceevent_callback(deviceevent_callback callback, void* usrdata = 0) override;
virtual void DogEar_callback(std::function<void(int)> fun) override;
virtual int aquire_bmpdata(std::vector<unsigned char>& bmpdata) override;
virtual BOOL IsConnected() override;
virtual std::string GetFWVersion() override;
virtual std::string GetSerialNum() override;
virtual std::string GetMacAdder() override;
virtual std::uint32_t GetMotorFPGA() override;
virtual std::uint32_t GetScanFPGA() override;
virtual bool is_scan() override;
virtual BOOL Get_Scanner_PaperOn() override;
virtual int Get_Roller_num() override;
virtual void config_params(GScanCap& param) override;
virtual void Scanner_StartScan(UINT16 count) override;
virtual void Stop_scan() override;
virtual int notifyscan() override;
virtual void ResetScanner() override;
virtual bool Get_IsImageQueueEmpty() override;
virtual void reset() override;
virtual void clear_hwerror() override;
virtual UINT32 get_ErrorCode() override;
virtual void Set_ErrorCode(UINT32 value) override;
virtual int get_scanned_num() override;
virtual void set_sleep_time(int mode) override;
virtual bool set_scannercode(std::string str) override;
virtual std::string get_scannercode() override;
private:
static void usbhotplug_callback(bool isconnect, void* userdata);
void usbhotplug(bool isleft);
int read_data(void* data, int length, int timeout);
void usbmainloop();
void readimg();
int tranxferimg(unsigned int datalen, std::shared_ptr<std::vector<char>> data);
int codeconvter(HGEIntInfo code);
bool getStatus();
private:
volatile int Error_Code;
volatile bool scanflag;
std::atomic_int imagecount;
int aquirenum = 0;
int getimgnum = 0;
GScanCap m_param;
std::shared_ptr<IUsb> m_usb;
volatile bool b_imgprothread;
volatile bool b_usbthread;
volatile int m_status;
ThreadPool m_readimgpool;
BlockingQueue<std::shared_ptr<std::vector<char>>> imgs;
std::shared_ptr<std::thread> m_usbthread;
std::shared_ptr<std::vector<char>> im_data;
BlockingQueue<std::shared_ptr<std::vector<unsigned char>>> m_imagedata;
deviceevent_callback dev_callback;
void* huagods;
};

View File

@ -440,7 +440,8 @@ void GScanO200::Scanner_StartScan(UINT16 count)
// return; // return;
// } // }
//#endif // !G200 //#endif // !G200
m_pImages->reset_DogEar();
m_pImages->reset_DogEar();
if (gcap.is_duplex) if (gcap.is_duplex)
count = count == 65535 ? 65535 : count / 2; count = count == 65535 ? 65535 : count / 2;
USBCB usbcb = { START_COMMAND,(UINT32)count ,0 }; USBCB usbcb = { START_COMMAND,(UINT32)count ,0 };

View File

@ -371,11 +371,11 @@ void GScanO400::config_params(GScanCap& params)
G400ScanConfig cfg = G400ScanConfig(params); G400ScanConfig cfg = G400ScanConfig(params);
UINT32 cfgdata = cfg.GetData(); UINT32 cfgdata = cfg.GetData();
auto fw = GetFWVersion(); auto fw = GetFWVersion();
if (atoi(fw.substr(4, 6).c_str()) >= 220117) //if (atoi(fw.substr(4, 6).c_str()) >= 220117)
{ //{
if (params.papertype == 52 || params.papertype == 54 || params.papertype == 131 || params.papertype == 0) // if (params.papertype == 52 || params.papertype == 54 || params.papertype == 131 || params.papertype == 0)
cfgdata = (cfgdata & 0xffffffe0) + 18; // cfgdata = (cfgdata & 0xffffffe0) + 18;
} //}
#ifdef G400 #ifdef G400
if (atoi(fw.substr(4, 6).c_str()) >= 220117) if (atoi(fw.substr(4, 6).c_str()) >= 220117)
{ {

View File

@ -190,6 +190,13 @@ enum Scanner_Reg_Defs
SR_SET_JSON, SR_SET_JSON,
SR_GET_FILE_POS, SR_GET_FILE_POS,
SR_SET_FILE_POS, SR_SET_FILE_POS,
SR_NOTIFY_SLEEP,
SR_GET_FEEDMODE,
SR_SET_FEEDMODE,
SR_GET_AUTOMATICCONTROLFEEDMODE_ENABLE,
SR_SET_AUTOMATICCONTROLFEEDMODE_ENABLE,
SR_GET_AUTOMATICCONTROLFEEDMODE_THRESHOLD,
SR_SET_AUTOMATICCONTROLFEEDMODE_THRESHOLD,
SR_GET_CUO_ERROR = 0x50, SR_GET_CUO_ERROR = 0x50,
SR_GET_DOU_ERROR, SR_GET_DOU_ERROR,
SR_GET_JAM_ERROR, SR_GET_JAM_ERROR,
@ -227,7 +234,10 @@ enum Scanner_Reg_Defs
SR_GET_MBVERSION_LENGHT, SR_GET_MBVERSION_LENGHT,
SR_GET_MBVERSION, SR_GET_MBVERSION,
SR_GET_USBVIDPID, SR_GET_USBVIDPID,
SR_SET_USBVIDPID SR_SET_USBVIDPID,
SR_SET_ANDROID_SCANCOUNT = 0x1000,
SR_GET_ANDROID_STATE = 0x1001,
}; };
enum Scanner_Cmd_Defs enum Scanner_Cmd_Defs

View File

@ -167,7 +167,7 @@ void ImageMatQueue::setparam(const GScanCap& param)
if (scanParam.fillhole.is_fillhole && scanParam.resolution_dst < 500) { if (scanParam.fillhole.is_fillhole && scanParam.resolution_dst < 500) {
float ratio = scanParam.fillhole.fillholeratio / 100.0; float ratio = scanParam.fillhole.fillholeratio / 100.0;
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyOutHole(200, ratio, 50))); m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyOutHole(25, ratio, 40)));
} //确保能够获取正反两面图 } //确保能够获取正反两面图

View File

@ -359,6 +359,7 @@ struct GScanCap_3399
uint32_t dogeardistabce; /**< 折角检测理论顶点到实际轮廓最新距离>*/ uint32_t dogeardistabce; /**< 折角检测理论顶点到实际轮廓最新距离>*/
bool fadeback; /**< 除底色>*/ bool fadeback; /**< 除底色>*/
int fadebackrange; /**< 除底色范围>*/ int fadebackrange; /**< 除底色范围>*/
bool isuploadexceptionimage; /**< 是否上传双张报错后的异常图像>*/
uint32_t reserve[1024]; /**< 预留4096字节做协议扩展*/ uint32_t reserve[1024]; /**< 预留4096字节做协议扩展*/
}; };

View File

@ -3,8 +3,8 @@
#include <tchar.h> #include <tchar.h>
#include <winioctl.h> #include <winioctl.h>
//#ifdef ANDROIDSERIAL #ifdef ANDROIDSERIAL
#if false
UsbScanEx::UsbScanEx(int index) UsbScanEx::UsbScanEx(int index)
{ {
@ -30,9 +30,9 @@ bool UsbScanEx::open()
//ut.TimeoutEvent = 1; //ut.TimeoutEvent = 1;
//ut.TimeoutRead = 1; //ut.TimeoutRead = 1;
//ut.TimeoutWrite = 1; //ut.TimeoutWrite = 1;
ut.TimeoutEvent = 0; ut.TimeoutEvent = 1;
ut.TimeoutRead = 0; ut.TimeoutRead = 2;
ut.TimeoutWrite = 0; ut.TimeoutWrite = 3;
_stprintf(szDevPath, TEXT("\\\\.\\Usbscan%d"), m_h_index); _stprintf(szDevPath, TEXT("\\\\.\\Usbscan%d"), m_h_index);
m_h_dev = CreateFile(szDevPath, m_h_dev = CreateFile(szDevPath,
@ -79,7 +79,6 @@ bool UsbScanEx::open()
CloseHandle(m_h_dev); CloseHandle(m_h_dev);
m_h_dev = INVALID_HANDLE_VALUE; m_h_dev = INVALID_HANDLE_VALUE;
} }
//FileTools::writelog(log_lv::log_INFO,"USB Open!");
return m_h_dev; return m_h_dev;
} }
@ -115,7 +114,6 @@ bool UsbScanEx::close()
} }
} }
m_b_is_connected = FALSE; m_b_is_connected = FALSE;
//FileTools::writelog(log_lv::log_INFO,"USB Close!");
return b_ret; return b_ret;
} }
@ -201,7 +199,7 @@ int UsbScanEx::control_msg(int rtype, int req, int value, int index, int len, vo
LPOVERLAPPED lp_overlap = ov + CTRL_IN_OUT; LPOVERLAPPED lp_overlap = ov + CTRL_IN_OUT;
b_ret = DeviceIoControl(m_h_dev, IOCTL_SEND_USB_REQUEST, &irp, sizeof(irp), data, len, &dw_ret, NULL); b_ret = DeviceIoControl(m_h_dev, IOCTL_SEND_USB_REQUEST, &irp, sizeof(irp), data, len, &dw_ret, NULL);
FileTools::writelog(log_ERROR, " USB control_msg ret = " + std::to_string(b_ret));
//if (!b_ret) //if (!b_ret)
// b_ret = WaitForSingleObject(lp_overlap->hEvent, timeout) == WAIT_OBJECT_0; // b_ret = WaitForSingleObject(lp_overlap->hEvent, timeout) == WAIT_OBJECT_0;
@ -234,7 +232,8 @@ int UsbScanEx::read_int(void* data, int len)
return dw_ret; return dw_ret;
} }
else { else {
switch (GetLastError()) int error_code = GetLastError();
switch (error_code)
{ {
case ERROR_FILE_NOT_FOUND: case ERROR_FILE_NOT_FOUND:
case ERROR_ACCESS_DENIED: case ERROR_ACCESS_DENIED:
@ -244,7 +243,7 @@ int UsbScanEx::read_int(void* data, int len)
} }
break; break;
default: default:
break; break;
} }
} }
@ -393,7 +392,6 @@ bool UsbScanEx::open()
CloseHandle(m_h_dev); CloseHandle(m_h_dev);
m_h_dev = INVALID_HANDLE_VALUE; m_h_dev = INVALID_HANDLE_VALUE;
} }
//FileTools::writelog(log_lv::log_INFO,"USB Open!");
return m_h_dev; return m_h_dev;
} }
@ -446,7 +444,6 @@ bool UsbScanEx::close()
} }
} }
m_b_is_connected = FALSE; m_b_is_connected = FALSE;
//FileTools::writelog(log_lv::log_INFO,"USB Close!");
return b_ret; return b_ret;
} }
@ -481,7 +478,7 @@ int UsbScanEx::read_bulk(void* data, int len)
#ifdef ANDROIDSERIAL #ifdef ANDROIDSERIAL
GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, TRUE); GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, TRUE);
#else #else
WaitForSingleObject(lp_overlap->hEvent, 500); WaitForSingleObject(lp_overlap->hEvent, 1000);
GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, FALSE); GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, FALSE);
#endif // ANDROIDSERIAL #endif // ANDROIDSERIAL
return pdw_ret; return pdw_ret;
@ -489,7 +486,6 @@ int UsbScanEx::read_bulk(void* data, int len)
case ERROR_FILE_NOT_FOUND: case ERROR_FILE_NOT_FOUND:
case ERROR_ACCESS_DENIED: case ERROR_ACCESS_DENIED:
m_b_is_connected = false; m_b_is_connected = false;
//FileTools::writelog(log_lv::log_WARN, "errorcode =" + std::to_string(error_code));
if (hotplug_call) { if (hotplug_call) {
hotplug_call(true, usrdata); hotplug_call(true, usrdata);
} }

View File

@ -60,7 +60,7 @@ public:
{ {
log4cplus::SharedAppenderPtr rf(new log4cplus::RollingFileAppender( log4cplus::SharedAppenderPtr rf(new log4cplus::RollingFileAppender(
path, path,
2048 * 1024, 1024 * 1024 * 10,
5 5
)); ));
rf->setName(LOG4CPLUS_TEXT("file")); rf->setName(LOG4CPLUS_TEXT("file"));

View File

@ -1,6 +1,10 @@
#include "ImageApplyOutHole.h" #include "ImageApplyOutHole.h"
#include "ImageProcess_Public.h" #include "ImageProcess_Public.h"
#ifdef LOG
#include "Device/filetools.h"
#endif // LOG
CImageApplyOutHole::CImageApplyOutHole(void) CImageApplyOutHole::CImageApplyOutHole(void)
: CImageApply() : CImageApply()
, m_borderSize(600) , m_borderSize(600)
@ -29,13 +33,23 @@ void CImageApplyOutHole::apply(cv::Mat& pDib, int side)
void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide) void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
{ {
#ifdef LOG
FileTools::write_log("imgprc.txt", "enter ImageOutHole apply");
#endif // LOG
if (mats.size() < 2) if (mats.size() < 2)
{ {
#ifdef LOG
FileTools::write_log("imgprc.txt", "exit ImageOutHole apply");
#endif // LOG
return; return;
} }
if (mats[0].empty() || mats[1].empty()) if (mats[0].empty() || mats[1].empty())
{ {
#ifdef LOG
FileTools::write_log("imgprc.txt", "exit ImageOutHole apply");
#endif // LOG
return; return;
} }
@ -63,6 +77,9 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
std::vector<cv::Point> maxContour_front = hg::getMaxContour(contours_front, b1_front); std::vector<cv::Point> maxContour_front = hg::getMaxContour(contours_front, b1_front);
std::vector<cv::Point> maxContour_back = hg::getMaxContour(contours_back, b1_back); std::vector<cv::Point> maxContour_back = hg::getMaxContour(contours_back, b1_back);
if (maxContour_front.empty() || maxContour_back.empty())
return;
cv::RotatedRect rrect_front = hg::getBoundingRect(maxContour_front); //提取正面最大轮廓的最小外接矩形 cv::RotatedRect rrect_front = hg::getBoundingRect(maxContour_front); //提取正面最大轮廓的最小外接矩形
cv::RotatedRect rrect_back = hg::getBoundingRect(maxContour_back); //提取反面最大轮廓的最小外接矩形 cv::RotatedRect rrect_back = hg::getBoundingRect(maxContour_back); //提取反面最大轮廓的最小外接矩形
@ -78,19 +95,25 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
cv::Mat roiMat_front(front_thre, roi_front); //在正面二值图像中截取重叠部分 cv::Mat roiMat_front(front_thre, roi_front); //在正面二值图像中截取重叠部分
cv::Mat roiMat_back(back_thre, roi_back); //在反面二值图像中截取重叠部分 cv::Mat roiMat_back(back_thre, roi_back); //在反面二值图像中截取重叠部分
//cv::imwrite("roiMat_front.jpg", roiMat_front);
//cv::imwrite("roiMat_back.jpg", roiMat_back);
//正反面二值图像做或运算真正镂空区域保留0其他地方填充为255 //正反面二值图像做或运算真正镂空区域保留0其他地方填充为255
cv::Mat mask; cv::Mat mask;
cv::bitwise_or(roiMat_front, roiMat_back, mask); //或运算,正反面二值图像重叠 cv::bitwise_or(roiMat_front, roiMat_back, mask); //或运算,正反面二值图像重叠
//cv::imwrite("mask1.jpg", mask);
//二值图像重叠图像颜色取反,膨胀,提取轮廓 //二值图像重叠图像颜色取反,膨胀,提取轮廓
cv::bitwise_not(mask, mask); //·´É« cv::bitwise_not(mask, mask);
//cv::imwrite("mask2.jpg", mask); //·´É«
element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(10, 10)); element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(10, 10));
cv::dilate(mask, mask, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar(255)); //膨胀算法,增大孔洞连通区域面积 cv::dilate(mask, mask, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar(255)); //膨胀算法,增大孔洞连通区域面积
//cv::imwrite("mask3.jpg", mask);
//为了避免孔洞彻底贯穿纸边,人为绘制纸张轮廓,确保所有孔洞为封闭图形,不会与背景粘连 //为了避免孔洞彻底贯穿纸边,人为绘制纸张轮廓,确保所有孔洞为封闭图形,不会与背景粘连
cv::polylines(mask, hg::getVertices(mask_rotatedRect), true, cv::Scalar(0), 15); //»æÖÆÖ½ÕžØÐαßÔµ cv::polylines(mask, hg::getVertices(mask_rotatedRect), true, cv::Scalar(255), 15); //»æÖÆÖ½ÕžØÐαßÔµ
//cv::imwrite("mask4.jpg", mask);
std::vector<std::vector<cv::Point>> contours_mask; std::vector<std::vector<cv::Point>> contours_mask;
std::vector<cv::Vec4i> b1_mask; std::vector<cv::Vec4i> b1_mask;
@ -215,7 +238,11 @@ std::vector<std::vector<cv::Point>> CImageApplyOutHole::filterPoly(std::vector<s
if (m[i][2] != -1) continue; if (m[i][2] != -1) continue;
cv::RotatedRect rrect = hg::getBoundingRect(contours[i]); cv::RotatedRect rrect = hg::getBoundingRect(contours[i]);
if (rrect.size.area() < areaThreshold) continue; if (rrect.size.width < areaThreshold ||
rrect.size.height < areaThreshold ||
rrect.size.width > areaThreshold * 6 ||
rrect.size.height > areaThreshold * 6)
continue;
bool enabled = true; bool enabled = true;
for (size_t j = 0, count = contours[i].size(); j < count; j++) for (size_t j = 0, count = contours[i].size(); j < count; j++)
@ -293,10 +320,10 @@ uchar CImageApplyOutHole::getBackGroudChannelMean(const cv::Mat& gray, int total
hist_array[i] = hist.at<float>(i, 0); hist_array[i] = hist.at<float>(i, 0);
int length = 1; int length = 1;
const int length_max = 255 - m_threshold; const int length_max = 255;
while (length < length_max) while (length < length_max)
{ {
for (size_t i = m_threshold + 1; i < 256 - length; i++) for (size_t i = 1; i < 256 - length; i++)
{ {
int count = 0; int count = 0;
uint pixSum = 0; uint pixSum = 0;

View File

@ -6,12 +6,17 @@
* 2020/11/21 * 2020/11/21
* 2020/05/12 v1.0 * 2020/05/12 v1.0
* 2020/11/17 v1.1 * 2020/11/17 v1.1
* 2021/09/06 v1.2 50100 * 2021/09/06 v1.2 50100
* 2021/11/03 v1.3 10穿 * 2021/11/03 v1.3 10穿
* 2021/11/04 v1.4 5 * 2021/11/04 v1.4 5
* 2021/11/17 v1.5 opencv版本导致的BUG * 2021/11/17 v1.5 opencv版本导致的BUG
* 2022/04/18 v1.6 BUG * 2022/04/18 v1.6 BUG
* v1.6 * 2022/05/04 v1.6.1
* 2022/07/16 v1.6.2 BUG
* 2022/07/18 v1.6.3 mask的一些逻辑错误
* 2022/07/18 v1.7 BUGborderSize逻辑,穿[borderSize, borderSize * 6]
* 2022/07/22 v1.7.1 BUG
* v1.7.1
* ==================================================== * ====================================================
*/ */
@ -72,4 +77,5 @@ private:
double m_threshold; double m_threshold;
}; };
#endif // !IMAGE_APPLY_OUT_HOLE_H #endif // !IMAGE_APPLY_OUT_HOLE_H

View File

@ -18,6 +18,7 @@
#include "Device/GScanO400.h" #include "Device/GScanO400.h"
#include "Device/GScanO400Android.h" #include "Device/GScanO400Android.h"
#include "Device/GScanO1003399.h" #include "Device/GScanO1003399.h"
#include "Device/GScan439Android.h"
#include "Device/filetools.h" #include "Device/filetools.h"
#include "Device/GScanVirtual.h" #include "Device/GScanVirtual.h"
#include <list> #include <list>
@ -98,7 +99,7 @@ using namespace std::placeholders;
TWPP_ENTRY_MFC(HuagaoDs) TWPP_ENTRY_MFC(HuagaoDs)
static constexpr const Identity srcIdent( static constexpr const Identity srcIdent(
Version(3, 3, Language::English, Country::China, "v3.3.5.8"), Version(3, 3, Language::English, Country::China, "v3.3.5.9"),
DataGroup::Image, DataGroup::Image,
#ifdef MAKEHUAGAO #ifdef MAKEHUAGAO
"HUAGO", "HUAGO",
@ -202,8 +203,10 @@ static constexpr const Identity srcIdent(
#ifdef MAKEHUAGAO #ifdef MAKEHUAGAO
#ifdef UV #ifdef UV
"HUAGOSCAN G300UV TWAIN" "HUAGOSCAN G300UV TWAIN"
#elif defined ANDROIDSERIAL
"HUAGOSCAN G300 Android TWAIN"// ¼æÈݾɼ«¿Î pm changed "HUAGOSCAN G300 TWAIN"
#else #else
"HUAGOSCAN G300 TWAIN"// ¼æÈݾɼ«¿Î pm changed "HUAGOSCAN G300 TWAIN" "HUAGOSCAN G300 Linux TWAIN"
#endif #endif
#elif defined UV && defined MAKERIGHTWAY #elif defined UV && defined MAKERIGHTWAY
"RIGHTWAYSCAN G300 TWAIN" "RIGHTWAYSCAN G300 TWAIN"
@ -224,7 +227,11 @@ static constexpr const Identity srcIdent(
#endif #endif
#elif defined(G400) // G200 #elif defined(G400) // G200
#ifdef MAKEHUAGAO #ifdef MAKEHUAGAO
"HUAGOSCAN G400 TWAIN" #ifdef ANDROIDSERIAL
"HUAGOSCAN G400 Android TWAIN"
#else
"HUAGOSCAN G400 Linux TWAIN"
#endif // ANDROIDSERIES
#elif defined HANVON #elif defined HANVON
#ifdef ANDROIDSERIAL #ifdef ANDROIDSERIAL
"Hanvon HW-7000 TAWIN" "Hanvon HW-7000 TAWIN"
@ -333,6 +340,7 @@ static std::vector<Vid_pid> DeviceID{
#endif // ISG100 #endif // ISG100
#elif defined G300 #elif defined G300
{0x31c9,0x8420}, {0x31c9,0x8420},
{0x31c9,0x8429},
#elif defined G400 #elif defined G400
{0x31c9,0x8520}, {0x31c9,0x8520},
{0x31c9,0x8529}, {0x31c9,0x8529},
@ -396,10 +404,18 @@ static std::vector<Vid_pid> DeviceID{
#endif // ISG100 #endif // ISG100
#elif defined G300 #elif defined G300
{0x3072,0x0300}, {0x3072,0x0300},
{0x3072,0x0339}, #ifdef ANDROIDSERIAL
{0x3072,0x0302},
#else
{0x3072,0x0339},
#endif // ANDROIDSERIAL
#elif defined G400 #elif defined G400
{0x3072,0x0400}, {0x3072,0x0400},
{0x3072,0x0439}, #ifdef ANDROIDSERIAL
{0x3072,0x0402},
#else
{0x3072,0x0439},
#endif // ANDROIDSERIAL
#endif // ISG100 #endif // ISG100
}; };
@ -881,6 +897,7 @@ Result HuagaoDs::capabilitySet(const Identity& origin, Capability& data) {
Result HuagaoDs::eventProcess(const Identity&, Event& event) { Result HuagaoDs::eventProcess(const Identity&, Event& event) {
// Qt needs to process its events, otherwise the GUI will appear frozen // Qt needs to process its events, otherwise the GUI will appear frozen
// this is Windows-only method, Linux and macOS behave differently // this is Windows-only method, Linux and macOS behave differently
//FileTools::writelog(log_ERROR, "eventProcess " + to_string((int)event.message()));
if (guiTwain) { if (guiTwain) {
// // QApplication::processEvents(); - TODO: needs more investigation; results in freeze when attempting to scan using old DSM // // QApplication::processEvents(); - TODO: needs more investigation; results in freeze when attempting to scan using old DSM
// QApplication::sendPostedEvents(); // QApplication::sendPostedEvents();
@ -983,14 +1000,18 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
scanner.reset(new GScanO200()); scanner.reset(new GScanO200());
#else #else
if (pid == 0x339 || pid == 0x439 || pid == 0x7039 || pid == 0x8529) if (pid == 0x339 || pid == 0x439 || pid == 0x7039 || pid == 0x8529 || pid == 0x8429)
scanner.reset(new GScanO1003399()); scanner.reset(new GScanO1003399());
else else {
#ifdef ANDROIDSERIAL #ifdef ANDROIDSERIAL
scanner.reset(new GScanO400Android()); if (pid == 0x402 || pid == 0x302)
scanner.reset(new GScan439Android());
else
scanner.reset(new GScanO400Android());
#else #else
scanner.reset(new GScanO400()); scanner.reset(new GScanO400());
#endif #endif
}
#endif // G400 #endif // G400
break; break;
} }
@ -2816,7 +2837,7 @@ Twpp::Result HuagaoDs::showTwainUI(Twpp::UserInterface& ui, bool bUiOnly)
::GetWindowRect(static_cast<HWND>(ui.parent().raw()), &newRect); ::GetWindowRect(static_cast<HWND>(ui.parent().raw()), &newRect);
if (newRect.top <= 0 || newRect.left <= 0) if (newRect.top <= 0 || newRect.left <= 0)
newRect.top = newRect.left = 20; newRect.top = newRect.left = 20;
SetWindowPos(guiTwain->m_hWnd, HWND_TOPMOST, newRect.left + 20, newRect.top + 100, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOACTIVATE); SetWindowPos(guiTwain->m_hWnd, HWND_TOP, newRect.left + 20, newRect.top + 100, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOACTIVATE);
//SetWindowPos(guiTwain->m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE); //SetWindowPos(guiTwain->m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE);
guiTwain->ShowWindow(SW_SHOWNORMAL); guiTwain->ShowWindow(SW_SHOWNORMAL);
return success(); return success();

Binary file not shown.

Binary file not shown.