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