diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8c3fb723fd..ac72fd36e5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -179,6 +179,7 @@ jobs: cargo clippy -p test_weak_ref && cargo clippy -p test_win32 && cargo clippy -p test_win32_arrays && + cargo clippy -p test_window_long && cargo clippy -p test_winrt && cargo clippy -p tool_bindings && cargo clippy -p tool_gnu && diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 672222e6d3..aad56b8d39 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -126,8 +126,8 @@ jobs: cargo test --target ${{ matrix.target }} -p test_component_client && cargo test --target ${{ matrix.target }} -p test_const_fields && cargo test --target ${{ matrix.target }} -p test_core && - cargo clean && cargo test --target ${{ matrix.target }} -p test_data_object && + cargo clean && cargo test --target ${{ matrix.target }} -p test_debug && cargo test --target ${{ matrix.target }} -p test_deprecated && cargo test --target ${{ matrix.target }} -p test_dispatch && @@ -163,6 +163,7 @@ jobs: cargo test --target ${{ matrix.target }} -p test_weak_ref && cargo test --target ${{ matrix.target }} -p test_win32 && cargo test --target ${{ matrix.target }} -p test_win32_arrays && + cargo test --target ${{ matrix.target }} -p test_window_long && cargo test --target ${{ matrix.target }} -p test_winrt && cargo test --target ${{ matrix.target }} -p tool_bindings && cargo test --target ${{ matrix.target }} -p tool_gnu && diff --git a/crates/libs/bindgen/src/lib.rs b/crates/libs/bindgen/src/lib.rs index 0057909f7d..850080597b 100644 --- a/crates/libs/bindgen/src/lib.rs +++ b/crates/libs/bindgen/src/lib.rs @@ -109,12 +109,29 @@ pub fn namespace(gen: &Gen, tree: &Tree) -> String { let types = types.values(); - let tokens = quote! { + let mut tokens = quote! { #(#namespaces)* #(#functions)* #(#types)* }; + if tree.namespace == "Windows.Win32.UI.WindowsAndMessaging" { + tokens.combine("e! { + #[cfg(target_pointer_width = "32")] + #[cfg(feature = "Win32_Foundation")] + pub use SetWindowLongA as SetWindowLongPtrA; + #[cfg(target_pointer_width = "32")] + #[cfg(feature = "Win32_Foundation")] + pub use GetWindowLongA as GetWindowLongPtrA; + #[cfg(target_pointer_width = "32")] + #[cfg(feature = "Win32_Foundation")] + pub use SetWindowLongW as SetWindowLongPtrW; + #[cfg(target_pointer_width = "32")] + #[cfg(feature = "Win32_Foundation")] + pub use GetWindowLongW as GetWindowLongPtrW; + }); + } + tokens.into_string() } diff --git a/crates/libs/sys/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs b/crates/libs/sys/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs index a34639bc81..1e7f455750 100644 --- a/crates/libs/sys/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs +++ b/crates/libs/sys/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs @@ -7187,3 +7187,15 @@ pub const __WARNING_RETURNING_BAD_RESULT: u32 = 28196u32; pub const __WARNING_RETURN_UNINIT_VAR: u32 = 6101u32; #[doc = "*Required features: `\"Win32_UI_WindowsAndMessaging\"`*"] pub const __WARNING_USING_UNINIT_VAR: u32 = 6001u32; +#[cfg(target_pointer_width = "32")] +#[cfg(feature = "Win32_Foundation")] +pub use GetWindowLongA as GetWindowLongPtrA; +#[cfg(target_pointer_width = "32")] +#[cfg(feature = "Win32_Foundation")] +pub use GetWindowLongW as GetWindowLongPtrW; +#[cfg(target_pointer_width = "32")] +#[cfg(feature = "Win32_Foundation")] +pub use SetWindowLongA as SetWindowLongPtrA; +#[cfg(target_pointer_width = "32")] +#[cfg(feature = "Win32_Foundation")] +pub use SetWindowLongW as SetWindowLongPtrW; diff --git a/crates/libs/windows/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs b/crates/libs/windows/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs index fee0450599..b322cecf10 100644 --- a/crates/libs/windows/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs +++ b/crates/libs/windows/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs @@ -15356,5 +15356,17 @@ where } wvsprintfW(::core::mem::transmute(param0), param1.into(), ::core::mem::transmute(arglist)) } +#[cfg(target_pointer_width = "32")] +#[cfg(feature = "Win32_Foundation")] +pub use GetWindowLongA as GetWindowLongPtrA; +#[cfg(target_pointer_width = "32")] +#[cfg(feature = "Win32_Foundation")] +pub use GetWindowLongW as GetWindowLongPtrW; +#[cfg(target_pointer_width = "32")] +#[cfg(feature = "Win32_Foundation")] +pub use SetWindowLongA as SetWindowLongPtrA; +#[cfg(target_pointer_width = "32")] +#[cfg(feature = "Win32_Foundation")] +pub use SetWindowLongW as SetWindowLongPtrW; #[cfg(feature = "implement")] ::core::include!("impl.rs"); diff --git a/crates/samples/direct2d/src/main.rs b/crates/samples/direct2d/src/main.rs index c32e17439e..4c3168b42c 100644 --- a/crates/samples/direct2d/src/main.rs +++ b/crates/samples/direct2d/src/main.rs @@ -362,9 +362,9 @@ impl Window { let this = (*cs).lpCreateParams as *mut Self; (*this).handle = window; - SetWindowLong(window, GWLP_USERDATA, this as _); + SetWindowLongPtrA(window, GWLP_USERDATA, this as _); } else { - let this = GetWindowLong(window, GWLP_USERDATA) as *mut Self; + let this = GetWindowLongPtrA(window, GWLP_USERDATA) as *mut Self; if !this.is_null() { return (*this).message_handler(message, wparam, lparam); @@ -498,27 +498,3 @@ fn create_swapchain(device: &ID3D11Device, window: HWND) -> Result isize { - SetWindowLongA(window, index, value as _) as _ -} - -#[allow(non_snake_case)] -#[cfg(target_pointer_width = "64")] -unsafe fn SetWindowLong(window: HWND, index: WINDOW_LONG_PTR_INDEX, value: isize) -> isize { - SetWindowLongPtrA(window, index, value) -} - -#[allow(non_snake_case)] -#[cfg(target_pointer_width = "32")] -unsafe fn GetWindowLong(window: HWND, index: WINDOW_LONG_PTR_INDEX) -> isize { - GetWindowLongA(window, index) as _ -} - -#[allow(non_snake_case)] -#[cfg(target_pointer_width = "64")] -unsafe fn GetWindowLong(window: HWND, index: WINDOW_LONG_PTR_INDEX) -> isize { - GetWindowLongPtrA(window, index) -} diff --git a/crates/samples/direct3d12/src/main.rs b/crates/samples/direct3d12/src/main.rs index aee629db45..bd7d926728 100644 --- a/crates/samples/direct3d12/src/main.rs +++ b/crates/samples/direct3d12/src/main.rs @@ -132,36 +132,12 @@ fn sample_wndproc(sample: &mut S, message: u32, wparam: WPARAM) -> } } -#[allow(non_snake_case)] -#[cfg(target_pointer_width = "32")] -unsafe fn SetWindowLong(window: HWND, index: WINDOW_LONG_PTR_INDEX, value: isize) -> isize { - SetWindowLongA(window, index, value as _) as _ -} - -#[allow(non_snake_case)] -#[cfg(target_pointer_width = "64")] -unsafe fn SetWindowLong(window: HWND, index: WINDOW_LONG_PTR_INDEX, value: isize) -> isize { - SetWindowLongPtrA(window, index, value) -} - -#[allow(non_snake_case)] -#[cfg(target_pointer_width = "32")] -unsafe fn GetWindowLong(window: HWND, index: WINDOW_LONG_PTR_INDEX) -> isize { - GetWindowLongA(window, index) as _ -} - -#[allow(non_snake_case)] -#[cfg(target_pointer_width = "64")] -unsafe fn GetWindowLong(window: HWND, index: WINDOW_LONG_PTR_INDEX) -> isize { - GetWindowLongPtrA(window, index) -} - extern "system" fn wndproc(window: HWND, message: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT { match message { WM_CREATE => { unsafe { let create_struct: &CREATESTRUCTA = transmute(lparam); - SetWindowLong(window, GWLP_USERDATA, create_struct.lpCreateParams as _); + SetWindowLongPtrA(window, GWLP_USERDATA, create_struct.lpCreateParams as _); } LRESULT::default() } @@ -170,7 +146,7 @@ extern "system" fn wndproc(window: HWND, message: u32, wparam: WPAR LRESULT::default() } _ => { - let user_data = unsafe { GetWindowLong(window, GWLP_USERDATA) }; + let user_data = unsafe { GetWindowLongPtrA(window, GWLP_USERDATA) }; let sample = std::ptr::NonNull::::new(user_data as _); let handled = sample.map_or(false, |mut s| sample_wndproc(unsafe { s.as_mut() }, message, wparam)); diff --git a/crates/tests/window_long/Cargo.toml b/crates/tests/window_long/Cargo.toml new file mode 100644 index 0000000000..c14faa18d2 --- /dev/null +++ b/crates/tests/window_long/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "test_window_long" +version = "0.0.0" +authors = ["Microsoft"] +edition = "2018" + +[dependencies.windows] +path = "../../libs/windows" +features = [ + "Win32_Foundation", + "Win32_UI_WindowsAndMessaging", +] + +[dependencies.windows-sys] +path = "../../libs/sys" +features = [ + "Win32_Foundation", + "Win32_UI_WindowsAndMessaging", +] diff --git a/crates/tests/window_long/src/lib.rs b/crates/tests/window_long/src/lib.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/crates/tests/window_long/src/lib.rs @@ -0,0 +1 @@ + diff --git a/crates/tests/window_long/tests/sys.rs b/crates/tests/window_long/tests/sys.rs new file mode 100644 index 0000000000..1245624bb7 --- /dev/null +++ b/crates/tests/window_long/tests/sys.rs @@ -0,0 +1,12 @@ +use windows_sys::Win32::UI::WindowsAndMessaging::*; + +// Validates that these possibly aliased functions can be called on all supported targets. +#[test] +fn test() { + unsafe { + SetWindowLongPtrA(0, GWLP_USERDATA, 0); + GetWindowLongPtrA(0, GWLP_USERDATA); + SetWindowLongPtrW(0, GWLP_USERDATA, 0); + GetWindowLongPtrW(0, GWLP_USERDATA); + } +} diff --git a/crates/tests/window_long/tests/win.rs b/crates/tests/window_long/tests/win.rs new file mode 100644 index 0000000000..552e3fb0d4 --- /dev/null +++ b/crates/tests/window_long/tests/win.rs @@ -0,0 +1,12 @@ +use windows::Win32::UI::WindowsAndMessaging::*; + +// Validates that these possibly aliased functions can be called on all supported targets. +#[test] +fn test() { + unsafe { + SetWindowLongPtrA(None, GWLP_USERDATA, 0); + GetWindowLongPtrA(None, GWLP_USERDATA); + SetWindowLongPtrW(None, GWLP_USERDATA, 0); + GetWindowLongPtrW(None, GWLP_USERDATA); + } +} diff --git a/crates/tools/sys/src/main.rs b/crates/tools/sys/src/main.rs index d2bb0ee624..1d7778ad58 100644 --- a/crates/tools/sys/src/main.rs +++ b/crates/tools/sys/src/main.rs @@ -3,22 +3,38 @@ use std::collections::*; use std::io::prelude::*; fn main() { - let rustfmt = std::env::args().nth(1).unwrap_or_default() != "-p"; + let mut rustfmt = true; + let mut expect_namespace = false; + let mut namespace = String::new(); + for arg in std::env::args() { + match arg.as_str() { + "-p" => rustfmt = false, + "-n" => expect_namespace = true, + _ => { + if expect_namespace { + namespace = arg; + } + } + } + } let mut output = std::path::PathBuf::from("crates/libs/sys/src/Windows"); - let _ = std::fs::remove_dir_all(&output); + if namespace.is_empty() { + let _ = std::fs::remove_dir_all(&output); + } output.pop(); - let files = vec![metadata::reader::File::new("crates/libs/metadata/default/Windows.winmd").unwrap(), metadata::reader::File::new("crates/libs/metadata/default/Windows.Win32.winmd").unwrap(), metadata::reader::File::new("crates/libs/metadata/default/Windows.Win32.Interop.winmd").unwrap()]; let reader = &metadata::reader::Reader::new(&files); + if !namespace.is_empty() { + let tree = reader.tree(&namespace, &[]).expect("Namespace not found"); + gen_tree(reader, &output, &tree, rustfmt); + return; + } let win32 = reader.tree("Windows.Win32", &lib::EXCLUDE_NAMESPACES).expect("`Windows.Win32` namespace not found"); let root = metadata::reader::Tree { namespace: "Windows", nested: BTreeMap::from([("Win32", win32)]) }; - let trees = root.flatten(); trees.par_iter().for_each(|tree| gen_tree(reader, &output, tree, rustfmt)); - output.pop(); output.push("Cargo.toml"); - let mut file = std::fs::File::create(&output).unwrap(); file.write_all( diff --git a/crates/tools/windows/src/main.rs b/crates/tools/windows/src/main.rs index c1d49f39f9..ab23bb4171 100644 --- a/crates/tools/windows/src/main.rs +++ b/crates/tools/windows/src/main.rs @@ -2,22 +2,37 @@ use rayon::prelude::*; use std::io::prelude::*; fn main() { - let rustfmt = std::env::args().nth(1).unwrap_or_default() != "-p"; - + let mut rustfmt = true; + let mut expect_namespace = false; + let mut namespace = String::new(); + for arg in std::env::args() { + match arg.as_str() { + "-p" => rustfmt = false, + "-n" => expect_namespace = true, + _ => { + if expect_namespace { + namespace = arg; + } + } + } + } let mut output = std::path::PathBuf::from("crates/libs/windows/src/Windows"); - let _ = std::fs::remove_dir_all(&output); + if namespace.is_empty() { + let _ = std::fs::remove_dir_all(&output); + } output.pop(); - let files = vec![metadata::reader::File::new("crates/libs/metadata/default/Windows.winmd").unwrap(), metadata::reader::File::new("crates/libs/metadata/default/Windows.Win32.winmd").unwrap(), metadata::reader::File::new("crates/libs/metadata/default/Windows.Win32.Interop.winmd").unwrap()]; let reader = &metadata::reader::Reader::new(&files); + if !namespace.is_empty() { + let tree = reader.tree(&namespace, &[]).expect("Namespace not found"); + gen_tree(reader, &output, &tree, rustfmt); + return; + } let root = reader.tree("Windows", &lib::EXCLUDE_NAMESPACES).expect("`Windows` namespace not found"); - let trees = root.flatten(); trees.par_iter().for_each(|tree| gen_tree(reader, &output, tree, rustfmt)); - output.pop(); output.push("Cargo.toml"); - let mut file = std::fs::File::create(&output).unwrap(); file.write_all( @@ -112,10 +127,8 @@ fn gen_tree(reader: &metadata::reader::Reader, output: &std::path::Path, tree: & gen.min_xaml = true; let mut tokens = bindgen::namespace(&gen, tree); tokens.push_str(r#"#[cfg(feature = "implement")] ::core::include!("impl.rs");"#); - lib::format(tree.namespace, &mut tokens, rustfmt); std::fs::write(path.join("mod.rs"), tokens).unwrap(); - let mut tokens = bindgen::namespace_impl(&gen, tree); lib::format(tree.namespace, &mut tokens, rustfmt); std::fs::write(path.join("impl.rs"), tokens).unwrap();