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