]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - sizetip.c
Silly mistake - restore-cursor-pos doesn't make sure the cursor
[PuTTY.git] / 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
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[32];
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 #if 0
120         /* Default values based on Windows Standard color scheme */
121
122         tip_font = GetStockObject(SYSTEM_FONT);
123         tip_bg = RGB(255, 255, 225);
124         tip_text = RGB(0, 0, 0);
125 #endif
126
127         /* Prepare other GDI objects and drawing info */
128
129         tip_bg = GetSysColor(COLOR_INFOBK);
130         tip_text = GetSysColor(COLOR_INFOTEXT);
131
132         memset(&nci, 0, sizeof(NONCLIENTMETRICS));
133         nci.cbSize = sizeof(NONCLIENTMETRICS);
134         SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &nci, 0);
135         tip_font = CreateFontIndirect(&nci.lfStatusFont);
136     }
137
138     /* Generate the tip text */
139
140     sprintf(str, "%dx%d", cx, cy);
141
142     if (!tip_wnd) {
143         HDC hdc;
144         SIZE sz;
145         RECT wr;
146         int ix, iy;
147
148         /* calculate the tip's size */
149
150         hdc = CreateCompatibleDC(NULL);
151         GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);
152         DeleteDC(hdc);
153
154         GetWindowRect(src, &wr);
155
156         ix = wr.left;
157         if (ix<16) ix = 16;
158
159         iy = wr.top - sz.cy;
160         if (iy<16) iy = 16;
161
162         /* Create the tip window */
163
164         tip_wnd = CreateWindowEx(WS_EX_TOOLWINDOW|WS_EX_TOPMOST, MAKEINTRESOURCE(tip_class), str, WS_POPUP,
165                                  ix, iy, sz.cx, sz.cy,
166                                  NULL, NULL, putty_inst, NULL);
167
168         ShowWindow(tip_wnd, SW_SHOWNOACTIVATE);
169
170     } else {
171
172         /* Tip already exists, just set the text */
173
174         SetWindowText(tip_wnd, str);
175     }
176 }
177
178 void EnableSizeTip(int bEnable)
179 {
180     if (tip_wnd && !bEnable) {
181         DestroyWindow(tip_wnd);
182         tip_wnd = NULL;
183     }
184
185     tip_enabled = bEnable;
186 }