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