diff options
| author | Fakhri Mouad <moad_fakhri_1999@outlook.com> | 2024-08-28 16:36:06 +0100 |
|---|---|---|
| committer | Fakhri Mouad <moad_fakhri_1999@outlook.com> | 2024-08-28 16:36:06 +0100 |
| commit | 16503c3b91694f5ce9262e7edd7607b85926327d (patch) | |
| tree | 34856732d65de18dde7cc4de2753d8623791a5d9 | |
| parent | 1e6419b5b7bdafe3f1d1a2b4321238b6257c44e6 (diff) | |
Add Win32 procs needed to handle clipboard
| -rw-r--r-- | core/sys/windows/kernel32.odin | 3 | ||||
| -rw-r--r-- | core/sys/windows/user32.odin | 35 | ||||
| -rw-r--r-- | tests/core/sys/windows/test_clipboard.odin | 52 |
3 files changed, 90 insertions, 0 deletions
diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index 629ece3de..81db67185 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -400,6 +400,9 @@ foreign kernel32 { GlobalAlloc :: proc(flags: UINT, bytes: SIZE_T) -> LPVOID --- GlobalReAlloc :: proc(mem: LPVOID, bytes: SIZE_T, flags: UINT) -> LPVOID --- GlobalFree :: proc(mem: LPVOID) -> LPVOID --- + + GlobalLock :: proc(hMem: HGLOBAL) -> LPVOID --- + GlobalUnlock :: proc(hMem: HGLOBAL) -> BOOL --- ReadDirectoryChangesW :: proc( hDirectory: HANDLE, diff --git a/core/sys/windows/user32.odin b/core/sys/windows/user32.odin index 31fc59f72..e13dcd55f 100644 --- a/core/sys/windows/user32.odin +++ b/core/sys/windows/user32.odin @@ -305,6 +305,13 @@ foreign user32 { GetProcessWindowStation :: proc() -> HWINSTA --- GetUserObjectInformationW :: proc(hObj: HANDLE, nIndex: GetUserObjectInformationFlags, pvInfo: PVOID, nLength: DWORD, lpnLengthNeeded: LPDWORD) -> BOOL --- + + OpenClipboard :: proc(hWndNewOwner: HWND) -> BOOL --- + CloseClipboard :: proc() -> BOOL --- + GetClipboardData :: proc(uFormat: UINT) -> HANDLE --- + SetClipboardData :: proc(uFormat: UINT, hMem: HANDLE) -> HANDLE --- + IsClipboardFormatAvailable :: proc(format: UINT) -> BOOL --- + EmptyClipboard :: proc() -> BOOL --- } CreateWindowW :: #force_inline proc "system" ( @@ -746,3 +753,31 @@ WinEventFlag :: enum DWORD { SKIPOWNPROCESS = 1, INCONTEXT = 2, } + +// Standard Clipboard Formats +CF_TEXT :: 1 +CF_BITMAP :: 2 +CF_METAFILEPICT :: 3 +CF_SYLK :: 4 +CF_DIF :: 5 +CF_TIFF :: 6 +CF_OEMTEXT :: 7 +CF_DIB :: 8 +CF_PALETTE :: 9 +CF_PENDATA :: 10 +CF_RIFF :: 11 +CF_WAVE :: 12 +CF_UNICODETEXT :: 13 +CF_ENHMETAFILE :: 14 +CF_HDROP :: 15 +CF_LOCALE :: 16 +CF_DIBV5 :: 17 +CF_DSPBITMAP :: 0x0082 +CF_DSPENHMETAFILE :: 0x008E +CF_DSPMETAFILEPICT :: 0x0083 +CF_DSPTEXT :: 0x0081 +CF_GDIOBJFIRST :: 0x0300 +CF_GDIOBJLAST :: 0x03FF +CF_OWNERDISPLAY :: 0x0080 +CF_PRIVATEFIRST :: 0x0200 +CF_PRIVATELAST :: 0x02FF diff --git a/tests/core/sys/windows/test_clipboard.odin b/tests/core/sys/windows/test_clipboard.odin new file mode 100644 index 000000000..460012cae --- /dev/null +++ b/tests/core/sys/windows/test_clipboard.odin @@ -0,0 +1,52 @@ +//+build windows +package test_core_sys_windows + +import "core:testing" +import win32 "core:sys/windows" +import "base:runtime" +import "core:strings" +import "core:mem" + +read_from_clipboard :: proc(wnd_handle: win32.HWND, allocator: runtime.Allocator) -> (result: string) +{ + if !win32.IsClipboardFormatAvailable(win32.CF_TEXT) do return; + + if !win32.OpenClipboard(wnd_handle) do return; + defer win32.CloseClipboard(); + + clipboard_data := win32.GetClipboardData(win32.CF_TEXT); + if clipboard_data != nil { + if cstr := cstring(win32.GlobalLock(win32.HGLOBAL(clipboard_data))); cstr != nil { + result = strings.clone_from_cstring(cstr, allocator); + } + win32.GlobalUnlock(win32.HGLOBAL(clipboard_data)); + } + return; +} + +write_to_clipboard :: proc(wnd_handle: win32.HWND, text: string) +{ + if !win32.OpenClipboard(wnd_handle) do return; + defer win32.CloseClipboard(); + win32.EmptyClipboard(); + + h_mem := win32.HGLOBAL(win32.GlobalAlloc(win32.GMEM_MOVEABLE, len(text) + 1)); + if h_mem == nil do return; + + cstr_dst := cast([^]u8)win32.GlobalLock(h_mem); + defer win32.GlobalUnlock(h_mem); + if cstr_dst == nil do return; + + mem.copy(rawptr(cstr_dst), raw_data(text), len(text)); + cstr_dst[len(text)] = 0; + + win32.SetClipboardData(win32.CF_TEXT, win32.HANDLE(h_mem)); +} + + +@(test) +verify_win32_clipboard :: proc(t: ^testing.T) { + write_to_clipboard(nil, "Hello everynyan! OH MY GAH"); + clipboard_content := read_from_clipboard(nil, context.temp_allocator); + testing.expect_value(t, clipboard_content, "Hello everynyan! OH MY GAH"); +} |