0

I'm trying to get the names of all the windows using

extern crate winapi;

// --- std ---
use std::ffi::CStr;
// --- external ---
use winapi::{
    shared::{minwindef::LPARAM, windef::HWND__},
    um::winuser::{EnumWindows, GetWindowTextA},
};

fn find_window() {
    extern "system" fn enum_windows_proc(hwnd: *mut HWND__, _l_param: LPARAM) -> i32 {
        let ptr = &mut 0;

        unsafe {
            GetWindowTextA(hwnd, ptr as *mut i8, 1024);
            println!("hwnd: {:?}, name: {:?}", hwnd, CStr::from_ptr(ptr));
        }

        1
    }

    unsafe {
        EnumWindows(Some(enum_windows_proc), 0);
    }
}

fn main() {
    find_window();
}

I found some solutions:

But I get something like this:

hwnd: 0x100d6, name: ""
hwnd: 0x10250, name: "B \xa3\xd6T\xf7\x7f\x00\x00\x03\x00\x00\x00"
hwnd: 0x10260, name: ""
hwnd: 0x1028a, name: "N \xa3\xd6T\xf7\x7f\x00\x00\x03\x00\x00\x00\x00"
hwnd: 0x10288, name: ""
hwnd: 0x706f8, name: "T \xa3\xd6T\xf7\x7f"
hwnd: 0x1011c, name: ""
hwnd: 0x10510, name: "W \xa3\xd6T\xf7"
hwnd: 0x2037c, name: ""
hwnd: 0x30742, name: "C \xa3\xd6T\xf7\x7f\x00\x00\x03\x00\x00\x00\x00\x00"
hwnd: 0x12019c, name: "M \xa3\xd6T\xf7\x7f\x00\x00\x03\x00\x00\x00\x00"
hwnd: 0x90754, name: "C \xa3\xd6T\xf7\x7f\x00\x00\x03\x00\x00\x00\x00\x00"
hwnd: 0x1004e4, name: "M \xa3\xd6T\xf7\x7f\x00\x00\x03\x00\x00\x00\x00"

Obviously, all the names are wrong. How could I get the string from ptr?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
AurevoirXavier
  • 2,543
  • 2
  • 17
  • 25
  • I believe your question is answered by the answers of [Calling the GetUserName WinAPI function with a mutable string doesn't populate the string](https://stackoverflow.com/q/44709780/155423) and [What is the right way to allocate data to pass to an FFI call?](https://stackoverflow.com/q/39550856/155423). If you disagree, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Mar 02 '19 at 20:19
  • TL;DR: `let ptr = &mut 0;` is completely and totally wrong. You never allocate any space to store the string in; this is a pointer to an `i32` which is 4 bytes long. – Shepmaster Mar 02 '19 at 20:20
  • You might as well switch to `GetWindowTextW` to handle non-ASCII names as well. – Shepmaster Mar 02 '19 at 20:26
  • Thanks your tips. I did't notice the allocation. After I change the`ptr` to `let name = Vec::with_capacity(1024); let ptr = name.as_ptr();`, it works. – AurevoirXavier Mar 02 '19 at 20:30
  • @Shepmaster Thanks ^ ^, this question can be closed. – AurevoirXavier Mar 02 '19 at 20:31
  • @Shepmaster I got some problems when I switch to `GetWindowTextW`. It takes a `u16 ptr`, I can't get the text from `CStr::from_ptr(ptr)`. Could you help me? – AurevoirXavier Mar 02 '19 at 22:04
  • [Convert it to a slice and use `OsString`](https://stackoverflow.com/a/48587087/155423) – Shepmaster Mar 03 '19 at 00:54

0 Answers0