1
0
Fork 0

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
This commit is contained in:
Jussi Viiri 2023-06-10 22:21:37 +03:00
parent 2019efde65
commit eb3a02115a

View file

@ -34,7 +34,6 @@ use std::os::windows::ffi::OsStrExt;
use std::os::windows::prelude::OsStringExt; use std::os::windows::prelude::OsStringExt;
use std::ptr::null_mut; use std::ptr::null_mut;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc;
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle, Win32Handle}; use raw_window_handle::{HasRawWindowHandle, RawWindowHandle, Win32Handle};
@ -802,16 +801,20 @@ pub struct DropTarget {
drop_data: DropData, 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 { const DROP_TARGET_VTBL: IDropTargetVtbl = IDropTargetVtbl {
parent: IUnknownVtbl { parent: IUnknownVtbl {
QueryInterface: DropTarget::query_interface, QueryInterface: DropTarget::query_interface,
AddRef: DropTarget::add_ref, AddRef: DropTarget::add_ref,
Release: DropTarget::release, Release: DropTarget::release,
}, },
DragEnter: DropTarget::drag_enter, DragEnter: unsafe { transmute(DRAG_ENTER_PTR) },
DragOver: DropTarget::drag_over, DragOver: unsafe { transmute(DRAG_OVER_PTR) },
DragLeave: DropTarget::drag_leave, DragLeave: DropTarget::drag_leave,
Drop: DropTarget::drop, Drop: unsafe { transmute(DROP_PTR) },
}; };
impl DropTarget { impl DropTarget {
@ -847,17 +850,10 @@ impl DropTarget {
} }
} }
fn parse_coordinates(&mut self, pt: *const POINTL) { fn parse_coordinates(&mut self, pt: 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
let window_state = unsafe { &*self.window_state }; let window_state = unsafe { &*self.window_state };
let x = pt as i64 & u32::MAX as i64; let phy_point = PhyPoint::new(pt.x, pt.y);
let y = pt as i64 >> 32;
let phy_point = PhyPoint::new(x as i32, y as i32);
self.drag_position = phy_point.to_logical(&window_state.window_info.borrow()) self.drag_position = phy_point.to_logical(&window_state.window_info.borrow())
} }
@ -947,7 +943,7 @@ impl DropTarget {
this: *mut IDropTarget, this: *mut IDropTarget,
pDataObj: *const IDataObject, pDataObj: *const IDataObject,
grfKeyState: DWORD, grfKeyState: DWORD,
pt: *const POINTL, pt: POINTL,
pdwEffect: *mut DWORD, pdwEffect: *mut DWORD,
) -> HRESULT ) -> HRESULT
{ {
@ -973,7 +969,7 @@ impl DropTarget {
unsafe extern "system" fn drag_over( unsafe extern "system" fn drag_over(
this: *mut IDropTarget, this: *mut IDropTarget,
grfKeyState: DWORD, grfKeyState: DWORD,
pt: *const POINTL, pt: POINTL,
pdwEffect: *mut DWORD, pdwEffect: *mut DWORD,
) -> HRESULT ) -> HRESULT
{ {
@ -1005,7 +1001,7 @@ impl DropTarget {
this: *mut IDropTarget, this: *mut IDropTarget,
pDataObj: *const IDataObject, pDataObj: *const IDataObject,
grfKeyState: DWORD, grfKeyState: DWORD,
pt: *const POINTL, pt: POINTL,
pdwEffect: *mut DWORD, pdwEffect: *mut DWORD,
) -> HRESULT ) -> HRESULT
{ {