diff --git a/sane/DlgPage.cpp b/sane/DlgPage.cpp index e55c47c..994149c 100644 --- a/sane/DlgPage.cpp +++ b/sane/DlgPage.cpp @@ -8,6 +8,11 @@ #include "DlgGamma.h" #include "gb_json.h" + +// #pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") + + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // #define FLOAT_FORMAT L"%.2f" @@ -134,39 +139,6 @@ int dlg_base::select_combo_text(HWND combo, const wchar_t* text) return ret; } -HWND dlg_base::create_tooltip_for(HWND ctrl, const wchar_t* tips) -{ - HWND tipwnd = CreateWindowExW(NULL, TOOLTIPS_CLASSW, NULL, - WS_POPUP |TTS_ALWAYSTIP | TTS_BALLOON, - CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, CW_USEDEFAULT, - ctrl, NULL, - GetModuleHandle(NULL), NULL), - parent = GetParent(ctrl); - - if (tipwnd) - { - TTTOOLINFOW toolInfo = { 0 }; - - SetWindowPos(tipwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - toolInfo.cbSize = sizeof(toolInfo); - toolInfo.hwnd = parent; - toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS; - toolInfo.uId = (UINT_PTR)ctrl; - toolInfo.lpszText = (wchar_t*)(DWORD_PTR)tips; // LPSTR_TEXTCALLBACK - WM_NOTIFY.TTN_GETDISPINFO - toolInfo.hinst = GetModuleHandle(NULL); - GetWindowRect(ctrl, &toolInfo.rect); - dlg_base::screen_2_client(parent, &toolInfo.rect); - if (!SendMessageW(tipwnd, TTM_ADDTOOL, 0, (LPARAM)&toolInfo)) - { - DWORD err = GetLastError(); - DestroyWindow(tipwnd); - tipwnd = NULL; - } - } - - return tipwnd; -} BOOL dlg_base::handle_message(UINT msg, WPARAM wp, LPARAM lp) { @@ -327,12 +299,90 @@ bool dlg_base::track_mouse_hover(void) return TrackMouseEvent(&tme); } + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// tooltip_wnd +tooltip_wnd::tooltip_wnd() : hwnd_(NULL), parent_(NULL) +{ +} +tooltip_wnd::~tooltip_wnd() +{ + DestroyWindow(hwnd_); +} + +bool tooltip_wnd::create(HWND parent) +{ + if (!IsWindow(hwnd_)) + { + parent_ = parent; + hwnd_ = CreateWindowExW(NULL, TOOLTIPS_CLASSW, NULL, + WS_POPUP | TTS_ALWAYSTIP | TTS_BALLOON, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + parent_, NULL, + GetModuleHandle(NULL), NULL); + SetWindowPos(hwnd_, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + } + + return IsWindow(hwnd_); +} +void tooltip_wnd::enable(bool enabled) +{ + if (enabled) + { + + } + else + { + + } +} +bool tooltip_wnd::add_tool_tip_for_rect(const RECT& r, const wchar_t* tips) +{ + TTTOOLINFOW toolInfo = { 0 }; + + toolInfo.cbSize = sizeof(toolInfo) - sizeof(toolInfo.lpReserved); // TOOLTIPS_CLASSW in old style, not with member 'lpReserved' + toolInfo.hwnd = parent_; + toolInfo.uFlags = TTF_SUBCLASS; + toolInfo.lpszText = (wchar_t*)(DWORD_PTR)tips; // LPSTR_TEXTCALLBACK - WM_NOTIFY.TTN_GETDISPINFO + toolInfo.hinst = GetModuleHandle(NULL); + memcpy(&toolInfo.rect, &r, sizeof(toolInfo.rect)); + + return SendMessageW(hwnd_, TTM_ADDTOOL, 0, (LPARAM)&toolInfo) == TRUE; +} + +bool tooltip_wnd::add_tool_tip_for_ctrl(HWND ctrl, const wchar_t* tips) +{ + TTTOOLINFOW toolInfo = { 0 }; + + toolInfo.cbSize = sizeof(toolInfo) - sizeof(toolInfo.lpReserved); // TOOLTIPS_CLASSW in old style, not with member 'lpReserved' + toolInfo.hwnd = parent_; + toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS; + toolInfo.uId = (UINT_PTR)ctrl; + toolInfo.lpszText = (wchar_t*)(DWORD_PTR)tips; // LPSTR_TEXTCALLBACK - WM_NOTIFY.TTN_GETDISPINFO + toolInfo.hinst = GetModuleHandle(NULL); + + return SendMessageW(hwnd_, TTM_ADDTOOL, 0, (LPARAM)&toolInfo) == TRUE; +} + +bool tooltip_wnd::remove_tool_tip_for_ctrl(HWND ctrl) +{ + TTTOOLINFOW toolInfo = { 0 }; + + toolInfo.cbSize = sizeof(toolInfo) - sizeof(toolInfo.lpReserved); // TOOLTIPS_CLASSW in old style, not with member 'lpReserved' + toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS; + toolInfo.hwnd = parent_; + toolInfo.uId = (UINT_PTR)ctrl; + + return SendMessageW(hwnd_, TTM_DELTOOL, 0, (LPARAM)&toolInfo) == TRUE; +} + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // dlg_page 对话框 std::wstring dlg_page::property_type = L"option_type"; std::wstring dlg_page::property_host = L"option_host_wnd"; std::wstring dlg_page::property_size = L"option_size"; -std::wstring dlg_page::property_tooltip_wnd = L"option_tooltips_wnd"; UINT dlg_page::dyn_id_base = 3000; int dlg_page::gap_x = 20; int dlg_page::gap_y = 15; @@ -351,16 +401,12 @@ dlg_page::dlg_page(HWND parent, const wchar_t* name pos_.x = 12; pos_.y = 8; create(); + tips_wnd_.create(hwnd()); } dlg_page::~dlg_page() { for (auto& v : ctrls_) - { - HWND tooltip = (HWND)GetPropW(v, dlg_page::property_tooltip_wnd.c_str()); - if (tooltip) - DestroyWindow(tooltip); DestroyWindow(v); - } } BOOL dlg_page::handle_message(UINT msg, WPARAM wp, LPARAM lp) @@ -1206,12 +1252,8 @@ bool dlg_page::add_control(int sn, const SANE_Option_Descriptor* desc, void* cur ret = IsWindow(wnd); if (ret) { - // if (desc->desc && *desc->desc) - // { - // HWND tooltip = dlg_base::create_tooltip_for(wnd, local_trans::a2u(desc->desc, CP_UTF8).c_str()); - // if (tooltip) - // SetPropW(wnd, dlg_page::property_tooltip_wnd.c_str(), tooltip); - // } + if (desc->desc && *desc->desc) + tips_wnd_.add_tool_tip_for_ctrl(wnd, local_trans::a2u(desc->desc, CP_UTF8).c_str()); SetPropW(wnd, dlg_page::property_type.c_str(), (HANDLE)creat[i].sane_type); SetPropW(wnd, dlg_page::property_size.c_str(), (HANDLE)desc->size); if (desc->cap & SANE_CAP_INACTIVE) diff --git a/sane/DlgPage.h b/sane/DlgPage.h index c92460c..1d28bdf 100644 --- a/sane/DlgPage.h +++ b/sane/DlgPage.h @@ -46,7 +46,6 @@ public: 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 HWND create_tooltip_for(HWND ctrl, const wchar_t* tips); public: void set_ui_event_notify(void(__stdcall* notify)(int, void*, void*), void* param); @@ -63,6 +62,47 @@ public: 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_; @@ -73,6 +113,7 @@ class dlg_page : public dlg_base SANE_Handle dev_; bool done_; std::vector ctrls_; + tooltip_wnd tips_wnd_; int id_dpi_; float dpi_; @@ -89,7 +130,6 @@ class dlg_page : public dlg_base static std::wstring property_type; static std::wstring property_host; static std::wstring property_size; - static std::wstring property_tooltip_wnd; static UINT dyn_id_base; static int gap_x; static int gap_y;