]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - sizetip.c
Fiddly things involving pruning .svn directories, not mentioning
[PuTTY.git] / sizetip.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <tchar.h>
4
5 #include "putty.h"
6
7 static ATOM tip_class = 0;
8
9 static HFONT tip_font;
10 static COLORREF tip_bg;
11 static COLORREF tip_text;
12
13 static LRESULT CALLBACK SizeTipWndProc(HWND hWnd, UINT nMsg,
14                                        WPARAM wParam, LPARAM lParam)
15 {
16
17     switch (nMsg) {
18       case WM_ERASEBKGND:
19         return TRUE;
20
21       case WM_PAINT:
22         {
23             HBRUSH hbr;
24             HGDIOBJ holdbr;
25             RECT cr;
26             int wtlen;
27             LPTSTR wt;
28             HDC hdc;
29
30             PAINTSTRUCT ps;
31             hdc = BeginPaint(hWnd, &ps);
32
33             SelectObject(hdc, tip_font);
34             SelectObject(hdc, GetStockObject(BLACK_PEN));
35
36             hbr = CreateSolidBrush(tip_bg);
37             holdbr = SelectObject(hdc, hbr);
38
39             GetClientRect(hWnd, &cr);
40             Rectangle(hdc, cr.left, cr.top, cr.right, cr.bottom);
41
42             wtlen = GetWindowTextLength(hWnd);
43             wt = (LPTSTR) snewn(wtlen + 1, TCHAR);
44             GetWindowText(hWnd, wt, wtlen + 1);
45
46             SetTextColor(hdc, tip_text);
47             SetBkColor(hdc, tip_bg);
48
49             TextOut(hdc, cr.left + 3, cr.top + 3, wt, wtlen);
50
51             sfree(wt);
52
53             SelectObject(hdc, holdbr);
54             DeleteObject(hbr);
55
56             EndPaint(hWnd, &ps);
57         }
58         return 0;
59
60       case WM_NCHITTEST:
61         return HTTRANSPARENT;
62
63       case WM_DESTROY:
64         DeleteObject(tip_font);
65         tip_font = NULL;
66         break;
67
68       case WM_SETTEXT:
69         {
70             LPCTSTR str = (LPCTSTR) lParam;
71             SIZE sz;
72             HDC hdc = CreateCompatibleDC(NULL);
73
74             SelectObject(hdc, tip_font);
75             GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);
76
77             SetWindowPos(hWnd, NULL, 0, 0, sz.cx + 6, sz.cy + 6,
78                          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 static HWND tip_wnd = NULL;
90 static int tip_enabled = 0;
91
92 void UpdateSizeTip(HWND src, int cx, int cy)
93 {
94     TCHAR str[32];
95
96     if (!tip_enabled)
97         return;
98
99     if (!tip_wnd) {
100         NONCLIENTMETRICS nci;
101
102         /* First make sure the window class is registered */
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 = hinst;
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 #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,
135                              sizeof(NONCLIENTMETRICS), &nci, 0);
136         tip_font = CreateFontIndirect(&nci.lfStatusFont);
137     }
138
139     /* Generate the tip text */
140
141     sprintf(str, "%dx%d", cx, cy);
142
143     if (!tip_wnd) {
144         HDC hdc;
145         SIZE sz;
146         RECT wr;
147         int ix, iy;
148
149         /* calculate the tip's size */
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)
159             ix = 16;
160
161         iy = wr.top - sz.cy;
162         if (iy < 16)
163             iy = 16;
164
165         /* Create the tip window */
166
167         tip_wnd =
168             CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
169                            MAKEINTRESOURCE(tip_class), str, WS_POPUP, ix,
170                            iy, sz.cx, sz.cy, NULL, NULL, hinst, NULL);
171
172         ShowWindow(tip_wnd, SW_SHOWNOACTIVATE);
173
174     } else {
175
176         /* Tip already exists, just set the text */
177
178         SetWindowText(tip_wnd, str);
179     }
180 }
181
182 void EnableSizeTip(int bEnable)
183 {
184     if (tip_wnd && !bEnable) {
185         DestroyWindow(tip_wnd);
186         tip_wnd = NULL;
187     }
188
189     tip_enabled = bEnable;
190 }