ponsic_winsafe/
events.rs

1use winapi::{
2    shared::minwindef::{LPARAM, UINT, WPARAM},
3    um::winuser::*,
4};
5
6use crate::{TimerId, graphics::Context};
7
8/// 按键标识
9///
10/// 此枚举标识(美式)键盘上所有的按键
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
12pub enum Key {
13    /// A
14    A,
15    /// B
16    B,
17    /// C
18    C,
19    /// D
20    D,
21    /// E
22    E,
23    /// F
24    F,
25    /// G
26    G,
27    /// H
28    H,
29    /// I
30    I,
31    /// J
32    J,
33    /// K
34    K,
35    /// L
36    L,
37    /// M
38    M,
39    /// N
40    N,
41    /// O
42    O,
43    /// P
44    P,
45    /// Q
46    Q,
47    /// R
48    R,
49    /// S
50    S,
51    /// T
52    T,
53    /// U
54    U,
55    /// V
56    V,
57    /// W
58    W,
59    /// X
60    X,
61    /// Y
62    Y,
63    /// Z
64    Z,
65
66    /// 1
67    Num1,
68    /// 2
69    Num2,
70    /// 3
71    Num3,
72    /// 4
73    Num4,
74    /// 5
75    Num5,
76    /// 6
77    Num6,
78    /// 7
79    Num7,
80    /// 8
81    Num8,
82    /// 9
83    Num9,
84    /// 0
85    Num0,
86
87    /// NumPad 1
88    NumPad1,
89    /// NumPad 2
90    NumPad2,
91    /// NumPad 3
92    NumPad3,
93    /// NumPad 4
94    NumPad4,
95    /// NumPad 5
96    NumPad5,
97    /// NumPad 6
98    NumPad6,
99    /// NumPad 7
100    NumPad7,
101    /// NumPad 8
102    NumPad8,
103    /// NumPad 9
104    NumPad9,
105    /// NumPad 0
106    NumPad0,
107
108    /// F1
109    F1,
110    /// F2
111    F2,
112    /// F3
113    F3,
114    /// F4
115    F4,
116    /// F5
117    F5,
118    /// F6
119    F6,
120    /// F7
121    F7,
122    /// F8
123    F8,
124    /// F9
125    F9,
126    /// F10
127    F10,
128    /// F11
129    F11,
130    /// F12
131    F12,
132
133    /// Shift
134    Shift,
135    /// Ctrl
136    Ctrl,
137    /// Alt
138    Alt,
139
140    // Special symbols for American keyboards
141    /// `
142    Backtick,
143    /// ,
144    Comma,
145    /// .
146    Dot,
147    /// /
148    Slash,
149    /// ;
150    Semicolon,
151    /// '
152    Apostrophe,
153    /// [
154    LeftBracket,
155    /// ]
156    RightBracket,
157    /// \
158    Backslash,
159    /// -
160    Minus,
161    /// =
162    Equals,
163
164    /// NumPad +
165    NumAdd,
166    /// NumPad -
167    NumSub,
168    /// NumPad *
169    NumMul,
170    /// NumPad /
171    NumDiv,
172    /// NumPad .
173    NumDot,
174
175    /// Tab
176    Tab,
177    /// Space
178    Space,
179    /// Enter
180    Enter,
181    /// Backspace
182    Backspace,
183
184    /// Esc
185    Esc,
186    /// CapsLock
187    CapsLock,
188    /// Left Ctrl
189    LeftCtrl,
190    /// Left Shift
191    LeftShift,
192    /// Left Alt
193    LeftAlt,
194    /// Right Ctrl
195    RightCtrl,
196    /// Right Shift
197    RightShift,
198    /// Right Alt
199    RightAlt,
200    /// ScrollLock
201    ScrollLock,
202    /// NumLock
203    NumLock,
204    /// Delete
205    Delete,
206    /// Insert
207    Insert,
208    /// Home
209    Home,
210    /// End
211    End,
212    /// PageUp
213    PageUp,
214    /// PageDown
215    PageDown,
216    /// Clear
217    Clear,
218
219    /// Left mouse button
220    LeftButton,
221    /// Right mouse button
222    RightButton,
223    /// Middle mouse button
224    MiddleButton,
225    /// Mouse extension button 1
226    X1Button,
227    /// Mouse extension button 2
228    X2Button,
229
230    /// Left arrow
231    Left,
232    /// Right arrow
233    Right,
234    /// Up arrow
235    Up,
236    /// Down arrow
237    Down,
238
239    /// Unknown key
240    Unknown(i32),
241}
242
243impl PartialEq<char> for Key {
244    #[inline(never)]
245    fn eq(&self, other: &char) -> bool {
246        match (self, other) {
247            // 字母键 (A-Z)
248            (Key::A, 'a' | 'A') => true,
249            (Key::B, 'b' | 'B') => true,
250            (Key::C, 'c' | 'C') => true,
251            (Key::D, 'd' | 'D') => true,
252            (Key::E, 'e' | 'E') => true,
253            (Key::F, 'f' | 'F') => true,
254            (Key::G, 'g' | 'G') => true,
255            (Key::H, 'h' | 'H') => true,
256            (Key::I, 'i' | 'I') => true,
257            (Key::J, 'j' | 'J') => true,
258            (Key::K, 'k' | 'K') => true,
259            (Key::L, 'l' | 'L') => true,
260            (Key::M, 'm' | 'M') => true,
261            (Key::N, 'n' | 'N') => true,
262            (Key::O, 'o' | 'O') => true,
263            (Key::P, 'p' | 'P') => true,
264            (Key::Q, 'q' | 'Q') => true,
265            (Key::R, 'r' | 'R') => true,
266            (Key::S, 's' | 'S') => true,
267            (Key::T, 't' | 'T') => true,
268            (Key::U, 'u' | 'U') => true,
269            (Key::V, 'v' | 'V') => true,
270            (Key::W, 'w' | 'W') => true,
271            (Key::X, 'x' | 'X') => true,
272            (Key::Y, 'y' | 'Y') => true,
273            (Key::Z, 'z' | 'Z') => true,
274
275            // 数字键 (0-9)
276            (Key::Num0 | Key::NumPad0, '0') => true,
277            (Key::Num1 | Key::NumPad1, '1') => true,
278            (Key::Num2 | Key::NumPad2, '2') => true,
279            (Key::Num3 | Key::NumPad3, '3') => true,
280            (Key::Num4 | Key::NumPad4, '4') => true,
281            (Key::Num5 | Key::NumPad5, '5') => true,
282            (Key::Num6 | Key::NumPad6, '6') => true,
283            (Key::Num7 | Key::NumPad7, '7') => true,
284            (Key::Num8 | Key::NumPad8, '8') => true,
285            (Key::Num9 | Key::NumPad9, '9') => true,
286
287            // Shift + 数字键
288            (Key::Num0, ')') => true,
289            (Key::Num1, '!') => true,
290            (Key::Num2, '@') => true,
291            (Key::Num3, '#') => true,
292            (Key::Num4, '$') => true,
293            (Key::Num5, '%') => true,
294            (Key::Num6, '^') => true,
295            (Key::Num7, '&') => true,
296            (Key::Num8, '*') => true,
297            (Key::Num9, '(') => true,
298
299            // 符号键
300            (Key::Backtick, '`' | '~') => true,
301            (Key::Comma, ',' | '<') => true,
302            (Key::Dot, '.' | '>') => true,
303            (Key::Slash, '/' | '?') => true,
304            (Key::Semicolon, ';' | ':') => true,
305            (Key::Apostrophe, '\'' | '"') => true,
306            (Key::LeftBracket, '[' | '{') => true,
307            (Key::RightBracket, ']' | '}') => true,
308            (Key::Backslash, '\\' | '|') => true,
309            (Key::Minus, '-' | '_') => true,
310            (Key::Equals, '=' | '+') => true,
311
312            // 小键盘符号
313            (Key::NumAdd, '+') => true,
314            (Key::NumSub, '-') => true,
315            (Key::NumMul, '*') => true,
316            (Key::NumDiv, '/') => true,
317            (Key::NumDot, '.') => true,
318
319            // 控制字符
320            (Key::Space, ' ') => true,
321            (Key::Tab, '\t') => true,
322            (Key::Enter, '\n' | '\r') => true, // 同时支持 LF 和 CR
323            (Key::Backspace, '\x08') => true,  // ASCII 退格符
324
325            _ => false,
326        }
327    }
328}
329
330#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
331pub enum Button {
332    Left,
333    Right,
334    Middle,
335    X1,
336    X2,
337}
338
339#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
340pub enum Wheel {
341    Up,
342    Down,
343}
344
345#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
346pub enum ModifierKey {
347    Shift,
348    Ctrl,
349    Alt,
350    Win,
351    Mouse(Button),
352}
353
354#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
355pub enum SizeChangeType {
356    Resize,
357    Minimize,
358    Maximize,
359    Restore,
360    MaxHide,
361    MaxShow,
362    Unknown(usize),
363}
364
365#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
366pub struct HotKeyFlags {
367    pub alt: bool,
368    pub ctrl: bool,
369    pub shift: bool,
370    pub win: bool,
371}
372
373#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
374pub enum ButtonStatus {
375    Down,
376    Up,
377    DoubleClick,
378}
379
380#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
381pub enum KeyStatus {
382    Down,
383    Up,
384}
385
386#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
387pub enum SizingSide {
388    Left,
389    Right,
390    Top,
391    Bottom,
392    TopLeft,
393    TopRight,
394    BottomLeft,
395    BottomRight,
396    MoveCauseExitMaximize,
397    Unknown(usize),
398}
399
400#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
401pub struct RefRect<'a> {
402    pub left: &'a mut i32,
403    pub top: &'a mut i32,
404    pub right: &'a mut i32,
405    pub bottom: &'a mut i32,
406}
407
408#[repr(isize)]
409#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
410pub enum CursorAt {
411    Border = HTBORDER,
412    Bottom = HTBOTTOM,
413    BottomLeft = HTBOTTOMLEFT,
414    BottomRight = HTBOTTOMRIGHT,
415    Caption = HTCAPTION,
416    Client = HTCLIENT,
417    Close = HTCLOSE,
418    Error = HTERROR,
419    Help = HTHELP,
420    HScroll = HTHSCROLL,
421    Left = HTLEFT,
422    Menu = HTMENU,
423    MaxButton = HTMAXBUTTON,
424    MinButton = HTMINBUTTON,
425    NoWhere = HTNOWHERE,
426    Right = HTRIGHT,
427    Size = HTSIZE,
428    Sysmenu = HTSYSMENU,
429    Top = HTTOP,
430    TopLeft = HTTOPLEFT,
431    TopRight = HTTOPRIGHT,
432    Transparent = HTTRANSPARENT,
433    VScroll = HTVSCROLL,
434}
435
436#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
437pub enum Event<'a> {
438    Key {
439        key: Key,
440        ex_key: bool,
441        status: KeyStatus,
442    },
443    Mouse {
444        button: Button,
445        pos: (i32, i32),
446        status: ButtonStatus,
447        modifier: Option<ModifierKey>,
448    },
449    Move {
450        pos: (i32, i32),
451        modifier: Option<ModifierKey>,
452    },
453    Wheel {
454        pos: (i32, i32),
455        wheel: Wheel,
456        modifier: Option<ModifierKey>,
457    },
458    Input {
459        ch: u16,
460    },
461    Paint {
462        context: Context,
463    },
464    Timer {
465        id: TimerId,
466    },
467    NoClient(NoClient),
468    Window(WindowEvent<'a>),
469    Other {
470        msg: UINT,
471        wparam: WPARAM,
472        lparam: LPARAM,
473    },
474}
475
476#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
477pub enum WindowEvent<'a> {
478    Destroy,
479    Create,
480    Close,
481    Move {
482        pos: (i32, i32),
483    },
484    UserDef {
485        msg: u32,
486        wparam: usize,
487        lparam: isize,
488    },
489    SizeRange {
490        max_width: &'a mut i32,
491        max_height: &'a mut i32,
492        max_left: &'a mut i32,
493        max_top: &'a mut i32,
494        min_track_width: &'a mut i32,
495        min_track_height: &'a mut i32,
496        max_track_width: &'a mut i32,
497        max_track_height: &'a mut i32,
498    },
499    SizeChanged {
500        width: u32,
501        height: u32,
502        type_: SizeChangeType,
503    },
504    SizeChanging {
505        ref_rect: RefRect<'a>,
506        type_: SizingSide,
507    },
508}
509
510#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
511pub enum NoClient {
512    /// 回调函数处理此消息应该返回 None,以确保执行默认行为
513    HitTest {
514        x: i32,
515        y: i32,
516    },
517    Mouse {
518        button: Button,
519        pos: (i16, i16),
520        status: ButtonStatus,
521        at: CursorAt,
522    },
523    Move {
524        pos: (i16, i16),
525        at: CursorAt,
526    },
527    Leave,
528    Create,
529}
530
531/// 窗口过程函数返回值
532#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
533pub enum Return {
534    /// 指示处理已完成且要返回 0
535    Finish,
536    /// 指示后续处理应交由窗口的默认行为
537    Default,
538    /// 指示处理已完成,但要返回自定义值
539    Data(isize),
540}