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