I'm working with Win32 and initializing a new thread with a message queue. I will be using the new window created in the thread outside the thread boundaries for sending windows messages. There must be a better way of doing this, right?
Here's the code I'm stuck with:
impl<T> ThreadedView<T> {
fn new(inner: T) -> Self {
// Static number to increase when creating new threads
static THREAD_NUMBER : Mutex<u64> = Mutex::new(0);
let mut thread_num = THREAD_NUMBER.lock().unwrap();
// Create a barrier to synchronize the new thread with this thread.
let init_barrier = Arc::new(RwLock::new(Barrier::new(2)));
let barrier_ptr = init_barrier.clone();
// Create an uninitialized window handle to initialize in the thread.
let window_handle = Arc::new(Mutex::new(MaybeUninit::<WindowHandle>::uninit()));
let window_handle_ptr = window_handle.clone();
// Create the thread.
let thread_handle = Builder::new()
.name((format!("View Thread #{}", *thread_num)))
.spawn(|| -> windows_result::Result<()> {
let instance = HINSTANCE::from(unsafe { GetModuleHandleW(None) }?);
// Initialize the handle in the thread.
let mut handle = window_handle_ptr.lock().unwrap();
handle.write(WindowHandle::from(unsafe { CreateWindowExW(
WINDOW_EX_STYLE::default(),
w!("window"),
w!("window"),
WINDOW_STYLE::default(),
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
None, None, Some(instance), None
)}?));
drop(handle);
drop(window_handle_ptr);
// Trigger the barrier.
let barrier = barrier_ptr.read().unwrap();
barrier.wait();
drop(barrier);
drop(barrier_ptr);
// Continue processing.
message_loop();
Ok(())
}).ok();
// Increase thread number after creation.
*thread_num += 1;
// Wait until the barrier triggers.
init_barrier.read().unwrap().wait();
// I just gave up here, this doesn't work.
let window_result = window_handle.lock().unwrap();
let new_handle = unsafe { window_result.assume_init() };
ThreadedView { window_handle, thread_handle, inner }
}
}
fn message_loop() {
let mut win_msg = MSG { ..Default::default() };
while win_msg.message != WM_QUIT {
flush_messages(&mut win_msg);
}
}