xref: /reactos/modules/rosapps/lib/vfdlib/vfdguitip.c (revision 40462c92)
1 /*
2 	vfdguitip.c
3 
4 	Virtual Floppy Drive for Windows
5 	Driver control library
6 	tooltip information GUI utility functions
7 
8 	Copyright (c) 2003-2005 Ken Kato
9 */
10 
11 #ifdef __cplusplus
12 #pragma message(__FILE__": Compiled as C++ for testing purpose.")
13 #endif	// __cplusplus
14 
15 #define WIN32_LEAN_AND_MEAN
16 #include <windows.h>
17 
18 #include "vfdtypes.h"
19 #include "vfdapi.h"
20 #include "vfdlib.h"
21 #ifndef __REACTOS__
22 #include "vfdmsg.h"
23 #else
24 #include "vfdmsg_lib.h"
25 #endif
26 
27 //
28 //	tooltip window class name
29 //
30 #define VFD_INFOTIP_WNDCLASS	"VfdInfoTip"
31 
32 //
33 //	the window procedure
34 //
35 static LRESULT CALLBACK ToolTipProc(
36 	HWND			hWnd,
37 	UINT			uMsg,
38 	WPARAM			wParam,
39 	LPARAM			lParam)
40 {
41 	switch (uMsg) {
42 	case WM_CREATE:
43 		//	Store Font handle
44 		SetWindowLongPtr(hWnd, GWLP_USERDATA,
45 			(LONG_PTR)((LPCREATESTRUCT)lParam)->lpCreateParams);
46 		return 0;
47 
48 	case WM_PAINT:
49 		{
50 			PAINTSTRUCT paint;
51 			HDC hDC = BeginPaint(hWnd, &paint);
52 
53 			if (hDC) {
54 				char text[MAX_PATH];
55 				int len;
56 				RECT rc;
57 
58 
59 				SelectObject(hDC, (HFONT)GetWindowLongPtr(hWnd, GWLP_USERDATA));
60 
61 				SetTextColor(hDC, GetSysColor(COLOR_INFOTEXT));
62 				SetBkMode(hDC, TRANSPARENT);
63 
64 				len = GetWindowText(hWnd, text, sizeof(text));
65 
66 				rc.top = 8;
67 				rc.left = 8;
68 				rc.right = paint.rcPaint.right;
69 				rc.bottom = paint.rcPaint.bottom;
70 
71 				DrawText(hDC, text, len, &rc, DT_LEFT | DT_TOP);
72 
73 				EndPaint(hWnd, &paint);
74 			}
75 		}
76 		return 0;
77 
78 	case WM_KILLFOCUS:
79 		if (!(GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOPMOST)) {
80 			//	Stick tool tip - Closed on kill focus
81 			DestroyWindow(hWnd);
82 		}
83 		return 0;
84 
85 	case WM_SETCURSOR:
86 		if (GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) {
87 			//	Non-stick tool tip - Closed when cursor leaves
88 			TRACKMOUSEEVENT track;
89 
90 			track.cbSize	= sizeof(track);
91 			track.dwFlags	= TME_LEAVE;
92 			track.hwndTrack	= hWnd;
93 			track.dwHoverTime = 0;
94 
95 			TrackMouseEvent(&track);
96 		}
97 		return 0;
98 
99 	case WM_MOUSELEAVE:
100 		//	Non-stick tool tip - Closed when cursor leaves
101 		DestroyWindow(hWnd);
102 		return 0;
103 
104 	case WM_LBUTTONDOWN:
105 	case WM_MBUTTONDOWN:
106 	case WM_RBUTTONDOWN:
107 		//	Both stick and non-stick tool tip
108 		//	Closed when clicked
109 		SetCapture(hWnd);
110 		return 0;
111 
112 	case WM_LBUTTONUP:
113 	case WM_MBUTTONUP:
114 	case WM_RBUTTONUP:
115 		//	Both stick and non-stick tool tip
116 		//	Closed when clicked
117 		if (GetCapture() == hWnd) {
118 			DestroyWindow(hWnd);
119 		}
120 		return 0;
121 
122 	case WM_DESTROY:
123 		//	delete font
124 		DeleteObject((HFONT)GetWindowLongPtr(hWnd, GWLP_USERDATA));
125 		return 0;
126 	}
127 
128 	return DefWindowProc(hWnd, uMsg, wParam, lParam);
129 }
130 
131 //
132 //	Create and show tooltip window
133 //
134 void WINAPI VfdToolTip(
135 	HWND			hParent,
136 	PCSTR			sText,
137 	int				pos_x,
138 	int				pos_y,
139 	BOOL			stick)
140 {
141 #ifndef __REACTOS__
142 	HWND			hWnd;
143 #endif
144 	WNDCLASS		wc = {0};
145 	LOGFONT			lf;
146 	HFONT			font;
147 	HDC				dc;
148 	int				len;
149 	SIZE			sz;
150 	RECT			rc;
151 	int				scr_x;
152 	int				scr_y;
153 
154 	//
155 	//	Register Window Class
156 	//
157 
158 	wc.lpfnWndProc		= ToolTipProc;
159 	wc.hInstance		= g_hDllModule;
160 	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);
161 	wc.hbrBackground	= (HBRUSH)(COLOR_INFOBK + 1);
162 	wc.lpszClassName	= VFD_INFOTIP_WNDCLASS;
163 
164 	RegisterClass(&wc);
165 
166 	//
167 	//	Create Tool Tip Font (== Icon title font)
168 	//
169 
170 	SystemParametersInfo(
171 		SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0);
172 
173 	font = CreateFontIndirect(&lf);
174 
175 	//
176 	//	Calculate Tool Tip Window size
177 	//
178 
179 	dc = GetDC(hParent);
180 
181 	SelectObject(dc, font);
182 
183 	len = strlen(sText);
184 
185 	GetTextExtentPoint32(dc, sText, len, &sz);
186 
187 	rc.left		= 0;
188 	rc.top		= 0;
189 	rc.right	= sz.cx;
190 	rc.bottom	= sz.cy;
191 
192 	DrawText(dc, sText, len, &rc, DT_CALCRECT | DT_LEFT | DT_TOP);
193 
194 	ReleaseDC(hParent, dc);
195 
196 	sz.cx = rc.right - rc.left + 16;
197 	sz.cy = rc.bottom - rc.top + 16;
198 
199 	//
200 	//	Decide the window position
201 	//
202 	if (pos_x == -1 || pos_y == -1) {
203 		//
204 		//	Use current cursor position
205 		//
206 		POINT	pt;
207 
208 		GetCursorPos(&pt);
209 
210 		pos_x = pt.x - (sz.cx / 2);
211 		pos_y = pt.y - (sz.cy / 2);
212 	}
213 	else {
214 		pos_x = pos_x - (sz.cx / 2);
215 	}
216 
217 	//
218 	//	make sure the tip window fits in visible area
219 	//
220 	scr_x = GetSystemMetrics(SM_CXSCREEN);
221 	scr_y = GetSystemMetrics(SM_CYSCREEN);
222 
223 	if (pos_x < 0) {
224 		pos_x = 0;
225 	}
226 	if (pos_x + sz.cx > scr_x) {
227 		pos_x = scr_x - sz.cx;
228 	}
229 	if (pos_y < 0) {
230 		pos_y = 0;
231 	}
232 	if (pos_y + sz.cy > scr_y) {
233 		pos_y = scr_y - sz.cy;
234 	}
235 
236 	//
237 	//	Create the tool tip window
238 	//
239 #ifndef __REACTOS__
240 	hWnd = CreateWindowEx(
241 #else
242 	CreateWindowEx(
243 #endif
244 		stick ? 0 : WS_EX_TOPMOST,
245 		VFD_INFOTIP_WNDCLASS,
246 		sText,
247 		WS_BORDER | WS_POPUP | WS_VISIBLE,
248 		pos_x, pos_y,
249 		sz.cx, sz.cy,
250 		hParent,
251 		NULL,
252 		NULL,
253 		(PVOID)font);
254 
255 	//
256 	//	Give focus if it is not a stick tool-tip
257 	//
258 	if (!stick) {
259 		SetFocus(hParent);
260 	}
261 }
262 
263 //
264 //	Show an image information tooltip
265 //
266 void WINAPI VfdImageTip(
267 	HWND			hParent,
268 	ULONG			nDevice)
269 {
270 	HANDLE			hDevice;
271 	PSTR			info_str	= NULL;
272 	PSTR			type_str	= NULL;
273 	PSTR			prot_str	= NULL;
274 	PCSTR			media_str	= NULL;
275 	CHAR			path[MAX_PATH];
276 	CHAR			desc[MAX_PATH];
277 	VFD_DISKTYPE	disk_type;
278 	VFD_MEDIA		media_type;
279 	VFD_FLAGS		media_flags;
280 	VFD_FILETYPE	file_type;
281 	ULONG			image_size;
282 	DWORD			file_attr;
283 	ULONG			ret;
284 
285 	hDevice = VfdOpenDevice(nDevice);
286 
287 	if (hDevice == INVALID_HANDLE_VALUE) {
288 		VfdToolTip(hParent,
289 			SystemMessage(GetLastError()), -1, -1, FALSE);
290 		return;
291 	}
292 
293 	ret = VfdGetImageInfo(
294 		hDevice,
295 		path,
296 		&disk_type,
297 		&media_type,
298 		&media_flags,
299 		&file_type,
300 		&image_size);
301 
302 	CloseHandle(hDevice);
303 
304 	if (ret != ERROR_SUCCESS) {
305 		VfdToolTip(hParent, SystemMessage(ret), -1, -1, FALSE);
306 		return;
307 	}
308 
309 	if (path[0]) {
310 		file_attr = GetFileAttributes(path);
311 	}
312 	else {
313 		if (disk_type != VFD_DISKTYPE_FILE) {
314 			strcpy(path, "<RAM>");
315 		}
316 		file_attr = 0;
317 	}
318 
319 	VfdMakeFileDesc(desc, sizeof(desc),
320 		file_type, image_size, file_attr);
321 
322 	if (disk_type == VFD_DISKTYPE_FILE) {
323 		type_str = "FILE";
324 	}
325 	else {
326 		type_str = "RAM";
327 	}
328 
329 	media_str = VfdMediaTypeName(media_type);
330 
331 	if (media_flags & VFD_FLAG_WRITE_PROTECTED) {
332 		prot_str = ModuleMessage(MSG_WRITE_PROTECTED);
333 	}
334 	else {
335 		prot_str = ModuleMessage(MSG_WRITE_ALLOWED);
336 	}
337 
338 	info_str = ModuleMessage(
339 		MSG_IMAGE_INFOTIP,
340 		path,
341 		desc,
342 		type_str ? type_str : "",
343 		media_str ? media_str : "",
344 		prot_str ? prot_str : "");
345 
346 	if (info_str) {
347 		VfdToolTip(hParent, info_str, -1, -1, FALSE);
348 		LocalFree(info_str);
349 	}
350 
351 	if (prot_str) {
352 		LocalFree(prot_str);
353 	}
354 }
355