标签:剪贴板 end hmem Windows hwnd void text Ruby def
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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# Copyright © 2022, 飞麦 <fitmap@qq.com>, All rights reserved. # frozen_string_literal: true require 'fiddle/import' # Clipboard only for Windows, can use both in x86 and x64 # size_t and handles must use void* (NOT uint) in Fiddle to fit the pointer size of x86 or x64 # if use size_t as return value, you need add to_i to it. module Clipboard module_function extend Fiddle::Importer include Fiddle::CParser dlload 'kernel32', 'user32' # HWND GetClipboardOwner(); extern 'void* GetClipboardOwner()' # HWND GetClipboardViewer(); extern 'void* GetClipboardViewer()' # HWND GetDesktopWindow(); extern 'void* GetDesktopWindow()' # BOOL OpenClipboard( # _In_opt_ HWND hWndNewOwner # ); extern 'int OpenClipboard(void*)' # BOOL CloseClipboard(); extern 'int CloseClipboard()' # BOOL EmptyClipboard(); extern 'int EmptyClipboard()' # Predefined Clipboard Formats CF_UNICODETEXT = 13 # HANDLE GetClipboardData( # _In_ UINT uFormat # ); extern 'void* GetClipboardData(uint)' # HANDLE SetClipboardData( # _In_ UINT uFormat, # _In_opt_ HANDLE hMem # ); extern 'void* SetClipboardData(uint, void*)' # Global Memory Flags GMEM_FIXED = 0x0000 # Don't use GMEM_MOVEABLE = 0x0002(need GlobalLock and GlobalUnlock) # HGLOBAL GlobalAlloc( # _In_ UINT uFlags, # _In_ SIZE_T dwBytes # ); extern 'void* GlobalAlloc(uint, void*)' # SIZE_T GlobalSize( # _In_ HGLOBAL hMem # ); extern 'void* GlobalSize(void*)' # void RtlCopyMemory( # _In_ PVOID Destination, # _In_ const VOID *Source, # _In_ SIZE_T Length # ); extern 'void RtlCopyMemory(void*, const void*, void*)' # DWORD GetLastError(); extern 'uint GetLastError()' def show(_str) # puts _str # uncomment only when debug nil end def clip_hwnd hwnd = GetClipboardOwner() show("GetClipboardOwner fail! Error=#{GetLastError()}") if hwnd.null? hwnd.null? ? nil : hwnd end def view_hwnd hwnd = GetClipboardViewer() show("GetClipboardViewer fail! Error=#{GetLastError()}") if hwnd.null? hwnd.null? ? nil : hwnd end def desk_hwnd GetDesktopWindow() end def find_hwnd clip_hwnd || view_hwnd || desk_hwnd end # Sometimes OpenClipboard will fail without any error, so we need retry def open_cb 999.times do hwnd = find_hwnd next unless hwnd break unless OpenClipboard(hwnd).zero? show("OpenClipboard fail! Error=#{GetLastError()}") end end def empty_cb 999.times do break unless EmptyClipboard().zero? show("EmptyClipboard fail! Error=#{GetLastError()}") end end def close_cb 999.times do break unless CloseClipboard().zero? show("CloseClipboard fail! Error=#{GetLastError()}") end end def move_it(text) text_16le = "#{text}\u0000".encode(Encoding::UTF_16LE) # must append \u0000 for text len = text_16le.bytesize hmem = GlobalAlloc(GMEM_FIXED, len) show("#GlobalAlloc fail! Error=#{GetLastError()}") if hmem.null? RtlCopyMemory(hmem, text_16le, len) hmem end def save_it(hmem) hndl = SetClipboardData(CF_UNICODETEXT, hmem) show("#SetClipboardData Error=#{GetLastError()} hmem=#{hmem.to_i} != hndl=#{hndl.to_i}") if hndl != hmem end def copy(text) open_cb empty_cb hmem = move_it(text) save_it(hmem) close_cb end def clear open_cb empty_cb close_cb end def load_it(hmem) len = GlobalSize(hmem).to_i show("GlobalSize Error=#{GetLastError()} len=#{len}") if len.zero? len -= 2 # needn't copy tail \u0000 text = ''.encode(Encoding::UTF_16LE) * (len / 2) RtlCopyMemory(text, hmem, len) text.encode(Encoding::UTF_8) end def paste open_cb hmem = GetClipboardData(CF_UNICODETEXT) text = hmem.null? ? '' : load_it(hmem) close_cb text end end |
标签:剪贴板,end,hmem,Windows,hwnd,void,text,Ruby,def 来源: https://www.cnblogs.com/fitmap/p/16581575.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。