调整组件名称,增加设置界面
This commit is contained in:
parent
eec6290cf4
commit
9ce97e3061
|
@ -10,96 +10,19 @@
|
||||||
#define WM_IMAGE_RECEIVED WM_USER + 2
|
#define WM_IMAGE_RECEIVED WM_USER + 2
|
||||||
#define WM_SCAN_FINISHED WM_USER + 3 // WPARAM: std::string* msg; LPARAM: boo err
|
#define WM_SCAN_FINISHED WM_USER + 3 // WPARAM: std::string* msg; LPARAM: boo err
|
||||||
|
|
||||||
ATOM dlg_indicator::indicator_class_atom = 0;
|
|
||||||
std::wstring dlg_indicator::handle_name = L"dlg_indicator_prop_handle";
|
|
||||||
std::wstring dlg_indicator::indicator_class_name = L"dlg_indicator_class";
|
|
||||||
extern HMODULE g_my_inst;
|
|
||||||
|
|
||||||
dlg_indicator::dlg_indicator() : hwnd_(NULL), papers_(0), images_(0), notify_(NULL), notify_param_(NULL), parent_(NULL), err_(false)
|
dlg_indicator::dlg_indicator(HWND parent) : dlg_base(parent, IDD_INDICATOR)
|
||||||
|
, papers_(0), images_(0), notify_(NULL), notify_param_(NULL), err_(false)
|
||||||
{
|
{
|
||||||
HANDLE wait = CreateEvent(NULL, TRUE, FALSE, NULL);
|
create();
|
||||||
#ifdef USE_SOLE_WIN_THREAD
|
SetWindowLongW(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE, GetWindowLong(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE) | SS_OWNERDRAW);
|
||||||
thread_.reset(new std::thread(&dlg_indicator::create, this, wait));
|
|
||||||
#else
|
|
||||||
create(wait);
|
|
||||||
#endif
|
|
||||||
WaitForSingleObject(wait, INFINITE);
|
|
||||||
CloseHandle(wait);
|
|
||||||
}
|
}
|
||||||
dlg_indicator::~dlg_indicator()
|
dlg_indicator::~dlg_indicator()
|
||||||
{
|
{
|
||||||
#ifdef USE_SOLE_WIN_THREAD
|
|
||||||
if (IsWindow(hwnd_))
|
|
||||||
PostMessage(hwnd_, WM_QUIT, 0, 0);
|
|
||||||
|
|
||||||
if (thread_.get() && thread_->joinable())
|
|
||||||
thread_->join();
|
|
||||||
thread_.reset();
|
|
||||||
#else
|
|
||||||
if (IsWindow(hwnd_))
|
|
||||||
DestroyWindow(hwnd_);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL CALLBACK dlg_indicator::dlg_indicator_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
|
|
||||||
{
|
|
||||||
if (msg == WM_INITDIALOG)
|
|
||||||
{
|
|
||||||
dlg_indicator *obj = (dlg_indicator*)lp;
|
|
||||||
|
|
||||||
SetPropW(hwnd, dlg_indicator::handle_name.c_str(), (HANDLE)obj);
|
BOOL dlg_indicator::handle_message(UINT msg, WPARAM wp, LPARAM lp)
|
||||||
}
|
|
||||||
|
|
||||||
dlg_indicator* obj = (dlg_indicator*)GetPropW(hwnd, dlg_indicator::handle_name.c_str());
|
|
||||||
BOOL handled = FALSE, ret = FALSE;
|
|
||||||
|
|
||||||
if (obj)
|
|
||||||
ret = obj->handle_msg(msg, wp, lp);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
ATOM dlg_indicator::register_indicator_class(void)
|
|
||||||
{
|
|
||||||
WNDCLASSEXW wcex;
|
|
||||||
|
|
||||||
wcex.cbSize = sizeof(WNDCLASSEXW);
|
|
||||||
wcex.style = WS_POPUP;
|
|
||||||
wcex.lpfnWndProc = (WNDPROC)dlg_indicator::dlg_indicator_proc;
|
|
||||||
wcex.cbClsExtra = 0;
|
|
||||||
wcex.cbWndExtra = 0;
|
|
||||||
wcex.hInstance = g_my_inst;
|
|
||||||
wcex.hIcon = NULL;
|
|
||||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
||||||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
|
||||||
wcex.lpszMenuName = NULL;
|
|
||||||
wcex.lpszClassName = dlg_indicator::indicator_class_name.c_str();
|
|
||||||
wcex.hIconSm = NULL;
|
|
||||||
|
|
||||||
return RegisterClassExW(&wcex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dlg_indicator::create(HANDLE wait)
|
|
||||||
{
|
|
||||||
MSG msg = { 0 };
|
|
||||||
BOOL ret = TRUE;
|
|
||||||
|
|
||||||
hwnd_ = CreateDialogParamW(g_my_inst, MAKEINTRESOURCE(IDD_INDICATOR), NULL, &dlg_indicator::dlg_indicator_proc, (LPARAM)this);
|
|
||||||
SetWindowLongW(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE, GetWindowLong(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE) | SS_OWNERDRAW);
|
|
||||||
SetEvent(wait);
|
|
||||||
|
|
||||||
#ifdef USE_SOLE_WIN_THREAD
|
|
||||||
while ((ret = GetMessage(&msg, NULL, 0, 0)))
|
|
||||||
{
|
|
||||||
if (ret == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
TranslateMessage(&msg);
|
|
||||||
DispatchMessage(&msg);
|
|
||||||
}
|
|
||||||
DestroyWindow(hwnd_);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
BOOL dlg_indicator::handle_msg(UINT msg, WPARAM wp, LPARAM lp)
|
|
||||||
{
|
{
|
||||||
wchar_t text[40] = { 0 };
|
wchar_t text[40] = { 0 };
|
||||||
BOOL ret = TRUE;
|
BOOL ret = TRUE;
|
||||||
|
@ -110,6 +33,7 @@ BOOL dlg_indicator::handle_msg(UINT msg, WPARAM wp, LPARAM lp)
|
||||||
swprintf_s(text, _countof(text) - 1, L"%u", papers_);
|
swprintf_s(text, _countof(text) - 1, L"%u", papers_);
|
||||||
SetDlgItemTextW(hwnd_, IDC_EDIT_IMAGE, text);
|
SetDlgItemTextW(hwnd_, IDC_EDIT_IMAGE, text);
|
||||||
SetDlgItemTextW(hwnd_, IDC_EDIT_PAPER, text);
|
SetDlgItemTextW(hwnd_, IDC_EDIT_PAPER, text);
|
||||||
|
UpdateWindow(hwnd_);
|
||||||
break;
|
break;
|
||||||
case WM_USB_PACKET_RECEIVED:
|
case WM_USB_PACKET_RECEIVED:
|
||||||
papers_++;
|
papers_++;
|
||||||
|
@ -206,17 +130,16 @@ HWND dlg_indicator::parent(void)
|
||||||
{
|
{
|
||||||
return parent_;
|
return parent_;
|
||||||
}
|
}
|
||||||
void dlg_indicator::show(HWND parent)
|
void dlg_indicator::show()
|
||||||
{
|
{
|
||||||
RECT rp, r;
|
RECT rp, r;
|
||||||
|
|
||||||
if (IsWindow(parent))
|
if (IsWindow(parent_))
|
||||||
GetWindowRect(parent, &rp);
|
GetWindowRect(parent_, &rp);
|
||||||
else
|
else
|
||||||
GetWindowRect(GetDesktopWindow(), &rp);
|
GetWindowRect(GetDesktopWindow(), &rp);
|
||||||
GetWindowRect(hwnd_, &r);
|
GetWindowRect(hwnd_, &r);
|
||||||
|
|
||||||
parent_ = parent;
|
|
||||||
rp.left += (rp.right - rp.left - (r.right - r.left)) / 2;
|
rp.left += (rp.right - rp.left - (r.right - r.left)) / 2;
|
||||||
rp.top += (rp.bottom - rp.top - (r.bottom - r.top)) / 2;
|
rp.top += (rp.bottom - rp.top - (r.bottom - r.top)) / 2;
|
||||||
SetWindowPos(hwnd_, HWND_TOPMOST, rp.left, rp.top, r.right - r.left, r.bottom - r.top, SWP_NOSIZE | SWP_SHOWWINDOW);
|
SetWindowPos(hwnd_, HWND_TOPMOST, rp.left, rp.top, r.right - r.left, r.bottom - r.top, SWP_NOSIZE | SWP_SHOWWINDOW);
|
||||||
|
|
|
@ -3,47 +3,31 @@
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "DlgPage.h"
|
||||||
|
|
||||||
// CDlgIndicator 对话框
|
// CDlgIndicator 对话框
|
||||||
//#define USE_SOLE_WIN_THREAD
|
|
||||||
|
|
||||||
#ifdef USE_SOLE_WIN_THREAD
|
class dlg_indicator : public dlg_base
|
||||||
#include <thread>
|
|
||||||
#include <memory>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class dlg_indicator
|
|
||||||
{
|
{
|
||||||
HWND hwnd_;
|
|
||||||
HWND parent_;
|
|
||||||
unsigned int papers_;
|
unsigned int papers_;
|
||||||
unsigned int images_;
|
unsigned int images_;
|
||||||
bool err_;
|
bool err_;
|
||||||
#ifdef USE_SOLE_WIN_THREAD
|
|
||||||
std::unique_ptr<std::thread> thread_;
|
|
||||||
#endif
|
|
||||||
void(__stdcall* notify_)(bool, void*);
|
void(__stdcall* notify_)(bool, void*);
|
||||||
void* notify_param_;
|
void* notify_param_;
|
||||||
|
|
||||||
static ATOM indicator_class_atom;
|
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
|
||||||
static std::wstring handle_name;
|
|
||||||
static std::wstring indicator_class_name;
|
|
||||||
static BOOL CALLBACK dlg_indicator_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
|
|
||||||
static ATOM register_indicator_class(void);
|
|
||||||
|
|
||||||
void create(HANDLE wait);
|
|
||||||
BOOL handle_msg(UINT msg, WPARAM wp, LPARAM lp);
|
|
||||||
void handle_command(WORD code, WORD id, HANDLE ctrl);
|
void handle_command(WORD code, WORD id, HANDLE ctrl);
|
||||||
void notify_over(void);
|
void notify_over(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
dlg_indicator();
|
dlg_indicator(HWND parent);
|
||||||
~dlg_indicator();
|
~dlg_indicator();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void set_quit_notify(void(__stdcall* notify)(bool cancel, void*), void* param);
|
void set_quit_notify(void(__stdcall* notify)(bool cancel, void*), void* param);
|
||||||
HWND window(void);
|
HWND window(void);
|
||||||
HWND parent(void);
|
HWND parent(void);
|
||||||
void show(HWND parent);
|
void show(void);
|
||||||
void hide(void);
|
void hide(void);
|
||||||
void notify_data_arrived(bool image);
|
void notify_data_arrived(bool image);
|
||||||
void notify_scan_over(const char* msg, bool err);
|
void notify_scan_over(const char* msg, bool err);
|
||||||
|
|
|
@ -0,0 +1,247 @@
|
||||||
|
// DlgIndicator.cpp: 实现文件
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "DlgPage.h"
|
||||||
|
#include "resource.h"
|
||||||
|
#include "scanned_img.h" // for local_trans
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// dlg_base 对话框
|
||||||
|
extern HMODULE g_my_inst;
|
||||||
|
|
||||||
|
std::wstring dlg_base::prop_name = L"dlg_base_object_prop_name";
|
||||||
|
|
||||||
|
dlg_base::dlg_base(HWND parent, UINT idd) : parent_(parent), hwnd_(NULL), idd_(idd)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
dlg_base::~dlg_base()
|
||||||
|
{
|
||||||
|
if(IsWindow(hwnd_))
|
||||||
|
DestroyWindow(hwnd_);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CALLBACK dlg_base::dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||||
|
{
|
||||||
|
if (msg == WM_INITDIALOG)
|
||||||
|
{
|
||||||
|
dlg_base* obj = (dlg_base*)lp;
|
||||||
|
|
||||||
|
SetPropW(hwnd, dlg_base::prop_name.c_str(), (HANDLE)obj);
|
||||||
|
obj->hwnd_ = hwnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
dlg_base *obj = (dlg_base*)GetPropW(hwnd, dlg_base::prop_name.c_str());
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
|
if (obj)
|
||||||
|
ret = obj->handle_message(msg, wp, lp);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dlg_base::get_max_size(SIZE& dst, const SIZE& src)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (dst.cx < src.cx)
|
||||||
|
{
|
||||||
|
dst.cx = src.cx;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (dst.cy < src.cy)
|
||||||
|
{
|
||||||
|
dst.cy = src.cy;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
bool dlg_base::get_max_size(SIZE& dst, int cx, int cy)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (dst.cx < cx)
|
||||||
|
{
|
||||||
|
dst.cx = cx;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (dst.cy < cy)
|
||||||
|
{
|
||||||
|
dst.cy = cy;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL dlg_base::handle_message(UINT msg, WPARAM wp, LPARAM lp)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
void dlg_base::on_font_changed(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void dlg_base::create(void)
|
||||||
|
{
|
||||||
|
hwnd_ = CreateDialogParamW(g_my_inst, MAKEINTRESOURCE(idd_), parent_, &dlg_base::dlg_proc, (LPARAM)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND dlg_base::hwnd(void)
|
||||||
|
{
|
||||||
|
return hwnd_;
|
||||||
|
}
|
||||||
|
void dlg_base::screen_2_client(LPRECT r)
|
||||||
|
{
|
||||||
|
POINT pt = { r->left, r->top };
|
||||||
|
|
||||||
|
ScreenToClient(hwnd_, &pt);
|
||||||
|
OffsetRect(r, pt.x - r->left, pt.y - r->top);
|
||||||
|
}
|
||||||
|
void dlg_base::client_2_screen(LPRECT r)
|
||||||
|
{
|
||||||
|
POINT pt = { r->left, r->top };
|
||||||
|
|
||||||
|
ClientToScreen(hwnd_, &pt);
|
||||||
|
OffsetRect(r, pt.x - r->left, pt.y - r->top);
|
||||||
|
}
|
||||||
|
HWND dlg_base::get_item(UINT id)
|
||||||
|
{
|
||||||
|
return GetDlgItem(hwnd_, id);
|
||||||
|
}
|
||||||
|
BOOL dlg_base::set_font(HFONT font)
|
||||||
|
{
|
||||||
|
BOOL ret = SendMessage(hwnd_, WM_SETFONT, (WPARAM)font, 1) == 0;
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
on_font_changed();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
HFONT dlg_base::get_font(void)
|
||||||
|
{
|
||||||
|
return (HFONT)SendMessage(hwnd_, WM_GETFONT, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// dlg_page 对话框
|
||||||
|
UINT dlg_page::dyn_id_base = 3000;
|
||||||
|
int dlg_page::gap_x = 20;
|
||||||
|
int dlg_page::gap_y = 12;
|
||||||
|
|
||||||
|
dlg_page::dlg_page(HWND parent, const wchar_t* name) : dlg_base(parent, IDD_PAGE), name_(name ? name : L""), ctrl_id_(0)
|
||||||
|
{
|
||||||
|
size_.cx = size_.cy = 0;
|
||||||
|
create();
|
||||||
|
refresh_font();
|
||||||
|
}
|
||||||
|
dlg_page::~dlg_page()
|
||||||
|
{}
|
||||||
|
|
||||||
|
BOOL dlg_page::handle_message(UINT msg, WPARAM wp, LPARAM lp)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
void dlg_page::on_font_changed(void)
|
||||||
|
{
|
||||||
|
refresh_font();
|
||||||
|
}
|
||||||
|
void dlg_page::refresh_font(void)
|
||||||
|
{
|
||||||
|
HFONT font = get_font();
|
||||||
|
LOGFONTW lf = { 0 };
|
||||||
|
|
||||||
|
GetObjectW(font, sizeof(lf), &lf);
|
||||||
|
font_size_.cx = lf.lfWidth;
|
||||||
|
font_size_.cy = lf.lfHeight < 0 ? -lf.lfHeight : lf.lfHeight;
|
||||||
|
}
|
||||||
|
bool dlg_page::create_control_bool(int sn, const SANE_Option_Descriptor* desc, void* cur_val)
|
||||||
|
{
|
||||||
|
std::wstring title(local_trans::a2u(desc->title, CP_UTF8));
|
||||||
|
bool ret = true;
|
||||||
|
bool now = *(SANE_Bool*)cur_val == SANE_TRUE ? true : false;
|
||||||
|
int w = title.length() * font_size_.cx + 18,
|
||||||
|
h = font_size_.cy;
|
||||||
|
HWND wnd = CreateWindowW(L"Button", L"check", WS_CHILD | WS_VISIBLE | WS_MAXIMIZEBOX, pos_.x, pos_.y, w, h, hwnd(), NULL, g_my_inst, NULL);
|
||||||
|
|
||||||
|
pos_.y += h + dlg_page::gap_y;
|
||||||
|
if (size_.cx < w)
|
||||||
|
size_.cx = w;
|
||||||
|
if (size_.cy < pos_.y)
|
||||||
|
size_.cy = pos_.y;
|
||||||
|
|
||||||
|
if (desc->cap & SANE_CAP_INACTIVE)
|
||||||
|
EnableWindow(wnd, FALSE);
|
||||||
|
ShowWindow(wnd, SW_SHOW);
|
||||||
|
if (now)
|
||||||
|
SendMessage(wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool dlg_page::create_control_int(int sn, const SANE_Option_Descriptor* desc, void* cur_val)
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool dlg_page::create_control_float(int sn, const SANE_Option_Descriptor* desc, void* cur_val)
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool dlg_page::create_control_string(int sn, const SANE_Option_Descriptor* desc, void* cur_val)
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool dlg_page::create_control_button(int sn, const SANE_Option_Descriptor* desc, void* cur_val)
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dlg_page::add_control(int sn, const SANE_Option_Descriptor* desc, void* cur_val)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int sane_type;
|
||||||
|
bool(dlg_page::* func)(int, const SANE_Option_Descriptor*, void*);
|
||||||
|
}creat[] = { {SANE_TYPE_BOOL, &dlg_page::create_control_bool}
|
||||||
|
, {SANE_TYPE_INT, &dlg_page::create_control_int}
|
||||||
|
, {SANE_TYPE_FIXED, &dlg_page::create_control_float}
|
||||||
|
, {SANE_TYPE_STRING, &dlg_page::create_control_string}
|
||||||
|
, {SANE_TYPE_BUTTON, &dlg_page::create_control_button}
|
||||||
|
};
|
||||||
|
for (int i = 0; i < _countof(creat); ++i)
|
||||||
|
{
|
||||||
|
if (creat[i].sane_type == desc->type)
|
||||||
|
{
|
||||||
|
ret = (this->*creat[i].func)(sn, desc, cur_val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
SIZE dlg_page::desired_size(void)
|
||||||
|
{
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
void dlg_page::show(void)
|
||||||
|
{
|
||||||
|
ShowWindow(hwnd_, SW_SHOW);
|
||||||
|
}
|
||||||
|
void dlg_page::hide(void)
|
||||||
|
{
|
||||||
|
ShowWindow(hwnd_, SW_HIDE);
|
||||||
|
}
|
||||||
|
const wchar_t* dlg_page::name(void)
|
||||||
|
{
|
||||||
|
return name_.c_str();
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <CommCtrl.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <sane/sane_ex.h>
|
||||||
|
#include <sane/sane_option_definitions.h>
|
||||||
|
|
||||||
|
// CDlgIndicator 对话框
|
||||||
|
#define WM_REFRESH_OPTION WM_USER + 111 // WPARAM: source option SN, LPARAM: unused now
|
||||||
|
|
||||||
|
extern HMODULE g_my_inst;
|
||||||
|
|
||||||
|
class dlg_base
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
HWND hwnd_;
|
||||||
|
HWND parent_;
|
||||||
|
UINT idd_;
|
||||||
|
|
||||||
|
static std::wstring prop_name;
|
||||||
|
static BOOL CALLBACK dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);
|
||||||
|
|
||||||
|
virtual BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp);
|
||||||
|
virtual void on_font_changed(void);
|
||||||
|
void create(void);
|
||||||
|
|
||||||
|
public:
|
||||||
|
dlg_base(HWND parent, UINT idd);
|
||||||
|
virtual ~dlg_base();
|
||||||
|
|
||||||
|
static bool get_max_size(SIZE& dst, const SIZE& src); // return whether changed dst
|
||||||
|
static bool get_max_size(SIZE& dst, int cx, int cy); // return whether changed dst
|
||||||
|
|
||||||
|
public:
|
||||||
|
HWND hwnd(void);
|
||||||
|
void screen_2_client(LPRECT r);
|
||||||
|
void client_2_screen(LPRECT r);
|
||||||
|
HWND get_item(UINT id);
|
||||||
|
BOOL set_font(HFONT font);
|
||||||
|
HFONT get_font(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
class dlg_page : public dlg_base
|
||||||
|
{
|
||||||
|
std::wstring name_;
|
||||||
|
SIZE size_;
|
||||||
|
SIZE font_size_;
|
||||||
|
UINT ctrl_id_;
|
||||||
|
POINT pos_;
|
||||||
|
|
||||||
|
static UINT dyn_id_base;
|
||||||
|
static int gap_x;
|
||||||
|
static int gap_y;
|
||||||
|
|
||||||
|
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
|
||||||
|
void on_font_changed(void) override;
|
||||||
|
void refresh_font(void);
|
||||||
|
bool create_control_bool(int sn, const SANE_Option_Descriptor* desc, void* cur_val);
|
||||||
|
bool create_control_int(int sn, const SANE_Option_Descriptor* desc, void* cur_val);
|
||||||
|
bool create_control_float(int sn, const SANE_Option_Descriptor* desc, void* cur_val);
|
||||||
|
bool create_control_string(int sn, const SANE_Option_Descriptor* desc, void* cur_val);
|
||||||
|
bool create_control_button(int sn, const SANE_Option_Descriptor* desc, void* cur_val);
|
||||||
|
|
||||||
|
public:
|
||||||
|
dlg_page(HWND parent, const wchar_t* name);
|
||||||
|
~dlg_page();
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool add_control(int sn, const SANE_Option_Descriptor* desc, void* cur_val);
|
||||||
|
SIZE desired_size(void);
|
||||||
|
void show(void);
|
||||||
|
void hide(void);
|
||||||
|
const wchar_t* name(void);
|
||||||
|
};
|
|
@ -0,0 +1,324 @@
|
||||||
|
// DlgIndicator.cpp: 实现文件
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "DlgSetting.h"
|
||||||
|
#include "resource.h"
|
||||||
|
#include "scanned_img.h" // for local_trans
|
||||||
|
#include "DlgPage.h"
|
||||||
|
|
||||||
|
// CDlgIndicator 对话框
|
||||||
|
#define WM_USB_PACKET_RECEIVED WM_USER + 1
|
||||||
|
#define WM_IMAGE_RECEIVED WM_USER + 2
|
||||||
|
#define WM_SCAN_FINISHED WM_USER + 3 // WPARAM: std::string* msg; LPARAM: boo err
|
||||||
|
|
||||||
|
|
||||||
|
static IMPLEMENT_OPTION_STRING_COMPARE(cmp_sane_opt);
|
||||||
|
|
||||||
|
|
||||||
|
dlg_setting::dlg_setting(HWND parent, LPSANEAPI api, SANE_Handle dev, bool with_scan, const wchar_t* name) : dlg_base(parent, IDD_SETTING)
|
||||||
|
, sane_api_(*api), sane_dev_(dev), with_scan_(with_scan)
|
||||||
|
, papers_(0), images_(0), notify_(NULL), notify_param_(NULL), err_(false), tab_(NULL)
|
||||||
|
{
|
||||||
|
create();
|
||||||
|
SetWindowTextW(hwnd(), (std::wstring(name) + L" \u8bbe\u7f6e").c_str());
|
||||||
|
}
|
||||||
|
dlg_setting::~dlg_setting()
|
||||||
|
{
|
||||||
|
if (IsWindow(tab_))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < get_tab_count(); ++i)
|
||||||
|
{
|
||||||
|
TCITEMW item = { 0 };
|
||||||
|
|
||||||
|
item.mask = TCIF_PARAM;
|
||||||
|
TabCtrl_GetItem(tab_, i, &item);
|
||||||
|
if (item.lParam)
|
||||||
|
delete (dlg_page*)item.lParam;
|
||||||
|
}
|
||||||
|
DestroyWindow(tab_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL dlg_setting::handle_message(UINT msg, WPARAM wp, LPARAM lp)
|
||||||
|
{
|
||||||
|
wchar_t text[40] = { 0 };
|
||||||
|
BOOL ret = TRUE;
|
||||||
|
|
||||||
|
switch (msg)
|
||||||
|
{
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
on_init_dialog();
|
||||||
|
break;
|
||||||
|
case WM_COMMAND:
|
||||||
|
handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp);
|
||||||
|
break;
|
||||||
|
case WM_NOTIFY:
|
||||||
|
on_notify((int)wp, (LPNMHDR)lp);
|
||||||
|
break;
|
||||||
|
case WM_REFRESH_OPTION:
|
||||||
|
refresh_controls((int)wp);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void dlg_setting::handle_command(WORD code, WORD id, HANDLE ctrl)
|
||||||
|
{
|
||||||
|
if (id == IDOK)
|
||||||
|
{
|
||||||
|
notify_over();
|
||||||
|
}
|
||||||
|
else if (id == IDC_BUTTON_HELP)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (id == IDC_BUTTON_RESTORE)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void dlg_setting::notify_over(void)
|
||||||
|
{
|
||||||
|
if (notify_)
|
||||||
|
notify_(true, notify_param_);
|
||||||
|
}
|
||||||
|
void dlg_setting::on_init_dialog(void)
|
||||||
|
{
|
||||||
|
dlg_page* page = NULL;
|
||||||
|
SANE_Int sn = 1;
|
||||||
|
SIZE size = { 0 };
|
||||||
|
RECT r = { 0 }, rme = { 0 };
|
||||||
|
int y = 0;
|
||||||
|
const SANE_Option_Descriptor* desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
|
||||||
|
|
||||||
|
while (desc)
|
||||||
|
{
|
||||||
|
if (desc->type == SANE_TYPE_GROUP)
|
||||||
|
{
|
||||||
|
if (page)
|
||||||
|
dlg_base::get_max_size(size, page->desired_size());
|
||||||
|
page = add_tab(desc->title);
|
||||||
|
}
|
||||||
|
else if (page)
|
||||||
|
{
|
||||||
|
char* buf = new char[desc->size + 4];
|
||||||
|
SANE_Int info = 0;
|
||||||
|
|
||||||
|
memset(buf, 0, desc->size + 4);
|
||||||
|
sane_api_.sane_control_option_api(sane_dev_, sn - 1, SANE_ACTION_GET_VALUE, buf, &info);
|
||||||
|
page->add_control(sn - 1, desc, buf);
|
||||||
|
delete[] buf;
|
||||||
|
}
|
||||||
|
else if(desc->type == SANE_TYPE_BUTTON)
|
||||||
|
{
|
||||||
|
if (cmp_sane_opt(OPTION_TITLE_BZ, desc->title))
|
||||||
|
ShowWindow(GetDlgItem(hwnd_, IDC_BUTTON_HELP), SW_SHOW);
|
||||||
|
if (cmp_sane_opt(OPTION_TITLE_HFMRSZ, desc->title))
|
||||||
|
ShowWindow(GetDlgItem(hwnd_, IDC_BUTTON_RESTORE), SW_SHOW);
|
||||||
|
}
|
||||||
|
desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
|
||||||
|
}
|
||||||
|
if (page)
|
||||||
|
dlg_base::get_max_size(size, page->desired_size());
|
||||||
|
|
||||||
|
if (size.cx || size.cy || IsWindow(tab_))
|
||||||
|
{
|
||||||
|
// resize ...
|
||||||
|
GetClientRect(hwnd(), &rme);
|
||||||
|
if (size.cx < rme.right - rme.left)
|
||||||
|
size.cx = rme.right - rme.left;
|
||||||
|
|
||||||
|
if (IsWindow(tab_))
|
||||||
|
{
|
||||||
|
GetWindowRect(tab_, &r);
|
||||||
|
y = r.bottom - r.top;
|
||||||
|
size.cy += y;
|
||||||
|
r.right = r.left + rme.right - rme.left;
|
||||||
|
screen_2_client(&r);
|
||||||
|
MoveWindow(tab_, r.left, r.top, r.right - r.left, y, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetWindowRect(hwnd(), &r);
|
||||||
|
r.right += size.cx - (rme.right - rme.left);
|
||||||
|
r.bottom += size.cy;
|
||||||
|
MoveWindow(hwnd(), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
|
||||||
|
|
||||||
|
for (int i = 0; page = get_page(i); ++i)
|
||||||
|
{
|
||||||
|
MoveWindow(page->hwnd(), 0, y, size.cx, size.cy - y, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetWindowRect(get_item(IDC_BUTTON_SCAN), &r);
|
||||||
|
OffsetRect(&r, 0, size.cy);
|
||||||
|
screen_2_client(&r);
|
||||||
|
MoveWindow(get_item(IDC_BUTTON_SCAN), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
|
||||||
|
|
||||||
|
GetWindowRect(get_item(IDC_BUTTON_HELP), &r);
|
||||||
|
OffsetRect(&r, size.cx - (rme.right - rme.left), size.cy);
|
||||||
|
screen_2_client(&r);
|
||||||
|
MoveWindow(get_item(IDC_BUTTON_HELP), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
|
||||||
|
|
||||||
|
GetWindowRect(get_item(IDC_BUTTON_RESTORE), &r);
|
||||||
|
OffsetRect(&r, size.cx - (rme.right - rme.left), size.cy);
|
||||||
|
screen_2_client(&r);
|
||||||
|
MoveWindow(get_item(IDC_BUTTON_RESTORE), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
|
||||||
|
|
||||||
|
GetWindowRect(get_item(IDOK), &r);
|
||||||
|
OffsetRect(&r, size.cx - (rme.right - rme.left), size.cy);
|
||||||
|
screen_2_client(&r);
|
||||||
|
MoveWindow(get_item(IDOK), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
|
||||||
|
}
|
||||||
|
select_page(0);
|
||||||
|
UpdateWindow(hwnd());
|
||||||
|
}
|
||||||
|
void dlg_setting::on_notify(int ctrl_id, LPNMHDR pnmh)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
int dlg_setting::get_tab_count(void)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (IsWindow(tab_))
|
||||||
|
count = TabCtrl_GetItemCount(tab_);
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
dlg_page* dlg_setting::add_tab(const char* utf8_title)
|
||||||
|
{
|
||||||
|
std::wstring title(local_trans::a2u(utf8_title, CP_UTF8));
|
||||||
|
dlg_page *page = new dlg_page(hwnd(), title.c_str());
|
||||||
|
HFONT font = (HFONT)SendMessage(get_item(IDOK), WM_GETFONT, 0, 0);
|
||||||
|
LOGFONTW lf = { 0 };
|
||||||
|
|
||||||
|
GetObjectW(font, sizeof(lf), &lf);
|
||||||
|
page->set_font(font);
|
||||||
|
if (!IsWindow(tab_))
|
||||||
|
{
|
||||||
|
tab_ = CreateWindowW(L"SysTabControl32", L"pages", WS_CHILD | WS_VISIBLE, 0, 0, 100, lf.lfHeight < 0 ? -lf.lfHeight : lf.lfHeight, hwnd(), NULL, g_my_inst, NULL);
|
||||||
|
SendMessage(tab_, WM_SETFONT, (WPARAM)SendMessage(get_item(IDOK), WM_GETFONT, 0, 0), 1);
|
||||||
|
SetWindowLong(tab_, GWL_ID, 1234);
|
||||||
|
ShowWindow(tab_, SW_SHOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
TC_ITEMW item = { 0 };
|
||||||
|
|
||||||
|
item.mask = TCIF_PARAM | TCIF_TEXT;
|
||||||
|
item.lParam = (LPARAM)page;
|
||||||
|
item.pszText = &title[0];
|
||||||
|
TabCtrl_InsertItem(tab_, get_tab_count(), &item);
|
||||||
|
page->hide();
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
dlg_page* dlg_setting::get_page(int index)
|
||||||
|
{
|
||||||
|
dlg_page* page = NULL;
|
||||||
|
|
||||||
|
if (IsWindow(tab_) && index >= 0 && index < get_tab_count())
|
||||||
|
{
|
||||||
|
TCITEMW item = { 0 };
|
||||||
|
|
||||||
|
item.mask = TCIF_PARAM;
|
||||||
|
TabCtrl_GetItem(tab_, index, &item);
|
||||||
|
page = (dlg_page*)item.lParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
dlg_page* dlg_setting::get_page(const char* utf8_title)
|
||||||
|
{
|
||||||
|
dlg_page* page = NULL;
|
||||||
|
std::wstring unic(local_trans::a2u(utf8_title, CP_UTF8));
|
||||||
|
|
||||||
|
for (int i = 0; i < get_tab_count(); ++i)
|
||||||
|
{
|
||||||
|
TCITEMW item = { 0 };
|
||||||
|
wchar_t buf[80] = { 0 };
|
||||||
|
|
||||||
|
item.mask = TCIF_TEXT | TCIF_PARAM;
|
||||||
|
item.pszText = buf;
|
||||||
|
item.cchTextMax = _countof(buf) - 1;
|
||||||
|
TabCtrl_GetItem(tab_, i, &item);
|
||||||
|
if (unic == buf)
|
||||||
|
{
|
||||||
|
page = (dlg_page*)item.lParam;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
dlg_page* dlg_setting::select_page(int index)
|
||||||
|
{
|
||||||
|
dlg_page* ret = NULL, *cur = NULL;
|
||||||
|
|
||||||
|
for (int i = 0; cur = get_page(i); ++i)
|
||||||
|
{
|
||||||
|
if (i == index)
|
||||||
|
{
|
||||||
|
ret = cur;
|
||||||
|
cur->show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cur->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void dlg_setting::refresh_controls(int src_sn)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void dlg_setting::set_quit_notify(void(__stdcall* notify)(bool, void*), void* param)
|
||||||
|
{
|
||||||
|
notify_ = notify;
|
||||||
|
notify_param_ = param;
|
||||||
|
}
|
||||||
|
HWND dlg_setting::window(void)
|
||||||
|
{
|
||||||
|
return hwnd_;
|
||||||
|
}
|
||||||
|
HWND dlg_setting::parent(void)
|
||||||
|
{
|
||||||
|
return parent_;
|
||||||
|
}
|
||||||
|
void dlg_setting::show(void)
|
||||||
|
{
|
||||||
|
RECT rp, r;
|
||||||
|
|
||||||
|
if (IsWindow(parent_))
|
||||||
|
GetWindowRect(parent_, &rp);
|
||||||
|
else
|
||||||
|
GetWindowRect(GetDesktopWindow(), &rp);
|
||||||
|
GetWindowRect(hwnd_, &r);
|
||||||
|
|
||||||
|
rp.left += (rp.right - rp.left - (r.right - r.left)) / 2;
|
||||||
|
rp.top += (rp.bottom - rp.top - (r.bottom - r.top)) / 2;
|
||||||
|
SetWindowPos(hwnd_, HWND_TOPMOST, rp.left, rp.top, r.right - r.left, r.bottom - r.top, SWP_NOSIZE | SWP_SHOWWINDOW);
|
||||||
|
UpdateWindow(hwnd_);
|
||||||
|
}
|
||||||
|
void dlg_setting::hide(void)
|
||||||
|
{
|
||||||
|
ShowWindow(hwnd_, SW_HIDE);
|
||||||
|
}
|
||||||
|
void dlg_setting::notify_data_arrived(bool image)
|
||||||
|
{
|
||||||
|
PostMessage(hwnd_, image ? WM_IMAGE_RECEIVED : WM_USB_PACKET_RECEIVED, 0, 0);
|
||||||
|
}
|
||||||
|
void dlg_setting::notify_scan_over(const char* msg, bool err)
|
||||||
|
{
|
||||||
|
std::string* mstr(new std::string(msg ? msg : ""));
|
||||||
|
|
||||||
|
err_ = err;
|
||||||
|
if (!PostMessage(hwnd_, WM_SCAN_FINISHED, (WPARAM)mstr, (LPARAM)err))
|
||||||
|
{
|
||||||
|
delete mstr;
|
||||||
|
notify_over();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// CDlgIndicator 消息处理程序
|
|
@ -0,0 +1,59 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <sane/sane_ex.h>
|
||||||
|
|
||||||
|
#include "DlgPage.h"
|
||||||
|
|
||||||
|
// CDlgIndicator 对话框
|
||||||
|
//#define USE_SOLE_WIN_THREAD
|
||||||
|
|
||||||
|
#ifdef USE_SOLE_WIN_THREAD
|
||||||
|
#include <thread>
|
||||||
|
#include <memory>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class dlg_setting : public dlg_base
|
||||||
|
{
|
||||||
|
SANEAPI sane_api_;
|
||||||
|
SANE_Handle sane_dev_;
|
||||||
|
bool with_scan_;
|
||||||
|
unsigned int papers_;
|
||||||
|
unsigned int images_;
|
||||||
|
bool err_;
|
||||||
|
|
||||||
|
HWND tab_;
|
||||||
|
|
||||||
|
#ifdef USE_SOLE_WIN_THREAD
|
||||||
|
std::unique_ptr<std::thread> thread_;
|
||||||
|
#endif
|
||||||
|
void(__stdcall* notify_)(bool, void*);
|
||||||
|
void* notify_param_;
|
||||||
|
|
||||||
|
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
|
||||||
|
void handle_command(WORD code, WORD id, HANDLE ctrl);
|
||||||
|
void notify_over(void);
|
||||||
|
void on_init_dialog(void);
|
||||||
|
void on_notify(int ctrl_id, LPNMHDR pnmh);
|
||||||
|
int get_tab_count(void);
|
||||||
|
dlg_page* add_tab(const char* utf8_title);
|
||||||
|
dlg_page* get_page(int index);
|
||||||
|
dlg_page* get_page(const char* utf8_title);
|
||||||
|
dlg_page* select_page(int index);
|
||||||
|
void refresh_controls(int src_sn);
|
||||||
|
|
||||||
|
public:
|
||||||
|
dlg_setting(HWND parent, LPSANEAPI api, SANE_Handle dev, bool with_scan, const wchar_t* name);
|
||||||
|
~dlg_setting();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void set_quit_notify(void(__stdcall* notify)(bool cancel, void*), void* param);
|
||||||
|
HWND window(void);
|
||||||
|
HWND parent(void);
|
||||||
|
void show(void);
|
||||||
|
void hide(void);
|
||||||
|
void notify_data_arrived(bool image);
|
||||||
|
void notify_scan_over(const char* msg, bool err);
|
||||||
|
};
|
|
@ -3,19 +3,25 @@
|
||||||
// ¹© sane.rc ʹÓÃ
|
// ¹© sane.rc ʹÓÃ
|
||||||
//
|
//
|
||||||
#define IDD_INDICATOR 101
|
#define IDD_INDICATOR 101
|
||||||
|
#define IDD_SETTING 103
|
||||||
|
#define IDD_PAGE 105
|
||||||
#define IDC_EDIT_PAPER 1001
|
#define IDC_EDIT_PAPER 1001
|
||||||
#define IDC_EDIT_IMAGE 1002
|
#define IDC_EDIT_IMAGE 1002
|
||||||
#define IDC_STATIC_PAPER 1003
|
#define IDC_STATIC_PAPER 1003
|
||||||
#define IDC_STATIC_IMAGE 1004
|
#define IDC_STATIC_IMAGE 1004
|
||||||
#define IDC_STATIC_ERR 1005
|
#define IDC_STATIC_ERR 1005
|
||||||
|
#define IDC_BUTTON_SCAN 1007
|
||||||
|
#define IDC_BUTTON_RESTORE 1008
|
||||||
|
#define IDC_BUTTON3 1009
|
||||||
|
#define IDC_BUTTON_HELP 1009
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 103
|
#define _APS_NEXT_RESOURCE_VALUE 107
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1006
|
#define _APS_NEXT_CONTROL_VALUE 1008
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,3 +4,19 @@ EXPORTS
|
||||||
open_scanner
|
open_scanner
|
||||||
is_scanner_online
|
is_scanner_online
|
||||||
uninitialize
|
uninitialize
|
||||||
|
sane_hgsane_init
|
||||||
|
sane_hgsane_exit
|
||||||
|
sane_hgsane_get_devices
|
||||||
|
sane_hgsane_open
|
||||||
|
sane_hgsane_close
|
||||||
|
sane_hgsane_get_option_descriptor
|
||||||
|
sane_hgsane_control_option
|
||||||
|
sane_hgsane_get_parameters
|
||||||
|
sane_hgsane_start
|
||||||
|
sane_hgsane_read
|
||||||
|
sane_hgsane_cancel
|
||||||
|
sane_hgsane_set_io_mode
|
||||||
|
sane_hgsane_get_select_fd
|
||||||
|
sane_hgsane_strstatus
|
||||||
|
sane_hgsane_init_ex
|
||||||
|
sane_hgsane_io_control
|
||||||
|
|
43
sane/sane.rc
43
sane/sane.rc
|
@ -63,6 +63,23 @@ BEGIN
|
||||||
LTEXT "",IDC_STATIC_ERR,7,7,131,9,NOT WS_VISIBLE
|
LTEXT "",IDC_STATIC_ERR,7,7,131,9,NOT WS_VISIBLE
|
||||||
END
|
END
|
||||||
|
|
||||||
|
IDD_SETTING DIALOGEX 0, 0, 263, 28
|
||||||
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
|
||||||
|
CAPTION "Dialog"
|
||||||
|
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||||
|
BEGIN
|
||||||
|
DEFPUSHBUTTON "确定",IDOK,223,8,33,13
|
||||||
|
PUSHBUTTON "扫描",IDC_BUTTON_SCAN,7,7,39,14,NOT WS_VISIBLE
|
||||||
|
PUSHBUTTON "恢复默认值",IDC_BUTTON_RESTORE,113,7,48,14,NOT WS_VISIBLE
|
||||||
|
PUSHBUTTON "帮助",IDC_BUTTON_HELP,167,7,48,14,NOT WS_VISIBLE
|
||||||
|
END
|
||||||
|
|
||||||
|
IDD_PAGE DIALOGEX 0, 0, 257, 133
|
||||||
|
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
|
||||||
|
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||||
|
BEGIN
|
||||||
|
END
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -79,6 +96,22 @@ BEGIN
|
||||||
TOPMARGIN, 7
|
TOPMARGIN, 7
|
||||||
BOTTOMMARGIN, 31
|
BOTTOMMARGIN, 31
|
||||||
END
|
END
|
||||||
|
|
||||||
|
IDD_SETTING, DIALOG
|
||||||
|
BEGIN
|
||||||
|
LEFTMARGIN, 7
|
||||||
|
RIGHTMARGIN, 256
|
||||||
|
TOPMARGIN, 7
|
||||||
|
BOTTOMMARGIN, 21
|
||||||
|
END
|
||||||
|
|
||||||
|
IDD_PAGE, DIALOG
|
||||||
|
BEGIN
|
||||||
|
LEFTMARGIN, 7
|
||||||
|
RIGHTMARGIN, 250
|
||||||
|
TOPMARGIN, 7
|
||||||
|
BOTTOMMARGIN, 126
|
||||||
|
END
|
||||||
END
|
END
|
||||||
#endif // APSTUDIO_INVOKED
|
#endif // APSTUDIO_INVOKED
|
||||||
|
|
||||||
|
@ -93,6 +126,16 @@ BEGIN
|
||||||
0
|
0
|
||||||
END
|
END
|
||||||
|
|
||||||
|
IDD_SETTING AFX_DIALOG_LAYOUT
|
||||||
|
BEGIN
|
||||||
|
0
|
||||||
|
END
|
||||||
|
|
||||||
|
IDD_PAGE AFX_DIALOG_LAYOUT
|
||||||
|
BEGIN
|
||||||
|
0
|
||||||
|
END
|
||||||
|
|
||||||
#endif // 中文(简体,中国) resources
|
#endif // 中文(简体,中国) resources
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>BACKEND_NAME=sane;TWPP_IS_DS;EXPORT_SANE_API;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>BACKEND_NAME=hgsane;TWPP_IS_DS;EXPORT_SANE_API;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
|
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
|
||||||
|
@ -128,7 +128,7 @@ move /Y "$(OutDirFullPath)$(ProjectName).pdb" "$(SolutionDir)..\..\sdk\lib\win\$
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>BACKEND_NAME=sane;TWPP_IS_DS;EXPORT_SANE_API;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>BACKEND_NAME=hgsane;TWPP_IS_DS;EXPORT_SANE_API;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
|
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
|
||||||
|
@ -198,6 +198,8 @@ move /Y "$(OutDirFullPath)$(ProjectName).pdb" "$(SolutionDir)..\..\sdk\lib\win\$
|
||||||
<ClCompile Include="..\..\code_device\hgsane\sane_hg_mdw.cpp" />
|
<ClCompile Include="..\..\code_device\hgsane\sane_hg_mdw.cpp" />
|
||||||
<ClCompile Include="..\..\code_device\hgsane\sane_option.cpp" />
|
<ClCompile Include="..\..\code_device\hgsane\sane_option.cpp" />
|
||||||
<ClCompile Include="DlgIndicator.cpp" />
|
<ClCompile Include="DlgIndicator.cpp" />
|
||||||
|
<ClCompile Include="DlgPage.cpp" />
|
||||||
|
<ClCompile Include="DlgSetting.cpp" />
|
||||||
<ClCompile Include="sane_option_trans.cpp" />
|
<ClCompile Include="sane_option_trans.cpp" />
|
||||||
<ClCompile Include="scanned_img.cpp" />
|
<ClCompile Include="scanned_img.cpp" />
|
||||||
<ClCompile Include="scanner.cpp" />
|
<ClCompile Include="scanner.cpp" />
|
||||||
|
@ -216,6 +218,8 @@ move /Y "$(OutDirFullPath)$(ProjectName).pdb" "$(SolutionDir)..\..\sdk\lib\win\$
|
||||||
<ClInclude Include="..\..\sdk\include\sane\sane_ex.h" />
|
<ClInclude Include="..\..\sdk\include\sane\sane_ex.h" />
|
||||||
<ClInclude Include="..\..\sdk\include\sane\sane_option_definitions.h" />
|
<ClInclude Include="..\..\sdk\include\sane\sane_option_definitions.h" />
|
||||||
<ClInclude Include="DlgIndicator.h" />
|
<ClInclude Include="DlgIndicator.h" />
|
||||||
|
<ClInclude Include="DlgPage.h" />
|
||||||
|
<ClInclude Include="DlgSetting.h" />
|
||||||
<ClInclude Include="resource.h" />
|
<ClInclude Include="resource.h" />
|
||||||
<ClInclude Include="s2t_api.h" />
|
<ClInclude Include="s2t_api.h" />
|
||||||
<ClInclude Include="sane_option_trans.h" />
|
<ClInclude Include="sane_option_trans.h" />
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
<Filter Include="sane2twain">
|
<Filter Include="sane2twain">
|
||||||
<UniqueIdentifier>{8ae15a45-410d-4611-b852-f82b64bb1fcc}</UniqueIdentifier>
|
<UniqueIdentifier>{8ae15a45-410d-4611-b852-f82b64bb1fcc}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="sane2twain\UI">
|
||||||
|
<UniqueIdentifier>{5c86255e-570e-4921-9c62-c98d05edcab4}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\code_device\hgsane\cJSON.c">
|
<ClCompile Include="..\..\code_device\hgsane\cJSON.c">
|
||||||
|
@ -43,7 +46,13 @@
|
||||||
<Filter>sane2twain</Filter>
|
<Filter>sane2twain</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="DlgIndicator.cpp">
|
<ClCompile Include="DlgIndicator.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>sane2twain\UI</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DlgSetting.cpp">
|
||||||
|
<Filter>sane2twain\UI</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DlgPage.cpp">
|
||||||
|
<Filter>sane2twain\UI</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -99,7 +108,13 @@
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="DlgIndicator.h">
|
<ClInclude Include="DlgIndicator.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>sane2twain\UI</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="DlgSetting.h">
|
||||||
|
<Filter>sane2twain\UI</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="DlgPage.h">
|
||||||
|
<Filter>sane2twain\UI</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include "DlgIndicator.h"
|
#include "DlgIndicator.h"
|
||||||
|
#include "DlgSetting.h"
|
||||||
|
|
||||||
static IMPLEMENT_OPTION_STRING_COMPARE(compare_sane_opt);
|
static IMPLEMENT_OPTION_STRING_COMPARE(compare_sane_opt);
|
||||||
|
|
||||||
|
@ -24,6 +25,27 @@ static IMPLEMENT_OPTION_STRING_COMPARE(compare_sane_opt);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// callback
|
// callback
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
extern SANE_Status inner_sane_init(SANE_Int* version_code, SANE_Auth_Callback authorize);
|
||||||
|
extern void inner_sane_exit(void);
|
||||||
|
extern SANE_Status inner_sane_get_devices(const SANE_Device*** device_list, SANE_Bool local_only);
|
||||||
|
extern SANE_Status inner_sane_open(SANE_String_Const devicename, SANE_Handle* handle);
|
||||||
|
extern void inner_sane_close(SANE_Handle handle);
|
||||||
|
extern const SANE_Option_Descriptor* inner_sane_get_option_descriptor(SANE_Handle handle, SANE_Int option);
|
||||||
|
extern SANE_Status inner_sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void* value, SANE_Int* info);
|
||||||
|
extern SANE_Status inner_sane_get_parameters(SANE_Handle handle, SANE_Parameters* params);
|
||||||
|
extern SANE_Status inner_sane_start(SANE_Handle handle);
|
||||||
|
extern SANE_Status inner_sane_read(SANE_Handle handle, SANE_Byte* data, SANE_Int max_length, SANE_Int* length);
|
||||||
|
extern void inner_sane_cancel(SANE_Handle handle);
|
||||||
|
extern SANE_Status inner_sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking);
|
||||||
|
extern SANE_Status inner_sane_get_select_fd(SANE_Handle handle, SANE_Int* fd);
|
||||||
|
extern SANE_String_Const inner_sane_strstatus(SANE_Status status);
|
||||||
|
|
||||||
|
extern SANE_Status inner_sane_init_ex(SANE_Int* version_code, sane_callback cb, void* param);
|
||||||
|
extern SANE_Status inner_sane_io_control(SANE_Handle h, unsigned long code, void* data, unsigned* len);
|
||||||
|
}
|
||||||
|
|
||||||
namespace callback
|
namespace callback
|
||||||
{
|
{
|
||||||
static std::mutex cb_lock_;
|
static std::mutex cb_lock_;
|
||||||
|
@ -87,7 +109,7 @@ namespace callback
|
||||||
// class scanner
|
// class scanner
|
||||||
scanner::scanner(SCANNERID id) : handle_(NULL), id_(id), ex_id_(EXTENSION_ID_BASE), prev_start_result_(SCANNER_ERR_NOT_START)
|
scanner::scanner(SCANNERID id) : handle_(NULL), id_(id), ex_id_(EXTENSION_ID_BASE), prev_start_result_(SCANNER_ERR_NOT_START)
|
||||||
, dpi_(200), tmp_path_(L""), img_ind_(0), cb_invoker_(NULL), cb_param_(NULL), working_(false)
|
, dpi_(200), tmp_path_(L""), img_ind_(0), cb_invoker_(NULL), cb_param_(NULL), working_(false)
|
||||||
, ui_quit_(true)
|
, ui_quit_(true), scanner_name_(L"")
|
||||||
{
|
{
|
||||||
tmp_path_ = local_trans::a2u(hg_sane_middleware::sane_path().c_str());
|
tmp_path_ = local_trans::a2u(hg_sane_middleware::sane_path().c_str());
|
||||||
tmp_path_ += L"imgs";
|
tmp_path_ += L"imgs";
|
||||||
|
@ -190,12 +212,14 @@ int scanner::open(void)
|
||||||
int ret = close();
|
int ret = close();
|
||||||
std::string name(scanner::get_scanner_name(id_));
|
std::string name(scanner::get_scanner_name(id_));
|
||||||
|
|
||||||
|
scanner_name_ = L"";
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
return SCANNER_ERR_DEVICE_NOT_FOUND;
|
return SCANNER_ERR_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
ret = hg_sane_middleware::instance()->open_device(name.c_str(), &handle_);
|
ret = hg_sane_middleware::instance()->open_device(name.c_str(), &handle_);
|
||||||
if (ret == SANE_STATUS_GOOD)
|
if (ret == SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
|
scanner_name_ = local_trans::a2u(name.c_str(), CP_UTF8);
|
||||||
callback::reg_callback(handle_, this);
|
callback::reg_callback(handle_, this);
|
||||||
ret = init_options_id();
|
ret = init_options_id();
|
||||||
}
|
}
|
||||||
|
@ -1818,18 +1842,34 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_main(HWND parent))
|
||||||
}
|
}
|
||||||
COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan))
|
COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan))
|
||||||
{
|
{
|
||||||
indicator_.reset(new dlg_indicator());
|
SANEAPI api = { NULL };
|
||||||
indicator_->set_quit_notify(&scanner::ui_callback, this);
|
|
||||||
indicator_->show(parent);
|
api.sane_cancel_api = inner_sane_cancel;
|
||||||
|
api.sane_close_api = inner_sane_close;
|
||||||
|
api.sane_control_option_api = inner_sane_control_option;
|
||||||
|
api.sane_get_devices_api = inner_sane_get_devices;
|
||||||
|
api.sane_get_option_descriptor_api = inner_sane_get_option_descriptor;
|
||||||
|
api.sane_get_parameters_api = inner_sane_get_parameters;
|
||||||
|
api.sane_get_select_fd_api = inner_sane_get_select_fd;
|
||||||
|
api.sane_io_control_api = inner_sane_io_control;
|
||||||
|
api.sane_open_api = inner_sane_open;
|
||||||
|
api.sane_read_api = inner_sane_read;
|
||||||
|
api.sane_set_io_mode_api = inner_sane_set_io_mode;
|
||||||
|
api.sane_start_api = inner_sane_start;
|
||||||
|
api.sane_strstatus_api = inner_sane_strstatus;
|
||||||
|
|
||||||
|
setting_.reset(new dlg_setting(parent, &api, handle_, with_scan, scanner_name_.c_str()));
|
||||||
|
setting_->set_quit_notify(&scanner::ui_callback, this);
|
||||||
|
setting_->show();
|
||||||
ui_quit_ = false;
|
ui_quit_ = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent))
|
COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent))
|
||||||
{
|
{
|
||||||
indicator_.reset(new dlg_indicator());
|
indicator_.reset(new dlg_indicator(parent));
|
||||||
indicator_->set_quit_notify(&scanner::ui_callback, this);
|
indicator_->set_quit_notify(&scanner::ui_callback, this);
|
||||||
indicator_->show(parent);
|
indicator_->show();
|
||||||
ui_quit_ = false;
|
ui_quit_ = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1838,6 +1878,8 @@ COM_API_IMPLEMENT(scanner, void, ui_hide(void))
|
||||||
{
|
{
|
||||||
if (indicator_.get())
|
if (indicator_.get())
|
||||||
indicator_.reset();
|
indicator_.reset();
|
||||||
|
if (setting_.get())
|
||||||
|
setting_.reset();
|
||||||
}
|
}
|
||||||
COM_API_IMPLEMENT(scanner, bool, ui_is_ok(void))
|
COM_API_IMPLEMENT(scanner, bool, ui_is_ok(void))
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
|
|
||||||
class dlg_indicator;
|
class dlg_indicator;
|
||||||
|
class dlg_setting;
|
||||||
|
|
||||||
class scanner : public ISaneInvoker, virtual public refer
|
class scanner : public ISaneInvoker, virtual public refer
|
||||||
{
|
{
|
||||||
SANE_Handle handle_;
|
SANE_Handle handle_;
|
||||||
|
@ -34,6 +36,7 @@ class scanner : public ISaneInvoker, virtual public refer
|
||||||
int prev_start_result_;
|
int prev_start_result_;
|
||||||
int dpi_;
|
int dpi_;
|
||||||
unsigned int img_ind_;
|
unsigned int img_ind_;
|
||||||
|
std::wstring scanner_name_;
|
||||||
std::wstring tmp_path_;
|
std::wstring tmp_path_;
|
||||||
std::string scan_msg_;
|
std::string scan_msg_;
|
||||||
bool scan_err_;
|
bool scan_err_;
|
||||||
|
@ -43,6 +46,7 @@ class scanner : public ISaneInvoker, virtual public refer
|
||||||
bool ui_quit_;
|
bool ui_quit_;
|
||||||
SANE_FinalImgFormat img_fmt_;
|
SANE_FinalImgFormat img_fmt_;
|
||||||
std::unique_ptr<dlg_indicator> indicator_;
|
std::unique_ptr<dlg_indicator> indicator_;
|
||||||
|
std::unique_ptr<dlg_setting> setting_;
|
||||||
|
|
||||||
void on_ui_quit(bool cancel);
|
void on_ui_quit(bool cancel);
|
||||||
int open(void);
|
int open(void);
|
||||||
|
|
Loading…
Reference in New Issue