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