How to project event driven library?


Excuse me for a lot of posts - I am Rust newbie and am fascinated new language.
I have two problems with this project: 1)Rust 2)Winapi

  1. Rust:
    In object oriented languages usually main window or application was owner of list of children, all derived from widget. Owner call widget.Paint() which was virtual and owner doesn’t know about specified class. In rust is anything similar to events, virtual methods etc? Traits would be helping?
  2. WinApi
    Is possible draw on canvas only inside calling WM_PAINT in window_proc (this procedure is one for application or one for each window?) If I want draw on other event, for example for button click, would be not between BeginPaint-EndPaint (obtain hdc). How do it?

For example in Pascal VCL controls draws in Paint but applications in any place - OnCreate, OnClick etc.


Yeah, you’d do this with traits and trait objects. For example:

trait Widget {
   fn paint(&self); // maybe &mut self

struct WidgetContainer {
   widgets: Vec<Box<Widget>> // store (owned) Widget trait objects

impl WidgetContainer {
   fn add_widget(&mut self, w: Box<Widget>)

impl Widget for WidgetContainer {
     fn paint(&self) {
        for w in &self.widgets {
             w.paint();  // dynamic dispatch

You may want to look at existing GUI libs though rather than building from scratch.


To add to the previous reply, here are the crates (packages) dealing with GUI, sorted by most downloaded ones:


How do with traits? Is possible treat structure as trait?
I have

pub struct Widget {
    pub hwnd: HWND,
    pub parent: *const Widget,
    pub children: HashMap<HWND, Box<TWidget>>,


pub trait TWidget {
   fn command(&self);

impl TWidget for Button {
     fn command(&self) {
	     	println!("implementation TWidget for Button");

Next I want: window2.w.children.insert(button2.w.hwnd, button2);
is error, also Box is error. Is anything like button2.to_trait() ?
button2 as Box<< TWidget>> - is non scalar cast


You want let button2: Box<TWidget> = Box::new(Button {...}). That is, you need to erase the the type upfront (if using Box) to create the trait object. Box<Button> and Box<TWidget> have different representation, and that’s why the compiler is complaining about it being a non-scalar cast. Box<Button> contains a normal pointer to heap storage that contains the guts of your Button. Box<TWidget> consists of a fat pointer; this is basically two normal pointers, one for the vtable of TWidget for the underlying impl and the other to the data (guts) of the object.


It works in main example: `

window2.w.children.insert(button2.w.hwnd, Box::new(button2));

But I want hide it by moving it to struct button (the best would be move to struct w:Widget)

pub fn show(&mut self) {"New button",WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON);
    	(*self.w.parent).children.insert(self.w.hwnd, Box::new(*self));    	
    }                            ^error 

Is error: dereference of raw pointer requires unsafe function or block [E0133]:
whereas : pub parent: *const Widget,
unsafe nothing does:

unsafe{(*self.w.parent).children.insert(self.w.hwnd, Box::new(*self));}
                                           ^error                                     ^error

Multiple markers at this line
- cannot borrow immutable field self.w.parent.children as mutable [E0596]: cannot mutably borrow immutable field
- cannot move out of borrowed content [E0507]: cannot move out of borrowed content


I am trying change it to
pub parent: &'a Widget<'a>,
but is problem initialization in constructor , previously I initialize to ptr::null_mut() , I want initialize to self, but self is disabled in constructor.

impl<'a> Widget<'a> {
    pub fn new(class_name: &str, parent: &'a Widget<'a>) -> Widget<'a> {
        Widget {
            hwnd: 0 as HWND,
            parent: parent,
            children: HashMap::new(),
            font: Font::new(??????????),
            class_name_vec: to_vec(class_name),
            x: 0,
            y: 0,
            w: 100,
            h: 100,

how initialize owner for font?


Wasn’t that what you asked and got an answer in How to get pointer from embedded to owner??

I suggest learning more about Rust ownership system or else you’ll continue stumbling.