Sebastian Kuschel reports that pfd_closing can be called for a socket
[u/mdw/putty] / windows / sizetip.c
CommitLineData
eaf1e20a 1/*
2 * sizetip.c - resize tips for PuTTY(tel) terminal window.
3 */
4
73251d5d 5#include <stdio.h>
1d470ad2 6#include <stdlib.h>
dc3c8261 7#include <tchar.h>
73251d5d 8
9#include "putty.h"
10
75cab814 11static ATOM tip_class = 0;
73251d5d 12
75cab814 13static HFONT tip_font;
14static COLORREF tip_bg;
15static COLORREF tip_text;
73251d5d 16
75cab814 17static LRESULT CALLBACK SizeTipWndProc(HWND hWnd, UINT nMsg,
32874aea 18 WPARAM wParam, LPARAM lParam)
73251d5d 19{
20
21 switch (nMsg) {
b73fd1b1 22 case WM_ERASEBKGND:
32874aea 23 return TRUE;
73251d5d 24
b73fd1b1 25 case WM_PAINT:
32874aea 26 {
27 HBRUSH hbr;
28 HGDIOBJ holdbr;
29 RECT cr;
30 int wtlen;
31 LPTSTR wt;
32 HDC hdc;
73251d5d 33
32874aea 34 PAINTSTRUCT ps;
35 hdc = BeginPaint(hWnd, &ps);
73251d5d 36
32874aea 37 SelectObject(hdc, tip_font);
38 SelectObject(hdc, GetStockObject(BLACK_PEN));
73251d5d 39
32874aea 40 hbr = CreateSolidBrush(tip_bg);
41 holdbr = SelectObject(hdc, hbr);
73251d5d 42
32874aea 43 GetClientRect(hWnd, &cr);
44 Rectangle(hdc, cr.left, cr.top, cr.right, cr.bottom);
73251d5d 45
32874aea 46 wtlen = GetWindowTextLength(hWnd);
3d88e64d 47 wt = (LPTSTR) snewn(wtlen + 1, TCHAR);
32874aea 48 GetWindowText(hWnd, wt, wtlen + 1);
73251d5d 49
32874aea 50 SetTextColor(hdc, tip_text);
51 SetBkColor(hdc, tip_bg);
73251d5d 52
32874aea 53 TextOut(hdc, cr.left + 3, cr.top + 3, wt, wtlen);
73251d5d 54
32874aea 55 sfree(wt);
73251d5d 56
32874aea 57 SelectObject(hdc, holdbr);
58 DeleteObject(hbr);
73251d5d 59
32874aea 60 EndPaint(hWnd, &ps);
61 }
62 return 0;
73251d5d 63
b73fd1b1 64 case WM_NCHITTEST:
32874aea 65 return HTTRANSPARENT;
73251d5d 66
b73fd1b1 67 case WM_DESTROY:
32874aea 68 DeleteObject(tip_font);
69 tip_font = NULL;
70 break;
73251d5d 71
b73fd1b1 72 case WM_SETTEXT:
32874aea 73 {
74 LPCTSTR str = (LPCTSTR) lParam;
75 SIZE sz;
76 HDC hdc = CreateCompatibleDC(NULL);
73251d5d 77
32874aea 78 SelectObject(hdc, tip_font);
79 GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);
73251d5d 80
32874aea 81 SetWindowPos(hWnd, NULL, 0, 0, sz.cx + 6, sz.cy + 6,
82 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
83 InvalidateRect(hWnd, NULL, FALSE);
73251d5d 84
32874aea 85 DeleteDC(hdc);
86 }
87 break;
73251d5d 88 }
89
90 return DefWindowProc(hWnd, nMsg, wParam, lParam);
91}
92
75cab814 93static HWND tip_wnd = NULL;
94static int tip_enabled = 0;
73251d5d 95
96void UpdateSizeTip(HWND src, int cx, int cy)
97{
cfb1e4b1 98 TCHAR str[32];
73251d5d 99
32874aea 100 if (!tip_enabled)
101 return;
73251d5d 102
103 if (!tip_wnd) {
32874aea 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 }
b73fd1b1 123#if 0
32874aea 124 /* Default values based on Windows Standard color scheme */
b73fd1b1 125
32874aea 126 tip_font = GetStockObject(SYSTEM_FONT);
127 tip_bg = RGB(255, 255, 225);
128 tip_text = RGB(0, 0, 0);
b73fd1b1 129#endif
73251d5d 130
32874aea 131 /* Prepare other GDI objects and drawing info */
73251d5d 132
32874aea 133 tip_bg = GetSysColor(COLOR_INFOBK);
134 tip_text = GetSysColor(COLOR_INFOTEXT);
b73fd1b1 135
32874aea 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);
73251d5d 141 }
142
b73fd1b1 143 /* Generate the tip text */
73251d5d 144
cfb1e4b1 145 sprintf(str, "%dx%d", cx, cy);
73251d5d 146
147 if (!tip_wnd) {
32874aea 148 HDC hdc;
149 SIZE sz;
150 RECT wr;
151 int ix, iy;
73251d5d 152
32874aea 153 /* calculate the tip's size */
73251d5d 154
32874aea 155 hdc = CreateCompatibleDC(NULL);
156 GetTextExtentPoint32(hdc, str, _tcslen(str), &sz);
157 DeleteDC(hdc);
73251d5d 158
32874aea 159 GetWindowRect(src, &wr);
73251d5d 160
32874aea 161 ix = wr.left;
162 if (ix < 16)
163 ix = 16;
73251d5d 164
32874aea 165 iy = wr.top - sz.cy;
166 if (iy < 16)
167 iy = 16;
73251d5d 168
32874aea 169 /* Create the tip window */
73251d5d 170
32874aea 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);
73251d5d 175
32874aea 176 ShowWindow(tip_wnd, SW_SHOWNOACTIVATE);
73251d5d 177
178 } else {
179
32874aea 180 /* Tip already exists, just set the text */
73251d5d 181
32874aea 182 SetWindowText(tip_wnd, str);
73251d5d 183 }
184}
185
186void EnableSizeTip(int bEnable)
187{
188 if (tip_wnd && !bEnable) {
32874aea 189 DestroyWindow(tip_wnd);
190 tip_wnd = NULL;
73251d5d 191 }
b73fd1b1 192
73251d5d 193 tip_enabled = bEnable;
194}