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