microsoft / windows-rs

Rust for Windows
https://kennykerr.ca/rust-getting-started/
Apache License 2.0
10.23k stars 475 forks source link

Function `new` not implemented for `IDataObject_Vtbl` #3032

Closed toastmod closed 3 months ago

toastmod commented 3 months ago

Suggestion

It looks like the new function doesn't exist on the IDataObject_Vtbl struct, which the implement macro is trying to call. Can this be added please? Or am I doing something wrong maybe?

Error message:

error[E0599]: no function or associated item named `new` found for struct `IDataObject_Vtbl` in the current scope
  --> src\main.rs:22:1
   |
22 | #[implement(IDataObject)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^ function or associated item not found in `IDataObject_Vtbl`
   |
   = note: this error originates in the attribute macro `implement` (in Nightly builds, run with -Z macro-backtrace for more info)

Here is my Cargo.toml:

[package]
name = "dragsample"
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.56", features = [ 
    "implement",
    "Win32_Graphics_Gdi", 
    "Win32_System_LibraryLoader", 
    "Win32_UI_WindowsAndMessaging",
    "Win32_System_Com",
    "Win32_System_Ole",
    "Win32_UI_Shell"
] }

And my code:

use windows::{
    core::*, Win32::{
        Foundation::*, 
        Graphics::Gdi::ValidateRect, 
        System::{
            LibraryLoader::GetModuleHandleA,
            Com::{
                IDataObject,
                IDataObject_Vtbl
            }
        }, 
        UI::{Shell::SHDoDragDrop, WindowsAndMessaging::*}},
};

#[implement(IDataObject)]
struct MyDataObject(usize);

fn main() -> Result<()> {
    unsafe {
        let instance = GetModuleHandleA(None)?;
        debug_assert!(instance.0 != 0);

        let window_class = s!("window");

        let wc = WNDCLASSA {
            hCursor: LoadCursorW(None, IDC_ARROW)?,
            hInstance: instance.into(),
            lpszClassName: window_class,

            style: CS_HREDRAW | CS_VREDRAW,
            lpfnWndProc: Some(wndproc),
            ..Default::default()
        };

        let atom = RegisterClassA(&wc);
        debug_assert!(atom != 0);

        CreateWindowExA(
            WINDOW_EX_STYLE::default(),
            window_class,
            s!("This is a sample window"),
            WS_OVERLAPPEDWINDOW | WS_VISIBLE,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            None,
            None,
            instance,
            None,
        );

        let mut message = MSG::default();

        while GetMessageA(&mut message, None, 0, 0).into() {
            DispatchMessageA(&message);
        }

        Ok(())
    }
}

extern "system" fn wndproc(window: HWND, message: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT {
    unsafe {
        match message {
            WM_PAINT => {
                println!("WM_PAINT");
                _ = ValidateRect(window, None);
                LRESULT(0)
            },
            WM_DESTROY => {
                println!("WM_DESTROY");
                PostQuitMessage(0);
                LRESULT(0)
            },

            WM_LBUTTONDOWN => {
                println!("buttondown");
                // SHDoDragDrop(window, pdata, pdsrc, dweffect);
                LRESULT(0)
            },

            _ => {
                // println!("unhandled msg: {}", message);
                DefWindowProcA(window, message, wparam, lparam)
            },
        }
    }
}
toastmod commented 3 months ago

Additionally, it seems IDataObject_Impl does not exist. I am trying to implement IDataObject so I believe I would need this?

riverar commented 3 months ago

IDataObject relies on types that are unavailable in your crate.

In your Cargo.toml, add windows features:

"Win32_Graphics_Gdi", 
"Win32_System_Com_StructuredStorage",

Then implement IDataObject_Impl as you were going to.

Maybe @kennykerr can speak to how we can potentially emit a better warning/error here.

kennykerr commented 3 months ago

Yep, I have a few things in the works to improve the compiler diagnostics around COM authoring. Stay tuned.

kennykerr commented 3 months ago

Closing in favor of #3036.