完善收图流程

This commit is contained in:
gb 2024-01-27 17:57:15 +08:00
parent 2ecad189e8
commit 356be76a2e
5 changed files with 137 additions and 10 deletions

View File

@ -15,6 +15,7 @@
#include <sane_opts.h>
#define TIMER_ID_REFRESH_BULK 1001
HMODULE g_my_inst;
@ -718,19 +719,16 @@ const wchar_t* scanner_status(int s, wchar_t unk[20])
}
static DWORD thread_open_id_ = 0;
static safe_fifo<std::string> images_("images");
static safe_fifo<std::wstring> images_("images");
static DWORD WINAPI thread_open_image(void* lp)
{
while (1)
{
std::string file("");
std::wstring file(L"");
if (images_.take(file, true))
{
if (file.empty())
ShellExecuteW(NULL, L"Open", file.c_str(), NULL, NULL, SW_SHOWNORMAL);
else
break;
ShellExecuteA(NULL, "Open", file.c_str(), NULL, NULL, SW_SHOWNORMAL);
}
}
return 0;
@ -783,7 +781,7 @@ CDlgScanner::CDlgScanner(CWnd* pParent /*=nullptr*/)
CDlgScanner::~CDlgScanner()
{
::PostThreadMessage(thread_open_id_, WM_USER + 1001, 0, 0);
images_.save("", true);
images_.trigger();
if (scanner_)
{
scanner_->close();
@ -970,6 +968,83 @@ int CDlgScanner::set_option(const char* name, void* value, int type, size_t len,
return 0;
}
void CDlgScanner::thread_fetch_image(void)
{
size_t size = SIZE_MB(1), off = 0, rd = 0;
uint8_t *buf = new uint8_t[size];
int dpi = scanner_->get_resolution();
while (1)
{
SANE_Parameters sp;
memset(&sp, 0, sizeof(sp));
scanner_->get_image_info(&sp);
off = 0;
rd = size;
if (scanner_->read_image_data(buf, &rd) == SCANNER_ERR_NO_DATA && rd == 0)
break;
std::string bih(utils::bitmap_info_header(sp.pixels_per_line, sp.lines, sp.format == SANE_FRAME_RGB ? 3 * sp.depth : sp.depth, dpi)),
bfh(utils::bitmap_file_header((LPBITMAPINFOHEADER)&bih[0]));
LPBITMAPINFOHEADER head = (LPBITMAPINFOHEADER)&bih[0];
int line_l = BMP_LINE_BYTES(head->biWidth * head->biBitCount), err = SCANNER_ERR_OK;
char pad[4] = { 0 };
wchar_t name[40] = { 0 };
FILE *dst = nullptr;
swprintf_s(name, _countof(name) - 1, L"\\scanner_%04u.bmp", img_cnt_ + 1);
dst = _wfopen((save_root_ + name).c_str(), L"wb");
if (dst)
{
fwrite(bfh.c_str(), 1, bfh.length(), dst);
fwrite(bih.c_str(), 1, bih.length(), dst);
}
while (rd)
{
if (dst)
{
if (line_l == sp.bytes_per_line)
{
fwrite(buf, 1, rd, dst);
}
else
{
rd += off;
off = 0;
while (rd >= sp.bytes_per_line)
{
fwrite(buf + off, 1, sp.bytes_per_line, dst);
rd -= sp.bytes_per_line;
off += sp.bytes_per_line;
fwrite(pad, 1, line_l - sp.bytes_per_line, dst);
}
if (rd)
{
memcpy(buf, buf + off, rd);
off = rd;
}
else
off = 0;
}
}
if (SCANNER_ERR_NO_DATA == err)
break;
rd = size - off;
err = scanner_->read_image_data(buf + off, &rd);
}
if (dst)
{
fclose(dst);
if (auto_open_img_)
images_.save(save_root_ + name, true);
}
img_cnt_++;
::PostMessage(m_hWnd, WM_TX_IMAGE_CNT, 0, img_cnt_);
}
delete[] buf;
}
int CDlgScanner::refresh_bulk_status(bool en_dev_log)
{
@ -1233,6 +1308,8 @@ BEGIN_MESSAGE_MAP(CDlgScanner, CDialogEx)
ON_CBN_SELCHANGE(IDC_COMBO_BUF_SIZE, &CDlgScanner::OnCbnSelchangeComboBufSize)
ON_WM_DESTROY()
ON_MESSAGE(WM_SCAN_FINISHED, &CDlgScanner::OnScanFinished)
ON_MESSAGE(WM_TX_IMAGE_CNT, &CDlgScanner::OnImageFetched)
ON_BN_CLICKED(IDC_CHECK_AUTO_OPEN_IMG, &CDlgScanner::OnBnClickedCheckAutoOpenImg)
END_MESSAGE_MAP()
@ -1400,11 +1477,16 @@ void CDlgScanner::OnBnClickedButtonBrowseSavingPath()
void CDlgScanner::OnBnClickedButtonScan()
{
// TODO: 在此添加控件通知处理程序代码
wchar_t title[40] = { 0 };
wchar_t title[MAX_PATH] = { 0 };
::GetDlgItemTextW(m_hWnd, IDC_BUTTON_SCAN, title, _countof(title) - 1);
if (wcsicmp(title, L"Scan") == 0)
{
::GetDlgItemTextW(m_hWnd, IDC_EDIT_IMG_PATH, title, _countof(title) - 1);
save_root_ = title;
file_util::force_create_folder(title);
threads_.stop("thread_fetch_image");
img_cnt_ = 0;
paper_cnt_ = 0;
SetDlgItemInt(IDC_EDIT_COUNT, img_cnt_);
@ -1418,9 +1500,18 @@ void CDlgScanner::OnBnClickedButtonScan()
int err = scanner_->start(&cfg, over);
utils::to_log(LOG_LEVEL_DEBUG, "Start to scan = %s\r\n", usb::u2a(scanner_status(err, title)).c_str());
if (err)
{
OnDeviceStatus(0, (LPARAM)err);
msg_box(m_hWnd, MB_OK, L"Error", L"Failed in starting scanning with code: %s", scanner_status(err, title));
}
else
{
auto rcv = [this]() -> void
{
thread_fetch_image();
};
threads_.start(rcv, "thread_fetch_image");
utils::to_log(LOG_LEVEL_DEBUG, "Device configuration: %s\n", cfg.c_str());
::SetDlgItemTextW(m_hWnd, IDC_BUTTON_SCAN, L"Stop");
OnDeviceStatus(0, (LPARAM)SCANNER_ERR_DEVICE_BUSY);
@ -1542,6 +1633,12 @@ void CDlgScanner::OnBnClickedButtonRefresh()
refresh_bulk_status();
}
void CDlgScanner::OnBnClickedCheckAutoOpenImg()
{
// TODO: 在此添加控件通知处理程序代码
auto_open_img_ = ((CButton*)GetDlgItem(IDC_CHECK_AUTO_OPEN_IMG))->GetCheck() == BST_CHECKED;
}
void CDlgScanner::OnBnClickedCheckRepeat()
{
@ -1655,6 +1752,12 @@ LRESULT CDlgScanner::OnScanFinished(WPARAM wp, LPARAM lp)
return 0;
}
LRESULT CDlgScanner::OnImageFetched(WPARAM wp, LPARAM lp)
{
SetDlgItemInt(IDC_EDIT_COUNT, lp, FALSE);
return 0;
}
void CDlgScanner::OnCbnSelchangeComboBufSize()
@ -1685,3 +1788,4 @@ void CDlgScanner::OnDestroy()
// TODO: 在此处添加消息处理程序代码
set_device(NULL);
}

View File

@ -72,6 +72,8 @@ class CDlgScanner : public CDialogEx
uint32_t max_cmd_;
uint32_t bulk_statu_tick_ = 0;
safe_thread threads_;
std::wstring save_root_;
volatile bool auto_open_img_ = false;
public:
CDlgScanner(CWnd* pParent = nullptr); // 标准构造函数
@ -104,6 +106,7 @@ public:
void get_option(const char* name, void* value, size_t size);
int get_all_option(std::string& opts_json);
int set_option(const char* name, void* value, int type, size_t len, size_t max_len, int* after);
void thread_fetch_image(void);
public:
CTabCtrl tab_opt_;
@ -131,8 +134,10 @@ public:
afx_msg LRESULT OnTransDiretion(WPARAM wp, LPARAM lp);
afx_msg LRESULT OnTransProgress(WPARAM wp, LPARAM lp);
afx_msg LRESULT OnScanFinished(WPARAM wp, LPARAM lp);
afx_msg LRESULT OnImageFetched(WPARAM wp, LPARAM lp);
afx_msg void OnCbnSelchangeComboBufSize();
CComboBox buf_;
afx_msg void OnDestroy();
CProgressCtrl tx_prog_;
afx_msg void OnBnClickedCheckAutoOpenImg();
};

View File

@ -34,6 +34,7 @@
#define WM_DEVICE_STATTUS WM_USER + 324 // WPARAM: unused; LPARAM: scanner_status
#define WM_TX_DIRECTION WM_USER + 325 // WPARAM: unused; LPARAM: bool - true: send; false - receive
#define WM_TX_PROGRESS WM_USER + 326 // WPARAM: high of double; LPARAM: low of double
#define WM_TX_IMAGE_CNT WM_USER + 327 // WPARAM: unused; LPARAM: count
extern HMODULE g_my_inst;

View File

@ -207,8 +207,10 @@
<ClInclude Include="..\..\..\code_device\sdk\base\huagaoxxx_warraper_ex.h" />
<ClInclude Include="..\..\..\code_device\sdk\base\ini_file.h" />
<ClInclude Include="..\..\..\code_device\sdk\base\packet.h" />
<ClInclude Include="..\..\..\code_device\sdk\base\paper.h" />
<ClInclude Include="..\..\..\code_device\sdk\base\plat_types.h" />
<ClInclude Include="..\..\..\code_device\sdk\base\utils.h" />
<ClInclude Include="..\..\..\code_device\sdk\base\words.h" />
<ClInclude Include="..\..\..\code_device\sdk\json\cJSON.h" />
<ClInclude Include="..\..\..\code_device\sdk\json\gb_json.h" />
<ClInclude Include="..\..\..\code_device\sdk\sane_opt_json\base_opt.h" />
@ -268,6 +270,12 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\base\paper.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\base\utils.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>

View File

@ -132,6 +132,12 @@
<ClInclude Include="..\..\..\code_device\hgsane\sane_opt\sane_opts.h">
<Filter>opt-ui</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\sdk\base\paper.h">
<Filter>Imports\sdk</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\sdk\base\words.h">
<Filter>Imports\sdk</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="usb_tools.cpp">
@ -215,6 +221,9 @@
<ClCompile Include="..\..\..\code_device\hgsane\sane_opt\sane_opts.cpp">
<Filter>opt-ui</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\base\paper.cpp">
<Filter>Imports\sdk</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="usbtools.rc">