添加测试工程

This commit is contained in:
gb 2023-12-14 14:27:57 +08:00
parent f045f7187c
commit 0b445be68f
33 changed files with 8120 additions and 5 deletions

View File

@ -74,6 +74,20 @@ std::wstring ansi2unicode(const char* ansi, UINT cp = CP_ACP)
return unic; return unic;
} }
std::string unicode2ansi(const wchar_t* unic, UINT cp = CP_ACP)
{
int len = WideCharToMultiByte(cp, 0, unic, lstrlenW(unic), NULL, 0, NULL, NULL);
char *buf = new char[len + 4];
memset(buf, 0, len + 4);
len = WideCharToMultiByte(cp, 0, unic, lstrlenW(unic), buf, len, NULL, NULL);
buf[len--] = 0;
std::string ansi(buf);
delete[] buf;
return ansi;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// OVERLAPPED ... // OVERLAPPED ...
ovl_cls::ovl_cls(uint32_t type) : ref_(1), io_bytes_(0), type_(type) ovl_cls::ovl_cls(uint32_t type) : ref_(1), io_bytes_(0), type_(type)
@ -388,6 +402,16 @@ bool usb_device::init(void)
COPY_MEMBER(dev_desc_, &info->ConnectionInfo->DeviceDescriptor, iSerialNumber); COPY_MEMBER(dev_desc_, &info->ConnectionInfo->DeviceDescriptor, iSerialNumber);
COPY_MEMBER(dev_desc_, &info->ConnectionInfo->DeviceDescriptor, bNumConfigurations); COPY_MEMBER(dev_desc_, &info->ConnectionInfo->DeviceDescriptor, bNumConfigurations);
} }
PSTRING_DESCRIPTOR_NODE strdesc = info->StringDescs;
while (strdesc)
{
STRCFG sc;
sc.id = strdesc->DescriptorIndex;
sc.val = strdesc->StringDescriptor ? unicode2ansi(strdesc->StringDescriptor->bString) : "";
str_cfg_.push_back(sc);
strdesc = strdesc->Next;
}
if (info->ConfigDesc) if (info->ConfigDesc)
{ {
libusb_config_descriptor* desc = NULL; libusb_config_descriptor* desc = NULL;
@ -470,6 +494,7 @@ void usb_device::clear(void)
{ {
close(); close();
str_cfg_.clear();
if (dev_desc_) if (dev_desc_)
delete dev_desc_; delete dev_desc_;
dev_desc_ = NULL; dev_desc_ = NULL;
@ -535,6 +560,23 @@ int usb_device::get_config_descriptor(int index, libusb_config_descriptor** desc
return LIBUSB_SUCCESS; return LIBUSB_SUCCESS;
} }
int usb_device::get_config_string(uint8_t desc_index, unsigned char* data, int length)
{
for (auto& v : str_cfg_)
{
if (v.id == desc_index)
{
if (length < v.val.length())
memcpy(data, v.val.c_str(), length);
else
strcpy((char*)data, v.val.c_str());
return LIBUSB_SUCCESS;
}
}
return LIBUSB_ERROR_NOT_FOUND;
}
int usb_device::open(libusb_device_handle** dev_handle) int usb_device::open(libusb_device_handle** dev_handle)
{ {
if (handle_) if (handle_)
@ -679,9 +721,28 @@ int usb_device::transfer_bulk(unsigned endpoint, unsigned char* data, int* lengt
ret = LIBUSB_SUCCESS; ret = LIBUSB_SUCCESS;
} }
else else
{
if (!GetOverlappedResult(h, oc->over_lapped(), oc->io_bytes(), TRUE))
{
utils::to_log(LOG_LEVEL_DEBUG, "Bulk-Transfer of endpoint 0x%02x failed Wait timeout and failed in GetOverlappedResult, set error TIMEOUT.\n", endpoint);
ret = LIBUSB_ERROR_TIMEOUT; ret = LIBUSB_ERROR_TIMEOUT;
} }
else else
{
*length = *oc->io_bytes();
if (*length == 0 && oc->over_lapped()->Internal != ERROR_SUCCESS)
{
ret = oc->over_lapped()->Internal == STATUS_CANCELLED ? /*LIBUSB_ERROR_TRY_AGAIN*/LIBUSB_ERROR_INTERRUPTED : oc->over_lapped()->Internal;
if (ret == ERROR_NO_MORE_ITEMS)
ret = LIBUSB_ERROR_TIMEOUT;
utils::to_log(LOG_LEVEL_WARNING, "Bulk-Transfer of endpoint 0x%02x failed with code 0x%08X\n", endpoint, oc->over_lapped()->Internal);
}
else
ret = LIBUSB_SUCCESS;
}
}
}
else
{ {
if (endpoint & BULKIN_FLAG) if (endpoint & BULKIN_FLAG)
{ {
@ -815,11 +876,11 @@ UINT usb_monitor::find_usb_timer_ = 101;
usb_monitor::usb_monitor() : wnd_monitor_(NULL), handle_msg_id_(0), run_(true) usb_monitor::usb_monitor() : wnd_monitor_(NULL), handle_msg_id_(0), run_(true)
{ {
#ifdef USE_SAFE_THREAD #ifdef USE_SAFE_THREAD
auto tf = [this](void*) -> void auto tf = [this](void) -> void
{ {
thread_handle_device_change_msg(); thread_handle_device_change_msg();
}; };
handle_msg_.start(tf, nullptr, "usb_monitor::thread_handle_device_change_msg"); handle_msg_.start(tf, "usb_monitor::thread_handle_device_change_msg");
#else #else
handle_msg_.reset(new std::thread(&usb_monitor::thread_handle_device_change_msg, this)); handle_msg_.reset(new std::thread(&usb_monitor::thread_handle_device_change_msg, this));
#endif #endif
@ -1220,7 +1281,7 @@ void usb_monitor::thread_handle_device_change_msg(void)
else if(handled) else if(handled)
*handled = false; *handled = false;
return true; return run_;
}; };
handle_msg_id_ = GetCurrentThreadId(); handle_msg_id_ = GetCurrentThreadId();
@ -1230,6 +1291,7 @@ void usb_monitor::quit(void)
{ {
KillTimer(wnd_monitor_, usb_monitor::find_usb_timer_); KillTimer(wnd_monitor_, usb_monitor::find_usb_timer_);
run_ = false; run_ = false;
PostThreadMessageW(handle_msg_id_, WM_QUIT, 0, 0);
if (IsWindow(wnd_monitor_)) if (IsWindow(wnd_monitor_))
{ {
PostMessage(wnd_monitor_, WM_QUIT, 0, 0); PostMessage(wnd_monitor_, WM_QUIT, 0, 0);
@ -1239,7 +1301,6 @@ void usb_monitor::quit(void)
#ifndef USE_SAFE_THREAD #ifndef USE_SAFE_THREAD
if (handle_msg_.get()) if (handle_msg_.get())
{ {
PostThreadMessageW(handle_msg_id_, WM_QUIT, 0, 0);
if (handle_msg_->joinable()) if (handle_msg_->joinable())
handle_msg_->join(); handle_msg_->join();
handle_msg_.reset(); handle_msg_.reset();
@ -1505,3 +1566,8 @@ int LIBUSB_CALL libusb_cancel_transfer(struct libusb_transfer* transfer/*in wind
{ {
return ((usb_device*)transfer)->cancel_io(); return ((usb_device*)transfer)->cancel_io();
} }
int LIBUSB_CALL libusb_get_string_descriptor_ascii(libusb_device_handle* dev_handle,
uint8_t desc_index, unsigned char* data, int length)
{
return ((usb_device*)dev_handle)->get_config_string(desc_index, data, length);
}

View File

@ -106,6 +106,13 @@ class usb_device // consider as libusb_device
libusb_device_descriptor *dev_desc_; libusb_device_descriptor *dev_desc_;
std::vector<libusb_config_descriptor*> cfg_desc_; std::vector<libusb_config_descriptor*> cfg_desc_;
typedef struct _str_cfg
{
int id;
std::string val;
}STRCFG;
std::vector<STRCFG> str_cfg_;
typedef struct _usb_pipe typedef struct _usb_pipe
{ {
UCHAR address; UCHAR address;
@ -151,6 +158,7 @@ public:
void clear(void); void clear(void);
int get_descriptor(libusb_device_descriptor* desc); int get_descriptor(libusb_device_descriptor* desc);
int get_config_descriptor(int index, libusb_config_descriptor** desc); int get_config_descriptor(int index, libusb_config_descriptor** desc);
int get_config_string(uint8_t desc_index, unsigned char* data, int length);
int open(libusb_device_handle** dev_handle); int open(libusb_device_handle** dev_handle);
int close(void); int close(void);
int set_timeout(unsigned milliseconds); int set_timeout(unsigned milliseconds);

View File

@ -26,6 +26,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{53E5EDD9
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hgjson", "..\..\doc_and_tools\tools\apps\hgjson\hgjson.vcxproj", "{D3579C48-F5AB-4F15-9B49-A2970FBA76C5}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hgjson", "..\..\doc_and_tools\tools\apps\hgjson\hgjson.vcxproj", "{D3579C48-F5AB-4F15-9B49-A2970FBA76C5}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "usb_tools", "usb_tools\usb_tools.vcxproj", "{4C912767-88BE-463E-BFFC-AF994A92E425}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_TWAIN_App", "..\..\doc_and_tools\tools\apps\test_TWAIN_App\test_TWAIN_App.vcxproj", "{8C3DEF78-4DF1-4C26-A11E-7031FF773E7D}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
@ -72,6 +76,22 @@ Global
{D3579C48-F5AB-4F15-9B49-A2970FBA76C5}.Release|x64.ActiveCfg = Release|Win32 {D3579C48-F5AB-4F15-9B49-A2970FBA76C5}.Release|x64.ActiveCfg = Release|Win32
{D3579C48-F5AB-4F15-9B49-A2970FBA76C5}.Release|x86.ActiveCfg = Release|Win32 {D3579C48-F5AB-4F15-9B49-A2970FBA76C5}.Release|x86.ActiveCfg = Release|Win32
{D3579C48-F5AB-4F15-9B49-A2970FBA76C5}.Release|x86.Build.0 = Release|Win32 {D3579C48-F5AB-4F15-9B49-A2970FBA76C5}.Release|x86.Build.0 = Release|Win32
{4C912767-88BE-463E-BFFC-AF994A92E425}.Debug|x64.ActiveCfg = Debug|x64
{4C912767-88BE-463E-BFFC-AF994A92E425}.Debug|x64.Build.0 = Debug|x64
{4C912767-88BE-463E-BFFC-AF994A92E425}.Debug|x86.ActiveCfg = Debug|Win32
{4C912767-88BE-463E-BFFC-AF994A92E425}.Debug|x86.Build.0 = Debug|Win32
{4C912767-88BE-463E-BFFC-AF994A92E425}.Release|x64.ActiveCfg = Release|x64
{4C912767-88BE-463E-BFFC-AF994A92E425}.Release|x64.Build.0 = Release|x64
{4C912767-88BE-463E-BFFC-AF994A92E425}.Release|x86.ActiveCfg = Release|Win32
{4C912767-88BE-463E-BFFC-AF994A92E425}.Release|x86.Build.0 = Release|Win32
{8C3DEF78-4DF1-4C26-A11E-7031FF773E7D}.Debug|x64.ActiveCfg = Debug|x64
{8C3DEF78-4DF1-4C26-A11E-7031FF773E7D}.Debug|x64.Build.0 = Debug|x64
{8C3DEF78-4DF1-4C26-A11E-7031FF773E7D}.Debug|x86.ActiveCfg = Debug|Win32
{8C3DEF78-4DF1-4C26-A11E-7031FF773E7D}.Debug|x86.Build.0 = Debug|Win32
{8C3DEF78-4DF1-4C26-A11E-7031FF773E7D}.Release|x64.ActiveCfg = Release|x64
{8C3DEF78-4DF1-4C26-A11E-7031FF773E7D}.Release|x64.Build.0 = Release|x64
{8C3DEF78-4DF1-4C26-A11E-7031FF773E7D}.Release|x86.ActiveCfg = Release|Win32
{8C3DEF78-4DF1-4C26-A11E-7031FF773E7D}.Release|x86.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -82,6 +102,8 @@ Global
{C3B47CE2-27CE-4509-AB59-3C0F194F0FCE} = {C43532EF-1B31-457F-B40B-61F22E91A13E} {C3B47CE2-27CE-4509-AB59-3C0F194F0FCE} = {C43532EF-1B31-457F-B40B-61F22E91A13E}
{7776AB6D-6296-4F7A-A6ED-E9A4D6290DD9} = {C43532EF-1B31-457F-B40B-61F22E91A13E} {7776AB6D-6296-4F7A-A6ED-E9A4D6290DD9} = {C43532EF-1B31-457F-B40B-61F22E91A13E}
{D3579C48-F5AB-4F15-9B49-A2970FBA76C5} = {53E5EDD9-13BA-4F3C-A387-C73CB06C686D} {D3579C48-F5AB-4F15-9B49-A2970FBA76C5} = {53E5EDD9-13BA-4F3C-A387-C73CB06C686D}
{4C912767-88BE-463E-BFFC-AF994A92E425} = {53E5EDD9-13BA-4F3C-A387-C73CB06C686D}
{8C3DEF78-4DF1-4C26-A11E-7031FF773E7D} = {53E5EDD9-13BA-4F3C-A387-C73CB06C686D}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A89068FF-95C4-3C1E-B126-70B66C9824BB} SolutionGuid = {A89068FF-95C4-3C1E-B126-70B66C9824BB}

1484
sln/usb_tools/DlgScanner.cpp Normal file

File diff suppressed because it is too large Load Diff

132
sln/usb_tools/DlgScanner.h Normal file
View File

@ -0,0 +1,132 @@
#pragma once
// CDlgScanner 对话框
#include "../../../code_device/hgdriver/hgdev/hg_scanner.h"
#include <libusb-1.0/libusb.h>
#include "opt_ui/DlgSetting.h"
#include <huagao/brand.h>
#include <base/utils.h>
class CDlgScanner;
namespace usb
{
typedef struct _end_point
{
BYTE iface = -1;
BYTE type = -1;
BYTE addr = -1;
size_t packet = 0;
}USBEP;
typedef struct _usb_pnp
{
libusb_context* ctx = NULL;
libusb_device* device = NULL;
libusb_device_handle* handle = NULL;
CDlgScanner* dlg = NULL;
WORD vid = 0;
WORD pid = 0;
bool arrive = true;
std::vector<USBEP> eps;
}USBPNP, * LPUSBPNP;
std::wstring now(void);
const wchar_t* error_name(int err, wchar_t* unk = NULL);
std::wstring a2u(const char* ansi);
std::string u2a(const wchar_t* unic);
void enum_endpoints(libusb_device* device, std::vector<USBEP>& eps);
const wchar_t* ep_type(BYTE type);
BYTE ep_type(const wchar_t* str);
}
enum
{
WM_USB_PNP = WM_USER + 1001,
WM_RCV_MSG,
WM_OPENNING_DLG_CLOSED,
WM_TRAY_MSG,
WM_TIMER_CANCEL_TOPMOST,
};
class CDlgScanner : public CDialogEx
{
DECLARE_DYNAMIC(CDlgScanner)
enum
{
FILE_TX_RECEIVE = 1 << 0,
FILE_TX_SEND = 1 << 1,
};
HWND parent_;
hg_scanner* scanner_;
volatile int auto_tx_ = 0;
uint32_t auto_tx_file_;
HANDLE auto_wait_;
dlg_setting *setting_ui_;
SANEAPI sane_api_;
std::wstring img_root_;
uint32_t img_cnt_;
uint32_t paper_cnt_;
uint32_t max_sent_;
uint32_t max_cmd_;
safe_thread threads_;
public:
CDlgScanner(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CDlgScanner();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_SCANNER };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
virtual BOOL OnInitDialog();
virtual BOOL PreTranslateMessage(MSG* pMsg);
DECLARE_MESSAGE_MAP()
int refresh_bulk_status(void);
void thread_auto_tx_file(void);
void enable_buttons(bool enable);
void set_text(UINT id, const wchar_t* text);
bool is_checked(UINT id);
void set_check(UINT id, bool checked);
void click_repeat(bool enable_buttons = false, bool enable = true);
public:
void set_device(ONLNSCANNER* pnp);
bool is_online(void);
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);
public:
CTabCtrl tab_opt_;
CTabCtrl tab_oper_;
afx_msg void OnTcnSelchangeTabOper(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnBnClickedOk();
afx_msg void OnBnClickedButtonResetBulk();
afx_msg void OnBnClickedButtonBrowseSavingPath();
afx_msg void OnBnClickedButtonScan();
afx_msg void OnBnClickedButtonBrowseFile();
afx_msg void OnBnClickedButtonSendFile();
afx_msg void OnBnClickedButtonRecvFile();
afx_msg void OnBnClickedButtonStartProgram();
afx_msg void OnBnClickedButtonSendEp0();
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnBnClickedCheckAuto();
afx_msg void OnBnClickedButtonRefresh();
afx_msg void OnBnClickedCheckRepeat();
afx_msg LRESULT OnSetText(WPARAM wp, LPARAM lp);
afx_msg LRESULT OnIsButtonChecked(WPARAM wp, LPARAM lp);
afx_msg LRESULT OnSetButtonChecked(WPARAM wp, LPARAM lp);
afx_msg LRESULT OnEnableCtrls(WPARAM wp, LPARAM lp);
afx_msg LRESULT OnDeviceStatus(WPARAM wp, LPARAM lp);
afx_msg void OnCbnSelchangeComboBufSize();
CComboBox buf_;
afx_msg void OnDestroy();
};

57
sln/usb_tools/framework.h Normal file
View File

@ -0,0 +1,57 @@
#pragma once
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料
#endif
#include "targetver.h"
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的
// 关闭 MFC 的一些常见且经常可放心忽略的隐藏警告消息
#define _AFX_ALL_WARNINGS
// #define WIN32_LEAN_AND_MEAN
//#define _WINSOCK2API_
//#define _WS2IPDEF_
////#define IPV6STRICT
//#define __IPHLPAPI_H__
//#define _WINDNS_INCLUDED_
#include <afxwin.h> // MFC 核心组件和标准组件
#include <afxext.h> // MFC 扩展
#include <afxdisp.h> // MFC 自动化类
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h> // MFC 对 Internet Explorer 4 公共控件的支持
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC 对 Windows 公共控件的支持
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxcontrolbars.h> // MFC 支持功能区和控制条
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif

View File

@ -0,0 +1,813 @@
// DlgIndicator.cpp: 实现文件
//
#include "DlgArea.h"
#include "../resource.h"
#include "mem_dc.h"
// CDlgIndicator 对话框
#define MM_PER_INCH 25.4f
int dlg_area::area_min_pixel = 50;
dlg_area::dlg_area(HWND parent) : dlg_base(parent, IDD_AREA)
, unit_(PAPER_UNIT_MM), paper_w_(210), paper_h_(297), dpi_(200)
, x_(0), y_(0), w_(paper_w_), h_(paper_h_)
, paper_(L"A4")
, paper_w_0_(paper_w_), paper_h_0_(paper_h_), cursor_(NULL), drag_(DRAG_POS_NONE)
, in_set_func_(false)
{
std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_CUSTOM_AREA));
create();
SetWindowTextW(hwnd(), title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_MM) + L" (mm)";
SendMessageW(get_item(IDC_UNIT), CB_ADDSTRING, 0, (LPARAM)&title[0]);
title = local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_INCH) + L" (inch)";
SendMessageW(get_item(IDC_UNIT), CB_ADDSTRING, 0, (LPARAM)&title[0]);
title = local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_PIXEL) + L" (px)";
SendMessageW(get_item(IDC_UNIT), CB_ADDSTRING, 0, (LPARAM)&title[0]);
SendMessage(get_item(IDC_UNIT), CB_SETCURSEL, 0, 0);
if (!dlg_base::is_language_pack_default_code_page())
{
int width_diff = 0, w = 0;
RECT r = { 0 }, rp = { 0 };
title = local_trans::lang_trans_between_hz936(CONST_STRING_OPT_PAPER) + L":";
set_item_text(IDC_STATIC_PAPER, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_UNIT) + L":";
set_item_text(IDC_STATIC_UNIT, title.c_str());
title = L"DPI (" + local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_PIXEL) + L"/" + local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_INCH) + L"):";
set_item_text(IDC_STATIC_DPI, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_AREA_SET) + L":";
set_item_text(IDC_STATIC_AREA, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_LEFT) + L":";
set_item_text(IDC_STATIC_LEFT, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_TOP) + L":";
set_item_text(IDC_STATIC_TOP, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_WIDTH) + L":";
set_item_text(IDC_STATIC_W, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_HEIGHT) + L":";
set_item_text(IDC_STATIC_H, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_RESTORE_AREA);
set_item_text(IDC_BUTTON_RESET, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_CANCEL);
set_item_text(IDCANCEL, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_OK);
set_item_text(IDOK, title.c_str());
layout();
}
}
dlg_area::~dlg_area()
{
}
float dlg_area::mm_2_pixel(float mm, float dpi)
{
return inches_2_pixel(mm_2_inches(mm), dpi);
}
float dlg_area::mm_2_inches(float mm)
{
return mm / MM_PER_INCH;
}
float dlg_area::inches_2_pixel(float inch, float dpi)
{
return inch * dpi;
}
float dlg_area::inches_2_mm(float inch)
{
return inch * MM_PER_INCH;
}
float dlg_area::pixel_2_mm(float px, float dpi)
{
return inches_2_mm(pixel_2_inches(px, dpi));
}
float dlg_area::pixel_2_inches(float px, float dpi)
{
return px / dpi;
}
BOOL dlg_area::handle_message(UINT msg, WPARAM wp, LPARAM lp)
{
wchar_t text[40] = { 0 };
BOOL ret = TRUE;
switch (msg)
{
case WM_INITDIALOG:
UpdateWindow(hwnd());
break;
case WM_COMMAND:
handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp);
break;
case WM_PAINT:
{
PAINTSTRUCT ps = { 0 };
HDC hdc = BeginPaint(hwnd(), &ps);
{
compatible_dc dc(hdc);
on_paint(dc.get_dc());
}
EndPaint(hwnd(), &ps);
}
break;
case WM_MOUSEMOVE:
on_mouse_move(wp, LOWORD(lp), HIWORD(lp));
break;
case WM_LBUTTONDOWN:
on_lbutton_down(LOWORD(lp), HIWORD(lp));
break;
case WM_LBUTTONUP:
on_lbutton_up(LOWORD(lp), HIWORD(lp));
break;
default:
ret = FALSE;
}
return ret;
}
void dlg_area::handle_command(WORD code, WORD id, HANDLE ctrl)
{
if (id == IDC_UNIT)
{
if (code == CBN_SELCHANGE)
{
on_unit_changed((HWND)ctrl);
}
}
else if (id == IDCANCEL)
{
quit_modal(id);
}
else if (id == IDOK)
{
quit_modal(id);
}
else if (id == IDC_BUTTON_RESET)
{
clear_area();
}
else if (id == IDC_EDIT_x ||
id == IDC_EDIT_y ||
id == IDC_EDIT_W ||
id == IDC_EDIT_H)
{
if (code == EN_CHANGE && !in_set_func_)
{
wchar_t val[80] = { 0 };
float num = .0f;
GetWindowTextW((HWND)ctrl, val, _countof(val) - 1);
num = (float)_wtof(val);
if (id == IDC_EDIT_x)
{
if (num < .0f)
num = .0f;
if (num > paper_w_ - dlg_area::area_min_pixel)
num = paper_w_ - dlg_area::area_min_pixel;
x_ = num;
user_sel_.left = whole_.left + (LONG)(x_ / ratio_);
if (x_ + w_ > paper_w_)
w_ = paper_w_ - x_;
user_sel_.right = user_sel_.left + (LONG)(w_ / ratio_);
refresh_paper_info();
InvalidateRect(hwnd(), &whole_, FALSE);
}
else if (id == IDC_EDIT_y)
{
if (num < .0f)
num = .0f;
if (num > paper_h_ - dlg_area::area_min_pixel)
num = paper_h_ - dlg_area::area_min_pixel;
y_ = num;
user_sel_.top = whole_.top + (LONG)(y_ / ratio_);
if (y_ + h_ > paper_h_)
h_ = paper_h_ - y_;
user_sel_.bottom = user_sel_.top + (LONG)(h_ / ratio_);
refresh_paper_info();
InvalidateRect(hwnd(), &whole_, FALSE);
}
else if (id == IDC_EDIT_W)
{
if (num < dlg_area::area_min_pixel)
num = (float)dlg_area::area_min_pixel;
if (num > paper_w_)
num = paper_w_;
w_ = num;
user_sel_.right = user_sel_.left + (LONG)(w_ / ratio_);
if (user_sel_.right > whole_.right)
{
OffsetRect(&user_sel_, whole_.right - user_sel_.right, 0);
if (user_sel_.left < whole_.left)
{
user_sel_.left = whole_.left;
x_ = 0;
}
}
refresh_paper_info();
InvalidateRect(hwnd(), &whole_, FALSE);
}
else if (id == IDC_EDIT_H)
{
if (num < dlg_area::area_min_pixel)
num = (float)dlg_area::area_min_pixel;
if (num > paper_h_)
num = paper_h_;
h_ = num;
user_sel_.bottom = user_sel_.top + (LONG)(h_ / ratio_);
if (user_sel_.bottom > whole_.bottom)
{
OffsetRect(&user_sel_, 0, whole_.bottom - user_sel_.bottom);
if (user_sel_.top < whole_.top)
{
user_sel_.top = whole_.top;
y_ = 0;
}
}
refresh_paper_info();
InvalidateRect(hwnd(), &whole_, FALSE);
}
}
}
}
void dlg_area::layout(void)
{
RECT r = { 0 };
int w_dif = get_width_diff_as_text_length(IDC_STATIC_LEFT),
top1 = get_width_diff_as_text_length(IDC_STATIC_PAPER),
top21 = get_width_diff_as_text_length(IDC_STATIC_UNIT),
top22 = get_width_diff_as_text_length(IDC_STATIC_DPI);
#define CHECK_CTRL_W(id) \
if(w_dif < get_width_diff_as_text_length(id)) \
w_dif = get_width_diff_as_text_length(id);
CHECK_CTRL_W(IDC_STATIC_TOP);
CHECK_CTRL_W(IDC_STATIC_W);
CHECK_CTRL_W(IDC_STATIC_H);
CHECK_CTRL_W(IDC_BUTTON_RESET);
if (w_dif < top21 + top22)
w_dif = top21 + top22;
// layout ...
if (w_dif > 0)
{
GetWindowRect(hwnd(), &r);
r.right += w_dif;
MoveWindow(hwnd(), r.left, r.top, RECT_W(r), RECT_H(r), FALSE);
expand_item(IDC_STATIC_PAPER, top1, 0);
offset_item(IDC_EDIT_PAPER, top1, 0);
expand_item(IDC_EDIT_PAPER, w_dif - top1, 0);
expand_item(IDC_STATIC_UNIT, top21, 0);
offset_item(IDC_UNIT, top21, 0);
offset_item(IDC_STATIC_DPI, w_dif - top22, 0);
expand_item(IDC_STATIC_DPI, top22, 0);
offset_item(IDC_EDIT_DPI, top21 + top22, 0);
expand_item(IDC_STATIC_AREA, w_dif, 0);
expand_item(IDC_STATIC_LEFT, w_dif, 0);
offset_item(IDC_EDIT_x, w_dif, 0);
expand_item(IDC_STATIC_TOP, w_dif, 0);
offset_item(IDC_EDIT_y, w_dif, 0);
expand_item(IDC_STATIC_W, w_dif, 0);
offset_item(IDC_EDIT_W, w_dif, 0);
expand_item(IDC_STATIC_H, w_dif, 0);
offset_item(IDC_EDIT_H, w_dif, 0);
top1 = get_width_diff_as_text_length(IDC_BUTTON_RESET);
expand_item(IDC_BUTTON_RESET, top1, 0);
offset_item(IDC_BUTTON_RESET, (w_dif - top1) / 2, 0);
offset_item(IDOK, w_dif, 0);
offset_item(IDCANCEL, w_dif, 0);
}
}
float dlg_area::as_mm(float v)
{
if (unit_ == PAPER_UNIT_INCH)
return dlg_area::inches_2_mm(v);
else if (unit_ == PAPER_UNIT_PIXEL)
return dlg_area::pixel_2_mm(v, dpi_);
else
return v;
}
float dlg_area::from_mm(float v)
{
if (unit_ == PAPER_UNIT_INCH)
return dlg_area::mm_2_inches(v);
else if (unit_ == PAPER_UNIT_PIXEL)
return dlg_area::mm_2_pixel(v, dpi_);
else
return v;
}
float dlg_area::as_inches(float v)
{
if (unit_ == PAPER_UNIT_MM)
return dlg_area::mm_2_inches(v);
else if (unit_ == PAPER_UNIT_PIXEL)
return dlg_area::pixel_2_inches(v, dpi_);
else
return v;
}
float dlg_area::as_pixels(float v)
{
if (unit_ == PAPER_UNIT_MM)
return dlg_area::mm_2_pixel(v, dpi_);
else if (unit_ == PAPER_UNIT_INCH)
return dlg_area::inches_2_pixel(v, dpi_);
else
return v;
}
std::wstring dlg_area::format_number(float v)
{
wchar_t str[40] = { 0 };
if (unit_ == PAPER_UNIT_PIXEL)
swprintf_s(str, _countof(str) - 1, L"%d", (int)(v + .5f));
else
swprintf_s(str, _countof(str) - 1, L"%.2f", v);
return str;
}
void dlg_area::refresh_paper_info(void)
{
SetWindowTextW(get_item(IDC_EDIT_PAPER), (paper_ + L"" + format_number(paper_w_) + local_trans::lang_trans_between_hz936(CONST_STRING_MULTIPLE) + format_number(paper_h_) + L"").c_str());
SetDlgItemInt(hwnd(), IDC_EDIT_DPI, UINT(dpi_), FALSE);
in_set_func_ = true;
SetWindowTextW(get_item(IDC_EDIT_x), format_number(x_).c_str());
SetWindowTextW(get_item(IDC_EDIT_y), format_number(y_).c_str());
SetWindowTextW(get_item(IDC_EDIT_W), format_number(w_).c_str());
SetWindowTextW(get_item(IDC_EDIT_H), format_number(h_).c_str());
in_set_func_ = false;
InvalidateRect(hwnd(), &whole_, FALSE);
}
void dlg_area::to_unit(paper_unit unit)
{
float(dlg_area:: * conv)(float) = NULL;
if (unit == PAPER_UNIT_INCH)
{
conv = &dlg_area::as_inches;
paper_w_ = dlg_area::mm_2_inches(paper_w_0_);
paper_h_ = dlg_area::mm_2_inches(paper_h_0_);
}
else if (unit == PAPER_UNIT_PIXEL)
{
conv = &dlg_area::as_pixels;
paper_w_ = dlg_area::mm_2_pixel(paper_w_0_, dpi_);
paper_h_ = dlg_area::mm_2_pixel(paper_h_0_, dpi_);
}
else // if (unit == PAPER_UNIT_MM)
{
conv = &dlg_area::as_mm;
paper_w_ = paper_w_0_;
paper_h_ = paper_h_0_;
}
#define CONV_UNIT(v) \
v = (this->*conv)(v);
CONV_UNIT(x_);
CONV_UNIT(y_);
CONV_UNIT(w_);
CONV_UNIT(h_);
unit_ = unit;
refresh_paper_info();
}
void dlg_area::clear_area(void)
{
x_ = y_ = 0;
w_ = paper_w_;
h_ = paper_h_;
user_sel_ = whole_;
refresh_paper_info();
}
void dlg_area::drag_blocks(std::vector<DRAGRECT>& blocks)
{
int l = 5;
DRAGRECT r;
r.left = user_sel_.left;
r.top = user_sel_.top;
r.right = r.left + l;
r.bottom = r.top + l;
r.pos = DRAG_POS_LT;
blocks.clear();
blocks.push_back(r);
OffsetRect(&r, (user_sel_.right - user_sel_.left) / 2 - l / 2, 0); r.pos = DRAG_POS_MT;
blocks.push_back(r);
OffsetRect(&r, (user_sel_.right - r.right), 0); r.pos = DRAG_POS_RT;
blocks.push_back(r);
OffsetRect(&r, 0, (user_sel_.bottom - user_sel_.top) / 2 - l / 2); r.pos = DRAG_POS_RM;
blocks.push_back(r);
OffsetRect(&r, 0, (user_sel_.bottom - r.bottom)); r.pos = DRAG_POS_RB;
blocks.push_back(r);
OffsetRect(&r, -((user_sel_.right - user_sel_.left) / 2 - l / 2), 0); r.pos = DRAG_POS_MB;
blocks.push_back(r);
OffsetRect(&r, user_sel_.left - r.left, 0); r.pos = DRAG_POS_LB;
blocks.push_back(r);
OffsetRect(&r, 0, -((user_sel_.bottom - user_sel_.top) / 2 - l / 2)); r.pos = DRAG_POS_LM;
blocks.push_back(r);
}
float dlg_area::pos_2_area(int val, bool x)
{
float r = x ? (float)(val - whole_.left) : (float)(val - whole_.top);
r *= ratio_;
if (unit_ == PAPER_UNIT_INCH)
r = dlg_area::mm_2_inches(r);
else if (unit_ == PAPER_UNIT_PIXEL)
r = dlg_area::mm_2_pixel(r, dpi_);
return r;
}
void dlg_area::valid_x(int& x, bool left)
{
if (left)
{
if (x < whole_.left)
x = whole_.left;
if (x > user_sel_.right - dlg_area::area_min_pixel)
x = user_sel_.right - dlg_area::area_min_pixel;
}
else
{
if (x > whole_.right)
x = whole_.right;
if (x < user_sel_.left + dlg_area::area_min_pixel)
x = user_sel_.left + dlg_area::area_min_pixel;
}
}
void dlg_area::valid_y(int& y, bool top)
{
if (top)
{
if (y < whole_.top)
y = whole_.top;
if (y > user_sel_.bottom - dlg_area::area_min_pixel)
y = user_sel_.bottom - dlg_area::area_min_pixel;
}
else
{
if (y > whole_.bottom)
y = whole_.bottom;
if (y < user_sel_.top + dlg_area::area_min_pixel)
y = user_sel_.top + dlg_area::area_min_pixel;
}
}
void dlg_area::on_unit_changed(HWND wnd)
{
wchar_t text[80] = { 0 };
GetWindowTextW(wnd, text, _countof(text) - 1);
if (wcsstr(text, L"mm"))
{
if (unit_ != PAPER_UNIT_MM)
{
to_unit(PAPER_UNIT_MM);
}
}
else if (wcsstr(text, L"inch"))
{
if (unit_ != PAPER_UNIT_INCH)
{
to_unit(PAPER_UNIT_INCH);
}
}
else
{
if (unit_ != PAPER_UNIT_PIXEL)
{
to_unit(PAPER_UNIT_PIXEL);
}
}
}
void dlg_area::on_paint(HDC hdc)
{
HBRUSH brsh_all = CreateSolidBrush(RGB(192, 192, 192)),
brsh_drag = CreateSolidBrush(RGB(255, 0, 0)),
brsh_sel = CreateSolidBrush(RGB(255, 255, 255));
HPEN pen_border = CreatePen(PS_SOLID, 1, RGB(0, 255, 0)),
pen_ruler = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)),
pen_old = (HPEN)SelectObject(hdc, pen_border);
int step = 3, minor = 3, major = 5, count = 1, len = 0;
FillRect(hdc, &whole_, brsh_all);
FillRect(hdc, &user_sel_, brsh_sel);
Rectangle(hdc, user_sel_.left, user_sel_.top, user_sel_.right, user_sel_.bottom);
SelectObject(hdc, pen_ruler);
for (int i = whole_.left + step; i < whole_.right; i += step)
{
++count;
len = (count % 5) == 0 ? major : minor;
MoveToEx(hdc, i, whole_.top, NULL);
LineTo(hdc, i, whole_.top + len);
MoveToEx(hdc, i, whole_.bottom, NULL);
LineTo(hdc, i, whole_.bottom - len);
}
count = 1;
for (int i = whole_.top + step; i < whole_.bottom; i += step)
{
++count;
len = (count % 5) == 0 ? major : minor;
MoveToEx(hdc, whole_.left, i, NULL);
LineTo(hdc, whole_.left + len, i);
MoveToEx(hdc, whole_.right, i, NULL);
LineTo(hdc, whole_.right - len, i);
}
std::vector<DRAGRECT> r;
drag_blocks(r);
for(size_t i = 0; i < r.size(); ++i)
FillRect(hdc, &r[i], brsh_drag);
SelectObject(hdc, pen_old);
DeleteObject(pen_border);
DeleteObject(pen_ruler);
DeleteObject(brsh_all);
DeleteObject(brsh_sel);
DeleteObject(brsh_drag);
}
void dlg_area::on_mouse_move(DWORD key, int x, int y)
{
if (key == MK_LBUTTON)
{
if (drag_ == DRAG_POS_NONE)
return;
float dif = .0f;
SetCursor(LoadCursorW(NULL, cursor_));
if (drag_ == DRAG_POS_LT)
{
valid_x(x, true);
valid_y(y, true);
user_sel_.left = x;
user_sel_.top = y;
dif = x_;
x_ = pos_2_area(x, true);
w_ -= x_ - dif;
dif = y_;
y_ = pos_2_area(y, false);
h_ -= y_ - dif;
}
else if (drag_ == DRAG_POS_MT)
{
valid_y(y, true);
user_sel_.top = y;
dif = y_;
y_ = pos_2_area(y, false);
h_ -= y_ - dif;
}
else if(drag_ == DRAG_POS_RT)
{
valid_x(x, false);
valid_y(y, true);
user_sel_.right = x;
user_sel_.top = y;
w_ = pos_2_area(x, true) - x_;
if (x_ + w_ > paper_w_)
w_ = paper_w_ - x_;
dif = y_;
y_ = pos_2_area(y, false);
h_ -= y_ - dif;
}
else if (drag_ == DRAG_POS_LM)
{
valid_x(x, true);
user_sel_.left = x;
dif = x_;
x_ = pos_2_area(x, true);
w_ -= x_ - dif;
}
else if (drag_ == DRAG_POS_RM)
{
valid_x(x, false);
user_sel_.right = x;
w_ = pos_2_area(x, true) - x_;
if (x_ + w_ > paper_w_)
w_ = paper_w_ - x_;
}
else if (drag_ == DRAG_POS_LB)
{
valid_x(x, true);
valid_y(y, false);
user_sel_.left = x;
user_sel_.bottom = y;
dif = x_;
x_ = pos_2_area(x, true);
w_ -= x_ - dif;
h_ = pos_2_area(y, false) - y_;
}
else if (drag_ == DRAG_POS_MB)
{
valid_y(y, false);
user_sel_.bottom = y;
h_ = pos_2_area(y, false) - y_;
if (y_ + h_ > paper_h_)
h_ = paper_h_ - y_;
}
else if (drag_ == DRAG_POS_RB)
{
valid_x(x, false);
valid_y(y, false);
user_sel_.right = x;
user_sel_.bottom = y;
w_ = pos_2_area(x, true) - x_;
if (x_ + w_ > paper_w_)
w_ = paper_w_ - x_;
h_ = pos_2_area(y, false) - y_;
if (y_ + h_ > paper_h_)
h_ = paper_h_ - y_;
}
else if (drag_ == DRAG_POS_MOVE)
{
x += move_.x;
y += move_.y;
OffsetRect(&user_sel_, x - user_sel_.left, y - user_sel_.top);
if (user_sel_.left < whole_.left)
OffsetRect(&user_sel_, whole_.left - user_sel_.left, 0);
if (user_sel_.right > whole_.right)
OffsetRect(&user_sel_, whole_.right - user_sel_.right, 0);
if (user_sel_.top < whole_.top)
OffsetRect(&user_sel_, 0, whole_.top - user_sel_.top);
if (user_sel_.bottom > whole_.bottom)
OffsetRect(&user_sel_, 0, whole_.bottom - user_sel_.bottom);
x_ = pos_2_area(user_sel_.left, true);
if (x_ + w_ > paper_w_)
x_ = paper_w_ - w_;
y_ = pos_2_area(user_sel_.top, false);
if (y_ + h_ > paper_h_)
y_ = paper_h_ - h_;
}
refresh_paper_info();
InvalidateRect(hwnd(), &whole_, FALSE);
return;
}
POINT pt = { x, y };
std::vector<DRAGRECT> r;
bool handled = false;
drag_blocks(r);
for (size_t i = 0; i < r.size(); ++i)
{
if (PtInRect(&r[i], pt))
{
handled = true;
if (r[i].pos == DRAG_POS_LT || r[i].pos == DRAG_POS_RB)
cursor_ = IDC_SIZENWSE;
else if(r[i].pos == DRAG_POS_RT || r[i].pos == DRAG_POS_LB)
cursor_ = IDC_SIZENESW;
else if(r[i].pos == DRAG_POS_MT || r[i].pos == DRAG_POS_MB)
cursor_ = IDC_SIZENS;
else
cursor_ = IDC_SIZEWE;
drag_ = r[i].pos;
SetCursor(LoadCursor(NULL, cursor_));
break;
}
}
if (!handled)
{
if (PtInRect(&user_sel_, pt))
{
drag_ = DRAG_POS_MOVE;
cursor_ = IDC_SIZEALL;
SetCursor(LoadCursor(NULL, cursor_));
}
else
{
drag_ = DRAG_POS_NONE;
cursor_ = NULL;
}
}
}
void dlg_area::on_lbutton_down(int x, int y)
{
move_.x = user_sel_.left - x;
move_.y = user_sel_.top - y;
if (cursor_)
SetCursor(LoadCursorW(NULL, cursor_));
SetCapture(hwnd());
}
void dlg_area::on_lbutton_up(int x, int y)
{
drag_ = DRAG_POS_NONE;
cursor_ = NULL;
ReleaseCapture();
}
void dlg_area::set_paper(const wchar_t* name, int width_px, int height_px, float dpi)
{
wchar_t paper[40] = { 0 };
dpi_ = dpi;
paper_ = name;
paper_w_0_ = dlg_area::pixel_2_mm(width_px, dpi);
paper_h_0_ = dlg_area::pixel_2_mm(height_px, dpi);
if (unit_ == PAPER_UNIT_INCH)
{
paper_w_ = dlg_area::pixel_2_inches(width_px, dpi);
paper_h_ = dlg_area::pixel_2_inches(height_px, dpi);
}
else if (unit_ == PAPER_UNIT_MM)
{
paper_w_ = paper_w_0_;
paper_h_ = paper_h_0_;
}
else
{
paper_w_ = width_px;
paper_h_ = height_px;
}
RECT r = { 0 };
float xr = 1.0f,
yr = 1.0f;
GetWindowRect(get_item(IDC_STATIC_PAINT), &r);
screen_2_client(&r);
xr = paper_w_0_ / (r.right - r.left);
yr = paper_h_0_ / (r.bottom - r.top);
ratio_ = xr >= yr ? xr : yr;
xr = paper_w_0_ / ratio_;
xr = (r.right - r.left - xr) / 2;
yr = paper_h_0_ / ratio_;
yr = (r.bottom - r.top - yr) / 2;
whole_.left = r.left + (LONG)xr; whole_.right = r.right - (LONG)xr;
whole_.top = r.top + (LONG)yr; whole_.bottom = r.bottom - (LONG)yr;
clear_area();
}
void dlg_area::set_area(float x, float y, float w, float h)
{
x_ = from_mm(x);
y_ = from_mm(y);
w_ = from_mm(w);
h_ = from_mm(h);
if (x_ > paper_w_)
{
if (w_ < paper_w_)
x_ = paper_w_ - w_;
else
x_ = 0;
}
if (w_ + x_ > paper_w_)
w_ = paper_w_ - x_;
if (y_ > paper_h_)
{
if (h_ < paper_h_)
y_ = paper_h_ - h_;
else
y_ = 0;
}
if (h_ + y_ > paper_h_)
h_ = paper_h_ - y_;
user_sel_.left = whole_.left + (LONG)(x_ / ratio_);
user_sel_.top = whole_.top + (LONG)(y_ / ratio_);
user_sel_.right = user_sel_.left + (LONG)(w_ / ratio_);
user_sel_.bottom = user_sel_.top + (LONG)(h_ / ratio_);
refresh_paper_info();
}
float dlg_area::x_in_mm(void)
{
return as_mm(x_);
}
float dlg_area::y_in_mm(void)
{
return as_mm(y_);
}
float dlg_area::w_in_mm(void)
{
return as_mm(w_);
}
float dlg_area::h_in_mm(void)
{
return as_mm(h_);
}

View File

@ -0,0 +1,98 @@
#pragma once
#include <Windows.h>
#include <string>
#include "DlgPage.h"
// CDlgIndicator 对话框
class dlg_area: public dlg_base
{
enum paper_unit
{
PAPER_UNIT_MM = 0,
PAPER_UNIT_INCH,
PAPER_UNIT_PIXEL,
};
enum drag_pos
{
DRAG_POS_NONE = 0,
DRAG_POS_LT,
DRAG_POS_MT,
DRAG_POS_RT,
DRAG_POS_LM,
DRAG_POS_RM,
DRAG_POS_LB,
DRAG_POS_MB,
DRAG_POS_RB,
DRAG_POS_MOVE,
};
typedef struct _drag_block : RECT
{
drag_pos pos;
}DRAGRECT;
std::wstring paper_;
paper_unit unit_;
float paper_w_0_;
float paper_h_0_;
float paper_w_;
float paper_h_;
float dpi_;
float x_;
float y_;
float w_;
float h_;
RECT whole_;
RECT user_sel_;
float ratio_; // mm / pixel
drag_pos drag_;
POINT move_;
bool in_set_func_;
const wchar_t* cursor_;
static int area_min_pixel;
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
void handle_command(WORD code, WORD id, HANDLE ctrl);
void layout(void);
float as_mm(float v);
float from_mm(float v);
float as_inches(float v);
float as_pixels(float v);
std::wstring format_number(float v);
void refresh_paper_info(void);
void to_unit(paper_unit unit);
void clear_area(void);
void drag_blocks(std::vector<DRAGRECT>& blocks);
float pos_2_area(int val, bool x);
void valid_x(int& x, bool left);
void valid_y(int& y, bool top);
void on_unit_changed(HWND wnd);
void on_paint(HDC hdc);
void on_mouse_move(DWORD key, int x, int y);
void on_lbutton_down(int x, int y);
void on_lbutton_up(int x, int y);
public:
dlg_area(HWND parent);
~dlg_area();
static float mm_2_pixel(float mm, float dpi);
static float mm_2_inches(float mm);
static float inches_2_pixel(float inch, float dpi);
static float inches_2_mm(float inch);
static float pixel_2_mm(float px, float dpi);
static float pixel_2_inches(float px, float dpi);
public:
void set_paper(const wchar_t* name, int width_px, int height_px, float dpi);
void set_area(float x, float y, float w, float h);
float x_in_mm(void);
float y_in_mm(void);
float w_in_mm(void);
float h_in_mm(void);
};

View File

@ -0,0 +1,823 @@
// DlgIndicator.cpp: 实现文件
//
#include "DlgGamma.h"
#include "../resource.h"
#include "mem_dc.h"
#define MAX_KEY_POINTS 4 // not include (0, 0) and (255, 255)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// calculator
#include <math.h>
namespace calc
{
void solve_matrix(double** a, int n, std::vector<double>& coef)
{
int m = 0;
int i, j;
coef.clear();
for (j = 0; j < n; j++) {
double max = 0;
double imax = 0;
for (i = j; i < n; i++) {
if (imax < fabs(a[i][j])) {
imax = fabs(a[i][j]);
max = a[i][j];//得到各行中所在列最大元素
m = i;
}
}
if (fabs(a[j][j]) != max) {
double b = 0;
for (int k = j; k < n + 1; k++) {
b = a[j][k];
a[j][k] = a[m][k];
a[m][k] = b;
}
}
for (int r = j; r < n + 1; r++) {
a[j][r] = a[j][r] / max;//让该行的所在列除以所在列的第一个元素目的是让首元素为1
}
for (i = j + 1; i < n; i++) {
double c = a[i][j];
if (c == 0) continue;
for (int s = j; s < n + 1; s++) {
//double tempdata = a[i][s];
a[i][s] = a[i][s] - a[j][s] * c;//前后行数相减使下一行或者上一行的首元素为0
}
}
}
for (i = n - 2; i >= 0; i--) {
for (j = i + 1; j < n; j++) {
a[i][n] = a[i][n] - a[j][n] * a[i][j];
}
}
for (int k = 0; k < n; k++) {
coef.push_back(a[k][n]);
}
}
int power(int m, int exp)
{
int val = 1;
for (int i = 0; i < exp; ++i)
val *= m;
return val;
}
std::vector<double> coefs_from_points(const std::vector<POINT>& pt)
{
std::vector<double> coef;
double** a = new double* [pt.size()];
for (int i = 0; i < (int)pt.size(); ++i)
a[i] = new double[pt.size() + 1];
for (int i = 0; i < (int)pt.size(); ++i)
{
for (int j = 0; j < (int)pt.size(); ++j)
a[i][j] = power(pt[i].x, pt.size() - j - 1);
a[i][pt.size()] = pt[i].y;
}
solve_matrix(a, pt.size(), coef);
for (int i = 0; i < (int)pt.size(); ++i)
delete[] a[i];
delete[] a;
return coef;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// dlg_gamma
dlg_gamma::dlg_gamma(HWND parent, bool color) : dlg_base(parent, IDD_GAMMA), is_color_(color), bkgnd_(NULL)
, show_all_(false)
{
std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_CUSTOM_TONE));
create();
SetWindowTextW(hwnd(), title.c_str());
if (!dlg_base::is_language_pack_default_code_page())
{
title = local_trans::lang_trans_between_hz936(CONST_STRING_TONE_SCHEME);
set_item_text(IDC_STATIC_SCHEME, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_COLOR_CHANNEL);
set_item_text(IDC_STATIC_COLOR, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_INITIALIZE);
set_item_text(IDC_BUTTON_RESET, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_INPUT);
set_item_text(IDC_STATIC_INPUT, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_OUTPUT);
set_item_text(IDC_STATIC_OUTPUT, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_CANCEL);
set_item_text(IDCANCEL, title.c_str());
title = local_trans::lang_trans_between_hz936(CONST_STRING_OK);
set_item_text(IDOK, title.c_str());
layout();
}
}
dlg_gamma::~dlg_gamma()
{
DeleteObject(bkgnd_);
}
BOOL dlg_gamma::handle_message(UINT msg, WPARAM wp, LPARAM lp)
{
wchar_t text[40] = { 0 };
BOOL ret = TRUE;
switch (msg)
{
case WM_INITDIALOG:
on_init_dlg();
UpdateWindow(hwnd());
break;
case WM_COMMAND:
handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp);
break;
case WM_PAINT:
{
PAINTSTRUCT ps = { 0 };
HDC hdc = BeginPaint(hwnd(), &ps);
{
compatible_dc dc(hdc);
on_paint(dc.get_dc());
}
EndPaint(hwnd(), &ps);
}
break;
case WM_MOUSEMOVE:
on_mouse_move(wp, LOWORD(lp), HIWORD(lp));
break;
case WM_LBUTTONDOWN:
on_lbutton_down(LOWORD(lp), HIWORD(lp));
break;
case WM_LBUTTONUP:
on_lbutton_up(LOWORD(lp), HIWORD(lp));
break;
default:
ret = FALSE;
}
return ret;
}
void dlg_gamma::handle_command(WORD code, WORD id, HANDLE ctrl)
{
if (code == BN_CLICKED)
{
if (id == IDC_BUTTON_RESET)
{
init_curve(cur_, cur_->clr);
InvalidateRect(hwnd(), NULL, FALSE);
}
else
{
quit_modal(id);
}
}
else if (code == EN_CHANGE)
{
if (id == IDC_EDIT_INPUT)
{
wchar_t val[40] = { 0 };
int y = 0;
GetDlgItemTextW(hwnd(), id, val, _countof(val) - 1);
y = _wtoi(val);
if (y < cur_->points[0].x)
SetDlgItemInt(hwnd(), IDC_EDIT_INPUT, cur_->points[0].x, FALSE);
if (y > cur_->points[1].x)
SetDlgItemInt(hwnd(), IDC_EDIT_INPUT, cur_->points[1].x, FALSE);
else
{
y = calc_value(y);
SetDlgItemInt(hwnd(), IDC_EDIT_OUTPUT, y, FALSE);
}
}
}
else if (code == CBN_SELCHANGE)
{
on_combo_sel_changed(id, SendMessage((HWND)ctrl, CB_GETCURSEL, 0, 0));
}
}
void dlg_gamma::layout(void)
{
int r1 = get_width_diff_as_text_length(IDC_STATIC_SCHEME),
r21 = get_width_diff_as_text_length(IDC_STATIC_COLOR),
r22 = get_width_diff_as_text_length(IDC_BUTTON_RESET),
r31 = get_width_diff_as_text_length(IDC_STATIC_INPUT),
r32 = get_width_diff_as_text_length(IDC_STATIC_OUTPUT),
r33 = get_width_diff_as_text_length(IDCANCEL),
r34 = get_width_diff_as_text_length(IDOK),
diff = 0;
if (diff < r1)
diff = r1;
if (diff < r21 + r22)
diff = r21 + r22;
if (diff < r31 + r32 + r33 + r34)
diff = r31 + r32 + r33 + r34;
if (diff > 0)
{
RECT r = { 0 };
GetWindowRect(hwnd(), &r);
r.right += diff;
MoveWindow(hwnd(), r.left, r.top, RECT_W(r), RECT_H(r), FALSE);
expand_item(IDC_STATIC_SCHEME, r1, 0);
offset_item(IDC_SCHEME, r1, 0);
expand_item(IDC_SCHEME, diff - r1, 0);
expand_item(IDC_STATIC_COLOR, r21, 0);
offset_item(IDC_CHANNEL, r21, 0);
expand_item(IDC_BUTTON_RESET, r22, 0);
offset_item(IDC_BUTTON_RESET, diff - r22, 0);
expand_item(IDC_STATIC_INPUT, r31, 0);
offset_item(IDC_EDIT_INPUT, r31, 0);
offset_item(IDC_STATIC_OUTPUT, r31, 0);
expand_item(IDC_STATIC_OUTPUT, r32, 0);
offset_item(IDC_EDIT_OUTPUT, r31 + r32, 0);
offset_item(IDCANCEL, diff - r33, 0);
expand_item(IDCANCEL, r33, 0);
offset_item(IDOK, diff - r34, 0);
expand_item(IDOK, r34, 0);
expand_item(IDC_STATIC_PAINT, diff, 0);
}
}
void dlg_gamma::create_background(void)
{
COLORREF bclr = RGB(128, 128, 128);
HDC hdc = GetWindowDC(hwnd()),
cdc = CreateCompatibleDC(hdc);
HBRUSH bkg = CreateSolidBrush(bclr);
HPEN grid = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)),
old = (HPEN)SelectObject(cdc, grid);
HBITMAP ob = NULL;
int w = paint_area_.right - paint_area_.left + 2,
h = paint_area_.bottom - paint_area_.top + 2;
RECT r = { 1, 1, w - 1, h - 1};
if (bkgnd_)
DeleteObject(bkgnd_);
// create bitmap and select into DC
bkgnd_ = CreateCompatibleBitmap(hdc, w, h);
ob = (HBITMAP)SelectObject(cdc, bkgnd_);
SetBkColor(cdc, bclr);
// background and grid
FillRect(cdc, &r, bkg);
MoveToEx(cdc, r.left, r.top, NULL);
LineTo(cdc, r.right, r.top);
LineTo(cdc, r.right, r.bottom);
LineTo(cdc, r.left, r.bottom);
LineTo(cdc, r.left, r.top);
SelectObject(cdc, old);
DeleteObject(grid);
grid = CreatePen(PS_DASH, 1, RGB(0, 0, 0));
SelectObject(cdc, grid);
for (int i = 1; i < 6; ++i)
{
MoveToEx(cdc, r.left + i * 50, r.bottom, NULL);
LineTo(cdc, r.left + i * 50, r.top);
MoveToEx(cdc, r.left, r.bottom - i * 50, NULL);
LineTo(cdc, r.right, r.bottom - i * 50);
}
// default curve
MoveToEx(cdc, r.left, r.bottom, NULL);
LineTo(cdc, r.right, r.top);
// free resource
SelectObject(cdc, old);
SelectObject(cdc, ob);
DeleteDC(cdc);
ReleaseDC(hwnd(), hdc);
DeleteObject(bkg);
DeleteObject(grid);
}
void dlg_gamma::init_curve(GAMMACURVE* curv, COLORREF clr)
{
curv->points.clear();
curv->points.push_back({ 0, 0 });
curv->points.push_back({ 255, 255 });
curv->coefs = calc::coefs_from_points(curv->points);
curv->drag = -1;
curv->left = 0;
curv->right = 1;
curv->clr = clr;
}
int dlg_gamma::add_drag_point(int x, int y)
{
int ind = -1;
if (cur_->points.size() < MAX_KEY_POINTS + 2)
{
for (int i = 2; i < (int)cur_->points.size(); ++i)
{
if (x < cur_->points[i].x)
{
cur_->points.insert(cur_->points.begin() + i, { x, calc_value(x) });
ind = i;
cur_->coefs = calc::coefs_from_points(cur_->points);
break;
}
else if (x == cur_->points[i].x)
{
ind = i;
break;
}
}
if (ind == -1)
{
ind = cur_->points.size();
cur_->points.push_back({ x, calc_value(x) });
cur_->coefs = calc::coefs_from_points(cur_->points);
}
cur_->left = ind - 1;
cur_->right = ind + 1;
if (cur_->left == 1)
cur_->left = 0;
if (cur_->right >= (int)cur_->points.size())
cur_->right = 1;
}
else
{
for (int i = 2; i < (int)cur_->points.size(); ++i)
{
if (x == cur_->points[i].x)
{
ind = i;
cur_->left = ind - 1;
cur_->right = ind + 1;
if (cur_->left == 1)
cur_->left = 0;
if (cur_->right >= (int)cur_->points.size())
cur_->right = 1;
break;
}
}
}
cur_->drag = ind;
return ind;
}
BYTE dlg_gamma::calc_value(BYTE x)
{
double y = .0f;
for(int j = 0; j < (int)cur_->points.size(); ++j)
y += cur_->coefs[j] * calc::power(x, cur_->points.size() - j - 1);
if (y > 255.0f)
y = 255.0f;
if (y < .0f)
y = .0f;
bool upper = cur_->points[1].y > cur_->points[0].y;
if (y < cur_->points[!upper].y)
y = cur_->points[!upper].y;
if (y > cur_->points[upper].y)
y = cur_->points[upper].y;
return (BYTE)(y + .5f);
}
bool dlg_gamma::is_adjacent(POINT p1, POINT p2)
{
bool neighbour = abs(p1.x - p2.x) <= 3 && abs(p1.y - p2.y) <= 3;
return neighbour;
}
bool dlg_gamma::hit_test(int* x, int* y)
{
for (int i = 2; i < (int)cur_->points.size(); ++i)
{
POINT pt = { *x, *y };
if (is_adjacent(pt, cur_->points[i]))
{
*x = cur_->points[i].x;
*y = cur_->points[i].y;
return true;
}
}
int val = calc_value(*x), tolerant = 3;
bool hit = false;
if (abs(val - *y) < tolerant)
{
*y = val;
hit = true;
}
else
{
int l = *x - tolerant,
u = *x + tolerant;
if (l < 0)
l = 0;
if (u > 255)
u = 255;
for (; l <= u; ++l)
{
val = calc_value(l);
if (abs(val - *y) < tolerant)
{
hit = true;
*x = l;
*y = val;
break;
}
}
}
return hit;
}
void dlg_gamma::draw_ellipse(HDC hdc, POINT center, int xl, int yl)
{
center.x += paint_area_.left;
center.y = paint_area_.bottom - center.y;
HRGN rgn = CreateEllipticRgn(center.x - xl, center.y - yl, center.x + xl, center.y + yl);
HBRUSH brsh = CreateSolidBrush(RGB(255, 0, 255));
FillRgn(hdc, rgn, brsh);
DeleteObject(brsh);
DeleteObject(rgn);
}
void dlg_gamma::draw_current_curve(HDC hdc)
{
MoveToEx(hdc, paint_area_.left + cur_->points[0].x, paint_area_.bottom - cur_->points[0].y, NULL);
for (int i = 0; i < 256; ++i)
{
int y = calc_value(i);
LineTo(hdc, paint_area_.left + i, paint_area_.bottom - y);
}
}
void dlg_gamma::on_init_dlg(void)
{
HWND combo = get_item(IDC_SCHEME);
GetWindowRect(get_item(IDC_STATIC_PAINT), &paint_area_);
screen_2_client(&paint_area_);
paint_area_.right = paint_area_.left + 255;
paint_area_.bottom = paint_area_.top + 255;
create_background();
init_curve(&rgb_gray_);
init_curve(&red_, RGB(255, 0, 0));
init_curve(&green_, RGB(0, 255, 0));
init_curve(&blue_, RGB(0, 0, 255));
std::wstring lang(local_trans::lang_trans_between_hz936(CONST_STRING_CUSTOM));
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
lang = local_trans::lang_trans_between_hz936(CONST_STRING_NEG_PHOTO) + L" (RGB)";
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
lang = local_trans::lang_trans_between_hz936(CONST_STRING_COLOR_NEG_PHOTO) + L" (RGB)";
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
lang = local_trans::lang_trans_between_hz936(CONST_STRING_DARKER) + L" (RGB)";
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
lang = local_trans::lang_trans_between_hz936(CONST_STRING_BRIGHTER) + L" (RGB)";
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
SendMessage(combo, CB_SETCURSEL, 0, 0);
combo = get_item(IDC_CHANNEL);
if (is_color_)
{
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)L"RGB");
lang = local_trans::lang_trans_between_hz936(CONST_STRING_RED);
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
lang = local_trans::lang_trans_between_hz936(CONST_STRING_GREEN);
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
lang = local_trans::lang_trans_between_hz936(CONST_STRING_BLUE);
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
}
else
{
lang = local_trans::lang_trans_between_hz936(CONST_STRING_GRAY);
SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]);
}
SendMessage(combo, CB_SETCURSEL, 0, 0);
cur_ = &rgb_gray_;
SetDlgItemInt(hwnd(), IDC_EDIT_INPUT, 0, FALSE);
SetDlgItemInt(hwnd(), IDC_EDIT_OUTPUT, 0, FALSE);
}
void dlg_gamma::on_paint(HDC hdc)
{
HPEN pen = CreatePen(PS_SOLID, 1, cur_->clr),
drag = CreatePen(PS_SOLID, 1, RGB(255, 0, 255)),
old = (HPEN)SelectObject(hdc, pen);
HDC cdc = CreateCompatibleDC(hdc);
HBITMAP ob = (HBITMAP)SelectObject(cdc, bkgnd_);
BitBlt(hdc, paint_area_.left - 1, paint_area_.top - 1, paint_area_.right - paint_area_.left + 2, paint_area_.bottom - paint_area_.top + 2,
cdc, 0, 0, SRCCOPY);
SelectObject(cdc, ob);
DeleteDC(cdc);
if (show_all_)
{
GAMMACURVE* prev = cur_;
HPEN now = NULL;
cur_ = &red_;
now = CreatePen(PS_SOLID, 1, cur_->clr);
SelectObject(hdc, now);
draw_current_curve(hdc);
cur_ = &green_;
SelectObject(hdc, old);
DeleteObject(now);
now = CreatePen(PS_SOLID, 1, cur_->clr);
SelectObject(hdc, now);
draw_current_curve(hdc);
cur_ = &blue_;
SelectObject(hdc, old);
DeleteObject(now);
now = CreatePen(PS_SOLID, 1, cur_->clr);
SelectObject(hdc, now);
draw_current_curve(hdc);
SelectObject(hdc, pen);
DeleteObject(now);
cur_ = prev;
}
else
draw_current_curve(hdc);
SelectObject(hdc, drag);
for (int i = 0; i < (int)cur_->points.size(); ++i)
{
draw_ellipse(hdc, cur_->points[i], 3, 3);
}
SelectObject(hdc, old);
DeleteObject(pen);
}
void dlg_gamma::on_mouse_move(DWORD key, int x, int y)
{
POINT pt = { x, y };
if (PtInRect(&paint_area_, pt))
{
x -= paint_area_.left;
y = paint_area_.bottom - y;
if (key == MK_LBUTTON && cur_->drag != -1)
{
if (x <= cur_->points[cur_->left].x)
x = cur_->points[cur_->left].x + 1;
else if (x >= cur_->points[cur_->right].x)
x = cur_->points[cur_->right].x - 1;
cur_->points[cur_->drag].x = x;
cur_->points[cur_->drag].y = y;
cur_->coefs = calc::coefs_from_points(cur_->points);
InvalidateRect(hwnd(), NULL, FALSE);
}
else if (key == MK_CONTROL)
{
y = calc_value(x);
pt.y = paint_area_.bottom - y;
ClientToScreen(hwnd(), &pt);
SetCursorPos(pt.x, pt.y);
}
SetDlgItemInt(hwnd(), IDC_EDIT_INPUT, x, FALSE);
SetDlgItemInt(hwnd(), IDC_EDIT_OUTPUT, y, FALSE);
}
}
void dlg_gamma::on_lbutton_down(int x, int y)
{
x -= paint_area_.left;
y = paint_area_.bottom - y;
if (hit_test(&x, &y))
{
if(add_drag_point(x, y) != -1)
SetCapture(hwnd());
}
}
void dlg_gamma::on_lbutton_up(int x, int y)
{
cur_->drag = -1;
cur_->left = 0;
cur_->right = 1;
ReleaseCapture();
}
void dlg_gamma::on_combo_sel_changed(int id, int sel)
{
show_all_ = false;
if (id == IDC_SCHEME)
{
if (sel == 1)
{
cur_ = &rgb_gray_;
init_curve(cur_);
cur_->points.clear();
cur_->points.push_back({ 0, 255 });
cur_->points.push_back({ 255, 0 });
cur_->coefs = calc::coefs_from_points(cur_->points);
}
else if (sel == 2)
{
show_all_ = true;
cur_ = &red_;
init_curve(cur_, cur_->clr);
cur_->points.clear();
cur_->points.push_back({ 33, 255 });
cur_->points.push_back({ 185, 0 });
cur_->points.push_back({ 119, 127 });
cur_->coefs = calc::coefs_from_points(cur_->points);
cur_ = &green_;
init_curve(cur_, cur_->clr);
cur_->points.clear();
cur_->points.push_back({ 28, 255 });
cur_->points.push_back({ 132, 0 });
cur_->points.push_back({ 77, 127 });
cur_->coefs = calc::coefs_from_points(cur_->points);
cur_ = &blue_;
init_curve(cur_, cur_->clr);
cur_->points.clear();
cur_->points.push_back({ 25, 255 });
cur_->points.push_back({ 108, 0 });
cur_->points.push_back({ 60, 127 });
cur_->coefs = calc::coefs_from_points(cur_->points);
cur_ = &red_;
}
else if (sel == 3)
{
cur_ = &rgb_gray_;
init_curve(cur_);
cur_->points.push_back({ 130, 101 });
cur_->coefs = calc::coefs_from_points(cur_->points);
}
else if (sel == 4)
{
cur_ = &rgb_gray_;
init_curve(cur_);
cur_->points.push_back({ 103, 125 });
cur_->coefs = calc::coefs_from_points(cur_->points);
}
InvalidateRect(hwnd(), NULL, FALSE);
}
else if (id == IDC_CHANNEL)
{
GAMMACURVE* prev = cur_, * all[] = { &rgb_gray_, &red_, &green_, &blue_ };
cur_ = all[sel];
if (prev != cur_)
{
if (cur_->points.size() == 2)
{
COLORREF clr = cur_->clr;
*cur_ = *prev;
cur_->clr = clr;
}
InvalidateRect(hwnd(), NULL, FALSE);
}
}
}
void dlg_gamma::get_gamma(SANE_Gamma* gamma)
{
//gamma->apply_to_back = SANE_FALSE;
////if (cur_ == &rgb_gray_)
//{
// cur_ = &rgb_gray_;
// gamma->pt_count = (SANE_Byte)(cur_->points.size() - 2);
//// gamma->pt_count_r = gamma->pt_count_g = gamma->pt_count_b = 0;
// for (int i = 2; i < (int)cur_->points.size(); ++i)
// {
// gamma->keypoint[i - 2].x = (SANE_Byte)cur_->points[i].x;
// gamma->keypoint[i - 2].y = (SANE_Byte)cur_->points[i].y;
// }
// for (int i = 0; i < 256; ++i)
// gamma->table[i] = calc_value(i);
//}
////else
//{
//// gamma->pt_count = 0;
// cur_ = &red_;
// gamma->pt_count_r = (SANE_Byte)(cur_->points.size() - 2);
// for (int i = 2; i < (int)cur_->points.size(); ++i)
// {
// gamma->keypoint_r[i - 2].x = (SANE_Byte)cur_->points[i].x;
// gamma->keypoint_r[i - 2].y = (SANE_Byte)cur_->points[i].y;
// }
// for (int i = 0; i < 256; ++i)
// gamma->table[i] = calc_value(i);
// cur_ = &green_;
// gamma->pt_count_g = (SANE_Byte)(cur_->points.size() - 2);
// for (int i = 2; i < (int)cur_->points.size(); ++i)
// {
// gamma->keypoint_g[i - 2].x = (SANE_Byte)cur_->points[i].x;
// gamma->keypoint_g[i - 2].y = (SANE_Byte)cur_->points[i].y;
// }
// for (int i = 0; i < 256; ++i)
// gamma->table[256 + i] = calc_value(i);
// cur_ = &blue_;
// gamma->pt_count_b = (SANE_Byte)(cur_->points.size() - 2);
// for (int i = 2; i < (int)cur_->points.size(); ++i)
// {
// gamma->keypoint_b[i - 2].x = (SANE_Byte)cur_->points[i].x;
// gamma->keypoint_b[i - 2].y = (SANE_Byte)cur_->points[i].y;
// }
// for (int i = 0; i < 256; ++i)
// gamma->table[512 + i] = calc_value(i);
//}
}
void dlg_gamma::set_gamma(const SANE_Gamma* gamma, bool gray)
{
//int sel = 0;
//std::wstring text(L"");
//SendMessage(get_item(IDC_CHANNEL), CB_RESETCONTENT, 0, 0);
//is_color_ = !gray;
//cur_ = &rgb_gray_;
//init_curve(cur_);
//for (int i = 0; i < gamma->pt_count; ++i)
//{
// POINT pt = { gamma->keypoint[i].x, gamma->keypoint[i].y };
// cur_->points.push_back(pt);
//}
//cur_->coefs = calc::coefs_from_points(cur_->points);
//if (is_color_)
//{
// SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)L"RGB");
//}
//else
//{
// text = local_trans::lang_trans_between_hz936(CONST_STRING_GRAY);
// SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)&text[0]);
//}
//if(!gray)
//{
// is_color_ = true;
// cur_ = &red_;
// init_curve(cur_);
// for (int i = 0; i < gamma->pt_count_r; ++i)
// {
// POINT pt = { gamma->keypoint_r[i].x, gamma->keypoint_r[i].y };
// cur_->points.push_back(pt);
// }
// cur_->coefs = calc::coefs_from_points(cur_->points);
// cur_ = &green_;
// init_curve(cur_);
// for (int i = 0; i < gamma->pt_count_g; ++i)
// {
// POINT pt = { gamma->keypoint_g[i].x, gamma->keypoint_g[i].y };
// cur_->points.push_back(pt);
// }
// cur_->coefs = calc::coefs_from_points(cur_->points);
// cur_ = &blue_;
// init_curve(cur_);
// for (int i = 0; i < gamma->pt_count_b; ++i)
// {
// POINT pt = { gamma->keypoint_b[i].x, gamma->keypoint_b[i].y };
// cur_->points.push_back(pt);
// }
// cur_->coefs = calc::coefs_from_points(cur_->points);
//// SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)L"RGB");
// text = local_trans::lang_trans_between_hz936(CONST_STRING_RED);
// SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)&text[0]);
// text = local_trans::lang_trans_between_hz936(CONST_STRING_GREEN);
// SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)&text[0]);
// text = local_trans::lang_trans_between_hz936(CONST_STRING_BLUE);
// SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)&text[0]);
//}
//cur_ = &rgb_gray_;
//sel = 0;
//SendMessage(get_item(IDC_CHANNEL), CB_SETCURSEL, sel, 0);
//SendMessage(get_item(IDC_SCHEME), CB_SETCURSEL, 0, 0);
}

View File

@ -0,0 +1,58 @@
#pragma once
#include <Windows.h>
#include <string>
#include "DlgPage.h"
// CDlgIndicator 对话框
class dlg_gamma: public dlg_base
{
bool is_color_;
bool show_all_;
RECT paint_area_;
HBITMAP bkgnd_;
typedef struct _gamma_curve
{
std::vector<POINT> points;
std::vector<double> coefs;
int drag;
int left;
int right;
COLORREF clr;
}GAMMACURVE;
GAMMACURVE rgb_gray_;
GAMMACURVE red_;
GAMMACURVE green_;
GAMMACURVE blue_;
GAMMACURVE* cur_;
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
void handle_command(WORD code, WORD id, HANDLE ctrl);
void layout(void);
void create_background(void);
void init_curve(GAMMACURVE* curv, COLORREF clr = RGB(255, 255, 255));
int add_drag_point(int x, int y);
BYTE calc_value(BYTE x);
bool is_adjacent(POINT p1, POINT p2);
bool hit_test(int* x, int* y);
void draw_ellipse(HDC hdc, POINT center, int xl, int yl);
void draw_current_curve(HDC hdc);
void on_init_dlg(void);
void on_paint(HDC hdc);
void on_mouse_move(DWORD key, int x, int y);
void on_lbutton_down(int x, int y);
void on_lbutton_up(int x, int y);
void on_combo_sel_changed(int id, int sel);
public:
dlg_gamma(HWND parent, bool color);
~dlg_gamma();
public:
void get_gamma(SANE_Gamma* gamma);
void set_gamma(const SANE_Gamma* gamma, bool gray);
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,240 @@
#pragma once
#include <Windows.h>
#include <CommCtrl.h>
#include <string>
#include <vector>
#include <sane/sane_ex.h>
#include <sane/sane_option_definitions.h>
#include "./const_str.h"
// CDlgIndicator 对话框
#define FLOAT_FORMAT L"%.2f"
#define IS_STR_EQUAL(s1, s2) (wcscmp(s1, s2) == 0)
#define IS_EDIT(cls) IS_STR_EQUAL(cls, WC_EDITW)
#define IS_COMBOX(cls) IS_STR_EQUAL(cls, WC_COMBOBOXW)
#define IS_BUTTON(cls) IS_STR_EQUAL(cls, WC_BUTTONW)
#define IS_TRACKBAR(cls) IS_STR_EQUAL(cls, TRACKBAR_CLASSW)
#define IS_UPDOWN_ARROW(cls) IS_STR_EQUAL(cls, UPDOWN_CLASSW)
#define RECT_W(r) (r.right - r.left)
#define RECT_H(r) (r.bottom - r.top)
#define WM_SCAN_WORKING WM_USER + 301 // WPARAM: unused; LPARAM: unsed
#define WM_USB_PACKET_RECEIVED WM_USER + 302
#define WM_IMAGE_RECEIVED WM_USER + 303
#define WM_SCAN_FINISHED WM_USER + 304 // WPARAM: std::string* msg; LPARAM: boo err
#define WM_REFRESH_OPTION WM_USER + 311 // WPARAM: source option SN, LPARAM: unused now
#define WM_GET_CONFIG_OBJ WM_USER + 312 // WPARAM: bool*, [in]create new if NULL; [out]created, LPARAM: to receive the gb::sane_config_schm* object
#define WM_SET_TEXT WM_USER + 320 // WPARAM: id; LPARAM: std::wstring*
#define WM_IS_BUTTON_CHECKED WM_USER + 321 // WPARAM: id; LPARAM: bool*
#define WM_SET_BUTTON_CHECK WM_USER + 322 // WPARAM: id; LPARAM: bool
#define WM_ENABLE_CTRLS WM_USER + 323 // WPARAM: id (0 is click repeat button); LPARAM: bool
#define WM_DEVICE_STATTUS WM_USER + 324 // WPARAM: unused; LPARAM: scanner_status
extern HMODULE g_my_inst;
namespace local_trans
{
std::string u2a(const wchar_t* unic, UINT cp = CP_ACP);
std::wstring a2u(const char* asc, UINT cp = CP_ACP);
std::wstring lang_trans_between_hz936(const wchar_t* in, bool from_hz = true);
const char* __stdcall lang_trans_between_hz936(const char* in, bool from_hz, void* param);
}
class dlg_base
{
int modal_exit_; // set non-ZERO code to exit modal dialog
protected:
HWND hwnd_;
HWND parent_;
UINT idd_;
bool abandon_hold_;
void(__stdcall* ui_event_notify_)(int uev, void* sender, void* param);
void* ui_notify_param_;
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);
void notify_ui_event(int ev);
public:
dlg_base(HWND parent, UINT idd);
virtual ~dlg_base();
static void screen_2_client(HWND wnd, LPRECT r);
static void client_2_screen(HWND wnd, LPRECT r);
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
static int select_combo_text(HWND combo, const wchar_t* text);
static std::wstring get_wnd_text(HWND h);
static bool is_language_pack_default_code_page(void);
static std::wstring get_menu_text(HMENU menu, int ind);
static void center_window(HWND wnd, HWND parent);
static int list_insert_column(HWND list_wnd, const wchar_t* text, int cx = 20, int ind = -1);
static int list_insert_item(HWND list_wnd, const wchar_t* text, int ind = -1);
static int list_get_item_count(HWND list_wnd);
static int list_get_column_count(HWND list_wnd);
static std::wstring list_get_text(HWND list_wnd, int ind, int sub = 0);
static void list_get_selected_items(HWND list_wnd, std::vector<int>& sels);
static int list_set_item_text(HWND list_wnd, int item, int sub_item, const wchar_t* text);
public:
void set_ui_event_notify(void(__stdcall* notify)(int, void*, void*), void* param);
HWND hwnd(void);
void show(bool visible, bool hold = false);
int do_modal(HWND parent);
void quit_modal(int non_zero_code);
void enable(bool enable);
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);
int get_string_width(const wchar_t* str, HWND wnd = NULL);
bool get_item_rect(UINT id, LPRECT r, bool client = true);
std::wstring get_item_text(UINT id);
int get_width_diff_as_text_length(UINT id); //
void offset_item(HWND wnd, int dx, int dy);
void offset_item(UINT id, int dx, int dy);
void expand_item(UINT id, int dx, int dy);
bool set_item_text(UINT id, const wchar_t* text);
int set_item_fit_to_text(UINT id); // return difference
void show_scroll_bar(int bar = SB_VERT, bool show = true);
bool track_mouse_hover(void);
};
class tooltip_wnd
{
HWND hwnd_;
HWND parent_;
WNDPROC org_proc_;
typedef struct _tip_ele
{
HWND ctrl;
RECT rect;
std::wstring tips;
struct _tip_ele()
{
ctrl = NULL;
memset(&rect, 0, sizeof(rect));
tips = L"";
}
bool operator==(const HWND& wnd)
{
return ctrl == wnd;
}
bool operator==(const RECT& r)
{
return memcmp(&rect, &r, sizeof(r)) == 0;
}
}TIPELEM;
std::vector<TIPELEM> elements_;
public:
tooltip_wnd();
~tooltip_wnd();
public:
bool create(HWND parent);
void enable(bool enabled);
bool add_tool_tip_for_rect(const RECT& r, const wchar_t* tips);
bool add_tool_tip_for_ctrl(HWND ctrl, const wchar_t* tips);
bool remove_tool_tip_for_ctrl(HWND ctrl);
};
class dlg_page : public dlg_base
{
std::wstring name_;
SIZE size_;
UINT ctrl_id_;
POINT pos_;
SANEAPI sane_;
SANE_Handle dev_;
bool done_;
std::vector<HWND> ctrls_;
tooltip_wnd tips_wnd_;
int id_dpi_;
float dpi_;
int id_paper_;
std::wstring paper_;
int id_custom_area_;
int id_custom_left_;
int id_custom_right_;
int id_custom_top_;
int id_custom_bottom_;
int id_paper_w_;
int id_paper_h_;
int id_lateral_;
int id_custom_gamma_;
static std::wstring property_type;
static std::wstring property_host;
static std::wstring property_size;
static UINT dyn_id_base;
static int gap_x;
static int gap_y;
static int spin_w;
static int sb_adden;
SIZE size_view_;
int vsb_pos_;
int hsb_pos_;
bool vsb_;
bool hsb_;
BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override;
void on_font_changed(void) override;
void align_second_control(bool ignore_single = false); // align the second control of a option controls
HWND create_label(int sn, const wchar_t* title, int x, int y, SIZE size);
HWND create_slider(int sn, int x, int y, double lower, double upper, double step, double pos, LPSIZE size, bool is_double);
HWND create_edit(int sn, int x, int y, int h, int w = 50);
HWND create_combox(int sn, int x, int y, std::vector<std::wstring>& vals, const wchar_t* cur_val, LPSIZE size);
HWND create_spin(int sn, HWND edit, double pos, double lower, double upper, bool is_double);
HWND create_control_bool(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size);
HWND create_control_int(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size);
HWND create_control_float(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size);
HWND create_control_string(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size);
HWND create_control_button(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size);
void handle_command(WORD code, WORD id, HANDLE ctrl);
BOOL on_notify(int ctrl_id, LPNMHDR pnmh);
void* value_from_ctrl(HWND ctrl, SANE_Value_Type* type); // call free_ctrl_value to free the returned value, data according to SANE-standard
void set_ctrl_value(HWND ctrl, SANE_Value_Type type, void* val, bool only_me, bool skip_ctrl = false);
void free_ctrl_value(void* val);
int find_control_ind(HWND wnd);
void control_action(HWND wnd);
BOOL on_mouse_wheel(WORD vkey, short delta, short x, short y);
void on_vscroll(int pos, int sb_ev);
void on_hscroll(int pos, int sb_ev);
void on_mouse_hover(int x, int y, int flag);
public:
dlg_page(HWND parent, const wchar_t* name, LPSANEAPI api, SANE_Handle dev);
~dlg_page();
public:
bool add_control(int sn, const SANE_Option_Descriptor* desc, void* cur_val);
void add_control_done(void);
SIZE desired_size(void);
void show(void);
void hide(void);
bool refresh(int sn, const SANE_Option_Descriptor* desc, void* cur_val);
const wchar_t* name(void);
void set_view_size(SIZE size);
};

View File

@ -0,0 +1,490 @@
// DlgIndicator.cpp: 实现文件
//
#include "DlgSetting.h"
#include "../resource.h"
#include <lang/app_language.h>
// CDlgIndicator 对话框
#define MENU_CMD_0 ((unsigned short)0x8888)
static IMPLEMENT_OPTION_STRING_COMPARE(cmp_sane_opt);
namespace local_trans
{
std::string u2a(const wchar_t* u, UINT cp)
{
std::string a("");
if (u)
{
char* ansi = NULL;
int len = 0;
len = WideCharToMultiByte(cp, 0, u, lstrlenW(u), NULL, 0, NULL, NULL);
ansi = new char[len + 2];
len = WideCharToMultiByte(cp, 0, u, lstrlenW(u), ansi, len, NULL, NULL);
ansi[len--] = 0;
a = ansi;
delete[] ansi;
}
return std::move(a);
}
std::wstring a2u(const char* asc, UINT cp)
{
std::wstring u(L"");
if (asc)
{
wchar_t* buf = NULL;
int len = 0;
len = MultiByteToWideChar(cp, 0, asc, lstrlenA(asc), NULL, 0);
buf = new wchar_t[len + 2];
len = MultiByteToWideChar(cp, 0, asc, lstrlenA(asc), buf, len);
buf[len--] = 0;
u = buf;
delete[] buf;
}
return std::move(u);
}
std::wstring lang_trans_between_hz936(const wchar_t* in, bool from_hz)
{
std::string a(u2a(in, CP_UTF8));
if (from_hz)
a = from_default_language(a.c_str(), nullptr);
else
a = to_default_language(a.c_str(), nullptr);
return std::move(a2u(a.c_str(), CP_UTF8));
}
const char* __stdcall lang_trans_between_hz936(const char* in, bool from_hz, void* param)
{
return from_hz ? from_default_language(in, nullptr) : to_default_language(in, nullptr);
}
}
namespace known_name
{
struct
{
std::wstring name;
std::wstring title;
}
g_group[] = { {L"base", L"\u57FA\u672C\u8BBE\u7F6E"}, {L"imgp", L"\u56FE\u50CF\u5904\u7406"}, {L"feeder", L"\u9001\u7EB8\u65B9\u5F0F"}, {L"advance", L"\u9AD8\u7EA7\u8BBE\u7F6E"} },
g_cats[] = { {L"imgp", L"\u56FE\u50CF\u5904\u7406"} };
static std::wstring group_name(const wchar_t* grp_title)
{
for (auto& v : g_group)
{
if (v.title == grp_title)
return v.name;
}
return grp_title;
}
static std::wstring group_title(const wchar_t* grp_name)
{
if (wcscmp(grp_name, L"imgproc") == 0)
grp_name = L"imgp";
for (auto& v : g_group)
{
if (v.name == grp_name)
return v.title;
}
return grp_name;
}
static std::wstring category_name(const wchar_t* cat_title)
{
for (auto& v : g_cats)
{
if (v.title == cat_title)
return v.name;
}
return cat_title;
}
static std::wstring category_title(const wchar_t* cat_name)
{
if (wcscmp(cat_name, L"imgproc") == 0)
cat_name = L"imgp";
for (auto& v : g_cats)
{
if (v.name == cat_name)
return v.title;
}
return cat_name;
}
};
dlg_setting::dlg_setting(HWND parent, LPSANEAPI api, SANE_Handle dev, LPRECT area) : dlg_base(parent, IDD_SETTING)
, sane_api_(*api), sane_dev_(dev), area_(*area)
, papers_(0), images_(0), err_(false), tab_(NULL)
{
std::wstring setting(local_trans::lang_trans_between_hz936(CONST_STRING_SETTING));
create();
}
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:
ret = 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)
//{
// SANE_Int after = 0;
// SANE_Status statu = sane_api_.sane_control_option_api(sane_dev_, id_help_, SANE_ACTION_SET_VALUE, &after, &after);
//}
//else if (id == IDC_BUTTON_RESTORE)
//{
// SANE_Int after = 0;
// SANE_Status statu = sane_api_.sane_control_option_api(sane_dev_, id_restore_, SANE_ACTION_SET_VALUE, &after, &after);
// refresh_controls(id_restore_);
//}
//else if (id == IDC_BUTTON_SCAN)
//{
// // enable(false);
// notify_ui_event(SANE_EVENT_UI_SCAN_COMMAND);
//}
}
void dlg_setting::notify_over(void)
{
notify_ui_event(SANE_EVENT_UI_CLOSE_SETTING);
}
void dlg_setting::on_init_dialog(void)
{
dlg_page* page = NULL;
SANE_Int sn = 1;
SIZE size = { 0 };
RECT r = area_, rme = { 0 };
int y = 0;
const SANE_Option_Descriptor* desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
MoveWindow(hwnd(), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
while (desc)
{
if (desc->type == SANE_TYPE_GROUP)
{
if (page)
{
page->add_control_done();
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 (strcmp(SANE_STD_OPT_NAME_HELP, desc->name) == 0)
//{
// ShowWindow(GetDlgItem(hwnd_, IDC_BUTTON_HELP), SW_SHOW);
// id_help_ = sn - 1;
//}
//else if (strcmp(SANE_STD_OPT_NAME_RESTORE, desc->name) == 0)
//{
// ShowWindow(GetDlgItem(hwnd_, IDC_BUTTON_RESTORE), SW_SHOW);
// id_restore_ = sn - 1;
//}
}
desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
}
if (page)
{
page->add_control_done();
dlg_base::get_max_size(size, page->desired_size());
}
if (size.cx || size.cy || IsWindow(tab_))
{
// resize ...
//GetClientRect(hwnd(), &rme);
rme = area_;
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 + size.cx;
screen_2_client(&r);
MoveWindow(tab_, r.left, r.top, r.right - r.left, y, TRUE);
}
RECT desk = area_;
int diff = 0;
//GetClientRect(GetDesktopWindow(), &desk);
//GetWindowRect(hwnd(), &r);
//r.right += size.cx - (rme.right - rme.left);
//r.bottom += size.cy;
r = area_;
diff = size.cy - RECT_H(r);
//if (r.bottom - r.top > desk.bottom - desk.top)
//{
// diff = (r.bottom - r.top) - (desk.bottom - desk.top) + 100;
// r.top = desk.top;
// r.bottom = desk.bottom - 100;
//}
OffsetRect(&r, area_.left - r.left, area_.top - r.top);
MoveWindow(hwnd(), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
size.cy -= diff;
size.cx = RECT_W(r);
for (int i = 0; page = get_page(i); ++i)
{
MoveWindow(page->hwnd(), 0, y, size.cx, size.cy - y, TRUE);
page->set_view_size(size);
}
//offset_item(IDC_BUTTON_SCAN, 0, size.cy);
//offset_item(IDC_BUTTON_CONFIG_MGR, size.cx - RECT_W(rme), size.cy);
//offset_item(IDC_BUTTON_CONFIG_MENU, size.cx - RECT_W(rme), size.cy);
//offset_item(IDC_BUTTON_HELP, size.cx - RECT_W(rme), size.cy);
//offset_item(IDC_BUTTON_RESTORE, size.cx - RECT_W(rme), size.cy);
//offset_item(IDOK, size.cx - RECT_W(rme), size.cy);
//
//ShowWindow(get_item(IDC_BUTTON_CONFIG_MGR), SW_SHOW);
//ShowWindow(get_item(IDC_BUTTON_CONFIG_MENU), SW_SHOW);
}
//if (with_scan_)
// ShowWindow(get_item(IDC_BUTTON_SCAN), SW_SHOW);
//
//if (!dlg_base::is_language_pack_default_code_page())
//{
// std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_CFG_MANAGER));
//
// ::SetDlgItemTextW(hwnd(), IDC_BUTTON_CONFIG_MGR, title.c_str());
// y = set_item_fit_to_text(IDC_BUTTON_CONFIG_MGR);
// if (y)
// offset_item(IDC_BUTTON_CONFIG_MGR, -y, 0);
//
// ::SetDlgItemTextW(hwnd(), IDC_BUTTON_SCAN, local_trans::lang_trans_between_hz936(CONST_STRING_SCAN).c_str());
// ::SetDlgItemTextW(hwnd(), IDC_BUTTON_RESTORE, local_trans::lang_trans_between_hz936(CONST_STRING_RESTORE).c_str());
// ::SetDlgItemTextW(hwnd(), IDC_BUTTON_HELP, local_trans::lang_trans_between_hz936(CONST_STRING_HELP).c_str());
// ::SetDlgItemTextW(hwnd(), IDOK, local_trans::lang_trans_between_hz936(CONST_STRING_OK).c_str());
//}
select_page(0);
UpdateWindow(hwnd());
}
BOOL dlg_setting::on_notify(int ctrl_id, LPNMHDR pnmh)
{
BOOL ret = TRUE;
if (pnmh->hwndFrom == tab_)
{
if (pnmh->code == TCN_SELCHANGING)
ret = FALSE;
else if (pnmh->code == TCN_SELCHANGE)
select_page(TabCtrl_GetCurSel(tab_));
}
return ret;
}
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(known_name::group_title(local_trans::a2u(utf8_title, CP_UTF8).c_str()));
dlg_page *page = new dlg_page(hwnd(), title.c_str(), &sane_api_, sane_dev_);
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_))
{
HDC hdc = GetWindowDC(hwnd());
SIZE text = { 0 };
GetTextExtentPointW(hdc, title.c_str(), title.length(), &text);
ReleaseDC(hwnd(), hdc);
tab_ = CreateWindowW(L"SysTabControl32", L"pages", WS_CHILD | WS_VISIBLE, 0, 0, 100, text.cy + 6, hwnd(), NULL, g_my_inst, NULL);
wcscpy(lf.lfFaceName, L"微软雅黑");
lf.lfHeight = 18;
font = CreateFontIndirectW(&lf);
SendMessage(tab_, WM_SETFONT, (WPARAM)font, 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)
{
int sn = 1;
const SANE_Option_Descriptor* desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
while (desc)
{
if (desc->type != SANE_TYPE_BUTTON && desc->type != SANE_TYPE_GROUP)
{
char* buf = new char[desc->size + 8];
SANE_Int info = 0;
dlg_page* page = NULL;
memset(buf, 0, desc->size + 8);
sane_api_.sane_control_option_api(sane_dev_, sn - 1, SANE_ACTION_GET_VALUE, buf, &info);
for (int i = 0; page = get_page(i); ++i)
{
if (page->refresh(sn - 1, desc, buf))
break;
}
delete[] buf;
}
desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++);
}
}
HWND dlg_setting::window(void)
{
return hwnd_;
}
HWND dlg_setting::parent(void)
{
return parent_;
}
void dlg_setting::hide(void)
{
ShowWindow(hwnd_, SW_HIDE);
}
void dlg_setting::notify_scan_over(void)
{
enable(true);
}
// CDlgIndicator 消息处理程序

View File

@ -0,0 +1,54 @@
#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_;
unsigned int papers_;
unsigned int images_;
bool err_;
RECT area_;
HWND tab_;
#ifdef USE_SOLE_WIN_THREAD
std::unique_ptr<std::thread> thread_;
#endif
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);
BOOL 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, LPRECT area);
~dlg_setting();
public:
HWND window(void);
HWND parent(void);
//void show(void);
void hide(void);
void notify_scan_over(void);
};

View File

@ -0,0 +1,94 @@
// For: const string list
//
// Date: 2023-02-07
//
// Format: all strings are defined in unicode
//
#pragma once
#define CONST_STRING_CUSTOM_AREA L"\u81EA\u5B9A\u4E49\u626B\u63CF\u533A\u57DF"
#define CONST_STRING_UNIT L"\u5355\u4F4D"
#define CONST_STRING_UNIT_MM L"\u6BEB\u7C73"
#define CONST_STRING_UNIT_INCH L"\u82F1\u5BF8"
#define CONST_STRING_UNIT_PIXEL L"\u50CF\u7D20"
#define CONST_STRING_AREA_SET L"\u533A\u57DF\u8BBE\u7F6E"
#define CONST_STRING_LEFT L"\u5DE6"
#define CONST_STRING_TOP L"\u4E0A"
#define CONST_STRING_WIDTH L"\u5BBD"
#define CONST_STRING_HEIGHT L"\u9AD8"
#define CONST_STRING_RESTORE_AREA L"\u6062\u590D\u533A\u57DF"
#define CONST_STRING_OK L"\u786E\u5B9A"
#define CONST_STRING_CANCEL L"\u53D6\u6D88"
#define CONST_STRING_MULTIPLE L"\u00d7"
#define CONST_STRING_OPT_PAPER L"\u7EB8\u5F20\u5C3A\u5BF8"
#define CONST_STRING_CFG_MANAGER L"\u914D\u7F6E\u7BA1\u7406"
#define CONST_STRING_CFG_SCHEME L"\u914D\u7F6E\u65B9\u6848"
#define CONST_STRING_DEL_SELECTED L"\u5220\u9664\u9009\u4E2D\u9879"
#define CONST_STRING_DEL_ALL L"\u5168\u90E8\u5220\u9664"
#define CONST_STRING_CFG_CONTENT L"\u914D\u7F6E\u5185\u5BB9"
#define CONST_STRING_CFG_NAME L"\u914D\u7F6E\u540D\u79F0"
#define CONST_STRING_CUSTOM_TONE L"\u81EA\u5B9A\u4E49\u8272\u8C03\u66F2\u7EBF"
#define CONST_STRING_TONE_SCHEME L"\u8272\u8C03\u65B9\u6848"
#define CONST_STRING_COLOR_CHANNEL L"\u989C\u8272\u901A\u9053"
#define CONST_STRING_INITIALIZE L"\u521D\u59CB\u5316"
#define CONST_STRING_INPUT L"\u8F93\u5165"
#define CONST_STRING_OUTPUT L"\u8F93\u51FA"
#define CONST_STRING_CUSTOM L"\u81EA\u5B9A\u4E49"
#define CONST_STRING_NEG_PHOTO L"\u8d1f\u7247"
#define CONST_STRING_COLOR_NEG_PHOTO L"\u5f69\u8272\u8d1f\u7247"
#define CONST_STRING_DARKER L"\u8f83\u6697"
#define CONST_STRING_BRIGHTER L"\u8f83\u4eae"
#define CONST_STRING_RED L"\u7ea2"
#define CONST_STRING_GREEN L"\u7eff"
#define CONST_STRING_BLUE L"\u84dd"
#define CONST_STRING_GRAY L"\u7070"
#define CONST_STRING_SCANNING L"\u6B63\u5728\u626B\u63CF\u2026\u2026"
#define CONST_STRING_PAPER L"\u7EB8\u5F20"
#define CONST_STRING_IMAGE L"\u56FE\u7247"
#define CONST_STRING_TOTAL_SCANNED L"\u603b\u8ba1\u626b\u63cf\u56fe\u7247"
#define CONST_STRING_CLOSE L"\u5173\u95ed"
#define CONST_STRING_SCAN_OVER L"\u626b\u63cf\u7ed3\u675f"
#define CONST_STRING_CHOOSE_DEVICE L"\u8BF7\u9009\u62E9\u8BBE\u5907"
#define CONST_STRING_DEVICE_NAME L"\u8BBE\u5907\u540D\u79F0"
#define CONST_STRING_SERIAL_NUM L"\u5E8F\u5217\u53F7"
#define CONST_STRING_INPUT_VAL L"\u8BF7\u8F93\u5165\u65B0\u503C"
#define CONST_STRING_RE_INPUT L"\u8BF7\u91CD\u65B0\u8F93\u5165"
#define CONST_STRING_NO_INPUT L"\u6CA1\u6709\u8F93\u5165\u5185\u5BB9"
#define CONST_STRING_ALREADY_EXISTS L"\u5DF2\u7ECF\u5B58\u5728"
#define CONST_STRING_NOT_SUPPORT_SET L"\u6B64\u8BBE\u5907\u4E0D\u652F\u6301\u5C06"
#define CONST_STRING_SET_TO_BE L"\u8BBE\u7F6E\u4E3A"
#define CONST_STRING_PARAMETER_ERROR L"\u53C2\u6570\u9519\u8BEF"
#define CONST_STRING_PARAMETER_ORIGIN L"\u539F\u53C2\u6570"
#define CONST_STRING_PARAMETER_INEXACT L"\u4E0D\u7CBE\u786E\u6216\u8BBE\u5907\u4E0D\u652F\u6301\uFF0C\u5DF2\u8C03\u6574\u4E3A"
#define CONST_STRING_PARAMETER_ADJUSTED L"\u53C2\u6570\u8C03\u6574"
#define CONST_STRING_SET_AREA L"\u8bbe\u7f6e\u533a\u57df"
#define CONST_STRING_SET_TONE L"\u8bbe\u7f6e\u8272\u8c03\u66f2\u7ebf"
#define CONST_STRING_SETTING L"\u8BBE\u7F6E"
#define CONST_STRING_SAVE_CUR_CFG_AS L"\u5F53\u524D\u914D\u7F6E\u53E6\u5B58\u4E3A"
#define CONST_STRING_SCAN L"\u626B\u63CF"
#define CONST_STRING_RESTORE L"\u6062\u590D\u9ED8\u8BA4\u503C"
#define CONST_STRING_HELP L"\u5E2E\u52A9"
#define CONST_STRING_OPEN_FAILED L"\u6253\u5F00\u5931\u8D25"
#define CONST_STRING_START_FAILED L"\u542F\u52A8\u5931\u8D25"
#define CONST_STRING_ERROR L"\u9519\u8BEF"
#define CONST_STRING_SAVE_TITLE L"\u5F53\u524D\u914D\u7F6E\u5DF2\u7ECF\u66F4\u6539\uFF0C\u8BF7\u9009\u62E9\u4FDD\u5B58\u65B9\u5F0F"
#define CONST_STRING_SAVE_DISCARD L"\u4E0D\u4FDD\u5B58\uFF0C\u4EC5\u7528\u4E8E\u8BE5\u6B21\u626B\u63CF\u6216\u653E\u5F03\u66F4\u6539"
#define CONST_STRING_SAVE_OVERWRITE L"\u8986\u76D6\u73B0\u6709\u65B9\u6848"
#define CONST_STRING_SAVE_NEW L"\u4FDD\u5B58\u4E3A\u65B0\u65B9\u6848"
#define CONST_STRING_REINPUT_SCHEME_NAME L"\u8BF7\u8F93\u5165\u65B0\u914D\u7F6E\u65B9\u6848\u540D\u79F0\u3002"
#define CONST_STRING_LEFT_QUOTE L"\u201C"
#define CONST_STRING_RIGHT_QUOTE L"\u201D"
#define CONST_STRING_REINPUT_WHEN_EXISTING L"\u5DF2\u7ECF\u5B58\u5728\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165\u3002"

View File

@ -0,0 +1,39 @@
// DlgIndicator.cpp: 实现文件
//
#include "mem_dc.h"
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// compatible_dc
compatible_dc::compatible_dc(HDC src) : src_(src), old_(NULL)
{
HWND hwnd = WindowFromDC(src);
RECT r = { 0 };
if (!IsWindow(hwnd))
hwnd = GetDesktopWindow();
GetWindowRect(hwnd, &r);
size_.cx = r.right - r.left;
size_.cy = r.bottom - r.top;
bmp_ = CreateCompatibleBitmap(src, size_.cx, size_.cy);
hdc_ = CreateCompatibleDC(src);
old_ = (HBITMAP)SelectObject(hdc_, bmp_);
BitBlt(hdc_, 0, 0, size_.cx, size_.cy, src, 0, 0, SRCCOPY);
}
compatible_dc::~compatible_dc()
{
BitBlt(src_, 0, 0, size_.cx, size_.cy, hdc_, 0, 0, SRCCOPY);
SelectObject(hdc_, old_);
DeleteObject(bmp_);
DeleteDC(hdc_);
}
HDC compatible_dc::get_dc()
{
return hdc_;
}

View File

@ -0,0 +1,19 @@
#pragma once
#include <Windows.h>
class compatible_dc
{
HBITMAP bmp_;
HBITMAP old_;
HDC hdc_;
HDC src_;
SIZE size_;
public:
compatible_dc(HDC src);
~compatible_dc();
public:
HDC get_dc(void);
};

5
sln/usb_tools/pch.cpp Normal file
View File

@ -0,0 +1,5 @@
// pch.cpp: 与预编译标头对应的源文件
#include "pch.h"
// 当使用预编译的头时,需要使用此源文件,编译才能成功。

13
sln/usb_tools/pch.h Normal file
View File

@ -0,0 +1,13 @@
// pch.h: 这是预编译标头文件。
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
#ifndef PCH_H
#define PCH_H
// 添加要在此处预编译的标头
#include "framework.h"
#endif //PCH_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

107
sln/usb_tools/resource.h Normal file
View File

@ -0,0 +1,107 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 usbtools.rc 使用
//
#define IDD_USB_TOOLS_DIALOG 102
#define IDD_SETTING 105
#define IDD_AREA 106
#define IDD_GAMMA 107
#define IDR_MAINFRAME 128
#define IDR_MENU1 134
#define IDD_SCANNER 135
#define IDD_PAGE 136
#define IDC_CHECK_AUTO_MON 1000
#define IDC_BUTTON_REFRESH 1001
#define IDC_EDIT_PAPER 1001
#define IDC_TREE_DEVICES 1002
#define IDC_STATIC_PAPER 1003
#define IDC_BUTTON_SEND 1005
#define IDC_BUTTON_SEND_EP0 1006
#define IDC_BUTTON_RESET_BULK 1007
#define IDC_LIST_DEVICES 1008
#define IDC_UNIT 1008
#define IDC_EDIT_PNP_MSG 1009
#define IDC_SCHEME 1009
#define IDC_CHECK_AUTO 1010
#define IDC_EDIT_DPI 1010
#define IDC_BUTTON_RECEIVE 1011
#define IDC_BUTTON_RESET 1011
#define IDC_EDIT_x 1012
#define IDC_EDIT_TYPE 1013
#define IDC_EDIT_y 1013
#define IDC_EDIT_REQ 1014
#define IDC_EDIT_W 1014
#define IDC_EDIT_H 1015
#define IDC_STATIC_PAINT 1016
#define IDC_EDIT_LEN 1017
#define IDC_CHANNEL 1017
#define IDC_EDIT_INPUT 1018
#define IDC_EDIT_INDEX2 1019
#define IDC_EDIT_OUTPUT 1019
#define IDC_BUTTON_CLEAR 1020
#define IDC_STATIC_UNIT 1021
#define IDC_STATIC_DPI 1022
#define IDC_STATIC_AREA 1023
#define IDC_STATIC_LEFT 1024
#define IDC_BUTTON1 1025
#define IDC_BUTTON_BROWSE_IMG_PATH 1025
#define IDC_STATIC_TOP 1025
#define IDC_EDIT_IMG_PATH 1026
#define IDC_STATIC_W 1026
#define IDC_EDIT_PROTOCOL_VER 1027
#define IDC_STATIC_H 1027
#define IDC_EDIT_BUILK_IN 1028
#define IDC_STATIC_SCHEME 1028
#define IDC_EDIT_BULK_OUT 1029
#define IDC_STATIC_COLOR 1029
#define IDC_BUTTON_SCAN 1030
#define IDC_STATIC_INPUT 1030
#define IDC_EDIT_LOCAL 1031
#define IDC_STATIC_OUTPUT 1031
#define IDC_EDIT_REMOTE 1032
#define IDC_BUTTON_BROWSE_LOCAL 1033
#define IDC_CHECK_REPEAT 1034
#define IDC_TAB_OPER 1035
#define IDC_EDIT_CMD 1036
#define IDC_EDIT_PARAM 1037
#define IDC_BUTTON_START_PROG 1038
#define IDC_EDIT_COUNT 1039
#define IDC_STATIC_LOCAL 1040
#define IDC_STATIC_REMOTE 1041
#define IDC_STATIC_IMG_PATH 1042
#define IDC_STATIC_CMD 1043
#define IDC_STATIC_PARAM 1044
#define IDC_STATIC_COUNT 1045
#define IDC_EDIT_STATUS 1046
#define IDC_EDIT_CMD_QUE 1047
#define IDC_EDIT_SENT_QUE 1048
#define IDC_EDIT_IND 1049
#define IDC_EDIT_VAL 1050
#define IDC_EDIT_DATA 1052
#define IDC_STATIC_TYPE 1053
#define IDC_STATIC_REQ 1054
#define IDC_STATIC_IND 1055
#define IDC_STATIC_VAL 1056
#define IDC_STATIC_LEN 1057
#define IDC_STATIC_DATA 1058
#define IDC_STATIC_BULK_IN 1059
#define IDC_STATIC_BULK_OUT 1060
#define IDC_STATIC_CMD_QUE 1061
#define IDC_STATIC_SENT_QUE 1062
#define IDC_STATIC_OPTS 1063
#define IDC_CHECK_AUTO_OPEN_IMG 1064
#define IDC_EDIT_LOG_FILE 1065
#define IDC_COMBO1 1066
#define IDC_COMBO_BUF_SIZE 1066
#define ID_TRAY_EXIT 32771
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 138
#define _APS_NEXT_COMMAND_VALUE 32772
#define _APS_NEXT_CONTROL_VALUE 1067
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -0,0 +1,8 @@
#pragma once
// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
//如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h
// 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
#include <SDKDDKVer.h>

125
sln/usb_tools/usb_tools.cpp Normal file
View File

@ -0,0 +1,125 @@

// usb_tools.cpp: 定义应用程序的类行为。
//
#include "pch.h"
#include "framework.h"
#include "usb_tools.h"
#include "usb_toolsDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CusbtoolsApp
BEGIN_MESSAGE_MAP(CusbtoolsApp, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CusbtoolsApp 构造
CusbtoolsApp::CusbtoolsApp()
{
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的 CusbtoolsApp 对象
CusbtoolsApp theApp;
// CusbtoolsApp 初始化
static bool find_instance(void)
{
// L"task_usb"
HWND hwnd = FindWindowExW(NULL, NULL, L"#32770", L"USB Tools");
while (IsWindow(hwnd))
{
HWND d = (HWND)GetProp(hwnd, L"task_usb");
if (d == hwnd)
{
PostMessage(hwnd, WM_TRAY_MSG, MAKELPARAM(MAKEWORD('P', 'O'), MAKEWORD('P', 'M')), (LPARAM)WM_LBUTTONDBLCLK);
return true;
}
hwnd = FindWindowExW(NULL, hwnd, L"#32770", L"USB Tools");
}
return false;
}
BOOL CusbtoolsApp::InitInstance()
{
// 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。 否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的
// 公共控件类。
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// 创建 shell 管理器,以防对话框包含
// 任何 shell 树视图控件或 shell 列表视图控件。
CShellManager *pShellManager = new CShellManager;
// 激活“Windows Native”视觉管理器以便在 MFC 控件中启用主题
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
if(!find_instance())
{
CusbtoolsDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: 在此放置处理何时用
// “确定”来关闭对话框的代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在此放置处理何时用
// “取消”来关闭对话框的代码
}
else if (nResponse == -1)
{
TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");
TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
}
// 删除上面创建的 shell 管理器。
if (pShellManager != nullptr)
{
delete pShellManager;
}
}
#if !defined(_AFXDLL) && !defined(_AFX_NO_MFC_CONTROLS_IN_DIALOGS)
ControlBarCleanUp();
#endif
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return FALSE;
}

32
sln/usb_tools/usb_tools.h Normal file
View File

@ -0,0 +1,32 @@

// usb_tools.h: PROJECT_NAME 应用程序的主头文件
//
#pragma once
#ifndef __AFXWIN_H__
#error "在包含此文件之前包含 'pch.h' 以生成 PCH"
#endif
#include "resource.h" // 主符号
// CusbtoolsApp:
// 有关此类的实现,请参阅 usb_tools.cpp
//
class CusbtoolsApp : public CWinApp
{
public:
CusbtoolsApp();
// 重写
public:
virtual BOOL InitInstance();
// 实现
DECLARE_MESSAGE_MAP()
};
extern CusbtoolsApp theApp;

View File

@ -0,0 +1,350 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<ProjectGuid>{4C912767-88BE-463E-BFFC-AF994A92E425}</ProjectGuid>
<Keyword>MFCProj</Keyword>
<RootNamespace>usbtools</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Dynamic</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Dynamic</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Dynamic</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Dynamic</UseOfMfc>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(ProjectDir)..\..\..\code_device\sdk;$(ProjectDir)..\sdk\include;$(ProjectDir)..\..\..\sdk\include;$(ProjectDir)..\..\device;$(ProjectDir)..\..\..\code_device\hgdriver\3rdparty\opencv\include;$(IncludePath);</IncludePath>
<LibraryPath>$(ProjectDir)..\sdk\lib\$(Configuration);$(ProjectDir)..\..\..\sdk\lib\win\x86\oem\huagao;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(ProjectDir)..\..\..\code_device\sdk</IncludePath>
<LibraryPath>$(SolutionDir)sdk\lib\$(Configuration);$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(ProjectDir)..\..\..\code_device\sdk;$(ProjectDir)..\sdk\include;$(ProjectDir)..\..\..\sdk\include;$(ProjectDir)..\..\device;$(ProjectDir)..\..\..\code_device\hgdriver\3rdparty\opencv\include;$(IncludePath);</IncludePath>
<LibraryPath>$(ProjectDir)..\sdk\lib\$(Configuration);$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(ProjectDir)..\..\..\code_device\sdk</IncludePath>
<LibraryPath>$(SolutionDir)sdk\lib\$(Configuration);$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_WINDOWS;HGSCANNER_EXPORT;PRODUCT_VENDOR="HuaGo";TEST_HGSCANNER;HGSCANNER_EXPORT;PRODUCT_VENDOR="HuaGo";_DEBUG;%(PreprocessorDefinitions);CUSTOM_USBVIEW</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
<ValidateAllParameters>true</ValidateAllParameters>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</Midl>
<ResourceCompile>
<Culture>0x0804</Culture>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions);CUSTOM_USBVIEW;_WINSOCK2API_</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
<ValidateAllParameters>true</ValidateAllParameters>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</Midl>
<ResourceCompile>
<Culture>0x0804</Culture>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_WINDOWS;HGSCANNER_EXPORT;PRODUCT_VENDOR="HuaGo";TEST_HGSCANNER;PRODUCT_VENDOR="HuaGo";NDEBUG;%(PreprocessorDefinitions);CUSTOM_USBVIEW;_WINSOCK2API_</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
<ValidateAllParameters>true</ValidateAllParameters>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</Midl>
<ResourceCompile>
<Culture>0x0804</Culture>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions);CUSTOM_USBVIEW;_WINSOCK2API_</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
<ValidateAllParameters>true</ValidateAllParameters>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</Midl>
<ResourceCompile>
<Culture>0x0804</Culture>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\..\code_device\hgdriver\hgdev\hg_scanner.h" />
<ClInclude Include="..\..\..\code_device\hgdriver\hgdev\scanner\async_usb_host.h" />
<ClInclude Include="..\..\..\code_device\hgdriver\hgdev\scanner\scanner_handler.h" />
<ClInclude Include="..\..\..\code_device\hgdriver\hgdev\usb_manager.h" />
<ClInclude Include="..\..\..\code_device\hgdriver\hgdev\user-opt\user.h" />
<ClInclude Include="..\..\..\code_device\sdk\base\data.h" />
<ClInclude Include="..\..\..\code_device\sdk\base\encrypt.h" />
<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\plat_types.h" />
<ClInclude Include="..\..\..\code_device\sdk\base\utils.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" />
<ClInclude Include="..\..\..\code_device\sdk\sane_opt_json\device_opt.h" />
<ClInclude Include="..\..\..\code_device\sdk\sane_opt_json\simple_logic.h" />
<ClInclude Include="..\..\device\win_usb\usbview\enum.h" />
<ClInclude Include="..\..\device\win_usb\usbview\usbdesc.h" />
<ClInclude Include="..\..\device\win_usb\usbview\uvcdesc.h" />
<ClInclude Include="..\..\device\win_usb\win_usb.h" />
<ClInclude Include="DlgScanner.h" />
<ClInclude Include="framework.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="Resource.h" />
<ClInclude Include="opt_ui\DlgArea.h" />
<ClInclude Include="opt_ui\DlgGamma.h" />
<ClInclude Include="opt_ui\DlgPage.h" />
<ClInclude Include="opt_ui\DlgSetting.h" />
<ClInclude Include="opt_ui\mem_dc.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="usb_tools.h" />
<ClInclude Include="usb_toolsDlg.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\code_device\hgdriver\hgdev\hg_scanner.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\code_device\hgdriver\hgdev\scanner\async_usb_host.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\code_device\hgdriver\hgdev\scanner\scanner_handler.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\code_device\hgdriver\hgdev\usb_manager.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\code_device\hgdriver\hgdev\user-opt\user.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\base\data.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\base\encrypt.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\base\ini_file.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">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>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\json\cJSON.c">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\json\gb_json.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\sane_opt_json\base_opt.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\sane_opt_json\device_opt.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\sane_opt_json\simple_logic.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\device\win_usb\usbview\devnode.c">
<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="..\..\device\win_usb\usbview\enum.c">
<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="..\..\device\win_usb\win_usb.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="DlgScanner.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="opt_ui\DlgArea.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="opt_ui\DlgGamma.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="opt_ui\DlgPage.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="opt_ui\DlgSetting.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="opt_ui\mem_dc.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="usb_tools.cpp" />
<ClCompile Include="usb_toolsDlg.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="usbtools.rc" />
</ItemGroup>
<ItemGroup>
<None Include="res\usbtools.rc2" />
</ItemGroup>
<ItemGroup>
<Image Include="res\usb_tools.ico" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,228 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="源文件">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="头文件">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="资源文件">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Imports">
<UniqueIdentifier>{daee46b5-b9e6-48f1-8c51-309ae6f0f1d2}</UniqueIdentifier>
</Filter>
<Filter Include="Imports\usbview">
<UniqueIdentifier>{3ae4886d-05e1-4b81-ad0c-90be56a8f2a4}</UniqueIdentifier>
</Filter>
<Filter Include="opt-ui">
<UniqueIdentifier>{97ca5d9c-2dc2-46cf-99a3-26c83a42ba05}</UniqueIdentifier>
</Filter>
<Filter Include="Imports\scanner">
<UniqueIdentifier>{1d14e64c-8b0e-4e0e-b35c-69ee76e726ad}</UniqueIdentifier>
</Filter>
<Filter Include="Imports\sdk">
<UniqueIdentifier>{49600e52-4fc8-41da-ace4-82fd9c1af621}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="usb_tools.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="usb_toolsDlg.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="framework.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="Resource.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="pch.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="..\..\device\win_usb\win_usb.h">
<Filter>Imports</Filter>
</ClInclude>
<ClInclude Include="..\..\device\win_usb\usbview\enum.h">
<Filter>Imports\usbview</Filter>
</ClInclude>
<ClInclude Include="..\..\device\win_usb\usbview\usbdesc.h">
<Filter>Imports\usbview</Filter>
</ClInclude>
<ClInclude Include="..\..\device\win_usb\usbview\uvcdesc.h">
<Filter>Imports\usbview</Filter>
</ClInclude>
<ClInclude Include="DlgScanner.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="opt_ui\DlgArea.h">
<Filter>opt-ui</Filter>
</ClInclude>
<ClInclude Include="opt_ui\DlgGamma.h">
<Filter>opt-ui</Filter>
</ClInclude>
<ClInclude Include="opt_ui\DlgPage.h">
<Filter>opt-ui</Filter>
</ClInclude>
<ClInclude Include="opt_ui\DlgSetting.h">
<Filter>opt-ui</Filter>
</ClInclude>
<ClInclude Include="opt_ui\mem_dc.h">
<Filter>opt-ui</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\hgdriver\hgdev\hg_scanner.h">
<Filter>Imports\scanner</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\hgdriver\hgdev\scanner\async_usb_host.h">
<Filter>Imports\scanner</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\hgdriver\hgdev\scanner\scanner_handler.h">
<Filter>Imports\scanner</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\sdk\base\data.h">
<Filter>Imports\sdk</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\sdk\base\encrypt.h">
<Filter>Imports\sdk</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\sdk\base\huagaoxxx_warraper_ex.h">
<Filter>Imports\sdk</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\sdk\base\ini_file.h">
<Filter>Imports\sdk</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\sdk\base\packet.h">
<Filter>Imports\sdk</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\sdk\base\plat_types.h">
<Filter>Imports\sdk</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\sdk\base\utils.h">
<Filter>Imports\sdk</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\sdk\json\cJSON.h">
<Filter>Imports\sdk</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\sdk\json\gb_json.h">
<Filter>Imports\sdk</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\sdk\sane_opt_json\base_opt.h">
<Filter>Imports\sdk</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\sdk\sane_opt_json\device_opt.h">
<Filter>Imports\sdk</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\sdk\sane_opt_json\simple_logic.h">
<Filter>Imports\sdk</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\hgdriver\hgdev\usb_manager.h">
<Filter>Imports</Filter>
</ClInclude>
<ClInclude Include="..\..\..\code_device\hgdriver\hgdev\user-opt\user.h">
<Filter>Imports\scanner</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="usb_tools.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="usb_toolsDlg.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="pch.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="..\..\device\win_usb\win_usb.cpp">
<Filter>Imports</Filter>
</ClCompile>
<ClCompile Include="..\..\device\win_usb\usbview\devnode.c">
<Filter>Imports\usbview</Filter>
</ClCompile>
<ClCompile Include="..\..\device\win_usb\usbview\enum.c">
<Filter>Imports\usbview</Filter>
</ClCompile>
<ClCompile Include="DlgScanner.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="opt_ui\DlgArea.cpp">
<Filter>opt-ui</Filter>
</ClCompile>
<ClCompile Include="opt_ui\DlgGamma.cpp">
<Filter>opt-ui</Filter>
</ClCompile>
<ClCompile Include="opt_ui\DlgPage.cpp">
<Filter>opt-ui</Filter>
</ClCompile>
<ClCompile Include="opt_ui\DlgSetting.cpp">
<Filter>opt-ui</Filter>
</ClCompile>
<ClCompile Include="opt_ui\mem_dc.cpp">
<Filter>opt-ui</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\hgdriver\hgdev\hg_scanner.cpp">
<Filter>Imports\scanner</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\hgdriver\hgdev\scanner\async_usb_host.cpp">
<Filter>Imports\scanner</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\hgdriver\hgdev\scanner\scanner_handler.cpp">
<Filter>Imports\scanner</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\base\data.cpp">
<Filter>Imports\sdk</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\base\encrypt.cpp">
<Filter>Imports\sdk</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\base\ini_file.cpp">
<Filter>Imports\sdk</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\base\utils.cpp">
<Filter>Imports\sdk</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\json\cJSON.c">
<Filter>Imports\sdk</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\json\gb_json.cpp">
<Filter>Imports\sdk</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\sane_opt_json\base_opt.cpp">
<Filter>Imports\sdk</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\sane_opt_json\device_opt.cpp">
<Filter>Imports\sdk</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\sdk\sane_opt_json\simple_logic.cpp">
<Filter>Imports\sdk</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\hgdriver\hgdev\usb_manager.cpp">
<Filter>Imports</Filter>
</ClCompile>
<ClCompile Include="..\..\..\code_device\hgdriver\hgdev\user-opt\user.cpp">
<Filter>Imports\scanner</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="usbtools.rc">
<Filter>资源文件</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="res\usbtools.rc2">
<Filter>资源文件</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Image Include="res\usb_tools.ico">
<Filter>资源文件</Filter>
</Image>
</ItemGroup>
</Project>

View File

@ -0,0 +1,934 @@

// usb_toolsDlg.cpp: 实现文件
//
#include "pch.h"
#include "framework.h"
#include "usb_tools.h"
#include "usb_toolsDlg.h"
#include "afxdialogex.h"
#include "DlgScanner.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#include <chrono>
#include <coding/coding.h>
#include <win/win_util.h>
#include "../../../code_device/hgdriver/hgdev/usb_manager.h"
// CusbtoolsDlg 对话框
#pragma warning(disable: 4996)
namespace usb
{
void enum_endpoints(libusb_device* device, std::vector<USBEP>& eps)
{
libusb_device_descriptor desc;
libusb_config_descriptor* conf = NULL;
int ret = libusb_get_device_descriptor(device, &desc);
if (ret != 0)
{
return;
}
for (int i = 0; i < (int)desc.bNumConfigurations; ++i)
{
ret = libusb_get_config_descriptor(device, i, &conf);
if (ret != 0)
{
continue;
}
for (int j = 0; j < conf->bNumInterfaces; ++j)
{
for (int k = 0; k < conf->interface[j].num_altsetting; ++k)
{
for (int l = 0; l < conf->interface[j].altsetting[k].bNumEndpoints; ++l)
{
USBEP ep;
ep.iface = j;
ep.type = conf->interface[j].altsetting[k].endpoint[l].bmAttributes;
ep.addr = conf->interface[j].altsetting[k].endpoint[l].bEndpointAddress;
ep.packet = conf->interface[j].altsetting[k].endpoint[l].wMaxPacketSize;
eps.push_back(std::move(ep));
}
}
}
libusb_free_config_descriptor(conf);
}
}
struct
{
BYTE type;
const wchar_t* str;
}g_ep_type[] = { {LIBUSB_TRANSFER_TYPE_BULK, L"Bulk"}
, {LIBUSB_TRANSFER_TYPE_BULK_STREAM, L"Bulk Stream"}
, {LIBUSB_TRANSFER_TYPE_CONTROL, L"Control"}
, {LIBUSB_TRANSFER_TYPE_INTERRUPT, L"Interrupt"}
, {LIBUSB_TRANSFER_TYPE_ISOCHRONOUS, L"Isochronous"}
};
const wchar_t* ep_type(BYTE type)
{
for (auto& v : g_ep_type)
{
if (v.type == type)
return v.str;
}
return L"Unknown type";
}
BYTE ep_type(const wchar_t* str)
{
for (auto& v : g_ep_type)
{
if (wcsicmp(v.str, str) == 0)
return v.type;
}
return -1;
}
BYTE from_hex_str(const wchar_t* str, bool* ok)
{
BYTE v = 0, cnt = 0;
if (ok)
*ok = false;
while (*str && cnt < 2)
{
if (*str >= L'0' && *str <= L'9')
{
v <<= 4;
v += *str - L'0';
}
else if (*str >= L'a' && *str <= L'f')
{
v <<= 4;
v += *str - L'a' + 10;
}
else if (*str >= L'A' && *str <= L'F')
{
v <<= 4;
v += *str - L'A' + 10;
}
else
{
break;
}
cnt++;
str++;
}
if (ok)
*ok = cnt == 2;
return v;
}
static int LIBUSB_CALL usb_pnp(libusb_context* ctx,
libusb_device* device,
libusb_hotplug_event event,
void* user_data)
{
ONLNSCANNER *pnp = new ONLNSCANNER;
HWND owner = (HWND)user_data;
libusb_device_descriptor desc;
pnp->dev = libusb_ref_device(device);
libusb_get_device_descriptor(pnp->dev, &desc);
pnp->vid = desc.idVendor;
pnp->pid = desc.idProduct;
pnp->scanner = NULL;
pnp->family = pnp->display_name = "";
if (!PostMessage(owner, WM_USB_PNP, event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, (LPARAM)pnp))
{
libusb_unref_device(pnp->dev);
delete pnp;
}
return 0;
}
static void custom_usb_event_handler(usb_event ev, libusb_device* device, int vid, int pid, int usb_ver_h, int usb_ver_l, bool* retry/*whether */, void* user)
{
ONLNSCANNER* pnp = new ONLNSCANNER;
HWND owner = (HWND)user;
pnp->dev = libusb_ref_device(device);
pnp->vid = vid;
pnp->pid = pid;
pnp->scanner = NULL;
pnp->family = pnp->display_name = "";
if (!PostMessage(owner, WM_USB_PNP, ev == USB_EVENT_DEVICE_ARRIVED, (LPARAM)pnp))
{
utils::to_log(LOG_LEVEL_WARNING, "Lost device PNP: %04X:%04X %s\r\n", vid, pid, ev == USB_EVENT_DEVICE_ARRIVED ? "arrival" : "left");
libusb_unref_device(pnp->dev);
delete pnp;
}
}
static int transfer(libusb_device_handle* h, BYTE type, BYTE addr, unsigned char* buf, int *len, const wchar_t** desc = NULL, DWORD to = -1)
{
int ret = -1;
const wchar_t* tmp = NULL;
if (!desc)
desc = &tmp;
if (type == LIBUSB_TRANSFER_TYPE_BULK)
{
*desc = L"Bulk";
ret = libusb_bulk_transfer(h, addr, buf, *len, len, to);
}
else if (type == LIBUSB_TRANSFER_TYPE_CONTROL)
{
// ret = libusb_control_transfer()
}
else if (type == LIBUSB_TRANSFER_TYPE_INTERRUPT)
{
*desc = L"Interrupt";
ret = libusb_interrupt_transfer(h, addr, buf, *len, len, to);
}
return ret;
}
std::wstring now(void)
{
std::string cur(std::move(chronograph::now()));
return std::move(a2u(cur.c_str()));
//wchar_t buf[40] = { 0 };
//time_t t = time(NULL);
//tm* lt = localtime(&t);
//swprintf_s(buf, _countof(buf) - 1, L"%04d-%02d-%02d %02d:%02d:%02d", lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec);
//return buf;
}
const wchar_t* error_name(int err, wchar_t* unk)
{
#define RETURN_IF(e) \
if(err == e) \
return L###e;
RETURN_IF(LIBUSB_SUCCESS);
RETURN_IF(LIBUSB_ERROR_IO);
RETURN_IF(LIBUSB_ERROR_INVALID_PARAM);
RETURN_IF(LIBUSB_ERROR_ACCESS);
RETURN_IF(LIBUSB_ERROR_NO_DEVICE);
RETURN_IF(LIBUSB_ERROR_NOT_FOUND);
RETURN_IF(LIBUSB_ERROR_BUSY);
RETURN_IF(LIBUSB_ERROR_TIMEOUT);
RETURN_IF(LIBUSB_ERROR_OVERFLOW);
RETURN_IF(LIBUSB_ERROR_PIPE);
RETURN_IF(LIBUSB_ERROR_INTERRUPTED);
RETURN_IF(LIBUSB_ERROR_NO_MEM);
RETURN_IF(LIBUSB_ERROR_NOT_SUPPORTED);
RETURN_IF(LIBUSB_ERROR_OTHER);
//RETURN_IF(LIBUSB_ERROR_TRY_AGAIN);
if (unk)
{
swprintf(unk, L"%d", err);
return unk;
}
wchar_t buf[20] = { 0 };
swprintf_s(buf, _countof(buf) - 1, L"%d", err);
return buf;
}
INTER_MODULE_CALLBACK(got_wstr)
{
*((std::wstring*)param) += std::wstring((const wchar_t*)data, len / 2);
return inter_module_data::SET_RESULT_CONTINUE;
}
INTER_MODULE_CALLBACK(got_str)
{
*((std::string*)param) += std::string(data, len);
return inter_module_data::SET_RESULT_CONTINUE;
}
std::wstring a2u(const char* ansi)
{
std::wstring u(L"");
coding_util::ansi_2_unicode(ansi, got_wstr, &u);
return std::move(u);
}
std::string u2a(const wchar_t* unic)
{
std::string a("");
coding_util::unicode_2_ansi(unic, got_str, &a);
return std::move(a);
}
static void register_tray(HWND owner, HICON icon, bool reg)
{
if(reg)
win_util::add_tray_icon(WM_TRAY_MSG, owner, WM_TRAY_MSG, L"Operate on USB device", icon);
else
win_util::remove_tray_icon(WM_TRAY_MSG, owner);
}
}
CusbtoolsDlg::CusbtoolsDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_USB_TOOLS_DIALOG, pParent)
{
log_file_ = utils::init_log(LOG_TYPE_FILE);
utils::to_log(LOG_LEVEL_DEBUG, "System info: page = %u, mapping-size = %u, disk-cluster-size = %u\r\n", sys_info::page_size, sys_info::page_map_size, sys_info::cluster_size);
{
//FILE* dst = fopen("D:\\boxroom\\usb-tx-file\\tx\\test.txt", "wb");
//int pos = 0;
//
//fwrite("T", 1, 100, dst);
//pos = ftell(dst);
//pos = fseek(dst, 0, SEEK_SET);
//pos = fseek(dst, 1024, SEEK_SET);
//fclose(dst);
}
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
CusbtoolsDlg::~CusbtoolsDlg()
{
usb_manager::instance()->register_hotplug(NULL, NULL);
usb_manager::clear();
remove_pnp_que();
utils::uninit();
}
void CusbtoolsDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_DEVICES, devl_);
}
BEGIN_MESSAGE_MAP(CusbtoolsDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_CHECK_AUTO_MON, &CusbtoolsDlg::OnBnClickedCheckAutoMon)
ON_MESSAGE(WM_USB_PNP, &CusbtoolsDlg::OnUsbPnp)
ON_MESSAGE(WM_RCV_MSG, &CusbtoolsDlg::OnRcvMsg)
ON_MESSAGE(WM_OPENNING_DLG_CLOSED, &CusbtoolsDlg::OnDevDlgClosed)
ON_MESSAGE(WM_TRAY_MSG, &CusbtoolsDlg::OnTray)
ON_NOTIFY(NM_DBLCLK, IDC_LIST_DEVICES, &CusbtoolsDlg::OnNMDblclkListDevices)
ON_BN_CLICKED(IDC_BUTTON_CLEAR, &CusbtoolsDlg::OnBnClickedButtonClear)
ON_WM_SYSCOMMAND()
ON_COMMAND(ID_TRAY_EXIT, &CusbtoolsDlg::OnTrayExit)
ON_COMMAND_RANGE(ID_TRAY_EXIT + 1, ID_TRAY_EXIT + 100, &CusbtoolsDlg::OnTrayDevice)
ON_BN_CLICKED(IDOK, &CusbtoolsDlg::OnBnClickedOk)
ON_WM_SIZE()
END_MESSAGE_MAP()
// CusbtoolsDlg 消息处理程序
bool show_balloon(int tray_id, HWND main_wnd, const wchar_t* tips, const wchar_t* title, DWORD dwTimeout, HICON hIcon, DWORD dwInfoFlag)
{
NOTIFYICONDATAW nid = { 0 };
nid.cbSize = NOTIFYICONDATA_V2_SIZE; // KEY parameter to show balloon message!
//nid.uVersion = NOTIFYICON_VERSION;
nid.hWnd = main_wnd;
nid.uID = tray_id;
nid.uFlags = /*NIF_INFO |*/ NIF_TIP;
wcscpy_s(nid.szTip, _countof(nid.szTip) - 1, tips);
wcscpy_s(nid.szInfoTitle, _countof(nid.szInfoTitle) - 1, title);
nid.hIcon = hIcon ? hIcon : (HICON)SendMessageW(main_wnd, WM_GETICON, ICON_SMALL, 0);
nid.uTimeout = dwTimeout;
nid.dwInfoFlags = dwInfoFlag;
return Shell_NotifyIconW(NIM_MODIFY, &nid) == TRUE;
}
BOOL CusbtoolsDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
int ind = 0;
devl_.InsertColumn(ind++, TEXT("No."), 0, 51);
devl_.InsertColumn(ind++, TEXT("VID"), 0, 75);
devl_.InsertColumn(ind++, TEXT("PID"), 0, 75);
devl_.SetExtendedStyle(devl_.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP);
//SetDlgItemInt(IDC_EDIT_TYPE, 0x40);
//SetDlgItemInt(IDC_EDIT_REQ, 0x64);
//SetDlgItemInt(IDC_EDIT_VALUE, 16);
//SetDlgItemInt(IDC_EDIT_INDEX, 0);
//SetDlgItemInt(IDC_EDIT_LEN, 20);
OnBnClickedCheckAutoMon();
tray_ = LoadMenu(NULL, MAKEINTRESOURCE(IDR_MENU1));
desktop_ = ::FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL);
usb::register_tray(m_hWnd, m_hIcon, true);
SetPropW(m_hWnd, L"task_usb", m_hWnd);
::SetDlgItemTextA(m_hWnd, IDC_EDIT_LOG_FILE, log_file_.c_str());
usb_manager::instance()->register_hotplug(&usb::custom_usb_event_handler, (void*)m_hWnd);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CusbtoolsDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CusbtoolsDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CusbtoolsDlg::enable_io_ui(bool enable)
{
GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(enable);
GetDlgItem(IDC_CHECK_AUTO)->EnableWindow(enable);
enable &= ((CButton*)GetDlgItem(IDC_CHECK_AUTO))->GetCheck() != BST_CHECKED;
GetDlgItem(IDC_BUTTON_RECEIVE)->EnableWindow(enable);
//GetDlgItem(IDC_COMBO_EP2)->EnableWindow(enable);
//OnCbnSelchangeComboEp();
//GetDlgItem(IDC_EDIT_TYPE)->EnableWindow(enable);
//GetDlgItem(IDC_EDIT_REQ)->EnableWindow(enable);
//GetDlgItem(IDC_EDIT_VALUE)->EnableWindow(enable);
//GetDlgItem(IDC_EDIT_INDEX)->EnableWindow(enable);
//GetDlgItem(IDC_EDIT_LEN)->EnableWindow(enable);
}
void CusbtoolsDlg::add_pnp_que(ONLNSCANNER* pnp)
{
int vid = pnp->vid,
pid = pnp->pid;
bool add = true;
for (auto& v : pnp_que_)
{
if (v.usb.dev == pnp->dev)
{
libusb_unref_device(pnp->dev);
if (v.dlg)
{
open_usb(v, false);
}
add = false;
break;
}
}
if (add)
{
SCANNER scnr;
scnr.usb = *pnp;
scnr.dlg = NULL;
scnr.id = InterlockedIncrement(&id_);
pnp_que_.push_back(scnr);
// add to UI ...
int item = devl_.InsertItem(devl_.GetItemCount(), std::to_wstring(devl_.GetItemCount() + 1).c_str());
TCHAR text[40] = { 0 };
_stprintf(text, TEXT("%04X"), pnp->vid);
devl_.SetItemText(item, 1, text);
_stprintf(text, TEXT("%04X"), pnp->pid);
devl_.SetItemText(item, 2, text);
devl_.SetItemData(item, (DWORD_PTR)scnr.id);
}
if (!IsWindowVisible())
{
wchar_t tips[128] = { 0 };
swprintf_s(tips, _countof(tips) - 1, L"%04X:%04X arrived", vid, pid);
show_balloon(WM_TRAY_MSG, m_hWnd, tips, L"USB", 1000, m_hIcon, NIF_TIP);
}
}
void CusbtoolsDlg::remove_pnp_que(ONLNSCANNER* pnp)
{
for (size_t i = 0; i < pnp_que_.size(); ++i)
{
if (!pnp || (pnp_que_[i].usb.dev == pnp->dev))
{
if (IsWindow(devl_.m_hWnd))
{
for (int j = 0; j < devl_.GetItemCount(); ++j)
{
if (!pnp || devl_.GetItemData(j) == (DWORD_PTR)pnp_que_[i].id)
{
//if (devl_.GetItemState(j, LVIS_SELECTED))
// enable_io_ui(false);
if (pnp_que_[i].dlg == NULL)
{
devl_.SetItemData(j, 0);
devl_.DeleteItem(j);
for (; pnp && j < devl_.GetItemCount(); ++j)
devl_.SetItemText(j, 0, std::to_wstring(j + 1).c_str());
}
if (pnp)
break;
}
}
}
if (pnp_que_[i].dlg && IsWindow(pnp_que_[i].dlg->m_hWnd))
{
pnp_que_[i].dlg->set_device(NULL);
//if(!pnp)
//{
// pnp_que_[i].dlg->DestroyWindow();
// delete pnp_que_[i].dlg;
// pnp_que_[i].dlg = NULL;
//}
}
libusb_unref_device(pnp_que_[i].usb.dev);
close_device(pnp_que_[i]);
if (pnp)
{
pnp_que_.erase(pnp_que_.begin() + i);
break;
}
else
{
if (pnp_que_[i].dlg)
{
delete pnp_que_[i].dlg;
pnp_que_[i].dlg = NULL;
}
}
}
}
if (IsWindow(m_hWnd) && !IsWindowVisible() && pnp)
{
wchar_t tips[128] = { 0 };
swprintf_s(tips, _countof(tips) - 1, L"%04X:%04X left", pnp->vid, pnp->pid);
show_balloon(WM_TRAY_MSG, m_hWnd, tips, L"USB", 1000, m_hIcon, NIF_TIP);
}
}
void CusbtoolsDlg::append_log(const wchar_t* log, UINT id)
{
if (!IsWindow(m_hWnd))
return;
int len = ::GetWindowTextLength(GetDlgItem(id)->m_hWnd);
wchar_t* buf = new wchar_t[len + 128];
libusb_device_descriptor desc;
::GetDlgItemTextW(m_hWnd, id, buf, len + 20);
::SetDlgItemTextW(m_hWnd, id, (std::wstring(buf) + log).c_str());
while (::SendMessage(GetDlgItem(id)->m_hWnd, EM_SCROLL, SB_PAGEDOWN, 0));
delete[] buf;
}
void CusbtoolsDlg::log_pnp(ONLNSCANNER* pnp, bool arrive)
{
wchar_t buf[128] = { 0 };
swprintf_s(buf + lstrlenW(buf), _countof(buf) - 1, L"%s: %04X:%04X %s\r\n", usb::now().c_str(),
pnp->vid, pnp->pid, arrive ? L"Arrive" : L"Left");
append_log(buf, IDC_EDIT_PNP_MSG);
utils::to_log(LOG_LEVEL_ALL, "%04X:%04X %s\r\n", pnp->vid, pnp->pid, arrive ? "Arrived" : "Left");
}
bool CusbtoolsDlg::endpoint_from_combo_text(wchar_t* text, BYTE& type, BYTE& addr)
{
wchar_t* ptr = wcsstr(text, L" ");
bool ret = false;
if (ptr)
{
*ptr++ = 0;
type = usb::ep_type(text);
if (type != -1)
{
ptr = wcsstr(ptr, L"-");
if (ptr++)
{
while (*ptr == L' ') ptr++;
addr = usb::from_hex_str(ptr, &ret);
}
}
}
return ret;
}
void CusbtoolsDlg::close_device(SCANNER& pnp)
{
wchar_t msg[128] = { 0 };
swprintf_s(msg, _countof(msg) - 1, L"%s: %04X:%04X closed.\r\n", usb::now().c_str(), pnp.usb.vid, pnp.usb.pid);
append_log(msg, IDC_EDIT_PNP_MSG);
}
ONLNSCANNER* CusbtoolsDlg::get_cur_device(void)
{
for (int i = 0; i < devl_.GetItemCount(); ++i)
{
if (devl_.GetItemState(i, LVIS_SELECTED))
return (ONLNSCANNER*)devl_.GetItemData(i);
}
return NULL;
}
void CusbtoolsDlg::open_usb(SCANNER& pnp, bool from_list)
{
wchar_t msg[256] = { 0 }, errb[40] = { 0 };
int face = -1, ret = 0;
//*
if (pnp.dlg == NULL)
{
pnp.dlg = new CDlgScanner(this); // new CDlgOpenning(this);
pnp.dlg->Create(IDD_SCANNER); // (IDD_OPENNING);
}
pnp.dlg->set_device(&pnp.usb);
pnp.dlg->ShowWindow(SW_SHOW);
if (!msg[0])
swprintf_s(msg, _countof(msg) - 1, L"%s: open %04X:%04X success\r\n", usb::now().c_str(), pnp.usb.vid, pnp.usb.pid);
else if (!from_list)
::MessageBoxW(m_hWnd, msg, L"Failed", MB_OK | MB_ICONERROR);
append_log(msg, IDC_EDIT_PNP_MSG);
}
LRESULT CusbtoolsDlg::OnUsbPnp(WPARAM wp, LPARAM lp)
{
ONLNSCANNER *pnp = (ONLNSCANNER*)lp;
log_pnp(pnp, wp);
if (pnp->pid == 0 && pnp->vid == 0)
{
libusb_unref_device(pnp->dev);
delete pnp;
return 0;
}
if (wp)
{
////for (auto& v : pnp_que_)
////{
//// if (v->ctx == pnp->ctx && v->device == pnp->device)
//// {
//// libusb_unref_device(pnp->device);
//// v->arrive = true;
//// delete pnp;
//// pnp = NULL;
//// break;
//// }
////}
//if (pnp)
add_pnp_que(pnp);
}
else
{
remove_pnp_que(pnp);
// libusb_unref_device(pnp->device);
}
delete pnp;
return 0;
}
LRESULT CusbtoolsDlg::OnRcvMsg(WPARAM wp, LPARAM lp)
{
std::wstring* msg = (std::wstring*)lp;
//append_log(msg->c_str(), IDC_EDIT_REPLY);
delete msg;
return 0;
}
LRESULT CusbtoolsDlg::OnDevDlgClosed(WPARAM wp, LPARAM lp)
{
CDlgScanner* dlg = (CDlgScanner*)lp;
//CDlgOpenning* dlg = (CDlgOpenning*)lp;
for (int i = 0; i < pnp_que_.size(); ++i)
{
if (pnp_que_[i].dlg == dlg)
{
bool online = dlg->is_online();
pnp_que_[i].dlg = NULL;
close_device(pnp_que_[i]);
if (!online)
{
remove_pnp_que(&pnp_que_[i].usb);
}
break;
}
}
dlg->DestroyWindow();
delete dlg;
return 0;
}
LRESULT CusbtoolsDlg::OnTray(WPARAM wp, LPARAM lp)
{
UINT msg = (UINT)lp;
if (msg == WM_LBUTTONDBLCLK)
{
ShowWindow(SW_RESTORE);
SetForegroundWindow();
if (MAKELPARAM(MAKEWORD('P', 'O'), MAKEWORD('P', 'M')) == wp)
{
HWND taskwnd = ::FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL);
if (desktop_ != taskwnd && IsWindow(taskwnd))
{
usb::register_tray(m_hWnd, m_hIcon, true);
desktop_ = taskwnd;
}
}
}
else if (msg == WM_RBUTTONDOWN)
{
// exit ...
POINT pt = { 0 };
HMENU hm = GetSubMenu(tray_, 0);
MENUITEMINFOW mi = { 0 };
mi.cbSize = sizeof(mi);
mi.fMask = MIIM_DATA;
while (GetMenuItemInfoW(hm, 0, TRUE, &mi) && mi.dwItemData)
DeleteMenu(hm, 0, MF_BYPOSITION);
for (int i = 0; i < devl_.GetItemCount(); ++i)
{
int tid = (int)devl_.GetItemData(i), vid = 0, pid = 0;
wchar_t id[40] = { 0 };
bool openned = false;
for (auto& v : pnp_que_)
{
if (v.id == tid)
{
vid = v.usb.vid;
pid = v.usb.pid;
openned = v.dlg != NULL;
break;
}
}
swprintf_s(id, _countof(id) - 1, L"%04X:%04X", vid, pid);
InsertMenuW(hm, i, MF_BYPOSITION, ID_TRAY_EXIT + 1 + i, id);
mi.dwItemData = (LONG)tid;
SetMenuItemInfoW(hm, i, TRUE, &mi);
if (openned)
CheckMenuItem(hm, i, MF_CHECKED | MF_BYPOSITION);
}
GetCursorPos(&pt);
TrackPopupMenu(hm, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, m_hWnd, NULL);
}
return 0;
}
void CusbtoolsDlg::OnBnClickedCheckAutoMon()
{
// TODO: 在此添加控件通知处理程序代码
static libusb_hotplug_callback_handle handle = NULL;
//if (ctx_)
//{
// libusb_context* cp = ctx_;
// mon_ = false;
// ctx_ = NULL;
// if (mon_thrd_.get() && mon_thrd_->joinable())
// mon_thrd_->join();
// mon_thrd_.reset();
// libusb_hotplug_deregister_callback(cp, handle);
// libusb_exit(cp);
// handle = NULL;
//}
//else
//{
// libusb_init(&ctx_);
// int ret = libusb_hotplug_register_callback(ctx_, (libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
// (libusb_hotplug_flag)LIBUSB_HOTPLUG_ENUMERATE,
// LIBUSB_HOTPLUG_MATCH_ANY,//LIBUSB_HOTPLUG_MATCH_ANY
// LIBUSB_HOTPLUG_MATCH_ANY,//LIBUSB_HOTPLUG_MATCH_ANY,
// LIBUSB_HOTPLUG_MATCH_ANY,
// &usb::usb_pnp,
// m_hWnd,
// &handle);
// mon_ = true;
// mon_thrd_.reset(new std::thread(&CusbtoolsDlg::usb_monitor_thread, this));
//}
}
void CusbtoolsDlg::OnNMDblclkListDevices(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
if (pNMItemActivate->iItem < 0 || pNMItemActivate->iItem >= devl_.GetItemCount())
return;
wchar_t msg[256] = { 0 }, unk[40] = { 0 };
int tid = (int)devl_.GetItemData(pNMItemActivate->iItem);
int face = -1, ret = 0;
SCANNER* pnp = NULL;
for (auto& v : pnp_que_)
{
if (v.id == tid)
{
pnp = &v;
break;
}
}
if (!pnp)
return;
if (!pnp->dlg)
{
open_usb(*pnp);
}
else
{
RECT r = { 0 };
pnp->dlg->GetWindowRect(&r);
::SetWindowPos(pnp->dlg->m_hWnd, HWND_TOPMOST, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
::SetTimer(pnp->dlg->m_hWnd, WM_TIMER_CANCEL_TOPMOST, 1000, NULL);
}
}
void CusbtoolsDlg::OnBnClickedButtonClear()
{
// TODO: 在此添加控件通知处理程序代码
SetDlgItemText(IDC_EDIT_PNP_MSG, TEXT(""));
}
void CusbtoolsDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (nID == SC_CLOSE)
{
ShowWindow(SW_MINIMIZE);
ShowWindow(SW_HIDE);
return;
}
CDialogEx::OnSysCommand(nID, lParam);
}
void CusbtoolsDlg::OnTrayExit()
{
// TODO: 在此添加命令处理程序代码
usb::register_tray(m_hWnd, m_hIcon, false);
PostQuitMessage(0);
}
void CusbtoolsDlg::OnTrayDevice(UINT id)
{
// TODO: 在此添加命令处理程序代码
HMENU hm = GetSubMenu(tray_, 0);
MENUITEMINFOW mi = { 0 };
mi.cbSize = sizeof(mi);
mi.fMask = MIIM_DATA | MIIM_STATE;
GetMenuItemInfoW(hm, id, FALSE, &mi);
if (mi.dwItemData)
{
SCANNER* pnp = NULL;
for (auto& v : pnp_que_)
{
if (v.id == (int)mi.dwItemData)
{
pnp = &v;
break;
}
}
if (!pnp)
return;
if (pnp->dlg)
pnp->dlg->OnBnClickedOk();
else
open_usb(*pnp, false);
}
}
void CusbtoolsDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
OnTrayExit();
CDialogEx::OnOK();
}
void CusbtoolsDlg::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);
// TODO: 在此处添加消息处理程序代码
//if (cx == 0 && cy == 0 && ::IsWindow(devl_.m_hWnd))
//{
// for (int i = 0; i < devl_.GetItemCount(); ++i)
// {
// ONLNSCANNER* pnp = (ONLNSCANNER*)devl_.GetItemData(i);
// if (pnp && pnp->dlg)
// pnp->dlg->ShowWindow(SW_SHOW);
// }
//}
}

View File

@ -0,0 +1,75 @@

// usb_toolsDlg.h: 头文件
//
#pragma once
#include <vector>
#include <thread>
#include <memory>
#include "DlgScanner.h"
// CusbtoolsDlg 对话框
class CusbtoolsDlg : public CDialogEx
{
typedef struct _scanner
{
DWORD id;
ONLNSCANNER usb;
CDlgScanner* dlg;
}SCANNER;
std::vector<SCANNER> pnp_que_;
HMENU tray_;
HWND desktop_;
DWORD id_ = 1;
void enable_io_ui(bool enable);
void add_pnp_que(ONLNSCANNER* pnp);
void remove_pnp_que(ONLNSCANNER* pnp = NULL);
void append_log(const wchar_t* log, UINT id);
void log_pnp(ONLNSCANNER* pnp, bool arrive);
bool endpoint_from_combo_text(wchar_t* text, BYTE& type, BYTE& addr);
void close_device(SCANNER& pnp);
ONLNSCANNER* get_cur_device(void);
void open_usb(SCANNER& pnp, bool from_list = true);
// 构造
public:
CusbtoolsDlg(CWnd* pParent = nullptr); // 标准构造函数
~CusbtoolsDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_USB_TOOLS_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
std::string log_file_;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg LRESULT OnUsbPnp(WPARAM wp, LPARAM lp);
afx_msg LRESULT OnRcvMsg(WPARAM wp, LPARAM lp);
afx_msg LRESULT OnDevDlgClosed(WPARAM wp, LPARAM lp);
afx_msg LRESULT OnTray(WPARAM wp, LPARAM lp);
afx_msg void OnBnClickedCheckAutoMon();
CListCtrl devl_;
afx_msg void OnNMDblclkListDevices(NMHDR* pNMHDR, LRESULT* pResult);
CComboBox ep2_;
afx_msg void OnBnClickedButtonClear();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnTrayExit();
afx_msg void OnTrayDevice(UINT id);
afx_msg void OnBnClickedOk();
afx_msg void OnSize(UINT nType, int cx, int cy);
};

BIN
sln/usb_tools/usbtools.rc Normal file

Binary file not shown.