#pragma once #include #include #include #include #include #include #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_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& 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 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 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& 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); };