doc_and_tools/tools/apps/hgjson/DlgTwain.cpp

887 lines
23 KiB
C++
Raw Permalink Normal View History

2023-02-24 08:55:03 +00:00
// DlgInput.cpp : implementation file
//
#include "stdafx.h"
#include "hgjson.h"
#include "DlgTwain.h"
#include "afxdialogex.h"
#include <algorithm>
#include <file/file_util.h>
#include <coding/coding.h>
namespace util
{
enum
{
BOM_ANSI,
BOM_UTF8,
BOM_UNICODE,
};
static INTER_MODULE_CALLBACK(got_str)
{
*(std::string*)param += std::string(data, len);
return inter_module_data::SET_RESULT_CONTINUE;
}
static INTER_MODULE_CALLBACK(got_wstr)
{
*(std::wstring*)param += std::wstring((const wchar_t*)data, len / 2);
return inter_module_data::SET_RESULT_CONTINUE;
}
static bool is_space(wchar_t ch)
{
return ch == L' ' || ch == L'\t' || ch == L'\r' || ch == L'\n';
}
static bool is_var_char(wchar_t ch, bool allow_num)
{
return ch == L'_' ||
(ch >= L'0' && ch <= L'9' && allow_num) ||
(ch >= L'a' && ch <= L'z') ||
(ch >= L'A' && ch <= L'Z');
}
static bool skip_space(const wchar_t** str)
{
const wchar_t* bgn = *str;
while (is_space(str[0][0]))
(*str)++;
return *str > bgn;
}
static void to_line_head(const wchar_t** str)
{
while (str[0][0] != L'\n')
(*str)--;
}
static void erase_multiline_comment(std::wstring& cont)
{
for (int i = 0; i < cont.length(); ++i)
{
if (cont[i] == L'/')
{
if (cont[i + 1] == L'/')
{
std::wstring val(L"");
int next = 0;
coding_util::pick_line(cont.c_str() + i, got_wstr, &val, &next);
i += next;
}
else if (cont[i + 1] == L'*')
{
size_t pos = cont.find(L"*/", i + 2);
if (pos++ == std::wstring::npos)
{
cont.erase(i);
break;
}
else
cont.erase(i, pos - i + 1);
}
}
}
}
static void transform_hz(std::wstring& hz)
{
int prev = -1;
std::string inner("");
for (int i = 0; i < hz.length() - 3; ++i)
{
if (hz[i] == L'\\')
{
if (hz[i + 1] == L'u')
{
}
else if (hz[i + 1] == L'x')
{
}
else if (hz[i + 1] >= L'0' && hz[i + 1] <= L'7')
{
if (hz[i + 2] >= L'0' && hz[i + 2] <= L'7' &&
hz[i + 3] >= L'0' && hz[i + 3] <= L'7')
{
if (prev == -1)
prev = i;
char ch = (hz[i + 1] - L'0') * 64 + (hz[i + 2] - L'0') * 8 + hz[i + 3] - L'0';
inner.append(1, ch);
i += 3;
}
}
}
else
{
if (inner.length())
{
std::wstring trans(L"");
coding_util::utf8_2_unicode(inner.c_str(), got_wstr, &trans);
hz.replace(prev, i - prev, trans);
i = prev + trans.length();
}
prev = -1;
inner = "";
}
}
if (inner.length())
{
std::wstring trans(L"");
coding_util::utf8_2_unicode(inner.c_str(), got_wstr, &trans);
hz.replace(prev, hz.length() - prev, trans);
}
}
static std::wstring now(void)
{
time_t t = time(NULL);
tm* pt = localtime(&t);
wchar_t buf[40] = { 0 };
swprintf_s(buf, _countof(buf) - 1, L"%04d-%02d-%02d %02d:%02d:%02d",
pt->tm_year + 1900, pt->tm_mon + 1, pt->tm_mday, pt->tm_hour, pt->tm_min, pt->tm_sec);
return buf;
}
static std::wstring get_text(HWND wnd)
{
int len = GetWindowTextLengthW(wnd);
wchar_t * buf = new wchar_t[len + 128];
std::wstring ret(L"");
len = ::GetWindowTextW(wnd, buf, len + 20);
buf[len] = 0;
ret = buf;
delete[] buf;
return std::move(ret);
}
static void append_log(const wchar_t* log, HWND edit, bool scroll_last)
{
std::wstring text(std::move(get_text(edit))), cur(now() + L": "), str(log), space(L"");
size_t pos = str.find(L"\r\n");
space.append(cur.length() * 2, L' ');
while (pos != std::wstring::npos && pos < str.length() - 2)
{
str.insert(pos + 2, space);
pos = str.find(L"\r\n", pos + space.length() + 2);
}
text += cur + str;
::SetWindowTextW(edit, text.c_str());
if (scroll_last)
::SendMessage(edit, EM_LINESCROLL, 0, ::SendMessageW(edit, EM_GETLINECOUNT, 0, 0));
else
::SendMessageW(edit, EM_LINESCROLL, 0, (LPARAM)::GetPropW(edit, L"stop_line"));
}
static std::wstring load_file(const wchar_t* file, int *bom)
{
std::wstring cont(L"");
std::string raw("");
file_util::load_file(file, got_str, &raw);
if (raw.empty())
return false;
if (bom)
*bom = coding_util::bom::is_unicode(raw.c_str(), NULL) ? BOM_UNICODE : (coding_util::bom::is_utf8(raw.c_str()) ? BOM_UTF8 : BOM_ANSI);
coding_util::bom::to_unicode(raw.c_str(), raw.length(), got_wstr, &cont);
return std::move(cont);
}
static bool save_file(const wchar_t* file, const wchar_t* cont, int bom, std::wstring* bak = NULL)
{
std::string raw("");
if (bom == BOM_UNICODE)
coding_util::bom::from_unicode(cont, lstrlenW(cont) * 2, got_str, &raw);
else if (bom == BOM_UTF8)
{
std::string utf8("");
coding_util::unicode_2_utf8(cont, got_str, &utf8);
coding_util::bom::from_utf8(utf8.c_str(), utf8.length(), got_str, &raw);
}
else
coding_util::unicode_2_ansi(cont, got_str, &raw);
if (bak)
{
*bak = file;
*bak += L".bak";
file_util::force_copy_file(file, bak->c_str());
}
return file_util::save_2_file(raw.c_str(), raw.length(), file) == 0;
}
std::string u2a(const wchar_t* u, bool to_utf8 = false)
{
std::string a("");
if (to_utf8)
coding_util::unicode_2_utf8(u, got_str, &a);
else
coding_util::unicode_2_ansi(u, got_str, &a);
return std::move(a);
}
std::wstring a2u(const char* a, bool from_utf8 = false)
{
std::wstring u(L"");
if (from_utf8)
coding_util::utf8_2_unicode(a, got_wstr, &u);
else
coding_util::ansi_2_unicode(a, got_wstr, &u);
return std::move(u);
}
static std::wstring get_sane_opt_title(const wchar_t* key, const std::wstring& cont)
{
size_t pos = cont.find(key);
std::wstring title(L"");
while (pos != std::wstring::npos)
{
if (pos)
{
int check = pos - 1;
if (cont[check] == L' ' || cont[check] == L'\t')
{
const wchar_t* l = cont.c_str() + check;
to_line_head(&l);
skip_space(&l);
if (wcsstr(l, L"#define") == l)
{
l += 7;
skip_space(&l);
if (wcsstr(l, key) == l)
{
l += lstrlenW(key);
if (skip_space(&l) && *l++ == L'\"')
{
while (*l != L'\r' && *l != L'\n' && *l != L'\"' && *l != 0)
title.append(1, *l++);
transform_hz(title);
break;
}
}
}
}
}
pos += lstrlenW(key);
pos = cont.find(key, pos);
}
return std::move(title);
}
static void get_sane_opts(const wchar_t* file, std::vector<SANEOPT>& opts)
{
std::wstring tf(file), name(L"\r\n"), title(L"\r\n")
, pre_n(L"SANE_STD_OPT_NAME_"), pre_t(L"OPTION_TITLE_"), define(L"#define")
, line(L""), val(L"");
std::string bom("");
SANEOPT opt;
int off = 0, next = 0;
STR_PARENT_FOLDER(tf);
tf += L"\\sane_option_definitions.h";
STR_TO_ABSOLUTE_PATH(tf);
file_util::load_file(file, got_str, &bom);
if (bom.empty())
return;
coding_util::bom::to_unicode(bom.c_str(), bom.length(), got_wstr, &name);
erase_multiline_comment(name);
bom = "";
file_util::load_file(tf.c_str(), got_str, &bom);
if (bom.empty())
return;
coding_util::bom::to_unicode(bom.c_str(), bom.length(), got_wstr, &title);
bom = "";
erase_multiline_comment(title);
// search ...
coding_util::pick_line(name.c_str(), got_wstr, &line, &next);
while (line.length() || next)
{
size_t pos = line.find(define);
if (pos == 0 && line.length() > define.length() && is_space(line[define.length()]))
{
const wchar_t* str = line.c_str() + define.length(), * bgn = NULL;;
util::skip_space(&str);
if (wcsstr(str, pre_n.c_str()) == str)
{
bgn = str;
str += pre_n.length();
while (is_var_char(*str, true))
str++;
opt.name_key = std::wstring(bgn, str - bgn);
if (util::skip_space(&str) && *str++ == L'\"')
{
bgn = str;
while (*str != L'\"')
str++;
opt.name = std::wstring(bgn, str - bgn);
str++;
util::skip_space(&str);
if (wcsstr(str, L"//") == str)
{
str += 2;
util::skip_space(&str);
if (wcsstr(str, pre_t.c_str()) == str)
{
bgn = str;
str += pre_t.length();
while (is_var_char(*str, true))
str++;
opt.title_key = std::wstring(bgn, str - bgn);
opt.title = std::move(get_sane_opt_title(opt.title_key.c_str(), title));
opts.push_back(opt);
}
}
}
}
}
off += next;
line = L"";
coding_util::pick_line(name.c_str() + off, got_wstr, &line, &next);
}
}
static bool pick_option_id_function(std::wstring& code, int* off = NULL, const wchar_t* api_decl = L"scanner::init_options_id(void)", const wchar_t* ret = L"int")
{
std::wstring api(api_decl);
size_t pos = code.find(api);
const wchar_t* l = NULL;
while (pos != std::wstring::npos)
{
l = code.c_str() + pos;
to_line_head(&l);
skip_space(&l);
if (wcsstr(l, ret) == l)
{
l += lstrlenW(ret);
if (skip_space(&l))
{
if (wcsstr(l, api.c_str()) == l)
{
int bgn = 0, end = 0;
coding_util::pick_value(l, L"{", L"}", &bgn, &end);
if (end > bgn)
{
api = std::wstring(l + bgn, end - bgn + 1);
if (off)
*off = l + bgn - code.c_str();
code = std::move(api);
return true;
}
}
}
}
pos += api.length();
pos = code.find(api, pos);
}
return false;
}
static bool pick_twain_ex_enum(std::wstring& code, int* start = NULL)
{
// enum CapTypeEx : unsigned short {
size_t pos = code.find(L"enum");
while (pos != std::wstring::npos)
{
const wchar_t* l = code.c_str() + pos;
to_line_head(&l);
skip_space(&l);
if (wcsstr(l, L"enum") == l)
{
l += 4;
if (skip_space(&l))
{
if (wcsstr(l, L"CapTypeEx") == l)
{
int bgn = 0, end = 0;
coding_util::pick_value(l, L"{", L"}", &bgn, &end);
if (start)
*start = l + bgn - code.c_str();
code = std::move(std::wstring(l + bgn, end - bgn + 1));
return true;
}
}
}
pos = code.find(L"enum", pos + 4);
}
return false;
}
static bool get_twain_id(const std::wstring& idtext, std::vector<OPTUSED>& used)
{
std::wstring pre(L"CAP_EX_SANE_"), line(L""), key(L"");
OPTUSED ou;
int off = 0, next = 0, id = 0x8801;
coding_util::pick_line(idtext.c_str(), got_wstr, &line, &next);
while (!line.empty() || next)
{
const wchar_t* bgn = line.c_str(), * l = bgn;
skip_space(&l);
if (wcsstr(l, pre.c_str()) == l)
{
l += pre.length();
bgn = l;
while (is_var_char(*l, true))
l++;
key = std::wstring(bgn, l - bgn);
ou.id_key = "";
coding_util::unicode_2_ansi(key.c_str(), got_str, &ou.id_key);
ou.id = id++;
used.push_back(ou);
}
off += next;
line.clear();
coding_util::pick_line(idtext.c_str() + off, got_wstr, &line, &next);
}
std::sort(used.begin(), used.end());
return true;
}
static void get_used_opts(const wchar_t* file, std::vector<OPTUSED>& used)
{
std::wstring key(L""), id(L""), idf(file), line(L""), pre_nk(L"SANE_STD_OPT_NAME_"), pre_ik(L"CAP_EX_SANE_"), setoid(L"SET_OPT_ID(");
std::string bom("");
OPTUSED ou;
int off = 0, next = 0;
STR_PARENT_FOLDER(idf);
idf += L"\\..\\..\\code_twain\\twain\\twain\\huagaods.cpp";
STR_TO_ABSOLUTE_PATH(idf);
file_util::load_file(file, got_str, &bom);
if (bom.empty())
return;
coding_util::bom::to_unicode(bom.c_str(), bom.length(), got_wstr, &key);
erase_multiline_comment(key);
bom = "";
file_util::load_file(idf.c_str(), got_str, &bom);
if (bom.empty())
return;
coding_util::bom::to_unicode(bom.c_str(), bom.length(), got_wstr, &id);
erase_multiline_comment(id);
get_twain_id(id, used);
if (!pick_option_id_function(key) || !pick_twain_ex_enum(id))
return;
bom = "";
coding_util::pick_line(key.c_str(), got_wstr, &line, &next);
while (!line.empty() || next > 0)
{
const wchar_t* l = line.c_str(), * bgn = NULL;
skip_space(&l);
if (wcsstr(l, L"else") == l)
{
l += 4;
skip_space(&l);
}
if (wcsstr(l, setoid.c_str()) == l)
{
l += setoid.length();
bgn = l;
if (is_var_char(*l++, false))
{
while (is_var_char(*l, true))
l++;
ou.id_key = "";
coding_util::unicode_2_ansi(std::wstring(bgn, l - bgn).c_str(), got_str, &ou.id_key);
skip_space(&l);
if (*l++ == L',')
{
skip_space(&l);
bgn = l;
if (is_var_char(*l++, false))
{
while (is_var_char(*l, true))
l++;
ou.name_key = std::wstring(bgn, l - bgn);
std::vector<OPTUSED>::iterator it = std::find(used.begin(), used.end(), ou.id_key.c_str());
if (it != used.end())
it->name_key = std::move(L"SANE_STD_OPT_NAME_" + ou.name_key);
}
}
}
}
off += next;
line = L"";
coding_util::pick_line(key.c_str() + off, got_wstr, &line, &next);
}
}
static bool add_2_huagaods_cpp(const wchar_t* file, const SANEOPT& sane, const OPTUSED& twain, std::wstring* msg)
{
int off = 0, next = 0, bom = BOM_ANSI;
std::wstring cont(std::move(load_file(file, &bom))), line(L""), lead(L"CAP_EX_SANE_");
if (cont.empty())
{
if (msg)
*msg = L"File 'huagaods.cpp' is not found or empty.";
return false;
}
line = cont;
if (pick_twain_ex_enum(line, &off))
{
size_t pos = line.rfind(L',');
const wchar_t* l = line.c_str() + pos, * bgn = NULL;
to_line_head(&l);
bgn = ++l;
skip_space(&l);
std::wstring en(bgn, l - bgn);
en += lead + a2u(twain.id_key.c_str()) + L",\t\t// " + now() + L" " + sane.title;
lead = line;
lead.insert(pos + 1, L"\r\n" + en);
cont.replace(off, line.length(), lead);
line = cont;
if (pick_option_id_function(line, &off, L"huagao_ds::init_support_caps_ex(void)", L"void"))
{
pos = line.rfind(L';');
l = line.c_str() + pos;
to_line_head(&l);
l++;
bgn = l;
skip_space(&l);
en = std::wstring(bgn, l - bgn);
en += L"ADD_SANE_CAP(";
en += a2u(twain.id_key.c_str());
en += L");\r\n";
lead = line + en;
cont.replace(off, line.length(), lead);
if (save_file(file, cont.c_str(), bom, &line))
{
if (msg)
*msg += std::wstring(L"Changed: ") + file + L"\r\n";
return true;
}
else if (msg)
*msg = L"Failed to save changes into file 'huagaods.cpp'.";
if (file_util::is_file_existing(line.c_str()))
file_util::force_move_file(line.c_str(), file);
}
else if (msg)
{
*msg = L"Failed to find function 'huagao_ds::init_support_caps_ex(void)' in huagaods.cpp.";
}
}
else if (msg)
{
*msg = L"Failed to find 'enum CapTypeEx' in huagaods.cpp.";
}
return false;
}
static bool add_2_scanner_codes(const wchar_t* cpp, const SANEOPT& sane, const OPTUSED& twain, std::wstring* msg)
{
int bom_c = BOM_ANSI, bom_h = BOM_ANSI;
std::wstring hf(cpp), code_c(load_file(cpp, &bom_c)), code_h(L""), tag(L"// SANE options ID ..."), val(L""), hbak(L""), cbak(L"");
size_t pos = hf.rfind(L'.');
const wchar_t *l = NULL, *bgn = NULL;
if (code_c.empty())
{
if (msg)
*msg = std::wstring(L"File '") + cpp + L"' is not found or empty.";
return false;
}
hf.erase(pos);
hf += L".h";
code_h = std::move(load_file(hf.c_str(), &bom_h));
if (code_h.empty())
{
if (msg)
*msg = std::wstring(L"File '") + hf + L"' is not found or empty.";
return false;
}
pos = code_h.find(tag);
if (pos == std::wstring::npos)
{
if (msg)
*msg = L"Cannot find tag '" + tag + L"' in file " + hf;
return false;
}
bgn = l = code_h.c_str() + pos;
to_line_head(&bgn);
bgn++;
val = L"\r\n" + std::wstring(bgn, l - bgn) + L"SANE_OPTION_ID(" + a2u(twain.id_key.c_str()) + L");";
code_h.insert(pos + tag.length(), val + L"\t\t// " + now() + L" " + sane.title);
if (save_file(hf.c_str(), code_h.c_str(), bom_h, &hbak))
{
code_h.clear();
pos = code_c.find(L"SANE_OPTION_ID_IMPLEMENT(");
if (pos != std::wstring::npos)
{
int off = 0;
val = L"SANE_OPTION_ID_IMPLEMENT(" + a2u(twain.id_key.c_str()) + L")\r\n";
code_c.insert(pos, val);
code_h = code_c;
if (pick_option_id_function(code_h, &off))
{
pos = code_h.find(L"op_id++;");
if (pos != std::wstring::npos)
{
l = bgn = code_h.c_str() + pos;
to_line_head(&bgn);
bgn++;
tag = sane.name_key;
if (tag.find(L"SANE_STD_OPT_NAME_") == 0)
tag.erase(0, lstrlenW(L"SANE_STD_OPT_NAME_"));
val = std::wstring(bgn, l - bgn) + L"else SET_OPT_ID(" + a2u(twain.id_key.c_str()) + L", " + tag + L", extension_none)\r\n";
off += bgn - code_h.c_str();
code_c.insert(off, val);
if (save_file(cpp, code_c.c_str(), bom_c, &cbak))
{
std::wstring s2t(hf);
STR_PARENT_FOLDER(s2t);
s2t += L"\\s2t_api.h";
code_h = std::move(load_file(s2t.c_str(), &bom_h));
if (!code_h.empty())
{
tag = L"// SANE options ID ...";
pos = code_h.find(tag);
if (pos == std::wstring::npos)
{
if (msg)
*msg = L"Cannot find tag '// SANE options ID ...' in file " + s2t;
return false;
}
bgn = l = code_h.c_str() + pos;
to_line_head(&bgn);
bgn++;
val = L"\r\n" + std::wstring(bgn, l - bgn) + L"SANE_OPTION_ID_API(" + a2u(twain.id_key.c_str()) + L");";
code_h.insert(pos + tag.length(), val + L"\t\t// " + now() + L" " + sane.title);
if (save_file(s2t.c_str(), code_h.c_str(), bom_h, &val))
{
if (msg)
*msg += std::wstring(L"Changed: ") + hf + L"\r\n" + L"Changed: " + cpp + L"\r\nChanged: " + s2t + L"\r\n";
return true;
}
else if (msg)
*msg = L"Failed to save changes into file: " + s2t;
if (file_util::is_file_existing(val.c_str()))
file_util::force_move_file(val.c_str(), s2t.c_str());
}
else if (msg)
*msg = std::wstring(L"File '") + s2t + L"' is not found or empty.";
}
else if (msg)
{
*msg = L"Failed to save changes into file: " + std::wstring(cpp);
}
if (file_util::is_file_existing(cbak.c_str()))
file_util::force_move_file(cbak.c_str(), cpp);
}
else if (msg)
{
*msg = L"Failed to find function 'scanner::init_options_id(void) - op_id++' in file: " + std::wstring(cpp);
}
}
else if (msg)
{
*msg = L"Failed to find function 'scanner::init_options_id(void)' in file: " + std::wstring(cpp);
}
}
else if (msg)
{
*msg = L"Failed to find 'SANE_OPTION_ID_IMPLEMENT' in file: " + std::wstring(cpp);
}
}
else if (msg)
{
*msg = L"Failed to save changes into file: " + hf;
}
if (file_util::is_file_existing(hbak.c_str()))
file_util::force_move_file(hbak.c_str(), hf.c_str());
return false;
}
}
// CDlgTwain dialog
IMPLEMENT_DYNAMIC(CDlgTwain, CDialogEx)
CDlgTwain::CDlgTwain(CWnd* pParent /*=NULL*/)
: CDialogEx(CDlgTwain::IDD, pParent)
{
}
CDlgTwain::~CDlgTwain()
{
}
void CDlgTwain::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_COMBO1, sane_);
}
BOOL CDlgTwain::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
return TRUE; // return TRUE unless you set the focus to a control
}
void CDlgTwain::on_sln_path_changed(void)
{
GetDlgItem(IDC_BUTTON_BROWSE)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(FALSE);
GetDlgItem(IDC_COMBO1)->EnableWindow(FALSE);
util::append_log(L"parsing SANE attributes ...\r\n", GetDlgItem(IDC_EDIT2)->m_hWnd, true);
sane_.ResetContent();
std::wstring path(util::get_text(GetDlgItem(IDC_EDIT1)->m_hWnd));
opts_.clear();
used_.clear();
STR_PARENT_FOLDER(path);
path += L"\\..\\..\\";
STR_TO_ABSOLUTE_PATH(path);
root_ = path;
util::get_sane_opts((path + L"sdk\\include\\sane\\sane_ex.h").c_str(), opts_);
if (opts_.size() == 0)
{
::MessageBoxW(m_hWnd, L"û<EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD>SANE<EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD>", L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", MB_OK | MB_ICONSTOP);
return;
}
for (auto& v : opts_)
sane_.AddString((v.title + L" (" + v.name + L")").c_str());
GetDlgItem(IDC_BUTTON_BROWSE)->EnableWindow(TRUE);
GetDlgItem(IDC_COMBO1)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON_ADD)->EnableWindow(TRUE);
util::append_log((L"Found " + std::to_wstring(opts_.size()) + L" options\r\n").c_str(), GetDlgItem(IDC_EDIT2)->m_hWnd, true);
// find used ...
util::get_used_opts((path + L"code_twain\\sane\\scanner.cpp").c_str(), used_);
}
void CDlgTwain::synchronize_opt(const SANEOPT& opt)
{
OPTUSED ou;
std::wstring pre(L"SANE_STD_OPT_NAME_"), key(L""), msg(L"");
if (used_.size())
ou.id = used_[used_.size() - 1].id + 1;
else
ou.id = 0x8801;
ou.name_key = opt.name_key;
if (ou.name_key.find(pre) == 0)
key = ou.name_key.substr(pre.length());
else
key = ou.name_key;
std::transform(key.begin(), key.end(), key.begin(), tolower);
coding_util::unicode_2_ansi(key.c_str(), util::got_str, &ou.id_key);
std::vector<OPTUSED>::iterator it = std::find(used_.begin(), used_.end(), ou.id_key.c_str());
if (it != used_.end())
{
::MessageBoxW(m_hWnd, (opt.title + L" already synchronized into TWAIN.").c_str(), L"Error", MB_OK | MB_ICONINFORMATION);
return;
}
if (util::add_2_huagaods_cpp((root_ + L"code_twain\\twain\\twain\\huagaods.cpp").c_str(), opt, ou, &msg) &&
util::add_2_scanner_codes((root_ + L"code_twain\\sane\\scanner.cpp").c_str(), opt, ou, &msg))
{
used_.push_back(ou);
std::wstring tips(L"Added New TWAIN extended ATTR: CAP_EX_SANE_");
wchar_t hex[40] = { 0 };
coding_util::ansi_2_unicode(ou.id_key.c_str(), util::got_wstr, &tips);
swprintf_s(hex, _countof(hex) - 1, L" (ID: 0x%04x) - ", ou.id);
tips += hex + opt.title + L"\r\n";
util::append_log(tips.c_str(), GetDlgItem(IDC_EDIT2)->m_hWnd, true);
}
util::append_log(msg.c_str(), GetDlgItem(IDC_EDIT2)->m_hWnd, true);
}
BEGIN_MESSAGE_MAP(CDlgTwain, CDialogEx)
ON_BN_CLICKED(IDC_BUTTON_BROWSE, &CDlgTwain::OnBnClickedButtonBrowse)
ON_BN_CLICKED(IDC_BUTTON_ADD, &CDlgTwain::OnBnClickedButtonAdd)
END_MESSAGE_MAP()
// CDlgTwain message handlers
void CDlgTwain::OnBnClickedButtonBrowse()
{
// TODO: <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>ӿؼ<D3BF>֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
file_util::PATHFILE path = { 0 };
if (file_util::browser_file(m_hWnd, &path, L"Solution File(*.sln)\0\0"))
{
::SetDlgItemTextW(m_hWnd, IDC_EDIT1, path.path);
on_sln_path_changed();
}
}
void CDlgTwain::OnBnClickedButtonAdd()
{
// TODO: <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>ӿؼ<D3BF>֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::wstring text(util::get_text(sane_.m_hWnd));
std::string ansi("");
size_t pos = text.rfind(L'(');
if (pos++ == std::wstring::npos)
{
::MessageBoxW(m_hWnd, L"Invalid option name! (lost '()')", L"Error", MB_OK | MB_ICONSTOP);
return;
}
text.erase(0, pos);
pos = text.find(L")");
if (pos != std::wstring::npos)
text.erase(pos);
if (text.empty())
{
::MessageBoxW(m_hWnd, L"Invalid option name! (empty)", L"Error", MB_OK | MB_ICONSTOP);
return;
}
coding_util::unicode_2_ansi(text.c_str(), util::got_str, &ansi);
pos = sane_.GetCurSel();
synchronize_opt(opts_[pos]);
}