#include #include #include #include "putty.h" static ATOM tip_class = 0; static HFONT tip_font; static COLORREF tip_bg; static COLORREF tip_text; static LRESULT CALLBACK SizeTipWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) { switch (nMsg) { case WM_ERASEBKGND: return TRUE; case WM_PAINT: { HBRUSH hbr; HGDIOBJ holdbr; RECT cr; int wtlen; LPTSTR wt; HDC hdc; PAINTSTRUCT ps; hdc = BeginPaint(hWnd, &ps); SelectObject(hdc, tip_font); SelectObject(hdc, GetStockObject(BLACK_PEN)); hbr = CreateSolidBrush(tip_bg); holdbr = SelectObject(hdc, hbr); GetClientRect(hWnd, &cr); Rectangle(hdc, cr.left, cr.top, cr.right, cr.bottom); wtlen = GetWindowTextLength(hWnd); wt = (LPTSTR) snewn(wtlen + 1, TCHAR); GetWindowText(hWnd, wt, wtlen + 1); SetTextColor(hdc, tip_text); SetBkColor(hdc, tip_bg); TextOut(hdc, cr.left + 3, cr.top + 3, wt, wtlen); sfree(wt); SelectObject(hdc, holdbr); DeleteObject(hbr); EndPaint(hWnd, &ps); } return 0; case WM_NCHITTEST: return HTTRANSPARENT; case WM_DESTROY: DeleteObject(tip_font); tip_font = NULL; break; case WM_SETTEXT: { LPCTSTR str = (LPCTSTR) lParam; SIZE sz; HDC hdc = CreateCompatibleDC(NULL); SelectObject(hdc, tip_font); GetTextExtentPoint32(hdc, str, _tcslen(str), &sz); SetWindowPos(hWnd, NULL, 0, 0, sz.cx + 6, sz.cy + 6, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); InvalidateRect(hWnd, NULL, FALSE); DeleteDC(hdc); } break; } return DefWindowProc(hWnd, nMsg, wParam, lParam); } static HWND tip_wnd = NULL; static int tip_enabled = 0; void UpdateSizeTip(HWND src, int cx, int cy) { TCHAR str[32]; if (!tip_enabled) return; if (!tip_wnd) { NONCLIENTMETRICS nci; /* First make sure the window class is registered */ if (!tip_class) { WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = SizeTipWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hinst; wc.hIcon = NULL; wc.hCursor = NULL; wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = "SizeTipClass"; tip_class = RegisterClass(&wc); } #if 0 /* Default values based on Windows Standard color scheme */ tip_font = GetStockObject(SYSTEM_FONT); tip_bg = RGB(255, 255, 225); tip_text = RGB(0, 0, 0); #endif /* Prepare other GDI objects and drawing info */ tip_bg = GetSysColor(COLOR_INFOBK); tip_text = GetSysColor(COLOR_INFOTEXT); memset(&nci, 0, sizeof(NONCLIENTMETRICS)); nci.cbSize = sizeof(NONCLIENTMETRICS); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &nci, 0); tip_font = CreateFontIndirect(&nci.lfStatusFont); } /* Generate the tip text */ sprintf(str, "%dx%d", cx, cy); if (!tip_wnd) { HDC hdc; SIZE sz; RECT wr; int ix, iy; /* calculate the tip's size */ hdc = CreateCompatibleDC(NULL); GetTextExtentPoint32(hdc, str, _tcslen(str), &sz); DeleteDC(hdc); GetWindowRect(src, &wr); ix = wr.left; if (ix < 16) ix = 16; iy = wr.top - sz.cy; if (iy < 16) iy = 16; /* Create the tip window */ tip_wnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, MAKEINTRESOURCE(tip_class), str, WS_POPUP, ix, iy, sz.cx, sz.cy, NULL, NULL, hinst, NULL); ShowWindow(tip_wnd, SW_SHOWNOACTIVATE); } else { /* Tip already exists, just set the text */ SetWindowText(tip_wnd, str); } } void EnableSizeTip(int bEnable) { if (tip_wnd && !bEnable) { DestroyWindow(tip_wnd); tip_wnd = NULL; } tip_enabled = bEnable; }