2017-09-09 4 views
1

Python 3.6に​​を使用するだけで、クリップボードに保存されているテキストを取得しようとしています。私はStackとGitHubで見つけた多くのソリューションをテストしましたが、Python 2からPython 3.4までしか動作しません。ctypesを使用してWindowsのクリップボードからテキストを読み取る

は、これはあなたがほとんどどこでも見つけることができますコードです:

from ctypes import * 

def get_clipboard_text(): 
    text = "" 
    if windll.user32.OpenClipboard(c_int(0)): 
     h_clip_mem = windll.user32.GetClipboardData(1) 
     windll.kernel32.GlobalLock.restype = c_char_p 
     text = windll.kernel32.GlobalLock(c_int(h_clip_mem)) 
     windll.kernel32.GlobalUnlock(c_int(h_clip_mem)) 
     windll.user32.CloseClipboard() 
    return text 

私はPython 3.4でそれをテストしました。それは正常に機能し、クリップボードにテキストを返しました。しかし、Python 3.6で同じスクリプトを実行すると、常にNoneが返されます。これまでのところPython 3.6の解決策が見つかりませんでした。

​​とCについてはあまり知らないので誰かが私を助けてくれるのだろうかと思っています。

+0

使用したインポートを含めることができますか?現在、コードは多くの 'NameError'を投げます。 – MSeifert

+0

申し訳ありませんが、インポートが追加されました。 – chrizator

答えて

3

64ビットのPython 3.6を使用しているので、ハンドルは64ビットで、c_int(32ビット)として渡していると思います。

ctypesでは、すべての引数と戻り値の型について明示的に指定することをお勧めします。次のコードは、32ビットと64ビットのPython 2と3で動作するはずです。

また、CF_UNICODETEXTはコピーするテキストを処理することができます。

from __future__ import print_function 
import ctypes 
import ctypes.wintypes as w 

CF_UNICODETEXT = 13 

u32 = ctypes.WinDLL('user32') 
k32 = ctypes.WinDLL('kernel32') 

OpenClipboard = u32.OpenClipboard 
OpenClipboard.argtypes = w.HWND, 
OpenClipboard.restype = w.BOOL 
GetClipboardData = u32.GetClipboardData 
GetClipboardData.argtypes = w.UINT, 
GetClipboardData.restype = w.HANDLE 
GlobalLock = k32.GlobalLock 
GlobalLock.argtypes = w.HGLOBAL, 
GlobalLock.restype = w.LPVOID 
GlobalUnlock = k32.GlobalUnlock 
GlobalUnlock.argtypes = w.HGLOBAL, 
GlobalUnlock.restype = w.BOOL 
CloseClipboard = u32.CloseClipboard 
CloseClipboard.argtypes = None 
CloseClipboard.restype = w.BOOL 

def get_clipboard_text(): 
    text = "" 
    if OpenClipboard(None): 
     h_clip_mem = GetClipboardData(CF_UNICODETEXT) 
     text = ctypes.wstring_at(GlobalLock(h_clip_mem)) 
     GlobalUnlock(h_clip_mem) 
     CloseClipboard() 
    return text 

print(get_clipboard_text()) 
+0

ありがとう、コードは完全に動作します!私はPythonの32ビット版と64ビット版は考えていませんでした。 – chrizator

+1

@chrizator、カーネル、およびウィンドウハンドルは32ビットです。しかし、負の値を持つ後者の特別なハンドルは64ビットに符号拡張する必要があります。また、実際には 'GlobalLock'の結果であるように、実際には' HMODULE'や 'HGLOBAL'のようなメモリアドレスがあります。実際には、ハードコード化の実装の詳細と前提を避けるために、ハンドルとポインタを使って作業するときは常に 'argtypes'と' restype'を宣言してください。 – eryksun

+0

ご清聴ありがとうございます。したがって、 'argtypes'と' restypes'を定義することにより、コードは32&64ビットで動作しますか?これらのばかげた質問におかけして申し訳ありませんが、私はこのトピックには本当に新しいです。 – chrizator

関連する問題