code_twain/sane/DlgPage.h

247 lines
8.1 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 IS_STATIC_TEXT(cls) IS_STR_EQUAL(cls, L"Static")
#define RECT_W(r) (r.right - r.left)
#define RECT_H(r) (r.bottom - r.top)
#define WM_QUIT_MSG_THREAD WM_USER + 300
#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
extern HMODULE g_my_inst;
namespace gb
{
class sane_config_schm;
}
#include <thread>
#include <memory>
class dlg_base
{
int modal_exit_; // set non-ZERO code to exit modal dialog
DWORD msg_thread_id_;
volatile bool destroyed_;
bool child_;
static volatile bool msg_thread_exited_;
static DWORD WINAPI start_thread(LPVOID lp);
void thread_pump_message(void);
protected:
HWND hwnd_;
HWND parent_;
UINT idd_;
bool abandon_hold_;
bool del_at_destroy_; // 是否在窗口销毁时,自动释放对象
volatile bool ready_ = false;
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(bool sole_thread = false);
void notify_ui_event(int ev);
gb::sane_config_schm* get_config(bool* create);
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 bool is_message_thread_exited(void);
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); // 该函数调用之后,自动销毁窗口。如果要反复使用,需要调整窗口创建时机,放到该函数入口处。(FIXED ME ...
void quit_modal(int non_zero_code);
void close(void);
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_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);
};