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 //
ToolTipProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)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 //
VfdToolTip(HWND hParent,PCSTR sText,int pos_x,int pos_y,BOOL stick)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 //
VfdImageTip(HWND hParent,ULONG nDevice)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