2023-04-08 00:56:20 +00:00
// DlgScanner.cpp: 实现文件
//
# include "pch.h"
# include "usb_tools.h"
# include "DlgScanner.h"
# include "afxdialogex.h"
# include <direct.h>
# include <file/file_util.h>
# define TIMER_ID_REFRESH_BULK 1001
2023-05-02 06:42:06 +00:00
# include <common/log_util.h>
# include <common/json/gb_json.h>
2023-04-08 00:56:20 +00:00
HMODULE g_my_inst ;
namespace sane
{
# define ALIGN_INTEGER(v) ALIGN_INT(v, sizeof(int))
static std : : vector < SANE_Option_Descriptor * > g_opts ;
SANE_Option_Descriptor g_opt0 ;
namespace local_utility
{
void * acquire_memory ( size_t bytes , const char * msg )
{
char * buf = new char [ bytes ] ;
memset ( buf , 0 , bytes ) ;
return buf ;
}
}
static void bzero ( void * buf , size_t len )
{
memset ( buf , 0 , len ) ;
}
SANE_Option_Descriptor * string_option_to_SANE_descriptor ( const char * name , const char * title , const char * desc
, const std : : vector < std : : string > & values )
{
int bytes = sizeof ( SANE_Option_Descriptor ) + sizeof ( char * ) ;
SANE_Option_Descriptor * sod = NULL ;
char * str = NULL , * * str_arr = NULL ;
bytes + = ALIGN_INTEGER ( strlen ( name ) + 1 ) ;
bytes + = ALIGN_INTEGER ( strlen ( title ) + 1 ) ;
bytes + = ALIGN_INTEGER ( strlen ( desc ) + 1 ) ;
bytes + = sizeof ( SANE_Option_Descriptor ) ;
bytes + = sizeof ( char * ) ;
for ( size_t i = 0 ; i < values . size ( ) ; + + i )
bytes + = ALIGN_INTEGER ( values [ i ] . length ( ) + 1 ) ;
bytes + = sizeof ( char * ) * ( values . size ( ) + 1 ) ;
sod = ( SANE_Option_Descriptor * ) local_utility : : acquire_memory ( bytes , " string_option_to_SANE_descriptor " ) ;
bzero ( sod , bytes ) ;
str = ( char * ) sod ;
str + = sizeof ( SANE_Option_Descriptor ) ;
sod - > name = str ;
strcpy ( str , name ) ;
str + = ALIGN_INTEGER ( strlen ( str ) + 1 ) ;
sod - > title = str ;
strcpy ( str , title ) ;
str + = ALIGN_INTEGER ( strlen ( str ) + 1 ) ;
sod - > desc = str ;
strcpy ( str , desc ) ;
str + = ALIGN_INTEGER ( strlen ( str ) + 1 ) ;
sod - > type = SANE_TYPE_STRING ;
sod - > unit = SANE_UNIT_NONE ;
sod - > size = values . size ( ) ;
sod - > cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT // 软件可设置选项
| SANE_CAP_AUTOMATIC ; // 硬件可设置默认<E9BB98> ?
if ( values . size ( ) )
{
sod - > constraint_type = SANE_CONSTRAINT_STRING_LIST ;
sod - > constraint . string_list = ( char * * ) str ;
str_arr = ( char * * ) str ;
str + = ( values . size ( ) + 1 ) * sizeof ( char * ) ;
for ( size_t i = 0 ; i < values . size ( ) ; + + i )
{
str_arr [ i ] = str ;
strcpy ( str , values [ i ] . c_str ( ) ) ;
str + = ALIGN_INTEGER ( values [ i ] . length ( ) + 1 ) ;
}
}
//VLOG_MINI_2(LOG_LEVEL_ALL, "Memory usage: %u/%u\n", str - (char*)sod, bytes);
return sod ;
}
SANE_Option_Descriptor * number_option_to_SANE_descriptor ( const char * name , const char * title , const char * desc
, bool double_val , double * lower , double * upper , double * step )
{
int bytes = sizeof ( SANE_Option_Descriptor ) + sizeof ( SANE_Range ) ;
SANE_Option_Descriptor * sod = NULL ;
char * str = NULL ;
bytes + = ALIGN_INTEGER ( strlen ( name ) + 1 ) ;
bytes + = ALIGN_INTEGER ( strlen ( title ) + 1 ) ;
bytes + = ALIGN_INTEGER ( strlen ( desc ) + 1 ) ;
bytes + = sizeof ( SANE_Option_Descriptor ) ;
bytes + = sizeof ( SANE_Range * ) + sizeof ( SANE_Range ) ;
sod = ( SANE_Option_Descriptor * ) local_utility : : acquire_memory ( bytes , " number_option_to_SANE_descriptor " ) ;
bzero ( sod , bytes ) ;
str = ( char * ) sod ;
str + = sizeof ( SANE_Option_Descriptor ) ;
sod - > name = str ;
strcpy ( str , name ) ;
str + = ALIGN_INTEGER ( strlen ( str ) + 1 ) ;
sod - > title = str ;
strcpy ( str , title ) ;
str + = ALIGN_INTEGER ( strlen ( str ) + 1 ) ;
sod - > desc = str ;
strcpy ( str , desc ) ;
str + = ALIGN_INTEGER ( strlen ( str ) + 1 ) ;
sod - > type = double_val ? SANE_TYPE_FIXED : SANE_TYPE_INT ;
sod - > unit = SANE_UNIT_NONE ;
sod - > size = sizeof ( SANE_Word ) ;
sod - > cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT
| SANE_CAP_AUTOMATIC ;
if ( lower | | upper )
{
sod - > size = sizeof ( SANE_Range ) ;
sod - > constraint_type = SANE_CONSTRAINT_RANGE ;
sod - > constraint . range = ( SANE_Range * ) str ;
if ( lower )
{
if ( double_val )
( * ( SANE_Range * ) str ) . min = SANE_FIX ( * lower ) ;
else
( * ( SANE_Range * ) str ) . min = ( SANE_Word ) * lower ;
}
if ( upper )
{
if ( double_val )
( * ( SANE_Range * ) str ) . max = SANE_FIX ( * upper ) ;
else
( * ( SANE_Range * ) str ) . max = ( SANE_Word ) * upper ;
}
( * ( SANE_Range * ) str ) . quant = 0 ;
if ( step )
{
if ( double_val )
( * ( SANE_Range * ) str ) . quant = SANE_FIX ( * step ) ;
else
( * ( SANE_Range * ) str ) . quant = ( SANE_Word ) ( * step ) ;
}
str = ( char * ) ( ( SANE_Range * ) str + 1 ) ;
}
//VLOG_MINI_2(LOG_LEVEL_ALL, "Memory usage: %u/%u\n", str - (char*)sod, bytes);
return sod ;
}
SANE_Option_Descriptor * number_option_to_SANE_descriptor ( const char * name , const char * title , const char * desc
, const std : : vector < int > & values )
{
int bytes = sizeof ( SANE_Option_Descriptor ) + sizeof ( SANE_Range ) ;
SANE_Option_Descriptor * sod = NULL ;
char * str = NULL ;
bytes + = ALIGN_INTEGER ( strlen ( name ) + 1 ) ;
bytes + = ALIGN_INTEGER ( strlen ( title ) + 1 ) ;
bytes + = ALIGN_INTEGER ( strlen ( desc ) + 1 ) ;
bytes + = sizeof ( SANE_Option_Descriptor ) ;
bytes + = sizeof ( SANE_Word * ) + sizeof ( SANE_Word ) * ( values . size ( ) + 1 ) ;
sod = ( SANE_Option_Descriptor * ) local_utility : : acquire_memory ( bytes , " number_option_to_SANE_descriptor " ) ;
bzero ( sod , bytes ) ;
str = ( char * ) sod ;
str + = sizeof ( SANE_Option_Descriptor ) ;
sod - > name = str ;
strcpy ( str , name ) ;
str + = ALIGN_INTEGER ( strlen ( str ) + 1 ) ;
sod - > title = str ;
strcpy ( str , title ) ;
str + = ALIGN_INTEGER ( strlen ( str ) + 1 ) ;
sod - > desc = str ;
strcpy ( str , desc ) ;
str + = ALIGN_INTEGER ( strlen ( str ) + 1 ) ;
sod - > type = SANE_TYPE_INT ;
sod - > unit = SANE_UNIT_NONE ;
sod - > size = sizeof ( SANE_Word ) ;
sod - > cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT // 软件可设置选项
| SANE_CAP_AUTOMATIC ; // 硬件可设置默认<E9BB98> ?
if ( values . size ( ) )
{
SANE_Word * val = ( SANE_Word * ) str ;
sod - > constraint . word_list = val ;
sod - > constraint_type = SANE_CONSTRAINT_WORD_LIST ;
* val + + = values . size ( ) ;
for ( size_t i = 0 ; i < values . size ( ) ; + + i )
val [ i ] = values [ i ] ;
str = ( char * ) ( val + values . size ( ) ) ;
}
//VLOG_MINI_2(LOG_LEVEL_ALL, "Memory usage: %u/%u\n", str - (char*)sod, bytes);
return sod ;
}
SANE_Option_Descriptor * number_option_to_SANE_descriptor ( const char * name , const char * title , const char * desc
, const std : : vector < double > & values )
{
int bytes = sizeof ( SANE_Option_Descriptor ) + sizeof ( SANE_Range ) ;
SANE_Option_Descriptor * sod = NULL ;
char * str = NULL ;
bytes + = ALIGN_INTEGER ( strlen ( name ) + 1 ) ;
bytes + = ALIGN_INTEGER ( strlen ( title ) + 1 ) ;
bytes + = ALIGN_INTEGER ( strlen ( desc ) + 1 ) ;
bytes + = sizeof ( SANE_Option_Descriptor ) ;
bytes + = sizeof ( SANE_Word * ) + sizeof ( SANE_Word ) * ( values . size ( ) + 1 ) ;
sod = ( SANE_Option_Descriptor * ) local_utility : : acquire_memory ( bytes , " number_option_to_SANE_descriptor " ) ;
bzero ( sod , bytes ) ;
str = ( char * ) sod ;
str + = sizeof ( SANE_Option_Descriptor ) ;
sod - > name = str ;
strcpy ( str , name ) ;
str + = ALIGN_INTEGER ( strlen ( str ) + 1 ) ;
sod - > title = str ;
strcpy ( str , title ) ;
str + = ALIGN_INTEGER ( strlen ( str ) + 1 ) ;
sod - > desc = str ;
strcpy ( str , desc ) ;
str + = ALIGN_INTEGER ( strlen ( str ) + 1 ) ;
sod - > type = SANE_TYPE_FIXED ;
sod - > unit = SANE_UNIT_NONE ;
sod - > size = sizeof ( SANE_Word ) ;
sod - > cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT // 软件可设置选项
| SANE_CAP_AUTOMATIC ; // 硬件可设置默认<E9BB98> ?
if ( values . size ( ) )
{
SANE_Word * val = ( SANE_Word * ) str ;
sod - > constraint . word_list = val ;
sod - > constraint_type = SANE_CONSTRAINT_WORD_LIST ;
* val + + = values . size ( ) ;
for ( size_t i = 0 ; i < values . size ( ) ; + + i )
val [ i ] = SANE_FIX ( values [ i ] ) ;
str = ( char * ) ( val + values . size ( ) ) ;
}
//VLOG_MINI_2(LOG_LEVEL_ALL, "Memory usage: %u/%u\n", str - (char*)sod, bytes);
return sod ;
}
2023-05-02 01:50:55 +00:00
SANE_Option_Descriptor * trans_json_to_opt_desc ( gb_json * jsn )
2023-04-08 00:56:20 +00:00
{
std : : string title ( " " ) ,
desc ( " " ) ,
name ( " " ) ,
val ( " " ) ;
std : : vector < std : : string > constraints ;
double lower = .0f , upper = .0f , step = .0f ;
bool db_val = false ;
SANE_Option_Descriptor * ret = NULL ;
jsn - > get_value ( " title " , title ) ;
jsn - > get_value ( " desc " , desc ) ;
name = jsn - > key ( ) ;
if ( ! jsn - > get_value ( " type " , val ) )
return NULL ;
if ( val = = " string " )
{
2023-05-02 01:50:55 +00:00
gb_json * range = NULL , * child = NULL ;
2023-04-08 00:56:20 +00:00
jsn - > get_value ( " range " , range ) ;
if ( range )
{
child = range - > first_child ( ) ;
while ( child )
{
if ( child - > value ( val ) )
constraints . push_back ( val ) ;
child - > release ( ) ;
child = range - > next_child ( ) ;
}
range - > release ( ) ;
}
ret = string_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
, constraints ) ;
}
else if ( val = = " int " | | val = = " float " )
{
2023-05-02 01:50:55 +00:00
gb_json * range = NULL ;
2023-04-08 00:56:20 +00:00
jsn - > get_value ( " range " , range ) ;
if ( range )
{
if ( val = = " int " )
{
int l = 0 ;
if ( range - > get_value ( " min " , l ) )
{
int u = 0 , s = 1 ;
range - > get_value ( " max " , u ) ;
range - > get_value ( " step " , s ) ;
lower = l ;
upper = u ;
step = s ;
ret = number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
, false , & lower , & upper , & step ) ;
}
else
{
std : : vector < int > constraints ;
2023-05-02 01:50:55 +00:00
gb_json * child = range - > first_child ( ) ;
2023-04-08 00:56:20 +00:00
while ( child )
{
int val = 0 ;
if ( child - > value ( val ) )
constraints . push_back ( val ) ;
child - > release ( ) ;
child = range - > next_child ( ) ;
}
ret = number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
, constraints ) ;
}
}
else
{
if ( range - > get_value ( " min " , lower ) )
{
range - > get_value ( " max " , upper ) ;
step = ( upper - lower ) / 10.0f ;
range - > get_value ( " step " , step ) ;
ret = number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
, true , & lower , & upper , & step ) ;
}
else
{
std : : vector < double > constraints ;
2023-05-02 01:50:55 +00:00
gb_json * child = range - > first_child ( ) ;
2023-04-08 00:56:20 +00:00
while ( child )
{
double val = .0f ;
if ( child - > value ( val ) )
constraints . push_back ( val ) ;
child - > release ( ) ;
child = range - > next_child ( ) ;
}
ret = number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
, constraints ) ;
}
}
range - > release ( ) ;
}
else
{
ret = number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
, false , NULL , NULL , NULL ) ;
}
}
else if ( val = = " bool " )
{
ret = number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
, false , NULL , NULL , NULL ) ;
ret - > type = SANE_TYPE_BOOL ;
}
else if ( val = = " button " )
{
ret = number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
, false , NULL , NULL , NULL ) ;
ret - > type = SANE_TYPE_BUTTON ;
}
else if ( val = = " group " )
{
ret = number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
, false , NULL , NULL , NULL ) ;
ret - > type = SANE_TYPE_GROUP ;
}
// fill the 'size' field, for SANE_ACTION_GET action ...
if ( ret )
{
int bytes = 0 ;
bool bv = false ;
jsn - > get_value ( " size " , bytes ) ;
ret - > size = bytes ;
if ( jsn - > get_value ( " readonly " , bv ) & & bv )
SET_CAP_READONLY ( ret - > cap )
else if ( jsn - > get_value ( " hwonly " , bv ) & & bv )
SET_CAP_DEVICE_SETTABLE ( ret - > cap , true )
2023-05-06 06:21:08 +00:00
val = " " ;
jsn - > get_value ( " group " , val ) ;
if ( val = = " advance " )
2023-04-08 00:56:20 +00:00
{
ret - > cap | = SANE_CAP_ADVANCED ;
}
2023-05-06 06:21:08 +00:00
val = " " ;
if ( jsn - > get_value ( " unit " , val ) )
2023-04-08 00:56:20 +00:00
{
2023-05-06 06:21:08 +00:00
if ( val = = " DPI " )
ret - > unit = SANE_UNIT_DPI ;
else if ( val = = " pixel " )
ret - > unit = SANE_UNIT_PIXEL ;
else if ( val = = " mm " )
ret - > unit = SANE_UNIT_MM ;
else if ( val = = " bit " )
ret - > unit = SANE_UNIT_BIT ;
else if ( val = = " microsec " )
ret - > unit = SANE_UNIT_MICROSECOND ;
else if ( val = = " % " )
ret - > unit = SANE_UNIT_PERCENT ;
else
ret - > unit = SANE_UNIT_NONE ;
2023-04-08 00:56:20 +00:00
}
2023-05-02 01:50:55 +00:00
bool enabled = true ;
if ( jsn - > get_value ( " enabled " , enabled ) & & ! enabled )
ret - > cap | = SANE_CAP_INACTIVE ;
2023-04-08 00:56:20 +00:00
// 关联<E585B3> ?
2023-05-02 01:50:55 +00:00
gb_json * depend = NULL ;
2023-04-08 00:56:20 +00:00
}
return ret ;
}
void reset_opts ( const char * json_txt )
{
for ( auto & v : g_opts )
delete [ ] v ;
g_opts . clear ( ) ;
g_opt0 . cap = CAPABILITY_READONLY ;
g_opt0 . name = " option-count " ;
g_opt0 . title = " " ;
g_opt0 . desc = " Number of options " ;
g_opt0 . type = SANE_TYPE_INT ;
g_opt0 . size = sizeof ( SANE_TYPE_INT ) ;
if ( json_txt )
{
2023-05-02 01:50:55 +00:00
gb_json * jsn = new gb_json ( ) , * child = NULL ;
2023-04-08 00:56:20 +00:00
if ( jsn - > attach_text ( ( char * ) json_txt ) )
{
child = jsn - > first_child ( ) ;
if ( child )
{
child - > release ( ) ;
while ( ( child = jsn - > next_child ( ) ) )
{
SANE_Option_Descriptor * desc = trans_json_to_opt_desc ( child ) ;
if ( desc )
g_opts . push_back ( desc ) ;
child - > release ( ) ;
}
}
}
jsn - > release ( ) ;
}
}
SANE_Status sane_get_devices_api ( const SANE_Device * * * device_list , SANE_Bool local_only )
{
return SANE_STATUS_INVAL ;
}
SANE_Status sane_open_api ( SANE_String_Const devicename , SANE_Handle * handle )
{
return SANE_STATUS_INVAL ;
}
void sane_close_api ( SANE_Handle handle )
{ }
const SANE_Option_Descriptor * sane_get_option_descriptor_api ( SANE_Handle handle , SANE_Int option )
{
if ( option = = 0 )
return & g_opt0 ;
else if ( option < = g_opts . size ( ) )
return g_opts [ option - 1 ] ;
else
return NULL ;
}
SANE_Status sane_control_option_api ( SANE_Handle handle , SANE_Int option , SANE_Action action , void * value , SANE_Int * info )
{
CDlgScanner * dlg = ( CDlgScanner * ) handle ;
if ( action = = SANE_ACTION_GET_VALUE & & option > 0 & & option < = g_opts . size ( ) )
{
2023-05-02 01:50:55 +00:00
if ( g_opts [ option - 1 ] - > type = = SANE_TYPE_FIXED )
{
double val = .0f ;
dlg - > get_option ( g_opts [ option - 1 ] - > name , & val , sizeof ( val ) ) ;
* ( SANE_Fixed * ) value = SANE_FIX ( val ) ;
}
else
{
dlg - > get_option ( g_opts [ option - 1 ] - > name , value , g_opts [ option - 1 ] - > size ) ;
}
2023-04-08 00:56:20 +00:00
return SANE_STATUS_GOOD ;
}
2023-04-12 09:57:04 +00:00
else if ( action = = SANE_ACTION_SET_VALUE & & option > 0 & & option < = g_opts . size ( ) )
{
size_t val_size = 0 ;
double val = .0f ;
void * buf = value ;
if ( g_opts [ option - 1 ] - > type = = SANE_TYPE_BOOL )
val_size = sizeof ( bool ) ;
else if ( g_opts [ option - 1 ] - > type = = SANE_TYPE_INT )
val_size = sizeof ( int ) ;
else if ( g_opts [ option - 1 ] - > type = = SANE_TYPE_FIXED )
{
val_size = sizeof ( val ) ;
val = SANE_UNFIX ( * ( SANE_Int * ) value ) ;
buf = & val ;
}
else
val_size = strlen ( ( char * ) value ) ;
2023-05-02 01:50:55 +00:00
SANE_Int after = 0 ;
2023-05-06 06:21:08 +00:00
SANE_Status ret = ( SANE_Status ) dlg - > set_option ( g_opts [ option - 1 ] - > name , buf , g_opts [ option - 1 ] - > type , val_size , g_opts [ option - 1 ] - > size , ( int * ) & after ) ;
2023-05-02 01:50:55 +00:00
if ( info )
* info = after ;
2023-04-12 09:57:04 +00:00
if ( buf = = & val )
{
* ( SANE_Int * ) value = SANE_FIX ( val ) ;
}
2023-05-02 01:50:55 +00:00
if ( after & SANE_INFO_RELOAD_OPTIONS )
{
std : : string str ( " " ) ;
if ( dlg - > get_all_option ( str ) = = 0 )
{
reset_opts ( str . c_str ( ) ) ;
}
}
2023-04-12 09:57:04 +00:00
return ret ;
}
2023-04-08 00:56:20 +00:00
return SANE_STATUS_INVAL ;
}
SANE_Status sane_get_parameters_api ( SANE_Handle handle , SANE_Parameters * params )
{
return SANE_STATUS_INVAL ;
}
SANE_Status sane_start_api ( SANE_Handle handle )
{
return SANE_STATUS_INVAL ;
}
SANE_Status sane_read_api ( SANE_Handle handle , SANE_Byte * data , SANE_Int max_length , SANE_Int * length )
{
return SANE_STATUS_INVAL ;
}
void sane_cancel_api ( SANE_Handle handle )
{ }
SANE_Status sane_set_io_mode_api ( SANE_Handle handle , SANE_Bool non_blocking )
{
return SANE_STATUS_INVAL ;
}
SANE_Status sane_get_select_fd_api ( SANE_Handle handle , SANE_Int * fd )
{
return SANE_STATUS_INVAL ;
}
SANE_String_Const sane_strstatus_api ( SANE_Status status )
{
return " " ;
}
SANE_Status sane_io_control_api ( SANE_Handle h , unsigned long code , void * data , unsigned * len )
{
return SANE_STATUS_INVAL ;
}
SANE_Status sane_init_api ( SANE_Int * version_code , SANE_Auth_Callback authorize )
{
return SANE_STATUS_INVAL ;
}
void sane_exit_api ( void )
{ }
} ;
2023-04-12 09:57:04 +00:00
# define RETURN_EQUAL(v, e) \
if ( v = = e ) \
return L # # # e ;
2023-04-08 00:56:20 +00:00
template < typename . . . Args >
static int msg_box ( HWND owner , UINT type , const wchar_t * title , const wchar_t * fmt , Args . . . args )
{
size_t size = _snwprintf ( nullptr , 0 , fmt , args . . . ) + 1 ;
std : : unique_ptr < wchar_t [ ] > buf ( new wchar_t [ size ] ) ;
_snwprintf ( buf . get ( ) , size , fmt , args . . . ) ;
return : : MessageBoxW ( owner , buf . get ( ) , title , type ) ;
}
const wchar_t * peer_bulk_status ( int s , wchar_t unk [ 20 ] )
{
RETURN_EQUAL ( s , BULK_STATUS_NOT_START ) ;
RETURN_EQUAL ( s , BULK_STATUS_IDLE ) ;
RETURN_EQUAL ( s , BULK_STATUS_IO ) ;
RETURN_EQUAL ( s , BULK_STATUS_ERROR ) ;
RETURN_EQUAL ( s , BULK_STATUS_RESET ) ;
swprintf_s ( unk , 18 , L " %x " , s ) ;
return unk ;
}
2023-04-12 09:57:04 +00:00
const wchar_t * scanner_status ( int s , wchar_t unk [ 20 ] )
{
RETURN_EQUAL ( s , SCANNER_STATUS_READY ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_NOT_OPEN ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_LOST_CONNECT ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_RESET_BULK ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_START_SCANNING ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_SCANNING ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_SCAN_FINISHED ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_BUSY ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_COVER_OPENNED ) ;
2023-04-15 06:17:48 +00:00
RETURN_EQUAL ( s , SCANNER_STATUS_COVER_CLOSED ) ;
2023-04-12 09:57:04 +00:00
RETURN_EQUAL ( s , SCANNER_STATUS_SLEEPING ) ;
2023-04-15 06:17:48 +00:00
RETURN_EQUAL ( s , SCANNER_STATUS_WAKED_UP ) ;
2023-04-12 09:57:04 +00:00
RETURN_EQUAL ( s , SCANNER_STATUS_COUNT_MODE ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_DOUBLE_FEEDED ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_PAPER_JAMMED ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_PAPER_ASKEW ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_FEED_FAILED ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_NO_PAPER ) ;
2023-04-15 06:17:48 +00:00
RETURN_EQUAL ( s , SCANNER_STATUS_PAPER_ON ) ;
2023-04-12 09:57:04 +00:00
RETURN_EQUAL ( s , SCANNER_STATUS_STAPLE_ON ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_SIZE_ERR ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_DOGEAR ) ;
RETURN_EQUAL ( s , SCANNER_STATUS_CFG_CHANGED ) ;
swprintf_s ( unk , 18 , L " 0x%x " , s ) ;
2023-04-08 00:56:20 +00:00
2023-04-12 09:57:04 +00:00
return unk ;
}
2023-05-11 09:19:00 +00:00
static DWORD thread_open_id_ = 0 ;
static safe_fifo < std : : string > images_ ;
static DWORD WINAPI thread_open_image ( void * lp )
{
while ( 1 )
{
std : : string file ( " " ) ;
if ( images_ . take ( file , true ) )
{
if ( file . empty ( ) )
break ;
ShellExecuteA ( NULL , " Open " , file . c_str ( ) , NULL , NULL , SW_SHOWNORMAL ) ;
}
}
return 0 ;
MSG msg = { 0 } ;
BOOL ret = TRUE ;
while ( ( ret = GetMessage ( & msg , NULL , 0 , 0 ) ) )
{
if ( ( DWORD ) ret = = - 1 )
break ;
if ( msg . message = = WM_USER + 1001 )
break ;
if ( msg . message = = WM_USER + 1 )
{
std : : string * file = ( std : : string * ) msg . lParam ;
ShellExecuteA ( NULL , " Open " , file - > c_str ( ) , NULL , NULL , SW_SHOWNORMAL ) ;
delete file ;
}
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
}
return 0 ;
}
2023-04-08 00:56:20 +00:00
// CDlgScanner 对话框
IMPLEMENT_DYNAMIC ( CDlgScanner , CDialogEx )
CDlgScanner : : CDlgScanner ( CWnd * pParent /*=nullptr*/ )
: CDialogEx ( IDD_SCANNER , pParent )
, scanner_ ( NULL ) , auto_tx_file_ ( - 1 ) , auto_tx_ ( false )
2023-05-06 06:21:08 +00:00
, setting_ui_ ( NULL ) , img_cnt_ ( 0 ) , paper_cnt_ ( 0 ) , max_sent_ ( 0 ) , max_cmd_ ( 0 )
2023-04-08 00:56:20 +00:00
{
g_my_inst = GetModuleHandle ( NULL ) ;
threads_ = new thread_pool < CDlgScanner > ( this ) ;
parent_ = pParent ? pParent - > m_hWnd : NULL ;
auto_wait_ = CreateEvent ( NULL , TRUE , FALSE , NULL ) ;
2023-05-11 09:19:00 +00:00
HANDLE h = CreateThread ( NULL , 0 , thread_open_image , NULL , 0 , & thread_open_id_ ) ;
CloseHandle ( h ) ;
2023-04-08 00:56:20 +00:00
2023-05-11 09:19:00 +00:00
std : : string tj ( " { \" resolution \" :{ \" cat \" : \" imgp \" , \" group \" : \" base \" , \" title \" : \" \\ u5206 \\ u8fa8 \\ u7387 \" , \" desc \" : \" \\ u8bbe \\ u7f6e \\ u626b \\ u63cf \\ u56fe \\ u50cf \\ u7684 \\ u5206 \\ u8fa8 \\ u7387 \" , \" ver \" :1, \" pos \" :200, \" type \" : \" int \" , \" unit \" : \" dpi \" , \" affect \" :6, \" readonly \" :false, \" visible \" :true, \" enabled \" :true, \" size \" :4, \" cur \" :400, \" default \" :200, \" range \" :{ \" min \" :100, \" max \" :600, \" step \" :50}}} " ) ;
gb_json * jsn = new gb_json ( ) ;
if ( jsn - > attach_text ( & tj [ 0 ] ) )
{
gb_json * child = jsn - > first_child ( ) ;
if ( child )
{
bool bv = false , r = false ;
int nv = 0 ;
double dv = .0f ;
std : : string sv ( " " ) ;
r = child - > get_value ( " cur " , bv ) ;
r = child - > get_value ( " cur " , nv ) ;
r = child - > get_value ( " cur " , dv ) ;
r = child - > get_value ( " cur " , sv ) ;
child - > release ( ) ;
}
}
jsn - > release ( ) ;
2023-04-08 00:56:20 +00:00
}
CDlgScanner : : ~ CDlgScanner ( )
{
2023-05-11 09:19:00 +00:00
: : PostThreadMessage ( thread_open_id_ , WM_USER + 1001 , 0 , 0 ) ;
images_ . save ( " " , true ) ;
2023-04-08 00:56:20 +00:00
if ( scanner_ )
{
scanner_ - > close ( ) ;
scanner_ - > release ( ) ;
}
}
void CDlgScanner : : DoDataExchange ( CDataExchange * pDX )
{
CDialogEx : : DoDataExchange ( pDX ) ;
2023-09-14 08:05:44 +00:00
// DDX_Control(pDX, IDC_TAB_OPT, tab_opt_);
2023-04-08 00:56:20 +00:00
DDX_Control ( pDX , IDC_TAB_OPER , tab_oper_ ) ;
2023-09-14 08:05:44 +00:00
DDX_Control ( pDX , IDC_COMBO_BUF_SIZE , buf_ ) ;
2023-04-08 00:56:20 +00:00
}
2023-05-11 09:19:00 +00:00
typedef struct _prog_data
{
CDlgScanner * obj ;
std : : string file ;
} PROGD , * LPPROGD ;
2023-04-08 00:56:20 +00:00
void CDlgScanner : : set_device ( usb : : LPUSBPNP pnp )
{
if ( ! pnp )
{
auto_tx_ = false ;
SetEvent ( auto_wait_ ) ;
}
( ( CButton * ) GetDlgItem ( IDC_CHECK_REPEAT ) ) - > SetCheck ( BST_UNCHECKED ) ;
KillTimer ( TIMER_ID_REFRESH_BULK ) ;
( ( CButton * ) GetDlgItem ( IDC_CHECK_AUTO ) ) - > SetCheck ( BST_UNCHECKED ) ;
enable_buttons ( pnp ! = NULL ) ;
if ( scanner_ )
{
scanner_ - > close ( ) ;
scanner_ - > release ( ) ;
scanner_ = NULL ;
}
if ( setting_ui_ )
{
delete setting_ui_ ;
setting_ui_ = NULL ;
}
2023-04-12 09:57:04 +00:00
auto progresser = [ & ] ( uint64_t total , uint64_t cur , uint32_t err , void * user_data ) - > int
2023-04-08 02:49:19 +00:00
{
2023-05-11 09:19:00 +00:00
LPPROGD param = ( LPPROGD ) user_data ;
CDlgScanner * dlg = param - > obj ;
2023-04-12 09:57:04 +00:00
2023-04-15 06:17:48 +00:00
if ( cur > = total )
log_cls : : log ( LOG_LEVEL_DEBUG , " Finished in receiving new image = %d \r \n " , err ) ;
2023-04-13 06:42:43 +00:00
2023-04-08 02:49:19 +00:00
if ( err )
2023-04-12 09:57:04 +00:00
//::SetDlgItemTextW(m_hWnd, IDC_EDIT_COUNT, (L"Receive image " + std::to_wstring(img_cnt_) + L" error: " + std::to_wstring(err)).c_str());
2023-04-23 03:50:17 +00:00
dlg - > set_text ( IDC_EDIT_COUNT , ( L " Receive image " + ( std : : to_wstring ( dlg - > img_cnt_ ) + L " / " + std : : to_wstring ( dlg - > paper_cnt_ ) ) + L " error: " + std : : to_wstring ( err ) ) . c_str ( ) ) ;
2023-04-08 02:49:19 +00:00
else if ( cur > = total )
2023-04-12 09:57:04 +00:00
{
2023-04-23 03:50:17 +00:00
dlg - > set_text ( IDC_EDIT_COUNT , ( std : : to_wstring ( dlg - > img_cnt_ ) + L " / " + std : : to_wstring ( dlg - > paper_cnt_ ) ) . c_str ( ) ) ;
2023-04-12 09:57:04 +00:00
if ( dlg - > is_checked ( IDC_CHECK_AUTO_OPEN_IMG ) )
2023-05-11 09:19:00 +00:00
{
images_ . save ( param - > file , true ) ;
//std::string* file(new std::string(param->file));
//if (!PostThreadMessage(thread_open_id_, WM_USER + 1, NULL, (LPARAM)file))
//{
// delete file;
// ShellExecuteA(dlg->m_hWnd, "Open", param->file.c_str(), NULL, NULL, SW_SHOWNORMAL);
//}
}
delete param ;
2023-04-12 09:57:04 +00:00
}
2023-04-08 02:49:19 +00:00
return 0 ;
} ;
auto img_keeper = [ & ] ( LPPACKIMAGE img , uint64_t size ) - > data_holder_ptr
{
2023-04-23 03:50:17 +00:00
if ( img = = IMG_RECEIVER_FINISHED )
{
// scan stopped ...
wchar_t buf [ 40 ] = { 0 } ;
HWND wnd = GetDlgItem ( IDC_EDIT_COUNT ) - > m_hWnd ;
HDC dc = : : GetDC ( wnd ) ;
set_text ( IDC_BUTTON_SCAN , L " Scan " ) ;
: : SetTextColor ( dc , size ? RGB ( 255 , 0 , 0 ) : RGB ( 0 , 0 , 0 ) ) ;
: : ReleaseDC ( wnd , dc ) ;
log_cls : : log ( LOG_LEVEL_DEBUG , " Scan stopped with error %s \r \n " , usb : : u2a ( scanner_status ( size , buf ) ) . c_str ( ) ) ;
set_text ( IDC_EDIT_COUNT , ( std : : to_wstring ( img_cnt_ ) + L " / " + std : : to_wstring ( paper_cnt_ ) ) . c_str ( ) ) ;
if ( size = = 0 )
size = SCANNER_STATUS_READY ;
: : PostMessage ( m_hWnd , WM_DEVICE_STATTUS , 0 , ( LPARAM ) size ) ;
return NULL ;
}
else if ( img = = IMG_RECEIVER_PAPER_CNT )
{
set_text ( IDC_EDIT_COUNT , ( std : : to_wstring ( img_cnt_ ) + L " / " + std : : to_wstring ( + + paper_cnt_ ) ) . c_str ( ) ) ;
return NULL ;
}
else
2023-04-08 02:49:19 +00:00
{
file_saver * saver = new file_saver ( ) ;
std : : string root ( usb : : u2a ( img_root_ . c_str ( ) ) ) ;
char name [ 40 ] = { 0 } ;
2023-04-13 06:42:43 +00:00
int err = 0 ;
2023-05-02 01:50:55 +00:00
std : : string ext ( " jpg " ) ;
if ( img - > format = = IMG_FMT_BMP )
ext = " bmp " ;
else if ( img - > format = = IMG_FMT_GIF )
ext = " gif " ;
else if ( img - > format = = IMG_FMT_PNG )
ext = " png " ;
else if ( img - > format = = IMG_FMT_TIFF )
ext = " tiff " ;
2023-05-11 09:19:00 +00:00
if ( paper_cnt_ < img - > pos . paper_ind )
paper_cnt_ = img - > pos . paper_ind ;
+ + img_cnt_ ;
sprintf_s ( name , _countof ( name ) - 1 , " scan_%04d " , ( int ) img - > pos . paper_ind ) ;
root + = name ;
if ( img - > pos . paper_side = = PAPER_SIDE_FRONT )
root + = " F " ;
else if ( img - > pos . paper_side = = PAPER_SIDE_BACK )
root + = " B " ;
else
root + = " C " ;
sprintf_s ( name , _countof ( name ) - 1 , " _%d.%s " , ( int ) img - > pos . split_ind , ext . c_str ( ) ) ;
root + = name ;
err = saver - > open ( root . c_str ( ) , size ) ;
log_cls : : log ( LOG_LEVEL_DEBUG , " Begin receiving new image (%s + %llu) = %d \r \n " , root . c_str ( ) , size , err ) ;
2023-04-13 06:42:43 +00:00
if ( err )
2023-04-08 02:49:19 +00:00
{
saver - > release ( ) ;
saver = NULL ;
}
else
2023-04-12 09:57:04 +00:00
{
2023-05-11 09:19:00 +00:00
LPPROGD param = new PROGD ;
param - > file = root ;
param - > obj = this ;
saver - > set_progress_notify ( progresser , param ) ;
2023-04-12 09:57:04 +00:00
}
2023-04-08 02:49:19 +00:00
return dynamic_cast < data_holder_ptr > ( saver ) ;
}
} ;
2023-04-15 06:17:48 +00:00
auto status_cb = [ & ] ( uint32_t status ) - > void
{
: : PostMessage ( m_hWnd , WM_DEVICE_STATTUS , 0 , ( LPARAM ) status ) ;
} ;
2023-04-08 02:49:19 +00:00
2023-05-06 06:21:08 +00:00
max_cmd_ = max_sent_ = 0 ;
2023-09-14 08:05:44 +00:00
buf_ . SetCurSel ( 0 ) ;
buf_ . EnableWindow ( pnp ! = NULL ) ;
2023-04-08 00:56:20 +00:00
if ( pnp )
{
int err = 0 ;
2023-04-15 06:17:48 +00:00
OnDeviceStatus ( 0 , ( LPARAM ) SCANNER_STATUS_READY ) ;
2023-04-08 00:56:20 +00:00
scanner_ = new scanner_handler ( ) ;
err = scanner_ - > open_usb_scanner ( pnp - > device ) ;
if ( err )
{
scanner_ - > release ( ) ;
scanner_ = NULL ;
msg_box ( m_hWnd , MB_OK , L " Error " , L " Open %04X:%04X failed with error %d. " , pnp - > vid , pnp - > pid , err ) ;
2023-04-08 02:49:19 +00:00
enable_buttons ( false ) ;
2023-09-14 08:05:44 +00:00
buf_ . EnableWindow ( FALSE ) ;
2023-04-15 06:17:48 +00:00
OnDeviceStatus ( 0 , ( LPARAM ) SCANNER_STATUS_NOT_OPEN ) ;
2023-04-08 00:56:20 +00:00
}
else
{
wchar_t buf [ 128 ] = { 0 } ;
2023-04-13 07:05:31 +00:00
uint16_t ver = 0 ;
2023-04-08 00:56:20 +00:00
swprintf_s ( buf , _countof ( buf ) - 1 , L " %04X:%04X " , pnp - > vid , pnp - > pid ) ;
: : SetWindowTextW ( m_hWnd , buf ) ;
2023-04-13 07:05:31 +00:00
err = scanner_ - > get_protocol_version ( & ver ) ;
if ( err | | ver ! = PROTOCOL_VER )
2023-04-08 00:56:20 +00:00
{
2023-04-13 07:05:31 +00:00
if ( err )
msg_box ( m_hWnd , MB_OK , L " Unsupported Scanner " , L " Failed to get protocol version with error %d. " , err ) ;
else
msg_box ( m_hWnd , MB_OK , L " Unsupported Scanner " , L " Protocol version is mismatch: expect %u.%u but return %u.%u " , HIBYTE ( PROTOCOL_VER ) , LOBYTE ( PROTOCOL_VER ) , HIBYTE ( ver ) , LOBYTE ( ver ) ) ;
2023-05-11 09:19:00 +00:00
if ( scanner_ )
{
scanner_ - > release ( ) ;
scanner_ = NULL ;
}
2023-04-08 02:49:19 +00:00
enable_buttons ( false ) ;
2023-09-14 08:05:44 +00:00
buf_ . EnableWindow ( FALSE ) ;
2023-04-15 06:17:48 +00:00
OnDeviceStatus ( 0 , ( LPARAM ) SCANNER_STATUS_NOT_OPEN ) ;
2023-04-08 00:56:20 +00:00
}
else
{
2023-04-08 02:49:19 +00:00
scanner_ - > set_image_receiver ( img_keeper ) ;
2023-04-13 07:05:31 +00:00
swprintf_s ( buf , _countof ( buf ) - 1 , L " %u.%u " , HIBYTE ( ver ) , LOBYTE ( ver ) ) ;
2023-04-08 00:56:20 +00:00
SetDlgItemTextW ( IDC_EDIT_PROTOCOL_VER , buf ) ;
refresh_bulk_status ( ) ;
//SetTimer(TIMER_ID_REFRESH_BULK, 1000, NULL);
RECT r = { 0 } ;
std : : string all ( " " ) ;
2023-04-15 06:17:48 +00:00
scanner_ - > set_status_notifyer ( status_cb ) ;
2023-04-08 06:04:40 +00:00
if ( scanner_ - > option_get_all ( all ) = = ETIMEDOUT )
{
// reset it ...
msg_box ( m_hWnd , MB_OK , L " Bulk Trouble " , L " Bulk communication TIMEOUTED, will try reset bulk ... " ) ;
scanner_ - > reset_message_que ( ) ;
refresh_bulk_status ( ) ;
scanner_ - > option_get_all ( all ) ;
}
2023-04-08 00:56:20 +00:00
scanner_handler : : reorder_device_config_json ( all ) ;
sane : : reset_opts ( all . c_str ( ) ) ;
GetDlgItem ( IDC_STATIC_OPTS ) - > GetWindowRect ( & r ) ;
ScreenToClient ( & r ) ;
//ClientToScreen(&r);
setting_ui_ = new dlg_setting ( m_hWnd , & sane_api_ , ( SANE_Handle ) this , & r ) ;
setting_ui_ - > show ( true ) ;
}
}
}
2023-04-12 09:57:04 +00:00
else
{
2023-04-15 06:17:48 +00:00
OnDeviceStatus ( 0 , ( LPARAM ) SCANNER_STATUS_LOST_CONNECT ) ;
2023-04-12 09:57:04 +00:00
: : SetDlgItemTextW ( m_hWnd , IDC_BUTTON_SCAN , L " Scan " ) ;
}
2023-04-13 07:05:31 +00:00
GetDlgItem ( IDC_CHECK_AUTO ) - > EnableWindow ( scanner_ ! = NULL ) ;
GetDlgItem ( IDC_BUTTON_RESET_BULK ) - > EnableWindow ( scanner_ ! = NULL ) ;
GetDlgItem ( IDC_BUTTON_REFRESH ) - > EnableWindow ( scanner_ ! = NULL ) ;
2023-04-08 00:56:20 +00:00
}
void CDlgScanner : : get_option ( const char * name , void * value , size_t size )
{
scanner_ - > option_value_get ( name , value , size ) ;
}
2023-05-02 01:50:55 +00:00
int CDlgScanner : : get_all_option ( std : : string & opts_json )
{
int ret = scanner_ - > option_get_all ( opts_json ) ;
if ( ret = = 0 )
{
scanner_handler : : reorder_device_config_json ( opts_json ) ;
}
return ret ;
}
2023-04-12 09:57:04 +00:00
int CDlgScanner : : set_option ( const char * name , void * value , int type , size_t len , size_t max_len , int * after )
{
return scanner_ - > option_value_set ( name , type , value , max_len , len , ( uint8_t * ) after ) ;
}
2023-04-08 00:56:20 +00:00
int CDlgScanner : : refresh_bulk_status ( void )
{
EP0REPLYSTATUS s = { 0 } ;
wchar_t buf [ 128 ] = { 0 } ;
int err = scanner_ - > get_scanner_status ( & s ) ;
if ( err = = 0 )
{
SetDlgItemTextW ( IDC_EDIT_BUILK_IN , peer_bulk_status ( s . in_status , buf ) ) ;
if ( s . in_status = = BULK_STATUS_IO )
{
swprintf_s ( buf , _countof ( buf ) - 1 , L " BULK_STATUS_IO(Want: %x) " , s . bytes_to_sent ) ;
SetDlgItemTextW ( IDC_EDIT_BUILK_IN , buf ) ;
}
SetDlgItemTextW ( IDC_EDIT_BULK_OUT , peer_bulk_status ( s . out_status , buf ) ) ;
if ( s . out_status = = BULK_STATUS_IO )
{
swprintf_s ( buf , _countof ( buf ) - 1 , L " BULK_STATUS_IO(Need: %x) " , s . task_required_bytes ) ;
SetDlgItemTextW ( IDC_EDIT_BULK_OUT , buf ) ;
}
2023-05-06 06:21:08 +00:00
if ( max_sent_ < s . packets_to_sent )
max_sent_ = s . packets_to_sent ;
if ( max_cmd_ < s . task_cnt )
max_cmd_ = s . task_cnt ;
2023-04-08 00:56:20 +00:00
2023-05-06 06:21:08 +00:00
swprintf_s ( buf , _countof ( buf ) - 1 , L " %u (max: %u) " , s . packets_to_sent , max_sent_ ) ;
2023-04-08 00:56:20 +00:00
SetDlgItemTextW ( IDC_EDIT_SENT_QUE , buf ) ;
2023-05-06 06:21:08 +00:00
swprintf_s ( buf , _countof ( buf ) - 1 , L " %u (max: %u) " , s . task_cnt , max_cmd_ ) ;
2023-04-08 00:56:20 +00:00
SetDlgItemTextW ( IDC_EDIT_CMD_QUE , buf ) ;
}
return err ;
}
void CDlgScanner : : thread_auto_tx_file ( void )
{
char loc [ 256 ] = { 0 } ,
remt [ 256 ] = { 0 } ;
uint32_t ind = 0 , err = 0 ;
std : : string file ( " " ) , prev ( " " ) , ext ( " " ) ;
: : GetDlgItemTextA ( m_hWnd , IDC_EDIT_LOCAL , loc , _countof ( loc ) - 1 ) ;
: : GetDlgItemTextA ( m_hWnd , IDC_EDIT_REMOTE , remt , _countof ( remt ) - 1 ) ;
prev = loc ;
ind = prev . rfind ( ' . ' ) ;
ext = " ) " + prev . substr ( ind ) ;
prev . erase ( ind ) ;
file = loc ;
prev + = " ( " ;
ind = file . rfind ( ' \\ ' ) ;
file . erase ( ind + 1 ) ;
file + = " tx " ;
mkdir ( file . c_str ( ) ) ;
file = loc ;
prev . insert ( ind , " \\ tx " ) ;
2023-04-12 09:57:04 +00:00
auto tx_over = [ & ] ( uint64_t size , uint64_t cur , uint32_t err_code , void * user_data ) - > int
2023-04-08 00:56:20 +00:00
{
err = err_code ;
if ( cur > = size | | err_code )
{
SetEvent ( auto_wait_ ) ;
log_cls : : log ( LOG_LEVEL_DEBUG , " File transfer ended with error code %d \r \n " , err_code ) ;
}
return 0 ;
} ;
ind = 0 ;
while ( auto_tx_ )
{
ResetEvent ( auto_wait_ ) ;
scanner_ - > file_transfer ( file . c_str ( ) , remt , true , tx_over ) ;
if ( WaitForSingleObject ( auto_wait_ , 10 * 60 * 1000 ) = = WAIT_TIMEOUT )
{
msg_box ( m_hWnd , MB_OK , L " Send file " , L " Wait timeouted! \r \n Send: %s " , usb : : a2u ( file . c_str ( ) ) . c_str ( ) ) ;
2023-04-12 09:57:04 +00:00
// ((CButton*)GetDlgItem(IDC_CHECK_REPEAT))->SetCheck(BST_UNCHECKED);
// OnBnClickedCheckRepeat();
set_check ( IDC_CHECK_REPEAT , false ) ;
click_repeat ( ) ;
2023-04-08 00:56:20 +00:00
break ;
}
else if ( err )
{
msg_box ( m_hWnd , MB_OK | MB_ICONSTOP , L " Send file " , L " Failed with error code : %d " , err ) ;
2023-04-12 09:57:04 +00:00
set_check ( IDC_CHECK_REPEAT , false ) ;
click_repeat ( ) ;
2023-04-08 00:56:20 +00:00
break ;
}
if ( ! auto_tx_ )
break ;
Sleep ( 1000 ) ;
ResetEvent ( auto_wait_ ) ;
// file_util::force_move_file(usb::a2u((file + ".reply").c_str()).c_str(), usb::a2u((prev + std::to_string(++ind) + ext).c_str()).c_str());
file = prev + std : : to_string ( + + ind ) + ext ;
scanner_ - > file_transfer ( file . c_str ( ) , remt , false , tx_over ) ;
if ( WaitForSingleObject ( auto_wait_ , 10 * 60 * 1000 ) = = WAIT_TIMEOUT )
{
msg_box ( m_hWnd , MB_OK , L " Receive file " , L " Wait timeouted! \r \n Receive to %s " , usb : : a2u ( file . c_str ( ) ) . c_str ( ) ) ;
2023-04-12 09:57:04 +00:00
set_check ( IDC_CHECK_REPEAT , false ) ;
click_repeat ( ) ;
2023-04-08 00:56:20 +00:00
break ;
}
else if ( err )
{
msg_box ( m_hWnd , MB_OK | MB_ICONSTOP , L " Receive file " , L " Failed with error code : %d " , err ) ;
2023-04-12 09:57:04 +00:00
set_check ( IDC_CHECK_REPEAT , false ) ;
click_repeat ( ) ;
2023-04-08 00:56:20 +00:00
break ;
}
Sleep ( 1000 ) ;
}
2023-04-12 09:57:04 +00:00
set_check ( IDC_CHECK_REPEAT , false ) ;
2023-04-08 00:56:20 +00:00
auto_tx_ = false ;
2023-04-12 09:57:04 +00:00
//enable_buttons(scanner_ != NULL);
click_repeat ( true ) ;
2023-04-08 00:56:20 +00:00
// msg_box(m_hWnd, MB_OK, L"Repeat S/R", L"exited.");
}
void CDlgScanner : : enable_buttons ( bool enable )
{
//GetDlgItem(IDC_BUTTON_RESET_BULK)->EnableWindow(enable);
//GetDlgItem(IDC_CHECK_AUTO)->EnableWindow(enable);
GetDlgItem ( IDC_BUTTON_SCAN ) - > EnableWindow ( enable ) ;
GetDlgItem ( IDC_BUTTON_SEND ) - > EnableWindow ( enable ) ;
GetDlgItem ( IDC_BUTTON_RECEIVE ) - > EnableWindow ( enable ) ;
GetDlgItem ( IDC_CHECK_REPEAT ) - > EnableWindow ( enable ) ;
GetDlgItem ( IDC_BUTTON_START_PROG ) - > EnableWindow ( enable ) ;
GetDlgItem ( IDC_BUTTON_SEND_EP0 ) - > EnableWindow ( enable ) ;
}
2023-04-12 09:57:04 +00:00
void CDlgScanner : : set_text ( UINT id , const wchar_t * text )
{
std : : wstring * str = new std : : wstring ( text ) ;
if ( ! : : PostMessageW ( m_hWnd , WM_SET_TEXT , id , ( LPARAM ) str ) )
delete str ;
}
bool CDlgScanner : : is_checked ( UINT id )
{
bool chk = false ;
: : SendMessage ( m_hWnd , WM_IS_BUTTON_CHECKED , id , ( LPARAM ) & chk ) ;
return chk ;
}
void CDlgScanner : : set_check ( UINT id , bool checked )
{
: : PostMessage ( m_hWnd , WM_SET_BUTTON_CHECK , id , checked ) ;
}
void CDlgScanner : : click_repeat ( bool enable_buttons , bool enable )
{
if ( enable_buttons )
: : PostMessage ( m_hWnd , WM_ENABLE_CTRLS , 1 , enable ) ;
else
: : PostMessage ( m_hWnd , WM_ENABLE_CTRLS , 0 , enable ) ;
}
2023-04-08 00:56:20 +00:00
BEGIN_MESSAGE_MAP ( CDlgScanner , CDialogEx )
ON_NOTIFY ( TCN_SELCHANGE , IDC_TAB_OPER , & CDlgScanner : : OnTcnSelchangeTabOper )
ON_BN_CLICKED ( IDOK , & CDlgScanner : : OnBnClickedOk )
ON_BN_CLICKED ( IDC_BUTTON_RESET_BULK , & CDlgScanner : : OnBnClickedButtonResetBulk )
ON_BN_CLICKED ( IDC_BUTTON_BROWSE_IMG_PATH , & CDlgScanner : : OnBnClickedButtonBrowseSavingPath )
ON_BN_CLICKED ( IDC_BUTTON_SCAN , & CDlgScanner : : OnBnClickedButtonScan )
ON_BN_CLICKED ( IDC_BUTTON_BROWSE_LOCAL , & CDlgScanner : : OnBnClickedButtonBrowseFile )
ON_BN_CLICKED ( IDC_BUTTON_SEND , & CDlgScanner : : OnBnClickedButtonSendFile )
ON_BN_CLICKED ( IDC_BUTTON_RECEIVE , & CDlgScanner : : OnBnClickedButtonRecvFile )
ON_BN_CLICKED ( IDC_BUTTON_START_PROG , & CDlgScanner : : OnBnClickedButtonStartProgram )
ON_BN_CLICKED ( IDC_BUTTON_SEND_EP0 , & CDlgScanner : : OnBnClickedButtonSendEp0 )
ON_WM_TIMER ( )
ON_BN_CLICKED ( IDC_CHECK_AUTO , & CDlgScanner : : OnBnClickedCheckAuto )
ON_BN_CLICKED ( IDC_BUTTON_REFRESH , & CDlgScanner : : OnBnClickedButtonRefresh )
ON_BN_CLICKED ( IDC_CHECK_REPEAT , & CDlgScanner : : OnBnClickedCheckRepeat )
2023-04-12 09:57:04 +00:00
ON_MESSAGE ( WM_SET_TEXT , & CDlgScanner : : OnSetText )
ON_MESSAGE ( WM_IS_BUTTON_CHECKED , & CDlgScanner : : OnIsButtonChecked )
ON_MESSAGE ( WM_SET_BUTTON_CHECK , & CDlgScanner : : OnSetButtonChecked )
ON_MESSAGE ( WM_ENABLE_CTRLS , & CDlgScanner : : OnEnableCtrls )
2023-04-15 06:17:48 +00:00
ON_MESSAGE ( WM_DEVICE_STATTUS , & CDlgScanner : : OnDeviceStatus )
2023-09-14 08:05:44 +00:00
ON_CBN_SELCHANGE ( IDC_COMBO_BUF_SIZE , & CDlgScanner : : OnCbnSelchangeComboBufSize )
2023-04-08 00:56:20 +00:00
END_MESSAGE_MAP ( )
// CDlgScanner 消息处理程序
BOOL CDlgScanner : : OnInitDialog ( )
{
CDialogEx : : OnInitDialog ( ) ;
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
// TODO: 在此添加额外的初始化代码
int ind = 0 ;
tab_oper_ . InsertItem ( ind + + , TEXT ( " Status " ) ) ;
tab_oper_ . InsertItem ( ind + + , TEXT ( " Scan " ) ) ;
tab_oper_ . InsertItem ( ind + + , TEXT ( " File " ) ) ;
tab_oper_ . InsertItem ( ind + + , TEXT ( " Prog " ) ) ;
tab_oper_ . InsertItem ( ind + + , TEXT ( " Ctrl " ) ) ;
tab_oper_ . SetCurSel ( 0 ) ;
OnTcnSelchangeTabOper ( NULL , ( LRESULT * ) & ind ) ;
SetDlgItemText ( IDC_EDIT_LOCAL , TEXT ( " D: \\ boxroom \\ usb-tx-file \\ VMwareworkstation.exe " ) ) ;
SetDlgItemText ( IDC_EDIT_REMOTE , TEXT ( " /root/.scanner/log/VMwareworkstation.exe " ) ) ;
sane_api_ . sane_get_devices_api = & sane : : sane_get_devices_api ;
sane_api_ . sane_open_api = & sane : : sane_open_api ;
sane_api_ . sane_close_api = & sane : : sane_close_api ;
sane_api_ . sane_get_option_descriptor_api = & sane : : sane_get_option_descriptor_api ;
sane_api_ . sane_control_option_api = & sane : : sane_control_option_api ;
sane_api_ . sane_get_parameters_api = & sane : : sane_get_parameters_api ;
sane_api_ . sane_start_api = & sane : : sane_start_api ;
sane_api_ . sane_read_api = & sane : : sane_read_api ;
sane_api_ . sane_cancel_api = & sane : : sane_cancel_api ;
sane_api_ . sane_set_io_mode_api = & sane : : sane_set_io_mode_api ;
sane_api_ . sane_get_select_fd_api = & sane : : sane_get_select_fd_api ;
sane_api_ . sane_strstatus_api = & sane : : sane_strstatus_api ;
sane_api_ . sane_io_control_api = & sane : : sane_io_control_api ;
sane_api_ . sane_init_api = & sane : : sane_init_api ;
sane_api_ . sane_exit_api = & sane : : sane_exit_api ;
2023-04-08 02:49:19 +00:00
wchar_t path [ MAX_PATH ] = { 0 } ;
std : : wstring root ( L " " ) ;
GetModuleFileNameW ( NULL , path , _countof ( path ) - 1 ) ;
wcsrchr ( path , L ' \\ ' ) [ 1 ] = 0 ;
root = path ;
if ( GetPrivateProfileStringW ( L " config " , L " img-path " , L " " , path , _countof ( path ) - 1 , ( root + L " config.txt " ) . c_str ( ) ) )
{
img_root_ = path ;
}
else
{
img_root_ = root + L " imgs " ;
}
STR_SIMPLIFY_PATH ( img_root_ ) ;
file_util : : force_create_folder ( img_root_ . c_str ( ) , NULL , false ) ;
if ( img_root_ [ img_root_ . length ( ) - 1 ] ! = L ' \\ ' )
img_root_ + = L " \\ " ;
: : SetDlgItemTextW ( m_hWnd , IDC_EDIT_IMG_PATH , img_root_ . c_str ( ) ) ;
2023-09-14 08:05:44 +00:00
buf_ . SetCurSel ( 0 ) ;
2023-04-08 02:49:19 +00:00
2023-04-08 00:56:20 +00:00
return FALSE ; // 除非将焦点设置到控件,否则返回 TRUE
}
BOOL CDlgScanner : : PreTranslateMessage ( MSG * pMsg )
{
if ( pMsg - > message = = WM_SHOWWINDOW & & pMsg - > wParam = = 0 & & pMsg - > lParam = = SW_PARENTCLOSING )
return TRUE ;
return FALSE ;
}
void CDlgScanner : : OnTcnSelchangeTabOper ( NMHDR * pNMHDR , LRESULT * pResult )
{
// TODO: 在此添加控件通知处理程序代码
UINT statu [ ] = { IDC_STATIC_BULK_IN , IDC_STATIC_BULK_OUT , IDC_STATIC_CMD_QUE , IDC_STATIC_SENT_QUE
, IDC_EDIT_BUILK_IN , IDC_EDIT_BULK_OUT , IDC_EDIT_CMD_QUE , IDC_EDIT_SENT_QUE
, IDC_BUTTON_RESET_BULK , IDC_CHECK_AUTO , IDC_BUTTON_REFRESH } ,
2023-04-12 09:57:04 +00:00
scan [ ] = { IDC_STATIC_IMG_PATH , IDC_STATIC_COUNT , IDC_EDIT_IMG_PATH , IDC_EDIT_COUNT , IDC_BUTTON_BROWSE_IMG_PATH
, IDC_CHECK_AUTO_OPEN_IMG , IDC_BUTTON_SCAN } ,
2023-04-08 00:56:20 +00:00
file [ ] = { IDC_STATIC_LOCAL , IDC_STATIC_REMOTE , IDC_EDIT_LOCAL , IDC_EDIT_REMOTE , IDC_BUTTON_BROWSE_LOCAL
, IDC_BUTTON_SEND , IDC_BUTTON_RECEIVE , IDC_CHECK_REPEAT } ,
prog [ ] = { IDC_STATIC_CMD , IDC_STATIC_PARAM , IDC_EDIT_CMD , IDC_EDIT_PARAM , IDC_BUTTON_START_PROG } ,
ctrl [ ] = { IDC_STATIC_TYPE , IDC_STATIC_REQ , IDC_STATIC_IND , IDC_STATIC_VAL , IDC_STATIC_LEN , IDC_STATIC_DATA
, IDC_EDIT_TYPE , IDC_EDIT_REQ , IDC_EDIT_IND , IDC_EDIT_VAL , IDC_EDIT_LEN , IDC_EDIT_DATA
, IDC_BUTTON_SEND_EP0 } ;
int sel = tab_oper_ . GetCurSel ( ) , show = sel - - = = 0 ? SW_SHOW : SW_HIDE ;
for ( auto & v : statu )
GetDlgItem ( v ) - > ShowWindow ( show ) ;
show = sel - - = = 0 ? SW_SHOW : SW_HIDE ;
for ( auto & v : scan )
GetDlgItem ( v ) - > ShowWindow ( show ) ;
show = sel - - = = 0 ? SW_SHOW : SW_HIDE ;
for ( auto & v : file )
GetDlgItem ( v ) - > ShowWindow ( show ) ;
show = sel - - = = 0 ? SW_SHOW : SW_HIDE ;
for ( auto & v : prog )
GetDlgItem ( v ) - > ShowWindow ( show ) ;
show = sel - - = = 0 ? SW_SHOW : SW_HIDE ;
for ( auto & v : ctrl )
GetDlgItem ( v ) - > ShowWindow ( show ) ;
* pResult = 0 ;
}
void CDlgScanner : : OnBnClickedOk ( )
{
// TODO: 在此添加控件通知处理程序代码
if ( IsWindow ( parent_ ) )
: : PostMessage ( parent_ , WM_OPENNING_DLG_CLOSED , 0 , ( LPARAM ) this ) ;
CDialogEx : : OnOK ( ) ;
}
void CDlgScanner : : OnBnClickedButtonResetBulk ( )
{
// TODO: 在此添加控件通知处理程序代码
int err = scanner_ - > reset_message_que ( ) ;
msg_box ( m_hWnd , MB_OK , L " Reset-Bulk " , L " Result = %d " , err ) ;
if ( err = = 0 )
{
enable_buttons ( true ) ;
auto_tx_ = false ;
SetEvent ( auto_wait_ ) ;
}
}
void CDlgScanner : : OnBnClickedButtonBrowseSavingPath ( )
{
// TODO: 在此添加控件通知处理程序代码
2023-04-08 02:49:19 +00:00
LPITEMIDLIST pidRoot = NULL ;
BROWSEINFOW bi = { 0 } ;
wchar_t path [ MAX_PATH ] = { 0 } ;
SHGetSpecialFolderLocation ( m_hWnd , CSIDL_DRIVES , & pidRoot ) ;
bi . hwndOwner = m_hWnd ;
bi . pidlRoot = pidRoot ;
bi . lpszTitle = L " Select folder to save scanning images " ;
bi . pszDisplayName = path ;
bi . ulFlags = BIF_RETURNONLYFSDIRS ;
pidRoot = SHBrowseForFolderW ( & bi ) ;
if ( pidRoot )
{
SHGetPathFromIDListW ( pidRoot , path ) ;
img_root_ = path ;
img_root_ + = L " \\ " ;
STR_SIMPLIFY_PATH ( img_root_ ) ;
: : SetDlgItemTextW ( m_hWnd , IDC_EDIT_IMG_PATH , img_root_ . c_str ( ) ) ;
std : : wstring root ( L " " ) ;
GetModuleFileNameW ( NULL , path , _countof ( path ) - 1 ) ;
wcsrchr ( path , L ' \\ ' ) [ 1 ] = 0 ;
root = path ;
WritePrivateProfileStringW ( L " config " , L " img-path " , img_root_ . c_str ( ) , ( root + L " config.txt " ) . c_str ( ) ) ;
}
2023-04-08 00:56:20 +00:00
}
void CDlgScanner : : OnBnClickedButtonScan ( )
{
// TODO: 在此添加控件通知处理程序代码
2023-04-08 02:49:19 +00:00
wchar_t title [ 40 ] = { 0 } ;
: : GetDlgItemTextW ( m_hWnd , IDC_BUTTON_SCAN , title , _countof ( title ) - 1 ) ;
if ( wcsicmp ( title , L " Scan " ) = = 0 )
{
img_cnt_ = 0 ;
2023-04-23 03:50:17 +00:00
paper_cnt_ = 0 ;
2023-04-08 02:49:19 +00:00
SetDlgItemInt ( IDC_EDIT_COUNT , img_cnt_ ) ;
if ( scanner_ )
{
int err = scanner_ - > scan_start ( ) ;
2023-04-15 09:42:55 +00:00
log_cls : : log ( LOG_LEVEL_DEBUG , " Start to scan = %s \r \n " , usb : : u2a ( scanner_status ( err , title ) ) . c_str ( ) ) ;
2023-04-08 02:49:19 +00:00
if ( err )
2023-04-15 09:42:55 +00:00
msg_box ( m_hWnd , MB_OK , L " Error " , L " Failed in startin scanning with code %s " , scanner_status ( err , title ) ) ;
2023-04-08 02:49:19 +00:00
else
2023-04-15 06:17:48 +00:00
{
2023-04-08 02:49:19 +00:00
: : SetDlgItemTextW ( m_hWnd , IDC_BUTTON_SCAN , L " Stop " ) ;
2023-04-15 06:17:48 +00:00
OnDeviceStatus ( 0 , ( LPARAM ) SCANNER_STATUS_SCANNING ) ;
}
2023-04-08 02:49:19 +00:00
}
}
else
{
if ( scanner_ )
{
int err = scanner_ - > scan_stop ( ) ;
if ( err )
msg_box ( m_hWnd , MB_OK , L " Error " , L " Failed to stop scanning with code %d " , err ) ;
}
}
2023-04-08 00:56:20 +00:00
}
void CDlgScanner : : OnBnClickedButtonBrowseFile ( )
{
// TODO: 在此添加控件通知处理程序代码
}
void CDlgScanner : : OnBnClickedButtonSendFile ( )
{
// TODO: 在此添加控件通知处理程序代码
char l [ 256 ] = { 0 } ,
r [ 256 ] = { 0 } ;
int err = 0 ;
: : GetDlgItemTextA ( m_hWnd , IDC_EDIT_LOCAL , l , _countof ( l ) - 1 ) ;
: : GetDlgItemTextA ( m_hWnd , IDC_EDIT_REMOTE , r , _countof ( r ) - 1 ) ;
err = scanner_ - > file_transfer ( l , r , true ) ;
if ( err )
msg_box ( m_hWnd , MB_OK , L " Send File " , L " Result = %d " , err ) ;
}
void CDlgScanner : : OnBnClickedButtonRecvFile ( )
{
// TODO: 在此添加控件通知处理程序代码
char l [ 256 ] = { 0 } ,
r [ 256 ] = { 0 } ;
int err = 0 ;
: : GetDlgItemTextA ( m_hWnd , IDC_EDIT_LOCAL , l , _countof ( l ) - 1 ) ;
: : GetDlgItemTextA ( m_hWnd , IDC_EDIT_REMOTE , r , _countof ( r ) - 1 ) ;
err = scanner_ - > file_transfer ( l , r , false ) ;
if ( err )
msg_box ( m_hWnd , MB_OK , L " Receive File " , L " Result = %d " , err ) ;
}
void CDlgScanner : : OnBnClickedButtonStartProgram ( )
{
// TODO: 在此添加控件通知处理程序代码
char key [ 80 ] = { 0 } , val [ 80 ] = { 0 } ;
int err = 0 ;
: : GetDlgItemTextA ( m_hWnd , IDC_EDIT_CMD , key , _countof ( key ) - 1 ) ;
err = scanner_ - > option_value_get ( key , val , 40 ) ;
if ( err = = 0 )
: : SetDlgItemTextA ( m_hWnd , IDC_EDIT_PARAM , val ) ;
}
void CDlgScanner : : OnBnClickedButtonSendEp0 ( )
{
// TODO: 在此添加控件通知处理程序代码
}
void CDlgScanner : : OnTimer ( UINT_PTR nIDEvent )
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if ( nIDEvent = = TIMER_ID_REFRESH_BULK )
refresh_bulk_status ( ) ;
CDialogEx : : OnTimer ( nIDEvent ) ;
}
void CDlgScanner : : OnBnClickedCheckAuto ( )
{
// TODO: 在此添加控件通知处理程序代码
bool checked = ( ( CButton * ) GetDlgItem ( IDC_CHECK_AUTO ) ) - > GetCheck ( ) = = BST_CHECKED ;
GetDlgItem ( IDC_BUTTON_REFRESH ) - > EnableWindow ( ! checked ) ;
if ( checked )
SetTimer ( TIMER_ID_REFRESH_BULK , 1000 , NULL ) ;
else
KillTimer ( TIMER_ID_REFRESH_BULK ) ;
}
void CDlgScanner : : OnBnClickedButtonRefresh ( )
{
// TODO: 在此添加控件通知处理程序代码
refresh_bulk_status ( ) ;
}
void CDlgScanner : : OnBnClickedCheckRepeat ( )
{
// TODO: 在此添加控件通知处理程序代码
auto_tx_ = ( ( CButton * ) GetDlgItem ( IDC_CHECK_REPEAT ) ) - > GetCheck ( ) = = BST_CHECKED ;
enable_buttons ( ! auto_tx_ ) ;
GetDlgItem ( IDC_CHECK_REPEAT ) - > EnableWindow ( TRUE ) ;
GetDlgItem ( IDC_CHECK_AUTO ) - > EnableWindow ( TRUE ) ;
if ( auto_tx_ )
{
if ( auto_tx_file_ = = - 1 )
auto_tx_file_ = threads_ - > thread_new ( & CDlgScanner : : thread_auto_tx_file ) ;
}
else
{
if ( auto_tx_file_ ! = - 1 )
{
SetEvent ( auto_wait_ ) ;
threads_ - > thread_stop ( auto_tx_file_ ) ;
auto_tx_file_ = - 1 ;
}
}
}
2023-04-12 09:57:04 +00:00
LRESULT CDlgScanner : : OnSetText ( WPARAM wp , LPARAM lp )
{
std : : wstring * str = ( std : : wstring * ) lp ;
: : SetDlgItemTextW ( m_hWnd , wp , str - > c_str ( ) ) ;
delete str ;
return 0 ;
}
LRESULT CDlgScanner : : OnIsButtonChecked ( WPARAM wp , LPARAM lp )
{
* ( bool * ) lp = ( ( CButton * ) GetDlgItem ( wp ) ) - > GetCheck ( ) = = BST_CHECKED ;
return 0 ;
}
LRESULT CDlgScanner : : OnSetButtonChecked ( WPARAM wp , LPARAM lp )
{
( ( CButton * ) GetDlgItem ( wp ) ) - > SetCheck ( lp ? BST_CHECKED : BST_UNCHECKED ) ;
return 0 ;
}
LRESULT CDlgScanner : : OnEnableCtrls ( WPARAM wp , LPARAM lp )
{
if ( wp = = 0 )
OnBnClickedCheckRepeat ( ) ;
else
enable_buttons ( lp ) ;
return 0 ;
}
2023-04-15 06:17:48 +00:00
LRESULT CDlgScanner : : OnDeviceStatus ( WPARAM wp , LPARAM lp )
{
wchar_t unk [ 20 ] = { 0 } ;
: : SetDlgItemTextW ( m_hWnd , IDC_EDIT_STATUS , scanner_status ( ( int ) lp , unk ) ) ;
return 0 ;
}
2023-09-14 08:05:44 +00:00
void CDlgScanner : : OnCbnSelchangeComboBufSize ( )
{
// TODO: 在此添加控件通知处理程序代码
int sel = buf_ . GetCurSel ( ) ;
sel = 1 < < sel ;
if ( scanner_ - > set_io_buffer_size ( sel ) )
{
int cur = 0 ;
sel = scanner_ - > get_io_buffer_size ( ) > > 1 ;
while ( sel )
{
cur + + ;
sel > > = 1 ;
}
buf_ . SetCurSel ( cur ) ;
}
}