1#[cfg(feature = "raw_input")]
2use crate::raw_input;
3use crate::{
4 api::*,
5 context::*,
6 device::*,
7 event,
8 event::{EventHandler, ResizingEdge},
9 geometry::*,
10 ime,
11 window::{Style, Window},
12};
13use std::panic::catch_unwind;
14use std::path::PathBuf;
15use windows::core::HSTRING;
16use windows::Win32::{
17 Foundation::*, Graphics::Gdi::*, System::SystemServices::*, UI::Controls::WM_MOUSELEAVE,
18 UI::HiDpi::*, UI::Input::Ime::*, UI::Input::KeyboardAndMouse::*, UI::Shell::*,
19 UI::WindowsAndMessaging::*,
20};
21
22#[derive(Clone, Copy, PartialEq, Eq, Debug)]
23#[repr(usize)]
24pub(crate) enum UserMessage {
25 SetTitle,
26 SetPosition,
27 SetInnerSize,
28 EnableIme,
29 DisableIme,
30 SetStyle,
31 AcceptDragFiles,
32}
33
34#[inline]
42fn hiword(x: i32) -> i16 {
43 ((x >> 16) & 0xffff) as _
44}
45
46#[inline]
47fn get_x_lparam(lp: LPARAM) -> i16 {
48 (lp.0 & 0xffff) as _
49}
50
51#[inline]
52fn get_y_lparam(lp: LPARAM) -> i16 {
53 ((lp.0 >> 16) & 0xffff) as _
54}
55
56#[inline]
57fn get_xbutton_wparam(wp: WPARAM) -> u16 {
58 ((wp.0 >> 16) & 0xffff) as _
59}
60
61#[inline]
62fn get_keystate_wparam(wp: WPARAM) -> u32 {
63 (wp.0 & 0xffff) as _
64}
65
66#[inline]
67fn lparam_to_point(lparam: LPARAM) -> PhysicalPosition<i32> {
68 PhysicalPosition::new(get_x_lparam(lparam) as i32, get_y_lparam(lparam) as i32)
69}
70
71#[inline]
72fn wparam_to_button(wparam: WPARAM) -> MouseButton {
73 match get_xbutton_wparam(wparam) {
74 0x0001 => MouseButton::Ex(0),
75 0x0002 => MouseButton::Ex(1),
76 _ => unreachable!(),
77 }
78}
79
80fn update_buttons(buttons: &mut Vec<MouseButton>, wparam: WPARAM) {
81 buttons.clear();
82 let values = get_keystate_wparam(wparam);
83 if values & MK_LBUTTON.0 != 0 {
84 buttons.push(MouseButton::Left);
85 }
86 if values & MK_RBUTTON.0 != 0 {
87 buttons.push(MouseButton::Right);
88 }
89 if values & MK_MBUTTON.0 != 0 {
90 buttons.push(MouseButton::Middle);
91 }
92 if values & MK_XBUTTON1.0 != 0 {
93 buttons.push(MouseButton::Ex(0));
94 }
95 if values & MK_XBUTTON2.0 != 0 {
96 buttons.push(MouseButton::Ex(1));
97 }
98}
99
100fn mouse_input<T: EventHandler + 'static>(
101 window: &Window,
102 button: MouseButton,
103 button_state: KeyState,
104 wparam: WPARAM,
105 lparam: LPARAM,
106) -> LRESULT {
107 call_handler(|eh: &mut T, state| {
108 match button_state {
109 KeyState::Pressed => unsafe {
110 SetCapture(HWND(window.raw_handle() as _));
111 },
112 KeyState::Released => unsafe {
113 ReleaseCapture();
114 },
115 }
116 let buttons = &mut state.mouse_buttons;
117 update_buttons(buttons, wparam);
118 let ev = event::MouseInput {
119 window,
120 button,
121 button_state,
122 mouse_state: MouseState {
123 position: lparam_to_point(lparam),
124 buttons,
125 },
126 };
127 eh.mouse_input(ev);
128 });
129 LRESULT(0)
130}
131
132fn mouse_wheel<T: EventHandler + 'static>(
133 window: &Window,
134 dir: MouseWheelAxis,
135 wparam: WPARAM,
136 lparam: LPARAM,
137) -> LRESULT {
138 call_handler(|eh: &mut T, state| {
139 let delta = hiword(wparam.0 as _);
140 let buttons = &mut state.mouse_buttons;
141 update_buttons(buttons, wparam);
142 let ev = event::MouseWheel {
143 window,
144 axis: dir,
145 distance: delta as i32,
146 mouse_state: MouseState {
147 position: lparam_to_point(lparam),
148 buttons,
149 },
150 };
151 eh.mouse_wheel(ev);
152 });
153 LRESULT(0)
154}
155
156fn key_input<T: EventHandler + 'static>(
157 window: &Window,
158 state: KeyState,
159 wparam: WPARAM,
160 lparam: LPARAM,
161) -> LRESULT {
162 let scan_code = ScanCode(((lparam.0 >> 16) & 0x7f) as u32);
163 call_handler(|eh: &mut T, _| {
164 let ev = event::KeyInput {
165 window,
166 key_code: KeyCode::new(as_virtual_key(VIRTUAL_KEY(wparam.0 as _)), scan_code),
167 state,
168 prev_pressed: (lparam.0 >> 30) & 0x01 != 0,
169 };
170 eh.key_input(ev);
171 });
172 LRESULT(0)
173}
174
175pub(crate) extern "system" fn window_proc<T: EventHandler + 'static>(
176 hwnd: HWND,
177 msg: u32,
178 wparam: WPARAM,
179 lparam: LPARAM,
180) -> LRESULT {
181 let ret = catch_unwind(|| unsafe {
182 let window = find_window(hwnd);
183 if window.is_none() {
184 return DefWindowProcW(hwnd, msg, wparam, lparam);
185 }
186 let window = window.unwrap();
187 let handle = &window.handle;
188 match msg {
189 WM_PAINT => {
190 let mut ps = PAINTSTRUCT::default();
191 BeginPaint(hwnd, &mut ps);
192 call_handler(|eh: &mut T, _| eh.draw(event::Draw { window: handle }));
193 EndPaint(hwnd, &ps);
194 LRESULT(0)
195 }
196 #[cfg(feature = "raw_input")]
197 WM_INPUT => raw_input::wm_input::<T>(handle, hwnd, wparam, lparam),
198 WM_MOUSEMOVE => {
199 call_handler(|eh: &mut T, state| {
200 let position = lparam_to_point(lparam);
201 update_buttons(&mut state.mouse_buttons, wparam);
202 if state.entered_window.is_none() {
203 TrackMouseEvent(&mut TRACKMOUSEEVENT {
204 cbSize: std::mem::size_of::<TRACKMOUSEEVENT>() as _,
205 dwFlags: TME_LEAVE,
206 hwndTrack: hwnd,
207 dwHoverTime: 0,
208 });
209 state.entered_window = Some(window.clone());
210 eh.cursor_entered(event::CursorEntered {
211 window: handle,
212 mouse_state: MouseState {
213 position,
214 buttons: &state.mouse_buttons,
215 },
216 });
217 } else {
218 eh.cursor_moved(event::CursorMoved {
219 window: handle,
220 mouse_state: MouseState {
221 position,
222 buttons: &state.mouse_buttons,
223 },
224 });
225 }
226 });
227 let wnd = handle.state.read().unwrap();
228 wnd.cursor.set();
229 LRESULT(0)
230 }
231 WM_MOUSELEAVE => {
232 call_handler(|eh: &mut T, state| {
233 state.entered_window = None;
234 update_buttons(&mut state.mouse_buttons, wparam);
235 let mut pos = POINT::default();
236 GetCursorPos(&mut pos);
237 eh.cursor_left(event::CursorLeft {
238 window: handle,
239 mouse_state: MouseState {
240 position: PhysicalPosition::new(pos.x, pos.y),
241 buttons: &mut state.mouse_buttons,
242 },
243 });
244 });
245 LRESULT(0)
246 }
247 WM_LBUTTONDOWN => {
248 mouse_input::<T>(handle, MouseButton::Left, KeyState::Pressed, wparam, lparam)
249 }
250 WM_RBUTTONDOWN => mouse_input::<T>(
251 handle,
252 MouseButton::Right,
253 KeyState::Pressed,
254 wparam,
255 lparam,
256 ),
257 WM_MBUTTONDOWN => mouse_input::<T>(
258 handle,
259 MouseButton::Middle,
260 KeyState::Pressed,
261 wparam,
262 lparam,
263 ),
264 WM_XBUTTONDOWN => mouse_input::<T>(
265 handle,
266 wparam_to_button(wparam),
267 KeyState::Pressed,
268 wparam,
269 lparam,
270 ),
271 WM_LBUTTONUP => mouse_input::<T>(
272 handle,
273 MouseButton::Left,
274 KeyState::Released,
275 wparam,
276 lparam,
277 ),
278 WM_RBUTTONUP => mouse_input::<T>(
279 handle,
280 MouseButton::Right,
281 KeyState::Released,
282 wparam,
283 lparam,
284 ),
285 WM_MBUTTONUP => mouse_input::<T>(
286 handle,
287 MouseButton::Middle,
288 KeyState::Released,
289 wparam,
290 lparam,
291 ),
292 WM_XBUTTONUP => mouse_input::<T>(
293 handle,
294 wparam_to_button(wparam),
295 KeyState::Released,
296 wparam,
297 lparam,
298 ),
299 WM_MOUSEWHEEL => mouse_wheel::<T>(handle, MouseWheelAxis::Vertical, wparam, lparam),
300 WM_MOUSEHWHEEL => mouse_wheel::<T>(handle, MouseWheelAxis::Horizontal, wparam, lparam),
301 WM_KEYDOWN => key_input::<T>(handle, KeyState::Pressed, wparam, lparam),
302 WM_KEYUP => key_input::<T>(handle, KeyState::Released, wparam, lparam),
303 WM_CHAR => {
304 call_handler(|eh: &mut T, _| {
305 if let Some(c) = std::char::from_u32(wparam.0 as u32) {
306 eh.char_input(event::CharInput { window: handle, c });
307 }
308 });
309 LRESULT(0)
310 }
311 WM_IME_SETCONTEXT => {
312 let lparam = {
313 let state = handle.state.read().unwrap();
314 let mut lparam = lparam.0 as u32;
315 if !state.visible_ime_composition_window {
316 lparam &= !ISC_SHOWUICOMPOSITIONWINDOW;
317 }
318 if !state.visible_ime_candidate_window {
319 lparam &= !ISC_SHOWUICANDIDATEWINDOW;
320 lparam &= !(ISC_SHOWUICANDIDATEWINDOW << 1);
321 lparam &= !(ISC_SHOWUICANDIDATEWINDOW << 2);
322 lparam &= !(ISC_SHOWUICANDIDATEWINDOW << 3);
323 }
324 LPARAM(lparam as _)
325 };
326 DefWindowProcW(hwnd, msg, wparam, lparam)
327 }
328 WM_IME_STARTCOMPOSITION => {
329 {
330 let imc = ime::Imc::get(hwnd);
331 let state = handle.state.read().unwrap();
332 if state.visible_ime_composition_window {
333 imc.set_composition_window_position(state.ime_position);
334 }
335 if state.visible_ime_candidate_window {
336 imc.set_candidate_window_position(
337 state.ime_position,
338 state.visible_ime_composition_window,
339 );
340 }
341 }
342 call_handler(|eh: &mut T, _| {
343 eh.ime_start_composition(event::ImeStartComposition { window: handle });
344 });
345 DefWindowProcW(hwnd, msg, wparam, lparam)
346 }
347 WM_IME_COMPOSITION => {
348 call_handler(|eh: &mut T, _| {
349 let imc = ime::Imc::get(hwnd);
350 if (lparam.0 as u32) & GCS_COMPSTR.0 != 0 {
351 let s = imc.get_composition_string(GCS_COMPSTR);
352 let attrs = imc.get_composition_string(GCS_COMPATTR);
353 let clause = imc.get_composition_string(GCS_COMPCLAUSE);
354 if let (
355 Some(ime::CompositionString::CompStr(s)),
356 Some(ime::CompositionString::CompAttr(attrs)),
357 Some(ime::CompositionString::CompClause(clause)),
358 ) = (s, attrs, clause)
359 {
360 eh.ime_composition(event::ImeComposition {
361 window: handle,
362 composition: &ime::Composition::new(s, attrs, clause),
363 candidate_list: imc.get_candidate_list().as_ref(),
364 cursor_position: imc.get_cursor_position(),
365 });
366 }
367 } else if (lparam.0 as u32) & GCS_RESULTSTR.0 != 0 {
368 let s = imc.get_composition_string(GCS_COMPSTR);
369 let attrs = imc.get_composition_string(GCS_COMPATTR);
370 let clause = imc.get_composition_string(GCS_COMPCLAUSE);
371 if let (
372 Some(ime::CompositionString::CompStr(s)),
373 Some(ime::CompositionString::CompAttr(attrs)),
374 Some(ime::CompositionString::CompClause(clause)),
375 ) = (s, attrs, clause)
376 {
377 eh.ime_composition(event::ImeComposition {
378 window: handle,
379 composition: &ime::Composition::new(s, attrs, clause),
380 candidate_list: None,
381 cursor_position: imc.get_cursor_position(),
382 });
383 }
384 }
385 });
386 let show_composition_window = {
387 let state = handle.state.read().unwrap();
388 state.visible_ime_composition_window
389 };
390 if show_composition_window {
391 DefWindowProcW(hwnd, msg, wparam, lparam)
392 } else {
393 LRESULT(0)
394 }
395 }
396 WM_IME_ENDCOMPOSITION => {
397 call_handler(|eh: &mut T, _| {
398 let imc = ime::Imc::get(hwnd);
399 let ret = imc.get_composition_string(GCS_RESULTSTR);
400 let ret = if let Some(ime::CompositionString::ResultStr(s)) = &ret {
401 Some(s.as_str())
402 } else {
403 None
404 };
405 let ev = event::ImeEndComposition {
406 window: handle,
407 result: ret,
408 };
409 eh.ime_end_composition(ev);
410 });
411 DefWindowProcW(hwnd, msg, wparam, lparam)
412 }
413 WM_ACTIVATE => {
414 let active = ((wparam.0 as u32) & WA_ACTIVE) != 0;
415 let click_active = ((wparam.0 as u32) & WA_CLICKACTIVE) != 0;
416 if active || click_active {
417 call_handler(|eh: &mut T, _| eh.activated(event::Activated { window: handle }));
418 } else {
419 call_handler(|eh: &mut T, _| {
420 eh.inactivated(event::Inactivated { window: handle })
421 });
422 }
423 LRESULT(0)
424 }
425 WM_SIZING => {
426 set_resizing(true);
427 let d = {
428 let mut wrc = RECT::default();
429 GetWindowRect(hwnd, &mut wrc);
430 let mut crc = RECT::default();
431 GetClientRect(hwnd, &mut crc);
432 PhysicalSize::new(
433 (wrc.right - wrc.left) - (crc.right - crc.left),
434 (wrc.bottom - wrc.top) - (crc.bottom - crc.top),
435 )
436 };
437 let mut rc = (lparam.0 as *mut RECT).as_mut().unwrap();
438 let mut size = Size::new(
439 (rc.right - rc.left - d.width) as u32,
440 (rc.bottom - rc.top - d.height) as u32,
441 );
442 let edge = match wparam.0 as u32 {
443 WMSZ_LEFT => ResizingEdge::Left,
444 WMSZ_RIGHT => ResizingEdge::Right,
445 WMSZ_TOP => ResizingEdge::Top,
446 WMSZ_TOPLEFT => ResizingEdge::TopLeft,
447 WMSZ_TOPRIGHT => ResizingEdge::TopRight,
448 WMSZ_BOTTOM => ResizingEdge::Bottom,
449 WMSZ_BOTTOMLEFT => ResizingEdge::BottomLeft,
450 WMSZ_BOTTOMRIGHT => ResizingEdge::BottomRight,
451 _ => unreachable!(),
452 };
453 call_handler(|eh: &mut T, _| {
454 eh.resizing(event::Resizing {
455 window: handle,
456 size: &mut size,
457 edge,
458 });
459 });
460 let tmp = adjust_window_rect(
461 size,
462 handle.style().value(),
463 WINDOW_EX_STYLE(0),
464 handle.dpi(),
465 );
466 rc.right = rc.left + tmp.right - tmp.left;
467 rc.bottom = rc.top + tmp.bottom - tmp.top;
468 DefWindowProcW(hwnd, msg, wparam, lparam)
469 }
470 WM_SIZE => {
471 match wparam.0 as u32 {
472 SIZE_MINIMIZED => {
473 call_handler(|eh: &mut T, _| {
474 eh.minimized(event::Minimized { window: handle });
475 });
476 set_minimized(true);
477 set_maximized(false);
478 }
479 SIZE_MAXIMIZED => {
480 call_handler(|eh: &mut T, _| {
481 eh.maximized(event::Maximized {
482 window: handle,
483 size: PhysicalSize::new(
484 get_x_lparam(lparam) as u32,
485 get_y_lparam(lparam) as u32,
486 ),
487 });
488 });
489 set_minimized(false);
490 set_maximized(true);
491 }
492 SIZE_RESTORED => {
493 call_handler(|eh: &mut T, state| {
494 if state.minimized || state.maximized {
495 eh.restored(event::Restored {
496 window: handle,
497 size: PhysicalSize::new(
498 get_x_lparam(lparam) as u32,
499 get_y_lparam(lparam) as u32,
500 ),
501 });
502 set_minimized(false);
503 set_maximized(false);
504 }
505 });
506 }
507 _ => {}
508 }
509 LRESULT(0)
510 }
511 WM_WINDOWPOSCHANGED => {
512 let pos = &*(lparam.0 as *const WINDOWPOS);
513 if pos.flags & SWP_NOMOVE == SET_WINDOW_POS_FLAGS(0) {
514 call_handler(|eh: &mut T, _| {
515 eh.moved(event::Moved {
516 window: handle,
517 position: ScreenPosition::new(pos.x, pos.y),
518 });
519 });
520 }
521 DefWindowProcW(hwnd, msg, wparam, lparam)
522 }
523 WM_EXITSIZEMOVE => {
524 let size = handle.inner_size();
525 call_handler(|eh: &mut T, state| {
526 if state.resizing {
527 eh.resized(event::Resized {
528 window: handle,
529 size,
530 });
531 set_resizing(false);
532 }
533 });
534 DefWindowProcW(hwnd, msg, wparam, lparam)
535 }
536 WM_DPICHANGED => {
537 let mut prev_rc = RECT::default();
538 GetWindowRect(hwnd, &mut prev_rc);
539 let rc = *(lparam.0 as *const RECT);
540 SetWindowPos(
541 hwnd,
542 HWND(0),
543 rc.left,
544 rc.top,
545 rc.right - rc.left,
546 rc.bottom - rc.top,
547 SWP_NOZORDER | SWP_NOACTIVATE,
548 );
549 let new_dpi = hiword(wparam.0 as _) as u32;
550 call_handler(|eh: &mut T, _| {
551 eh.dpi_changed(event::DpiChanged {
552 window: handle,
553 new_dpi,
554 })
555 });
556 let prev_size = prev_rc.right - prev_rc.left;
557 let next_size = rc.right - rc.left;
558 let children = child_windows(hwnd);
559 for child in children {
560 let child_rc = {
561 let mut rc = RECT::default();
562 let mut screen = RECT::default();
563 GetWindowRect(child, &mut screen);
564 let mut pt = POINT {
565 x: screen.left,
566 y: screen.top,
567 };
568 ScreenToClient(hwnd, &mut pt);
569 rc.left = pt.x;
570 rc.top = pt.y;
571 let mut pt = POINT {
572 x: screen.right,
573 y: screen.bottom,
574 };
575 ScreenToClient(hwnd, &mut pt);
576 rc.right = pt.x;
577 rc.bottom = pt.y;
578 rc
579 };
580 let pt = PhysicalPosition::new(
581 child_rc.left * next_size / prev_size,
582 child_rc.top * next_size / prev_size,
583 );
584 let size = PhysicalSize::new(
585 (child_rc.right - child_rc.left) * next_size / prev_size,
586 (child_rc.bottom - child_rc.top) * next_size / prev_size,
587 );
588 SetWindowPos(
589 child,
590 HWND(0),
591 pt.x,
592 pt.y,
593 size.width,
594 size.height,
595 SWP_NOACTIVATE | SWP_NOZORDER,
596 );
597 if let Some(child) = find_window(child) {
598 call_handler(|eh: &mut T, _| {
599 eh.dpi_changed(event::DpiChanged {
600 window: &child.handle,
601 new_dpi,
602 })
603 });
604 }
605 }
606 LRESULT(0)
607 }
608 WM_GETDPISCALEDSIZE => {
609 let prev_dpi = GetDpiForWindow(hwnd) as i32;
610 let next_dpi = wparam.0 as i32;
611 let mut rc = RECT::default();
612 GetClientRect(hwnd, &mut rc);
613 let size = PhysicalSize::new(
614 ((rc.right - rc.left) * next_dpi / prev_dpi) as u32,
615 ((rc.bottom - rc.top) * next_dpi / prev_dpi) as u32,
616 );
617 let rc = adjust_window_rect(
618 size,
619 WINDOW_STYLE(GetWindowLongPtrW(hwnd, GWL_STYLE) as _),
620 WINDOW_EX_STYLE(GetWindowLongPtrW(hwnd, GWL_EXSTYLE) as _),
621 next_dpi as u32,
622 );
623 let mut ret = (lparam.0 as *mut SIZE).as_mut().unwrap();
624 ret.cx = rc.right - rc.left;
625 ret.cy = rc.bottom - rc.top;
626 LRESULT(1)
627 }
628 WM_DROPFILES => {
629 let hdrop = HDROP(wparam.0 as _);
630 let file_count = DragQueryFileW(hdrop, std::u32::MAX, None);
631 let mut buffer = Vec::new();
632 let files = (0..file_count)
633 .map(|i| {
634 let len = DragQueryFileW(hdrop, i, None) as usize + 1;
635 buffer.resize(len, 0);
636 DragQueryFileW(hdrop, i, Some(&mut buffer));
637 buffer.pop();
638 PathBuf::from(String::from_utf16_lossy(&buffer))
639 })
640 .collect::<Vec<_>>();
641 let files_ref = files.iter().map(|pb| pb.as_path()).collect::<Vec<_>>();
642 let mut pt = POINT::default();
643 DragQueryPoint(hdrop, &mut pt);
644 call_handler(|eh: &mut T, _| {
645 eh.drop_files(event::DropFiles {
646 window: handle,
647 paths: &files_ref,
648 position: PhysicalPosition::new(pt.x, pt.y),
649 });
650 });
651 DragFinish(hdrop);
652 LRESULT(0)
653 }
654 #[cfg(feature = "raw_input")]
655 WM_INPUT_DEVICE_CHANGE => {
656 raw_input::wm_input_device_change::<T>(handle, hwnd, wparam, lparam)
657 }
658 WM_DESTROY => {
659 {
660 let mut state = handle.state.write().unwrap();
661 state.closed = true;
662 }
663 call_handler(|eh: &mut T, _| {
664 eh.closed(event::Closed { window: handle });
665 {
666 let state = handle.state.read().unwrap();
667 for child in state.children.iter() {
668 child.close();
669 }
670 }
671 });
672 remove_window(hwnd);
673 if window_table_is_empty() {
674 PostQuitMessage(0);
675 }
676 LRESULT(0)
677 }
678 WM_NCCREATE => {
679 EnableNonClientDpiScaling(hwnd);
680 DefWindowProcW(hwnd, msg, wparam, lparam)
681 }
682 WM_USER => {
683 match wparam.0 {
684 w if w == UserMessage::SetTitle as usize => {
685 let state = handle.state.read().unwrap();
686 SetWindowTextW(hwnd, &HSTRING::from(&state.title));
687 }
688 w if w == UserMessage::SetPosition as usize => {
689 let state = handle.state.read().unwrap();
690 SetWindowPos(
691 hwnd,
692 HWND(0),
693 state.set_position.0,
694 state.set_position.1,
695 0,
696 0,
697 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE,
698 );
699 }
700 w if w == UserMessage::SetInnerSize as usize => {
701 let state = handle.state.read().unwrap();
702 let rc = adjust_window_rect(
703 state.set_inner_size,
704 WINDOW_STYLE(GetWindowLongPtrW(hwnd, GWL_STYLE) as _),
705 WINDOW_EX_STYLE(GetWindowLongPtrW(hwnd, GWL_EXSTYLE) as _),
706 GetDpiForWindow(hwnd),
707 );
708 SetWindowPos(
709 hwnd,
710 HWND(0),
711 0,
712 0,
713 rc.right - rc.left,
714 rc.bottom - rc.top,
715 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE,
716 );
717 }
718 w if w == UserMessage::EnableIme as usize => {
719 window.ime_context.borrow().enable();
720 }
721 w if w == UserMessage::DisableIme as usize => {
722 window.ime_context.borrow().disable();
723 }
724 w if w == UserMessage::SetStyle as usize => {
725 let style = {
726 let state = handle.state.read().unwrap();
727 state.style
728 };
729 let rc = adjust_window_rect(
730 handle.inner_size().to_physical(handle.dpi()),
731 style,
732 WINDOW_EX_STYLE(0),
733 GetDpiForWindow(hwnd),
734 );
735 SetWindowLongPtrW(hwnd, GWL_STYLE, style.0 as _);
736 SetWindowPos(
737 hwnd,
738 HWND(0),
739 0,
740 0,
741 rc.right - rc.left,
742 rc.bottom - rc.top,
743 SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED,
744 );
745 ShowWindow(hwnd, SW_SHOW);
746 }
747 w if w == UserMessage::AcceptDragFiles as usize => {
748 DragAcceptFiles(hwnd, BOOL(lparam.0 as _));
749 }
750 _ => {
751 return call_other::<T>(hwnd, msg, wparam, lparam);
752 }
753 }
754 LRESULT(0)
755 }
756 _ => call_other::<T>(hwnd, msg, wparam, lparam),
757 }
758 });
759 ret.unwrap_or_else(|e| {
760 set_unwind(e);
761 LRESULT(0)
762 })
763}