[REACTOS] Fix a number of Get/SetWindowsLong*Ptr* issues and use GWLP_* instead of...
[reactos.git] / modules / rosapps / lib / vfdlib / vfdguitip.c
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 }