添加关于信息中子条目的TWAIN协议接口

This commit is contained in:
gb 2023-05-13 16:27:44 +08:00
parent 579a7c9d6c
commit 78a9c23b3f
8 changed files with 543 additions and 327 deletions

View File

@ -13,7 +13,7 @@
dlg_indicator::dlg_indicator(HWND parent) : dlg_base(parent, IDD_INDICATOR)
, papers_(0), images_(0), err_(false)
, papers_(0), images_(0), err_(false), finish_(false)
{
create();
SetWindowLongW(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE, GetWindowLong(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE) | SS_OWNERDRAW);
@ -111,6 +111,7 @@ BOOL dlg_indicator::handle_message(UINT msg, WPARAM wp, LPARAM lp)
notify_ui_event(SANE_EVENT_WORKING);
break;
case WM_SCAN_FINISHED:
finish_ = true;
if (lp)
{
std::string* str = (std::string*)wp;
@ -156,7 +157,7 @@ void dlg_indicator::handle_command(WORD code, WORD id, HANDLE ctrl)
{
if (id == IDCANCEL)
{
notify_over(true);
notify_over(!finish_);
}
}
void dlg_indicator::notify_over(bool cancel)

View File

@ -13,6 +13,7 @@ class dlg_indicator : public dlg_base
unsigned int papers_;
unsigned int images_;
bool err_;
bool finish_;
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
void handle_command(WORD code, WORD id, HANDLE ctrl);

View File

@ -162,7 +162,7 @@ struct __declspec(novtable) ISaneInvoker : public IRef
// Function: 获取配置项信息
//
// Parameter: sn - 配置项索引
// Parameter: sn - 配置项索引 - sane_option_id
//
// type - 配置项数据类型
//
@ -172,6 +172,7 @@ struct __declspec(novtable) ISaneInvoker : public IRef
COM_API_DECLARE(bool, get_option_info(int sn, value_type* type, value_limit* limit, int *bytes));
COM_API_DECLARE(bool, get_value(int sn, set_opt_value, void* param));
COM_API_DECLARE(bool, get_value(int sn, void* data, int* len)); // get operation with in-parameter
COM_API_DECLARE(int, set_value(int sn, void* val));
COM_API_DECLARE(int, convert_image(SANE_ImageFormatConvert* conv));
COM_API_DECLARE(void, free_buffer(void* buf, int len));
@ -395,25 +396,24 @@ namespace sane_opts
#define GET_SANE_OPT(type, object, id_name, limit, vct) \
{ \
int ind = object->sane_opt_id_##id_name##(); \
sane_opts::get_opts<type> op(limit, vct); \
if(ind > 0) \
object->get_value(ind, sane_opts::set_opt_value<type>, &op);\
else \
return capUnsupported(); \
object->get_value(SANE_OPT_ID_##id_name, sane_opts::set_opt_value<type>, &op); \
op.re_order(); \
}
#define GET_SANE_OPT_EX(type, object, id_name, limit, vct) \
{ \
sane_opts::get_opts<type> op(limit, vct); \
object->get_value(object->sane_opt_id_##id_name##(), sane_opts::set_opt_value<type>, &op); \
op.re_order(); \
}
#define SET_SANE_OPT(ret, object, id_name, val) \
{ \
int ind = object->sane_opt_id_##id_name##(); \
if(ind > 0) \
ret = object->set_value(ind, val); \
else \
{ \
ret = SCANNER_ERR_INVALID_PARAMETER; \
load_sane_util::log_info((std::wstring(L"Fatal: property '") + L###id_name + L"' not found !!!\r\n").c_str(), 0); \
} \
ret = object->set_value(SANE_OPT_ID_##id_name, val); \
}
#define SET_SANE_OPT_EX(ret, object, id_name, val) \
{ \
ret = object->set_value(object->sane_opt_id_##id_name##(), val);\
}
typedef unsigned int SCANNERID;

View File

@ -1,4 +1,4 @@

#include "scanner.h"
@ -16,17 +16,18 @@
#include "../../sdk/include/lang/app_language.h"
#include <functional>
#include "DlgIndicator.h"
#include "twain_user/twainui.h"
#include <twain_user/twainui.h>
#pragma comment(lib, "Shlwapi.lib")
static IMPLEMENT_OPTION_STRING_COMPARE(compare_sane_opt);
#define SET_SANE_OPT_ID(id, id_name, name, val, extension) \
if(strcmp(SANE_STD_OPT_NAME_##name, val) == 0) \
{ \
id_name##_id_ = id; \
extension(id); \
#define SET_SANE_OPT_ID(id, id_name, name, val, extension) \
if(strcmp(SANE_STD_OPT_NAME_##name, val) == 0) \
{ \
id_name##_id_ = id; \
sane_ids_[(sane_option_id)SANE_OPT_ID_##name] = id; \
extension(id); \
}
@ -342,7 +343,7 @@ namespace callback
// SANE_EVENT_USB_DATA_RECEIVED- void* unused, be NULL, flag - unused, be 0
// SANE_EVENT_IMAGE_OK - void* unused, be NULL, flag - unused, be 0
int (*choose_scanner)(const std::vector<DEVQUEUI>& devs) = NULL; // blocked. return selected DEVQUE::id or -1 if user cancelled
int (*apply_current_config)(const char* dev_name, SANE_Handle device, LPSANEAPI api) = NULL; // 应用设备的当前配
int (*apply_current_config)(const char* dev_name, SANE_Handle device, LPSANEAPI api) = NULL; // 应用设备的当前配<EFBFBD>?
int (*show_setting_ui)(SANE_Handle device, HWND parent, LPSANEAPI api, const char* devname, bool with_scan, std::function<void(ui_result)> callback) = NULL;
int (*show_progress_ui)(HWND parent, std::function<void(ui_result)> callback, std::function<void(int/*event*/, void*/*msg*/, int/*flag*/)>* notify) = NULL;
int (*show_messagebox_ui)(HWND parent, int event, void* msg, int flag) = NULL;
@ -614,6 +615,18 @@ COM_API_IMPLEMENT(scanner, long, release(void))
return refer::release();
}
int scanner::transfer_id(int id)
{
if (id > SANE_OPT_ID_BASE)
{
if (sane_ids_.count((sane_option_id)id) == 0)
id = -1;
else
id = sane_ids_[(sane_option_id)id];
}
return id;
}
void scanner::transport_config_file(void)
{
size_t pos = scanner_name_.find(L" - ");
@ -880,6 +893,28 @@ int scanner::init_options_id(void)
#define SET_OPT_ID(var, predef, func) \
SET_SANE_OPT_ID(op_id, var, predef, desc->name, func)
#define INIT_FIXED_IDS(id) \
sane_ids_[id] = id;
INIT_FIXED_IDS(SANE_OPT_ID_HISTORY_COUNT);
INIT_FIXED_IDS(SANE_OPT_ID_DRIVER_VERSION);
INIT_FIXED_IDS(SANE_OPT_ID_MANUFACTURER);
INIT_FIXED_IDS(SANE_OPT_ID_COPYRIGHT);
INIT_FIXED_IDS(SANE_OPT_ID_CO_URL);
INIT_FIXED_IDS(SANE_OPT_ID_CO_TEL);
INIT_FIXED_IDS(SANE_OPT_ID_CO_ADDR);
INIT_FIXED_IDS(SANE_OPT_ID_CO_GPS);
INIT_FIXED_IDS(SANE_OPT_ID_HELP);
INIT_FIXED_IDS(SANE_OPT_ID_VID);
INIT_FIXED_IDS(SANE_OPT_ID_PID);
INIT_FIXED_IDS(SANE_OPT_ID_DEV_NAME);
INIT_FIXED_IDS(SANE_OPT_ID_DEV_FAMILY);
INIT_FIXED_IDS(SANE_OPT_ID_LOGIN);
INIT_FIXED_IDS(SANE_OPT_ID_LOGOUT);
INIT_FIXED_IDS(SANE_OPT_ID_ROLLER_COUNT);
INIT_FIXED_IDS(SANE_OPT_ID_DRIVER_LOG);
INIT_FIXED_IDS(SANE_OPT_ID_DEVICE_LOG);
while ((desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (const void*)op_id)))
{
void* val = hg_sane_middleware::instance()->get_def_value(handle_, (void*)op_id, NULL, true);
@ -987,7 +1022,6 @@ int scanner::init_options_id(void)
else SET_OPT_ID(is_erase_hole_b, RID_HOLE_B, extension_none)
else SET_OPT_ID(search_hole_range_b, SEARCH_HOLE_RANGE_B, extension_none)
else SET_OPT_ID(fold_direction, FOLD_TYPE, extension_none)
else SET_OPT_ID(fold_type, FOLD_TYPE, extension_none)
else SET_OPT_ID(color_correction, COLOR_CORRECTION, extension_none)
op_id++;
}
@ -2536,6 +2570,56 @@ COM_API_IMPLEMENT(scanner, int, last_error(void))
COM_API_IMPLEMENT(scanner, bool, get_option_info(int sn, value_type* type, value_limit* limit, int* bytes))
{
#define SIMPLE_STR_INFO(id) \
if (sn == id) \
{ \
if (type) \
*type = VAL_TYPE_STR; \
if (limit) \
*limit = VAL_LIMIT_NONE; \
if (bytes) \
*bytes = 255; \
\
return true; \
}
#define SIMPLE_INT_INFO(id) \
if (sn == id) \
{ \
if (type) \
*type = VAL_TYPE_INT; \
if (limit) \
*limit = VAL_LIMIT_NONE; \
if (bytes) \
*bytes = sizeof(int); \
\
return true; \
}
SIMPLE_STR_INFO(SANE_OPT_ID_DRIVER_VERSION);
SIMPLE_STR_INFO(SANE_OPT_ID_MANUFACTURER);
SIMPLE_STR_INFO(SANE_OPT_ID_COPYRIGHT);
SIMPLE_STR_INFO(SANE_OPT_ID_CO_URL);
SIMPLE_STR_INFO(SANE_OPT_ID_CO_TEL);
SIMPLE_STR_INFO(SANE_OPT_ID_CO_ADDR);
SIMPLE_STR_INFO(SANE_OPT_ID_CO_GPS);
SIMPLE_STR_INFO(SANE_OPT_ID_DEV_NAME);
SIMPLE_STR_INFO(SANE_OPT_ID_DEV_FAMILY);
SIMPLE_STR_INFO(SANE_OPT_ID_LOGIN);
SIMPLE_STR_INFO(SANE_OPT_ID_LOGOUT);
SIMPLE_STR_INFO(SANE_OPT_ID_DRIVER_LOG);
SIMPLE_STR_INFO(SANE_OPT_ID_DEVICE_LOG);
SIMPLE_INT_INFO(SANE_OPT_ID_HELP);
SIMPLE_INT_INFO(SANE_OPT_ID_HISTORY_COUNT);
SIMPLE_INT_INFO(SANE_OPT_ID_ROLLER_COUNT);
SIMPLE_INT_INFO(SANE_OPT_ID_VID);
SIMPLE_INT_INFO(SANE_OPT_ID_PID);
sn = transfer_id(sn);
if (sn == -1)
return false;
EXAPIPOS ex = find_ex_api(sn);
SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, ex == ex_opts_.end() ? (void*)sn : (void*)ex->base_ind);
bool ret = false;
@ -2556,6 +2640,34 @@ COM_API_IMPLEMENT(scanner, bool, get_option_info(int sn, value_type* type, value
}
COM_API_IMPLEMENT(scanner, bool, get_value(int sn, set_opt_value setval, void* param))
{
if (sane_ids_.count((sane_option_id)sn) &&
sane_ids_[(sane_option_id)sn] == sn)
{
char buf[256] = { 0 };
value_type type = VAL_TYPE_NONE;
int ret = hg_sane_middleware::instance()->set_option(handle_, (void*)sn, SANE_ACTION_GET_VALUE, buf, NULL);
if (ret == SANE_STATUS_GOOD)
{
get_option_info(sn, &type, NULL, NULL);
if (type == VAL_TYPE_STR)
{
std::string str(buf);
setval(&str, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, param);
}
else
setval(buf, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, param);
return true;
}
return false;
}
sn = transfer_id(sn);
if (sn == -1)
return false;
EXAPIPOS ex = find_ex_api(sn);
int ret = SANE_STATUS_INVAL;
SANE_Int after = 0;
@ -2704,8 +2816,27 @@ COM_API_IMPLEMENT(scanner, bool, get_value(int sn, set_opt_value setval, void* p
return ret == SANE_STATUS_GOOD;
}
COM_API_IMPLEMENT(scanner, bool, get_value(int sn, void* data, int* len))
{
if (sn != SANE_OPT_ID_DRIVER_LOG && sn != SANE_OPT_ID_DEVICE_LOG)
return false;
return hg_sane_middleware::instance()->set_option(handle_, (const void*)sn, SANE_ACTION_GET_VALUE, data, NULL) == SANE_STATUS_GOOD;
}
COM_API_IMPLEMENT(scanner, int, set_value(int sn, void* val))
{
if (sane_ids_.count((sane_option_id)sn) &&
sane_ids_[(sane_option_id)sn] == sn)
{
int ret = hg_sane_middleware::instance()->set_option(handle_, (void*)sn, SANE_ACTION_SET_VALUE, val, NULL);
return ret == SANE_STATUS_GOOD;
}
sn = transfer_id(sn);
if (sn == -1)
return SANE_STATUS_UNSUPPORTED;
EXAPIPOS ex = find_ex_api(sn);
int ret = SANE_STATUS_INVAL;
SANE_Int after = 0;

View File

@ -5,6 +5,7 @@
#include <algorithm>
#include <memory>
#include <functional>
#include <map>
#define SANE_OPTION_ID(name) \
SANE_OPTION_ID_OVERRIDE(name); \
@ -32,6 +33,13 @@ namespace gb
class scanner : public ISaneInvoker, virtual public refer
{
typedef struct _simple_opt
{
value_type type;
value_limit limit;
int bytes;
}SIMPLEOPT;
SANE_Handle handle_;
SCANNERID id_;
int err_;
@ -59,11 +67,14 @@ class scanner : public ISaneInvoker, virtual public refer
gb::scanner_cfg* cfg_;
bool twain_set_;
SANEAPI sane_api_;
std::map<sane_option_id, int> sane_ids_;
std::function<void(int, void*, int)> ui_notify;
int(__stdcall* scanner_ev_handler_)(int, void*);
void* evh_param_;
HWND app_wnd_; // for MessageBox
bool is_show_ui_;
int transfer_id(int id); // transfer fixed SANE option ID to real id, -1 is none
void transport_config_file(void);
void update_config(void);
void load_config(const wchar_t* file);
@ -207,6 +218,7 @@ public:
COM_API_OVERRIDE(int, last_error(void));
COM_API_OVERRIDE(bool, get_option_info(int sn, value_type* type, value_limit* limit, int* bytes));
COM_API_OVERRIDE(bool, get_value(int sn, set_opt_value, void* param));
COM_API_OVERRIDE(bool, get_value(int sn, void* data, int* len)); // get operation with in-parameter
COM_API_OVERRIDE(int, set_value(int sn, void* val));
COM_API_OVERRIDE(int, convert_image(SANE_ImageFormatConvert* conv));
COM_API_OVERRIDE(void, free_buffer(void* buf, int len));
@ -329,4 +341,4 @@ public:
// methods:
public:
int handle_device_event(int ev_code, void* data, unsigned int* len);
};
};

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff