diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..c463ebe --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,11 @@ +[target.i686-pc-windows-msvc] +rustflags="-C target-feature=+crt-static" + +[target.x86-64-pc-windows-msvc] +rustflags="-C target-feature=+crt-static" + +[target.i686-pc-windows-gnu] +rustflags="-C target-feature=+crt-static" + +[target.x86-64-pc-windows-gnu] +rustflags="-C target-feature=+crt-static" \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..9a177ad --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,37 @@ +name: Build + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + target: i686-pc-windows-msvc + - name: Build x64 + run: cargo build --verbose --release --target x86_64-pc-windows-msvc + - name: Build x86 + run: cargo build --verbose --release --target i686-pc-windows-msvc + - uses: actions/upload-artifact@v4 + with: + path: target/*/release/*.exe + + fmt: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + components: rustfmt + - uses: actions-rust-lang/rustfmt@v1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..357d2ab --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,173 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aerotest" +version = "0.1.0" +dependencies = [ + "windows", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "2.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core", + "windows-targets", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ea851fb --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "aerotest" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +windows = { version = "0.58.0", features = ["Win32_UI_WindowsAndMessaging", "Win32_Graphics_Dwm", "Win32_Graphics_Gdi", "Win32_UI_Controls", "Win32_System_LibraryLoader"] } diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..4897b07 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,96 @@ +#![windows_subsystem = "windows"] + +use std::ffi::c_void; +use std::mem::size_of; + +use windows::core::*; +use windows::Win32::Foundation::*; +use windows::Win32::Graphics::Dwm::*; +use windows::Win32::Graphics::Gdi::*; +use windows::Win32::System::LibraryLoader::*; +use windows::Win32::UI::Controls::*; +use windows::Win32::UI::WindowsAndMessaging::*; + +const AERO_WINDOW_CLASS_NAME: PCSTR = s!("AeroWindow"); + +fn main() -> Result<()> { + unsafe { + let instance = GetModuleHandleA(None)?; + let black_brush = HBRUSH(GetStockObject(BLACK_BRUSH).0); // Don't ask me why + + let class = WNDCLASSA { + lpfnWndProc: Some(wndproc), + hInstance: instance.into(), + lpszClassName: AERO_WINDOW_CLASS_NAME, + hbrBackground: black_brush, + ..Default::default() + }; + + if RegisterClassA(&class) == 0 { + return Err(Error::from_win32()); + } + + let hwnd = CreateWindowExA( + WS_EX_OVERLAPPEDWINDOW, + AERO_WINDOW_CLASS_NAME, + s!("Aero Window"), + WS_OVERLAPPEDWINDOW, + 0, + 0, + 600, + 400, + None, + None, + instance, + None, + )?; + + let margins = MARGINS { + cxLeftWidth: -1, + cxRightWidth: -1, + cyTopHeight: -1, + cyBottomHeight: -1, + }; + + DwmExtendFrameIntoClientArea(hwnd, &margins)?; + + // Enable dark mode and Mica on Windows 11+ + _ = DwmSetWindowAttribute( + hwnd, + DWMWA_USE_IMMERSIVE_DARK_MODE, + (&TRUE) as *const _ as *const c_void, + size_of::().try_into()?, + ); + _ = DwmSetWindowAttribute( + hwnd, + DWMWA_SYSTEMBACKDROP_TYPE, + (&DWMSBT_MAINWINDOW) as *const _ as *const c_void, + size_of::().try_into()?, + ); + + _ = ShowWindow(hwnd, SW_NORMAL); + + let mut msg = Default::default(); + + while GetMessageA(&mut msg, None, 0, 0).into() { + _ = TranslateMessage(&msg); + DispatchMessageA(&msg); + } + + Ok(()) + } +} + +unsafe extern "system" fn wndproc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT { + match msg { + WM_CLOSE => { + DestroyWindow(hwnd).unwrap(); + LRESULT(0) + } + WM_DESTROY => { + PostQuitMessage(0); + LRESULT(0) + } + _ => DefWindowProcA(hwnd, msg, wparam, lparam), + } +}