]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - sizetip.c
Move MODULE files out of individual project directories into a
[PuTTY.git] / sizetip.c
1 #include <windows.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <tchar.h>
5
6 #include "putty.h"
7 #include "winstuff.h"
8
9 static ATOM tip_class = 0;
10
11 static HFONT tip_font;
12 static COLORREF tip_bg;
13 static COLORREF tip_text;
14
15 static LRESULT CALLBACK SizeTipWndProc(HWND hWnd, UINT nMsg,
16                                        WPARAM wParam, LPARAM lParam)
17 {
18
19     switch (nMsg) {
20       case WM_ERASEBKGND:
21         return TRUE;
22
23       case WM_PAINT:
24         {
25             HBRUSH hbr;
26             HGDIOBJ holdbr;
27             RECT cr;
28             int wtlen;
29             LPTSTR wt;
30             HDC hdc;
31
32             PAINTSTRUCT ps;
33             hdc = BeginPaint(hWnd, &ps);
34
35             SelectObject(hdc, tip_font);
36             SelectObject(hdc, GetStockObject(BLACK_PEN));
37
38             hbr = CreateSolidBrush(tip_bg);
39             holdbr = SelectObject(hdc, hbr);
40
41             GetClientRect(hWnd, &cr);
42             Rectangle(hdc, cr.left, cr.top, cr.right, cr.bottom);
43
44             wtlen = GetWindowTextLength(hWnd);
45             wt = (LPTSTR) smalloc((wtlen + 1) * sizeof(TCHAR));
46             GetWindowText(hWnd, wt, wtlen + 1);
47
48             SetTextColor(hdc, tip_text);
49             SetBkColor(hdc, tip_bg);
50
51             TextOut(hdc, cr.left + 3, cr.top + 3, wt, wtlen);
52
53             sfree(wt);
54
55             SelectObject(hdc, holdbr);
56             DeleteObject(hbr);
57
58             EndPaint(hWnd, &ps);
59         }
60         return 0;
61
62       case WM_NCHITTEST:
63         return HTTRANSPARENT;
64
65       case WM_DESTROY:
66         DeleteObject(tip_font);
67         tip_font = NULL;
68         break;
69
70       case WM_SETTEXT:
71         {
72             LPCTSTR str = (LPCTSTR) lParam;
73             SIZE sz;
74             HDC hdc = CreateCompatibleDC(NULL);
75
76             SelectObject(hdc, tip_font);
77             GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);
78
79             SetWindowPos(hWnd, NULL, 0, 0, sz.cx + 6, sz.cy + 6,
80                          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)
99         return;
100
101     if (!tip_wnd) {
102         NONCLIENTMETRICS nci;
103
104         /* First make sure the window class is registered */
105
106         if (!tip_class) {
107             WNDCLASS wc;
108             wc.style = CS_HREDRAW | CS_VREDRAW;
109             wc.lpfnWndProc = SizeTipWndProc;
110             wc.cbClsExtra = 0;
111             wc.cbWndExtra = 0;
112             wc.hInstance = hinst;
113             wc.hIcon = NULL;
114             wc.hCursor = NULL;
115             wc.hbrBackground = NULL;
116             wc.lpszMenuName = NULL;
117             wc.lpszClassName = "SizeTipClass";
118
119             tip_class = RegisterClass(&wc);
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,
137                              sizeof(NONCLIENTMETRICS), &nci, 0);
138         tip_font = CreateFontIndirect(&nci.lfStatusFont);
139     }
140
141     /* Generate the tip text */
142
143     sprintf(str, "%dx%d", cx, cy);
144
145     if (!tip_wnd) {
146         HDC hdc;
147         SIZE sz;
148         RECT wr;
149         int ix, iy;
150
151         /* calculate the tip's size */
152
153         hdc = CreateCompatibleDC(NULL);
154         GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);
155         DeleteDC(hdc);
156
157         GetWindowRect(src, &wr);
158
159         ix = wr.left;
160         if (ix < 16)
161             ix = 16;
162
163         iy = wr.top - sz.cy;
164         if (iy < 16)
165             iy = 16;
166
167         /* Create the tip window */
168
169         tip_wnd =
170             CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
171                            MAKEINTRESOURCE(tip_class), str, WS_POPUP, ix,
172                            iy, sz.cx, sz.cy, NULL, NULL, hinst, NULL);
173
174         ShowWindow(tip_wnd, SW_SHOWNOACTIVATE);
175
176     } else {
177
178         /* Tip already exists, just set the text */
179
180         SetWindowText(tip_wnd, str);
181     }
182 }
183
184 void EnableSizeTip(int bEnable)
185 {
186     if (tip_wnd && !bEnable) {
187         DestroyWindow(tip_wnd);
188         tip_wnd = NULL;
189     }
190
191     tip_enabled = bEnable;
192 }