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