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
#![allow(non_camel_case_types, non_snake_case)]
use crate::co;
use crate::decl::*;
use crate::kernel::privs::*;
use crate::user::ffi;
handle! { HCLIPBOARD;
/// Handle to the
/// [clipboard](https://learn.microsoft.com/en-us/windows/win32/dataxchg/about-the-clipboard).
///
/// This handle doesn't exist natively, it's just an abstraction to safely
/// group the related clipboard operations.
}
impl HCLIPBOARD {
/// [`EmptyClipboard`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-emptyclipboard)
/// function.
pub fn EmptyClipboard(&self) -> SysResult<()> {
BoolRet(unsafe { ffi::EmptyClipboard() }).to_sysresult()
}
/// [`GetClipboardData`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclipboarddata)
/// function.
///
/// Calls [`HGLOBAL::GlobalSize`](crate::HGLOBAL::GlobalSize) and
/// [`HGLOBAL::GlobalLock`](crate::HGLOBAL::GlobalLock) internally to
/// retrieve a copy of the raw clipboard data.
///
/// Note that you should not trust the clipboard format – the binary data
/// can be anything, despite what the format says. Be careful when parsing
/// the binary into your desired format.
///
/// # Examples
///
/// ```no_run
/// use winsafe::{self as w, prelude::*, co};
///
/// let hclip = w::HWND::NULL.OpenClipboard()?;
/// let data = hclip.GetClipboardData(co::CF::TEXT)?;
/// # w::SysResult::Ok(())
/// ```
#[must_use]
pub fn GetClipboardData(&self, format: co::CF) -> SysResult<Vec<u8>> {
let hglobal = PtrRet(unsafe { ffi::GetClipboardData(format.raw() as _) })
.to_sysresult_handle::<HGLOBAL>()?;
let copied = {
let block = hglobal.GlobalLock()?;
block.as_slice().to_vec()
};
Ok(copied)
}
/// [`GetClipboardSequenceNumber`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclipboardsequencenumber)
/// function.
#[must_use]
pub fn GetClipboardSequenceNumber(&self) -> u32 {
unsafe { ffi::GetClipboardSequenceNumber() }
}
/// [`SetClipboardData`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setclipboarddata)
/// function.
///
/// Calls [`HGLOBAL::GlobalAlloc`](crate::HGLOBAL::GlobalAlloc) and
/// [`HGLOBAL::GlobalLock`](crate::HGLOBAL::GlobalLock) internally before
/// copying the data into the clipboard.
///
/// # Examples
///
/// ```no_run
/// use winsafe::{self as w, prelude::*, co};
///
/// let hclip = w::HWND::NULL.OpenClipboard()?;
///
/// let str_nullt = "foo"
/// .as_bytes()
/// .iter()
/// .map(|ch| *ch)
/// .chain(std::iter::once(0)) // null-terminated
/// .collect::<Vec<_>>();
///
/// hclip.SetClipboardData(co::CF::TEXT, &str_nullt)?;
/// # w::SysResult::Ok(())
/// ```
pub fn SetClipboardData(&self, format: co::CF, data: &[u8]) -> SysResult<()> {
let mut hglobal = HGLOBAL::GlobalAlloc(co::GMEM::MOVEABLE, data.len())?;
{
let mut block = hglobal.GlobalLock()?;
block.as_mut_slice().copy_from_slice(data); // copy the contents into HGLOBAL
}
PtrRet(unsafe { ffi::SetClipboardData(format.raw() as _, hglobal.leak().ptr() as _) })
.to_sysresult()?;
Ok(())
}
}