Introduced wrapper macros snew(), snewn() and sresize() for the
[u/mdw/putty] / sizetip.c
CommitLineData
73251d5d 1#include <windows.h>
73251d5d 2#include <stdio.h>
1d470ad2 3#include <stdlib.h>
dc3c8261 4#include <tchar.h>
73251d5d 5
6#include "putty.h"
8c3cd914 7#include "winstuff.h"
73251d5d 8
75cab814 9static ATOM tip_class = 0;
73251d5d 10
75cab814 11static HFONT tip_font;
12static COLORREF tip_bg;
13static COLORREF tip_text;
73251d5d 14
75cab814 15static LRESULT CALLBACK SizeTipWndProc(HWND hWnd, UINT nMsg,
32874aea 16 WPARAM wParam, LPARAM lParam)
73251d5d 17{
18
19 switch (nMsg) {
b73fd1b1 20 case WM_ERASEBKGND:
32874aea 21 return TRUE;
73251d5d 22
b73fd1b1 23 case WM_PAINT:
32874aea 24 {
25 HBRUSH hbr;
26 HGDIOBJ holdbr;
27 RECT cr;
28 int wtlen;
29 LPTSTR wt;
30 HDC hdc;
73251d5d 31
32874aea 32 PAINTSTRUCT ps;
33 hdc = BeginPaint(hWnd, &ps);
73251d5d 34
32874aea 35 SelectObject(hdc, tip_font);
36 SelectObject(hdc, GetStockObject(BLACK_PEN));
73251d5d 37
32874aea 38 hbr = CreateSolidBrush(tip_bg);
39 holdbr = SelectObject(hdc, hbr);
73251d5d 40
32874aea 41 GetClientRect(hWnd, &cr);
42 Rectangle(hdc, cr.left, cr.top, cr.right, cr.bottom);
73251d5d 43
32874aea 44 wtlen = GetWindowTextLength(hWnd);
3d88e64d 45 wt = (LPTSTR) snewn(wtlen + 1, TCHAR);
32874aea 46 GetWindowText(hWnd, wt, wtlen + 1);
73251d5d 47
32874aea 48 SetTextColor(hdc, tip_text);
49 SetBkColor(hdc, tip_bg);
73251d5d 50
32874aea 51 TextOut(hdc, cr.left + 3, cr.top + 3, wt, wtlen);
73251d5d 52
32874aea 53 sfree(wt);
73251d5d 54
32874aea 55 SelectObject(hdc, holdbr);
56 DeleteObject(hbr);
73251d5d 57
32874aea 58 EndPaint(hWnd, &ps);
59 }
60 return 0;
73251d5d 61
b73fd1b1 62 case WM_NCHITTEST:
32874aea 63 return HTTRANSPARENT;
73251d5d 64
b73fd1b1 65 case WM_DESTROY:
32874aea 66 DeleteObject(tip_font);
67 tip_font = NULL;
68 break;
73251d5d 69
b73fd1b1 70 case WM_SETTEXT:
32874aea 71 {
72 LPCTSTR str = (LPCTSTR) lParam;
73 SIZE sz;
74 HDC hdc = CreateCompatibleDC(NULL);
73251d5d 75
32874aea 76 SelectObject(hdc, tip_font);
77 GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);
73251d5d 78
32874aea 79 SetWindowPos(hWnd, NULL, 0, 0, sz.cx + 6, sz.cy + 6,
80 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
81 InvalidateRect(hWnd, NULL, FALSE);
73251d5d 82
32874aea 83 DeleteDC(hdc);
84 }
85 break;
73251d5d 86 }
87
88 return DefWindowProc(hWnd, nMsg, wParam, lParam);
89}
90
75cab814 91static HWND tip_wnd = NULL;
92static int tip_enabled = 0;
73251d5d 93
94void UpdateSizeTip(HWND src, int cx, int cy)
95{
cfb1e4b1 96 TCHAR str[32];
73251d5d 97
32874aea 98 if (!tip_enabled)
99 return;
73251d5d 100
101 if (!tip_wnd) {
32874aea 102 NONCLIENTMETRICS nci;
103
104 /* First make sure the window class is registered */
105
106 if (!tip_class) {
107 WNDCLASS wc;
108 wc.style = CS_HREDRAW | CS_VREDRAW;
109 wc.lpfnWndProc = SizeTipWndProc;
110 wc.cbClsExtra = 0;
111 wc.cbWndExtra = 0;
112 wc.hInstance = hinst;
113 wc.hIcon = NULL;
114 wc.hCursor = NULL;
115 wc.hbrBackground = NULL;
116 wc.lpszMenuName = NULL;
117 wc.lpszClassName = "SizeTipClass";
118
119 tip_class = RegisterClass(&wc);
120 }
b73fd1b1 121#if 0
32874aea 122 /* Default values based on Windows Standard color scheme */
b73fd1b1 123
32874aea 124 tip_font = GetStockObject(SYSTEM_FONT);
125 tip_bg = RGB(255, 255, 225);
126 tip_text = RGB(0, 0, 0);
b73fd1b1 127#endif
73251d5d 128
32874aea 129 /* Prepare other GDI objects and drawing info */
73251d5d 130
32874aea 131 tip_bg = GetSysColor(COLOR_INFOBK);
132 tip_text = GetSysColor(COLOR_INFOTEXT);
b73fd1b1 133
32874aea 134 memset(&nci, 0, sizeof(NONCLIENTMETRICS));
135 nci.cbSize = sizeof(NONCLIENTMETRICS);
136 SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
137 sizeof(NONCLIENTMETRICS), &nci, 0);
138 tip_font = CreateFontIndirect(&nci.lfStatusFont);
73251d5d 139 }
140
b73fd1b1 141 /* Generate the tip text */
73251d5d 142
cfb1e4b1 143 sprintf(str, "%dx%d", cx, cy);
73251d5d 144
145 if (!tip_wnd) {
32874aea 146 HDC hdc;
147 SIZE sz;
148 RECT wr;
149 int ix, iy;
73251d5d 150
32874aea 151 /* calculate the tip's size */
73251d5d 152
32874aea 153 hdc = CreateCompatibleDC(NULL);
154 GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);
155 DeleteDC(hdc);
73251d5d 156
32874aea 157 GetWindowRect(src, &wr);
73251d5d 158
32874aea 159 ix = wr.left;
160 if (ix < 16)
161 ix = 16;
73251d5d 162
32874aea 163 iy = wr.top - sz.cy;
164 if (iy < 16)
165 iy = 16;
73251d5d 166
32874aea 167 /* Create the tip window */
73251d5d 168
32874aea 169 tip_wnd =
170 CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
171 MAKEINTRESOURCE(tip_class), str, WS_POPUP, ix,
172 iy, sz.cx, sz.cy, NULL, NULL, hinst, NULL);
73251d5d 173
32874aea 174 ShowWindow(tip_wnd, SW_SHOWNOACTIVATE);
73251d5d 175
176 } else {
177
32874aea 178 /* Tip already exists, just set the text */
73251d5d 179
32874aea 180 SetWindowText(tip_wnd, str);
73251d5d 181 }
182}
183
184void EnableSizeTip(int bEnable)
185{
186 if (tip_wnd && !bEnable) {
32874aea 187 DestroyWindow(tip_wnd);
188 tip_wnd = NULL;
73251d5d 189 }
b73fd1b1 190
73251d5d 191 tip_enabled = bEnable;
192}