680 lines
15 KiB
C++
680 lines
15 KiB
C++
|
// DlgIndicator.cpp: 实现文件
|
|||
|
//
|
|||
|
|
|||
|
#include "DlgBase.h"
|
|||
|
#include "resource.h"
|
|||
|
|
|||
|
// #pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
|||
|
|
|||
|
#pragma warning(disable: 4996)
|
|||
|
|
|||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
//
|
|||
|
|
|||
|
static IMPLEMENT_OPTION_STRING_COMPARE(is_sane_opt);
|
|||
|
|
|||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
// dlg_base 对话框
|
|||
|
extern HMODULE g_my_inst;
|
|||
|
|
|||
|
std::wstring dlg_base::prop_name = L"dlg_base_object_prop_name";
|
|||
|
|
|||
|
dlg_base::dlg_base(HWND parent, UINT idd) : parent_(parent), hwnd_(NULL), idd_(idd), ui_event_notify_(NULL), ui_notify_param_(NULL)
|
|||
|
{
|
|||
|
}
|
|||
|
dlg_base::~dlg_base()
|
|||
|
{
|
|||
|
if (IsWindow(hwnd_))
|
|||
|
{
|
|||
|
SetPropW(hwnd_, dlg_base::prop_name.c_str(), NULL);
|
|||
|
//if (GetCurrentThreadId() == GetWindowThreadProcessId(hwnd_, NULL))
|
|||
|
DestroyWindow(hwnd_);
|
|||
|
}
|
|||
|
EnableWindow(parent_, TRUE);
|
|||
|
BringWindowToTop(parent_);
|
|||
|
}
|
|||
|
|
|||
|
BOOL CALLBACK dlg_base::dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||
|
{
|
|||
|
if (msg == WM_INITDIALOG)
|
|||
|
{
|
|||
|
dlg_base* obj = (dlg_base*)lp;
|
|||
|
|
|||
|
SetPropW(hwnd, dlg_base::prop_name.c_str(), (HANDLE)obj);
|
|||
|
obj->hwnd_ = hwnd;
|
|||
|
}
|
|||
|
else if (msg == WM_DESTROY)
|
|||
|
{
|
|||
|
dlg_base* obj = (dlg_base*)GetPropW(hwnd, dlg_base::prop_name.c_str());
|
|||
|
SetPropW(hwnd, dlg_base::prop_name.c_str(), NULL);
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
dlg_base *obj = (dlg_base*)GetPropW(hwnd, dlg_base::prop_name.c_str());
|
|||
|
BOOL ret = FALSE;
|
|||
|
|
|||
|
if (obj)
|
|||
|
{
|
|||
|
ret = obj->handle_message(msg, wp, lp);
|
|||
|
}
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
void dlg_base::screen_2_client(HWND wnd, LPRECT r)
|
|||
|
{
|
|||
|
POINT pt = { r->left, r->top };
|
|||
|
|
|||
|
ScreenToClient(wnd, &pt);
|
|||
|
OffsetRect(r, pt.x - r->left, pt.y - r->top);
|
|||
|
}
|
|||
|
void dlg_base::client_2_screen(HWND wnd, LPRECT r)
|
|||
|
{
|
|||
|
POINT pt = { r->left, r->top };
|
|||
|
|
|||
|
ClientToScreen(wnd, &pt);
|
|||
|
OffsetRect(r, pt.x - r->left, pt.y - r->top);
|
|||
|
}
|
|||
|
bool dlg_base::get_max_size(SIZE& dst, const SIZE& src)
|
|||
|
{
|
|||
|
bool changed = false;
|
|||
|
|
|||
|
if (dst.cx < src.cx)
|
|||
|
{
|
|||
|
dst.cx = src.cx;
|
|||
|
changed = true;
|
|||
|
}
|
|||
|
if (dst.cy < src.cy)
|
|||
|
{
|
|||
|
dst.cy = src.cy;
|
|||
|
changed = true;
|
|||
|
}
|
|||
|
|
|||
|
return changed;
|
|||
|
}
|
|||
|
bool dlg_base::get_max_size(SIZE& dst, int cx, int cy)
|
|||
|
{
|
|||
|
bool changed = false;
|
|||
|
|
|||
|
if (dst.cx < cx)
|
|||
|
{
|
|||
|
dst.cx = cx;
|
|||
|
changed = true;
|
|||
|
}
|
|||
|
if (dst.cy < cy)
|
|||
|
{
|
|||
|
dst.cy = cy;
|
|||
|
changed = true;
|
|||
|
}
|
|||
|
|
|||
|
return changed;
|
|||
|
}
|
|||
|
int dlg_base::select_combo_text(HWND combo, const wchar_t* text)
|
|||
|
{
|
|||
|
int ind = SendMessageW(combo, CB_SELECTSTRING, -1, (LPARAM)text),
|
|||
|
ret = ind;
|
|||
|
|
|||
|
while (ind >= 0)
|
|||
|
{
|
|||
|
wchar_t buf[256] = { 0 };
|
|||
|
GetWindowTextW(combo, buf, _countof(buf) - 1);
|
|||
|
if (wcsicmp(buf, text) == 0)
|
|||
|
break;
|
|||
|
|
|||
|
ret = ind;
|
|||
|
ind = SendMessageW(combo, CB_SELECTSTRING, ret, (LPARAM)text);
|
|||
|
}
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
std::wstring dlg_base::get_wnd_text(HWND h)
|
|||
|
{
|
|||
|
int len = GetWindowTextLengthW(h);
|
|||
|
wchar_t* buf = new wchar_t[len + 8];
|
|||
|
std::wstring ret(L"");
|
|||
|
|
|||
|
memset(buf, 0, (len + 8) * 2);
|
|||
|
GetWindowTextW(h, buf, len + 2);
|
|||
|
ret = buf;
|
|||
|
delete[] buf;
|
|||
|
|
|||
|
return std::move(ret);
|
|||
|
}
|
|||
|
std::wstring dlg_base::get_menu_text(HMENU menu, int ind)
|
|||
|
{
|
|||
|
MENUITEMINFOW mi = { 0 };
|
|||
|
wchar_t text[128] = { 0 };
|
|||
|
|
|||
|
mi.cbSize = sizeof(mi);
|
|||
|
mi.fMask = mi.fType = MIIM_STRING; // MFT_STRING;
|
|||
|
mi.dwTypeData = text;
|
|||
|
mi.cch = _countof(text) - 1;
|
|||
|
GetMenuItemInfoW(menu, ind, MF_BYPOSITION, &mi);
|
|||
|
|
|||
|
return text;
|
|||
|
}
|
|||
|
void dlg_base::center_window(HWND wnd, HWND parent)
|
|||
|
{
|
|||
|
RECT rme = { 0 }, rp = { 0 };
|
|||
|
int x = 0, y = 0;
|
|||
|
|
|||
|
GetWindowRect(wnd, &rme);
|
|||
|
if (!IsWindow(parent))
|
|||
|
parent = GetDesktopWindow();
|
|||
|
GetWindowRect(parent, &rp);
|
|||
|
x = rp.left + (RECT_W(rp) - RECT_W(rme)) / 2;
|
|||
|
y = rp.top + (RECT_H(rp) - RECT_H(rme)) / 2;
|
|||
|
OffsetRect(&rme, x - rme.left, y - rme.top);
|
|||
|
MoveWindow(wnd, rme.left, rme.top, RECT_W(rme), RECT_H(rme), FALSE);
|
|||
|
}
|
|||
|
int dlg_base::get_combox_cur_sel(HWND wnd)
|
|||
|
{
|
|||
|
return SendMessageW(wnd, CB_GETCURSEL, 0, 0);
|
|||
|
}
|
|||
|
int dlg_base::get_button_check(HWND wnd)
|
|||
|
{
|
|||
|
return SendMessageW(wnd, BM_GETCHECK, 0, 0);
|
|||
|
}
|
|||
|
int dlg_base::list_insert_column(HWND list_wnd, const wchar_t* text, int cx, int ind)
|
|||
|
{
|
|||
|
LVCOLUMNW col = { 0 };
|
|||
|
|
|||
|
if (ind == -1)
|
|||
|
ind = dlg_base::list_get_column_count(list_wnd);
|
|||
|
col.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
|
|||
|
col.pszText = (LPWSTR)text;
|
|||
|
col.iSubItem = 0;
|
|||
|
col.cx = cx;
|
|||
|
|
|||
|
return ListView_InsertColumn(list_wnd, ind, &col);
|
|||
|
}
|
|||
|
int dlg_base::list_insert_item(HWND list_wnd, const wchar_t* text, int ind)
|
|||
|
{
|
|||
|
LV_ITEMW item = { 0 };
|
|||
|
|
|||
|
if (ind == -1)
|
|||
|
ind = dlg_base::list_get_item_count(list_wnd);
|
|||
|
item.mask = LVIF_TEXT;
|
|||
|
item.pszText = (PWSTR)text;
|
|||
|
item.iItem = ind;
|
|||
|
|
|||
|
return ListView_InsertItem(list_wnd, &item);
|
|||
|
}
|
|||
|
int dlg_base::list_get_item_count(HWND list_wnd)
|
|||
|
{
|
|||
|
return ListView_GetItemCount(list_wnd);
|
|||
|
}
|
|||
|
int dlg_base::list_get_column_count(HWND list_wnd)
|
|||
|
{
|
|||
|
return ListView_GetItemCount((HWND)ListView_GetHeader(list_wnd));
|
|||
|
}
|
|||
|
std::wstring dlg_base::list_get_text(HWND list_wnd, int ind, int sub)
|
|||
|
{
|
|||
|
LV_ITEMW item = { 0 };
|
|||
|
wchar_t text[128] = { 0 };
|
|||
|
|
|||
|
item.mask = LVIF_TEXT;
|
|||
|
item.pszText = (PWSTR)text;
|
|||
|
item.iItem = ind;
|
|||
|
item.iSubItem = sub;
|
|||
|
item.cchTextMax = _countof(text) - 1;
|
|||
|
ListView_GetItem(list_wnd, &item);
|
|||
|
|
|||
|
return text;
|
|||
|
}
|
|||
|
void dlg_base::list_get_selected_items(HWND list_wnd, std::vector<int>& sels)
|
|||
|
{
|
|||
|
LV_ITEMW item = { 0 };
|
|||
|
|
|||
|
item.mask = LVIF_STATE;
|
|||
|
for (int i = 0; i < dlg_base::list_get_item_count(list_wnd); ++i)
|
|||
|
{
|
|||
|
item.iItem = i;
|
|||
|
item.stateMask = LVIS_SELECTED;
|
|||
|
ListView_GetItem(list_wnd, &item);
|
|||
|
if (item.state & LVIS_SELECTED)
|
|||
|
sels.push_back(i);
|
|||
|
}
|
|||
|
}
|
|||
|
int dlg_base::list_set_item_text(HWND list_wnd, int item, int sub_item, const wchar_t* text)
|
|||
|
{
|
|||
|
LV_ITEMW lvi = { 0 };
|
|||
|
|
|||
|
lvi.iItem = item;
|
|||
|
lvi.iSubItem = sub_item;
|
|||
|
lvi.pszText = (LPWSTR)text;
|
|||
|
lvi.mask = LVIF_TEXT;
|
|||
|
|
|||
|
return ListView_SetItem(list_wnd, &lvi) ? 0 : 1;
|
|||
|
}
|
|||
|
int dlg_base::get_tab_count(HWND tab)
|
|||
|
{
|
|||
|
int count = -1;
|
|||
|
|
|||
|
if (IsWindow(tab))
|
|||
|
count = TabCtrl_GetItemCount(tab);
|
|||
|
|
|||
|
return count;
|
|||
|
}
|
|||
|
int dlg_base::insert_page_to_tab(HWND tab, dlg_base* page, const wchar_t* title)
|
|||
|
{
|
|||
|
TC_ITEMW item = { 0 };
|
|||
|
int ind = 0;
|
|||
|
std::wstring t(title);
|
|||
|
|
|||
|
item.mask = TCIF_PARAM | TCIF_TEXT;
|
|||
|
item.lParam = (LPARAM)page;
|
|||
|
item.pszText = &t[0];
|
|||
|
ind = TabCtrl_InsertItem(tab, dlg_base::get_tab_count(tab), &item);
|
|||
|
|
|||
|
return ind;
|
|||
|
}
|
|||
|
void* dlg_base::get_tab_item_data(HWND tab, int index)
|
|||
|
{
|
|||
|
TCITEMW item = { 0 };
|
|||
|
|
|||
|
item.mask = TCIF_PARAM;
|
|||
|
TabCtrl_GetItem(tab, index, &item);
|
|||
|
|
|||
|
return (void*)item.lParam;
|
|||
|
}
|
|||
|
std::string dlg_base::u2m(const wchar_t* u, int page)
|
|||
|
{
|
|||
|
char* ansi = NULL;
|
|||
|
int len = 0;
|
|||
|
std::string mb("");
|
|||
|
|
|||
|
len = WideCharToMultiByte(page, 0, u, lstrlenW(u), NULL, 0, NULL, NULL);
|
|||
|
ansi = new char[len + 2];
|
|||
|
len = WideCharToMultiByte(page, 0, u, lstrlenW(u), ansi, len, NULL, NULL);
|
|||
|
ansi[len--] = 0;
|
|||
|
mb = ansi;
|
|||
|
delete[] ansi;
|
|||
|
|
|||
|
return mb;
|
|||
|
}
|
|||
|
std::wstring dlg_base::m2u(const char* m, int page)
|
|||
|
{
|
|||
|
wchar_t* unic = NULL;
|
|||
|
int len = 0;
|
|||
|
std::wstring u(L"");
|
|||
|
|
|||
|
len = MultiByteToWideChar(page, 0, m, lstrlenA(m), NULL, 0);
|
|||
|
unic = new wchar_t[len + 2];
|
|||
|
len = MultiByteToWideChar(page, 0, m, lstrlenA(m), unic, len);
|
|||
|
unic[len--] = 0;
|
|||
|
u = unic;
|
|||
|
delete[] unic;
|
|||
|
|
|||
|
return u;
|
|||
|
}
|
|||
|
|
|||
|
BOOL dlg_base::handle_message(UINT msg, WPARAM wp, LPARAM lp)
|
|||
|
{
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
void dlg_base::on_font_changed(void)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
void dlg_base::create(void)
|
|||
|
{
|
|||
|
// InitCommonControls();
|
|||
|
hwnd_ = CreateDialogParamW(g_my_inst, MAKEINTRESOURCE(idd_), parent_, (DLGPROC)&dlg_base::dlg_proc, (LPARAM)this);
|
|||
|
}
|
|||
|
void dlg_base::notify_ui_event(int ev)
|
|||
|
{
|
|||
|
if (ui_event_notify_)
|
|||
|
ui_event_notify_(ev, this, ui_notify_param_);
|
|||
|
}
|
|||
|
|
|||
|
void dlg_base::set_ui_event_notify(void(__stdcall* notify)(int, void*, void*), void* param)
|
|||
|
{
|
|||
|
ui_event_notify_ = notify;
|
|||
|
ui_notify_param_ = param;
|
|||
|
}
|
|||
|
HWND dlg_base::hwnd(void)
|
|||
|
{
|
|||
|
return hwnd_;
|
|||
|
}
|
|||
|
void dlg_base::show(bool visible, bool hold)
|
|||
|
{
|
|||
|
UINT cmd = visible ? SW_SHOW : SW_HIDE;
|
|||
|
DWORD style = GetWindowLong(hwnd_, GWL_STYLE);
|
|||
|
|
|||
|
if (!(style & WS_CHILD))
|
|||
|
{
|
|||
|
if (visible)
|
|||
|
{
|
|||
|
RECT r0 = { 0 }, rp = { 0 }, rme = { 0 };
|
|||
|
POINT pt = { 0 };
|
|||
|
HWND after = HWND_TOP;
|
|||
|
|
|||
|
if (IsWindow(parent_))
|
|||
|
{
|
|||
|
HMONITOR mon = MonitorFromWindow(parent_, MONITOR_DEFAULTTOPRIMARY);
|
|||
|
MONITORINFO mi = { 0 };
|
|||
|
|
|||
|
mi.cbSize = sizeof(mi);
|
|||
|
GetMonitorInfoW(mon, &mi);
|
|||
|
r0 = mi.rcWork;
|
|||
|
GetWindowRect(parent_, &rp);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
GetWindowRect(GetDesktopWindow(), &r0);
|
|||
|
rp = r0;
|
|||
|
after = HWND_TOPMOST;
|
|||
|
}
|
|||
|
GetWindowRect(hwnd_, &rme);
|
|||
|
pt.x = rp.left + (RECT_W(rp) - RECT_W(rme)) / 2;
|
|||
|
pt.y = rp.top + (RECT_H(rp) - RECT_H(rme)) / 2;
|
|||
|
if (pt.x + RECT_W(rme) > r0.right)
|
|||
|
pt.x = r0.right - RECT_W(rme);
|
|||
|
if (pt.x < r0.left)
|
|||
|
pt.x = r0.left;
|
|||
|
if (pt.y + RECT_H(rme) > r0.bottom)
|
|||
|
pt.y = r0.bottom - RECT_H(rme);
|
|||
|
if (pt.y < r0.top)
|
|||
|
pt.y = r0.top;
|
|||
|
SetWindowPos(hwnd_, after, pt.x, pt.y, RECT_W(rme), RECT_H(rme), SWP_NOSIZE);
|
|||
|
UpdateWindow(hwnd_);
|
|||
|
}
|
|||
|
EnableWindow(parent_, !visible);
|
|||
|
}
|
|||
|
ShowWindow(hwnd_, cmd);
|
|||
|
|
|||
|
if (hold)
|
|||
|
{
|
|||
|
MSG msg = { 0 };
|
|||
|
BOOL ret = FALSE;
|
|||
|
|
|||
|
abandon_hold_ = false;
|
|||
|
while ((ret = GetMessageW(&msg, NULL, 0, 0)))
|
|||
|
{
|
|||
|
if (ret == -1 || abandon_hold_)
|
|||
|
break;
|
|||
|
|
|||
|
TranslateMessage(&msg);
|
|||
|
DispatchMessageW(&msg);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
int dlg_base::do_modal(HWND parent)
|
|||
|
{
|
|||
|
BOOL enable_parent = FALSE,
|
|||
|
got = TRUE;
|
|||
|
MSG msg = { 0 };
|
|||
|
|
|||
|
modal_exit_ = 0;
|
|||
|
if (IsWindow(parent) && parent != GetDesktopWindow())
|
|||
|
{
|
|||
|
EnableWindow(parent, FALSE);
|
|||
|
enable_parent = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
dlg_base::center_window(hwnd(), parent);
|
|||
|
ShowWindow(hwnd(), SW_SHOW);
|
|||
|
while ((got = GetMessage(&msg, NULL, 0, 0)))
|
|||
|
{
|
|||
|
if ((DWORD)got == -1)
|
|||
|
break;
|
|||
|
|
|||
|
//if (enable_parent && msg.hwnd == parent &&
|
|||
|
// msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST &&
|
|||
|
// msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST)
|
|||
|
// continue;
|
|||
|
|
|||
|
TranslateMessage(&msg);
|
|||
|
DispatchMessage(&msg);
|
|||
|
if (modal_exit_)
|
|||
|
break;
|
|||
|
}
|
|||
|
ShowWindow(hwnd(), SW_HIDE);
|
|||
|
|
|||
|
if (enable_parent)
|
|||
|
{
|
|||
|
EnableWindow(parent, TRUE);
|
|||
|
}
|
|||
|
|
|||
|
return modal_exit_;
|
|||
|
}
|
|||
|
void dlg_base::quit_modal(int non_zero_code)
|
|||
|
{
|
|||
|
// assert ( non_zero_code );
|
|||
|
modal_exit_ = non_zero_code;
|
|||
|
}
|
|||
|
void dlg_base::enable(bool enable)
|
|||
|
{
|
|||
|
EnableWindow(hwnd_, enable);
|
|||
|
}
|
|||
|
void dlg_base::screen_2_client(LPRECT r)
|
|||
|
{
|
|||
|
POINT pt = { r->left, r->top };
|
|||
|
|
|||
|
ScreenToClient(hwnd_, &pt);
|
|||
|
OffsetRect(r, pt.x - r->left, pt.y - r->top);
|
|||
|
}
|
|||
|
void dlg_base::client_2_screen(LPRECT r)
|
|||
|
{
|
|||
|
POINT pt = { r->left, r->top };
|
|||
|
|
|||
|
ClientToScreen(hwnd_, &pt);
|
|||
|
OffsetRect(r, pt.x - r->left, pt.y - r->top);
|
|||
|
}
|
|||
|
HWND dlg_base::get_item(UINT id)
|
|||
|
{
|
|||
|
return GetDlgItem(hwnd_, id);
|
|||
|
}
|
|||
|
BOOL dlg_base::set_font(HFONT font)
|
|||
|
{
|
|||
|
BOOL ret = SendMessage(hwnd_, WM_SETFONT, (WPARAM)font, 1) == 0;
|
|||
|
|
|||
|
if (ret)
|
|||
|
on_font_changed();
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
HFONT dlg_base::get_font(void)
|
|||
|
{
|
|||
|
return (HFONT)SendMessage(hwnd_, WM_GETFONT, 0, 0);
|
|||
|
}
|
|||
|
int dlg_base::get_string_width(const wchar_t* str, HWND wnd)
|
|||
|
{
|
|||
|
if (!wnd)
|
|||
|
wnd = hwnd_;
|
|||
|
|
|||
|
HDC hdc = GetWindowDC(wnd);
|
|||
|
SIZE size = { 0 };
|
|||
|
|
|||
|
GetTextExtentPointW(hdc, str, lstrlenW(str), &size);
|
|||
|
ReleaseDC(wnd, hdc);
|
|||
|
|
|||
|
return size.cx;
|
|||
|
}
|
|||
|
bool dlg_base::get_item_rect(UINT id, LPRECT r, bool client)
|
|||
|
{
|
|||
|
if (client)
|
|||
|
return GetClientRect(GetDlgItem(hwnd_, id), r) == TRUE;
|
|||
|
else
|
|||
|
return GetWindowRect(GetDlgItem(hwnd_, id), r) == TRUE;
|
|||
|
}
|
|||
|
std::wstring dlg_base::get_item_text(UINT id)
|
|||
|
{
|
|||
|
return std::move(dlg_base::get_wnd_text(get_item(id)));
|
|||
|
}
|
|||
|
int dlg_base::get_width_diff_as_text_length(UINT id)
|
|||
|
{
|
|||
|
RECT r = { 0 };
|
|||
|
|
|||
|
get_item_rect(id, &r);
|
|||
|
|
|||
|
return get_string_width(get_item_text(id).c_str()) - RECT_W(r);
|
|||
|
}
|
|||
|
void dlg_base::offset_item(HWND wnd, int dx, int dy)
|
|||
|
{
|
|||
|
RECT r = { 0 };
|
|||
|
|
|||
|
GetWindowRect(wnd, &r);
|
|||
|
OffsetRect(&r, dx, dy);
|
|||
|
screen_2_client(&r);
|
|||
|
MoveWindow(wnd, r.left, r.top, RECT_W(r), RECT_H(r), FALSE);
|
|||
|
}
|
|||
|
void dlg_base::offset_item(UINT id, int dx, int dy)
|
|||
|
{
|
|||
|
offset_item(get_item(id), dx, dy);
|
|||
|
}
|
|||
|
void dlg_base::expand_item(UINT id, int dx, int dy)
|
|||
|
{
|
|||
|
RECT r = { 0 };
|
|||
|
|
|||
|
get_item_rect(id, &r, false);
|
|||
|
r.right += dx;
|
|||
|
r.bottom += dy;
|
|||
|
screen_2_client(&r);
|
|||
|
MoveWindow(get_item(id), r.left, r.top, RECT_W(r), RECT_H(r), FALSE);
|
|||
|
}
|
|||
|
bool dlg_base::set_item_text(UINT id, const wchar_t* text)
|
|||
|
{
|
|||
|
return SetWindowTextW(GetDlgItem(hwnd_, id), text) == TRUE;
|
|||
|
}
|
|||
|
int dlg_base::set_item_fit_to_text(UINT id)
|
|||
|
{
|
|||
|
HWND wnd = get_item(id);
|
|||
|
std::wstring text(get_item_text(id));
|
|||
|
RECT r = { 0 };
|
|||
|
int w = get_string_width(text.c_str(), wnd);
|
|||
|
|
|||
|
get_item_rect(id, &r, false);
|
|||
|
if (w > RECT_W(r) || w <= RECT_W(r) / 2)
|
|||
|
{
|
|||
|
if (w > RECT_W(r))
|
|||
|
w -= RECT_W(r);
|
|||
|
else
|
|||
|
w -= RECT_W(r) / 2;
|
|||
|
expand_item(id, w, 0);
|
|||
|
}
|
|||
|
else
|
|||
|
w = 0;
|
|||
|
|
|||
|
return w;
|
|||
|
}
|
|||
|
void dlg_base::show_scroll_bar(int bar, bool show)
|
|||
|
{
|
|||
|
DWORD style = GetWindowLong(hwnd(), GWL_STYLE);
|
|||
|
if (bar == SB_VERT || bar == SB_BOTH)
|
|||
|
{
|
|||
|
if (show)
|
|||
|
style |= WS_VSCROLL;
|
|||
|
else
|
|||
|
style &= ~WS_VSCROLL;
|
|||
|
SetWindowLong(hwnd(), GWL_STYLE, style);
|
|||
|
}
|
|||
|
else if (bar == SB_HORZ || bar == SB_BOTH)
|
|||
|
{
|
|||
|
if (show)
|
|||
|
style |= WS_HSCROLL;
|
|||
|
else
|
|||
|
style &= ~WS_HSCROLL;
|
|||
|
SetWindowLong(hwnd(), GWL_STYLE, style);
|
|||
|
}
|
|||
|
}
|
|||
|
bool dlg_base::track_mouse_hover(void)
|
|||
|
{
|
|||
|
return true;
|
|||
|
TRACKMOUSEEVENT tme = { 0 };
|
|||
|
|
|||
|
tme.cbSize = sizeof(tme);
|
|||
|
tme.dwFlags = TME_HOVER;
|
|||
|
tme.dwHoverTime = HOVER_DEFAULT;
|
|||
|
tme.hwndTrack = hwnd_;
|
|||
|
|
|||
|
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;
|
|||
|
}
|
|||
|
|
|||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
//
|
|||
|
|
|||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
|
//
|