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