From eb3a02115a7cf8a0828680f46630c655338e2ad8 Mon Sep 17 00:00:00 2001 From: Jussi Viiri Date: Sat, 10 Jun 2023 22:21:37 +0300 Subject: [PATCH] Change how DragTarget functions parse coordinates Instead of working around the winapi bug by manually parsing the pointer we're (incorrectly) given, use the correct function signature and transmute the function pointer --- src/win/window.rs | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/win/window.rs b/src/win/window.rs index fc2c201..d3d3260 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -34,7 +34,6 @@ use std::os::windows::ffi::OsStrExt; use std::os::windows::prelude::OsStringExt; use std::ptr::null_mut; use std::rc::Rc; -use std::sync::Arc; use raw_window_handle::{HasRawWindowHandle, RawWindowHandle, Win32Handle}; @@ -802,16 +801,20 @@ pub struct DropTarget { drop_data: DropData, } +// These function pointers have to be stored in a (const) variable before they can be transmuted +const DRAG_ENTER_PTR: unsafe extern "system" fn(this: *mut IDropTarget, pDataObj: *const IDataObject, grfKeyState: DWORD, pt: POINTL, pdwEffect: *mut DWORD) -> HRESULT = DropTarget::drag_enter; +const DRAG_OVER_PTR: unsafe extern "system" fn(this: *mut IDropTarget, grfKeyState: DWORD, pt: POINTL, pdwEffect: *mut DWORD) -> HRESULT = DropTarget::drag_over; +const DROP_PTR: unsafe extern "system" fn(this: *mut IDropTarget, pDataObj: *const IDataObject, grfKeyState: DWORD, pt: POINTL, pdwEffect: *mut DWORD) -> HRESULT = DropTarget::drop; const DROP_TARGET_VTBL: IDropTargetVtbl = IDropTargetVtbl { parent: IUnknownVtbl { QueryInterface: DropTarget::query_interface, AddRef: DropTarget::add_ref, Release: DropTarget::release, }, - DragEnter: DropTarget::drag_enter, - DragOver: DropTarget::drag_over, + DragEnter: unsafe { transmute(DRAG_ENTER_PTR) }, + DragOver: unsafe { transmute(DRAG_OVER_PTR) }, DragLeave: DropTarget::drag_leave, - Drop: DropTarget::drop, + Drop: unsafe { transmute(DROP_PTR) }, }; impl DropTarget { @@ -847,17 +850,10 @@ impl DropTarget { } } - fn parse_coordinates(&mut self, pt: *const POINTL) { - // There's a bug in winapi: the POINTL pointer should actually be a POINTL structure - // This happens to work on 64-bit platforms because two c_longs (that translate to - // 32-bit signed integers) happen to be the same size as a 64-bit pointer... - // For now, just hack around that bug + fn parse_coordinates(&mut self, pt: POINTL) { let window_state = unsafe { &*self.window_state }; - let x = pt as i64 & u32::MAX as i64; - let y = pt as i64 >> 32; - - let phy_point = PhyPoint::new(x as i32, y as i32); + let phy_point = PhyPoint::new(pt.x, pt.y); self.drag_position = phy_point.to_logical(&window_state.window_info.borrow()) } @@ -947,7 +943,7 @@ impl DropTarget { this: *mut IDropTarget, pDataObj: *const IDataObject, grfKeyState: DWORD, - pt: *const POINTL, + pt: POINTL, pdwEffect: *mut DWORD, ) -> HRESULT { @@ -973,7 +969,7 @@ impl DropTarget { unsafe extern "system" fn drag_over( this: *mut IDropTarget, grfKeyState: DWORD, - pt: *const POINTL, + pt: POINTL, pdwEffect: *mut DWORD, ) -> HRESULT { @@ -1005,7 +1001,7 @@ impl DropTarget { this: *mut IDropTarget, pDataObj: *const IDataObject, grfKeyState: DWORD, - pt: *const POINTL, + pt: POINTL, pdwEffect: *mut DWORD, ) -> HRESULT {