code_twain/sane/DlgPage.h

229 lines
7.5 KiB
C++

#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
extern HMODULE g_my_inst;
namespace gb
{
class sane_config_schm;
}
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);
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 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_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);
};