Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WM_CHAR event does not arrive in custom control #131

Closed
Storeks opened this issue Jun 30, 2024 · 6 comments
Closed

WM_CHAR event does not arrive in custom control #131

Storeks opened this issue Jun 30, 2024 · 6 comments
Assignees
Labels
enhancement New feature or request gui Something within the gui module

Comments

@Storeks
Copy link

Storeks commented Jun 30, 2024

Hi all. I'm trying to create my own editor. In events fn I write

        self.wnd.on().wm_char(move |char| {
                    let sim = char.char_code as u8 as char;
                    println!("char: {}", sim);
                    Ok(())
        });

but this code is not executed! Why?

@rodrigocfd
Copy link
Owner

Actually there is a lot involved in WM_CHAR messages. As a general rule, they're dispatched as the result of WM_KEYDOWN being translated by TranslateMessage function.

It's hard to say without seeing the rest of your code, but try handling WM_KEYDOWN instead.

@rodrigocfd rodrigocfd added the gui Something within the gui module label Jul 7, 2024
@Storeks
Copy link
Author

Storeks commented Jul 9, 2024

The test example is simple:

mod ed {
use winsafe::{self as ws, gui, co, prelude::*};
use ws::gui::{Horz, Vert};

#[derive(Clone)]
pub struct Editor {
    wnd: gui::WindowControl,
}

impl GuiWindow for Editor {
    fn as_any(&self) -> &dyn std::any::Any {
        self
    }
    fn hwnd(&self) -> &ws::HWND {
        self.wnd.hwnd()
    }
}

impl GuiChild for Editor {
    fn ctrl_id(&self) -> u16 {
        self.wnd.ctrl_id()
    }
}

impl Editor {
    pub fn new(parent: &impl GuiParent, position: (i32, i32), size: (u32, u32)) -> Self {
        let wnd = gui::WindowControl::new(
            parent,
            gui::WindowControlOpts {
                position,
                size,
                ex_style: gui::WindowControlOpts::default().ex_style | co::WS_EX::CLIENTEDGE,
                resize_behavior: (Horz::Resize, Vert::Resize),
                ..Default::default()
            },
        );

        let new_self = Self {
            wnd,
        };
        new_self.events();
        new_self
    }

//=========================================================
    fn events(&self) {
        self.wnd.on().wm_char(move |ch| {
            let sim = ch.char_code as u8 as char;
            println!("char: {}", sim);
            Ok(())
        });

        self.wnd.on().wm_sys_char(move |ch| {
            let sim = ch.char_code as u8 as char;
            println!("sys char: {}", sim);
            Ok(())
        });

        self.wnd.on().wm_paint({
            let self2 = self.clone();
            move || {
                let hdc = self2.wnd.hwnd().BeginPaint()?;
                let i = 3;
                hdc.TextOut(10, 10 + 20 * i as i32, "Test WM_CHAR")?;
                Ok(())
            }
        })
    }
}
}

mod wi {
    use w::co;
    use winsafe::{self as w, gui, prelude::*};
    
    use crate::ed::Editor;
    
    #[derive(Clone)]
    pub struct MainWin {
        wnd: gui::WindowMain,
        ed: Editor,
    }
    
    impl MainWin {
        pub fn new() -> Self {
            let wnd = gui::WindowMain::new(
                // create the container window
                gui::WindowMainOpts {
                    title: "Native controls".to_owned(),
                    size: (580, 240),
                    style: gui::WindowMainOpts::default().style
                        | co::WS::MINIMIZEBOX
                        | co::WS::MAXIMIZEBOX
                        | co::WS::SIZEBOX, // window can be resized
                    ..Default::default()
                },
            );
    
            let editor = Editor::new(&wnd, (10, 10), (560, 210));
    
            let new_self = Self {
                wnd,
                ed: editor,
            };
    
            new_self.events();
            new_self
        }
    
        pub fn run(&self) -> w::AnyResult<i32> {
            self.wnd.run_main(None)
        }
    
        fn events(&self) {
            self.wnd.on().wm_char(move |ch|{
                let sim = ch.char_code as u8 as char;
                eprintln!("sys char: {}", sim);
                Ok(())
            })
        }
    }    
}

use wi::MainWin;
use winsafe::{self as w, co, prelude::*};

fn main() {
    if let Err(e) = (|| MainWin::new().run())() {
        w::HWND::NULL
            .MessageBox(&e.to_string(), "Uncaught error", co::MB::ICONERROR)
            .unwrap();
    }
}

or even simpler

use winsafe::gui;
use winsafe::prelude::*;

fn main() {
    let window = gui::WindowMain::new(gui::WindowMainOpts {
        title: "test1".into(),
        ..Default::default()
    });
    window.on().wm_create(|_| {
        println!("message");
        Ok(0)
    });
    window.on().wm_char(|ch| {
        println!("char {}", ch.char_code);
        Ok(())
    });
    let _ = window.run_main(None);
}

@rodrigocfd
Copy link
Owner

Does this work for you?

window.on().wm_key_down(|p| {
	println!("vk {}", p.vkey_code);
	Ok(())
});

@Storeks
Copy link
Author

Storeks commented Jul 21, 2024

Not satisfied. The editor is created for multilingual input. WM_CHAR already receives a letter processed depending on the language layout. But in your version comes the keyboard code.

@rodrigocfd
Copy link
Owner

I added a flag to suppress the IsDialogMessage call in the window loop, this should allow WM_CHAR messages to be dispatched to the window procedure:

let window = gui::WindowMain::new(gui::WindowMainOpts {
    process_dlg_msgs: false, // suppress IsDialogMessage call
    ..Default::default()
});

Let me know if this works for you.

@rodrigocfd rodrigocfd self-assigned this Jul 22, 2024
@rodrigocfd rodrigocfd added the enhancement New feature or request label Jul 22, 2024
@Storeks
Copy link
Author

Storeks commented Jul 23, 2024

Thanks alot. All work perfectly!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request gui Something within the gui module
Projects
None yet
Development

No branches or pull requests

2 participants