1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#![cfg(windows)]
extern crate windows_win;
extern crate clipboard_win;
extern crate winapi;
use std::io;
use std::ops::FnMut;
use windows_win::{
raw,
Window,
Messages
};
use winapi::windef::{
HWND
};
use std::os::raw::{
c_int
};
extern "system" {
fn AddClipboardFormatListener(hWnd: HWND) -> c_int;
fn RemoveClipboardFormatListener(hWnd: HWND) -> c_int;
}
pub enum CallbackResult {
Next,
Stop,
StopWithError(io::Error)
}
pub fn default_error(error: io::Error) -> CallbackResult {
CallbackResult::StopWithError(error)
}
pub struct Master<OK, ERR>
where OK: FnMut() -> CallbackResult,
ERR: FnMut(io::Error) -> CallbackResult
{
cb_ok: OK,
cb_err: ERR
}
impl<OK, ERR> Master<OK, ERR>
where OK: FnMut() -> CallbackResult,
ERR: FnMut(io::Error) -> CallbackResult
{
pub fn new(cb: OK, cb_err: ERR) -> Self {
Master {
cb_ok: cb,
cb_err: cb_err
}
}
pub fn run(&mut self) -> io::Result<()> {
let window = Window::from_builder(raw::window::Builder::new().class_name("STATIC").parent_message())?;
unsafe {
if AddClipboardFormatListener(window.inner()) != 1 {
return Err(io::Error::last_os_error());
};
}
for msg in Messages::new().window(Some(window.inner())).low(Some(797)).high(Some(797)) {
match msg {
Ok(_) => {
match (self.cb_ok)() {
CallbackResult::Next => (),
CallbackResult::Stop => break,
CallbackResult::StopWithError(error) => return Err(error),
}
},
Err(error) => {
match (self.cb_err)(error) {
CallbackResult::Next => (),
CallbackResult::Stop => break,
CallbackResult::StopWithError(error) => return Err(error),
}
}
}
}
unsafe {
RemoveClipboardFormatListener(window.inner());
}
Ok(())
}
}