Interacting with the Windows Clipboard using WinAPI in Rust

In this article, we will learn how to interact with the Windows clipboard using the Windows API (WinAPI) in Rust. The clipboard is a temporary storage area for data that the user wants to copy from one place to another. It allows users to perform copy-paste operations across different applications. We will cover the following topics:
- Setting up the Rust environment
- Accessing WinAPI functions in Rust
- Implementing clipboard functions
- Example application
1. Setting up the Rust environment
Section titled “1. Setting up the Rust environment”First, you need to have Rust installed on your system. You can follow the official installation guide here.
Next, create a new Rust project:
$ cargo new winapi_clipboard$ cd winapi_clipboard2. Accessing WinAPI functions in Rust
Section titled “2. Accessing WinAPI functions in Rust”To access WinAPI functions in Rust, we will use the winapi crate. Add the following dependencies to your Cargo.toml file:
[dependencies]winapi = { version = "0.3", features = ["winuser"] }The winuser feature enables the necessary clipboard functions.
3. Implementing clipboard functions
Section titled “3. Implementing clipboard functions”Let’s create a new module named clipboard in src/lib.rs:
mod clipboard { use winapi::um::winuser::{ CloseClipboard, EmptyClipboard, GetClipboardData, OpenClipboard, SetClipboardData, CF_TEXT, }; use winapi::ctypes::c_void; use winapi::shared::minwindef::{HGLOBAL, UINT}; use winapi::shared::ntdef::NULL; use std::ptr::{null_mut, null}; use std::ffi::CString;
// WinAPI clipboard functions}Now, let’s implement the clipboard functions:
Opening and closing the clipboard
Section titled “Opening and closing the clipboard”To interact with the clipboard, we need to open it first. We can do this using the OpenClipboard function:
fn open_clipboard() -> Result<(), &'static str> { let result = unsafe { OpenClipboard(null_mut()) }; if result == 0 { Err("Failed to open the clipboard") } else { Ok(()) }}After we are done interacting with the clipboard, we need to close it using the CloseClipboard function:
fn close_clipboard() { unsafe { CloseClipboard(); }}Reading from the clipboard
Section titled “Reading from the clipboard”To read text from the clipboard, we’ll use the GetClipboardData function:
fn get_clipboard_text() -> Result<String, &'static str> { let clipboard_data = unsafe { GetClipboardData(CF_TEXT) as *mut u8 }; if clipboard_data.is_null() { return Err("Failed to get clipboard data"); }
let mut text = String::new(); let mut index = 0; loop { let ch = unsafe { *clipboard_data.offset(index) } as char; if ch == '\0' { break; } text.push(ch); index += 1; }
Ok(text)}Writing to the clipboard
Section titled “Writing to the clipboard”To write text to the clipboard, we’ll use the EmptyClipboard and SetClipboardData functions:
fn set_clipboard_text(text: &str) -> Result<(), &'static str> { let text_len = text.len() + 1; let text_cstring = CString::new(text).unwrap(); let h_mem = unsafe { GlobalAlloc(GMEM_MOVEABLE, text_len) } as *mut c_void;
if h_mem.is_null() { return Err("Failed to allocate memory for clipboard data"); }
let h_mem_text = unsafe { GlobalLock(h_mem) as *mut u8 }; for (i, ch) in text_cstring.as_bytes_with_nul().iter().enumerate() { unsafe { *h_mem_text.offset(i as isize) = *ch; } }
unsafe { GlobalUnlock(h_mem); EmptyClipboard(); if SetClipboardData(CF_TEXT, h_mem as HGLOBAL) == NULL { GlobalFree(h_mem); return Err("Failed to set clipboard data"); } }
Ok(())}4. Example application
Section titled “4. Example application”Now, let’s create an example application that reads and writes text to the clipboard:
fn main() { let example_text = "Hello, clipboard!";
println!("Writing to clipboard: {}", example_text); clipboard::open_clipboard().unwrap(); clipboard::set_clipboard_text(example_text).unwrap(); clipboard::close_clipboard();
println!("Reading from clipboard:"); clipboard::open_clipboard().unwrap(); let clipboard_text = clipboard::get_clipboard_text().unwrap(); clipboard::close_clipboard();
println!("Clipboard content: {}", clipboard_text);}Compile and run the example:
$ cargo build --release$ target/release/winapi_clipboardYou should see the following output:
Writing to clipboard: Hello, clipboard!Reading from clipboard:Clipboard content: Hello, clipboard!Conclusion
Section titled “Conclusion”In this article, we’ve learned how to interact with the Windows clipboard using WinAPI in Rust. We covered setting up the Rust environment, accessing WinAPI functions, and implementing clipboard functions for reading and writing text data. This example can serve as a starting point for more advanced clipboard manipulation in your Rust applications.
© 2026 David Li · Home · Blog · RSS ·Classic site · Built with Astro, Starlight and three.js