Python+TkでD&D 2
以前以下のような記事を書いた。
masahero.hatenablog.jp
時間もたってこのままでは動作しなくなっているようなので修正版を作った。
Python 3.6.9では動作するが、Python 3.7.3では元のウィンドウプロシージャを呼び出す箇所で"Access violation"が発生する。原因調査中。分かる人がいたら教えて。
import ctypes from ctypes.wintypes import HWND, UINT, WPARAM, LPARAM import sys import collections WM_DROPFILES = 0x0233 GWL_WNDPROC = -4 WINPROC = ctypes.c_void_p() drop_files = collections.deque() @ctypes.WINFUNCTYPE(ctypes.c_void_p, HWND, UINT, WPARAM, LPARAM) def drop_func(hwnd, msg, wp, lp): """D&D用のコールバック ファイルのドラッグアンドドロップイベント(WM_DROPFILES)を検出して、 ドロップされたファイル名を保持する。 ここでウィンドウ(tk)を使用するとハングアップするのでデータ保存だけ行う。 """ hwnd = HWND(hwnd) wp = WPARAM(wp) lp = LPARAM(lp) if msg == WM_DROPFILES: count = ctypes.windll.shell32.DragQueryFile(wp, -1, None, None) print(count) for tmp in range(count): szFile = ctypes.c_buffer(260) ctypes.windll.shell32.DragQueryFile(wp, tmp, szFile, ctypes.sizeof(szFile)) try: drop_files.append( szFile.value.decode(sys.getfilesystemencoding())) except UnicodeDecodeError: drop_files.append( szFile.value.decode("mbcs")) ctypes.windll.shell32.DragFinish(wp) msg = ctypes.c_uint(msg) return ctypes.windll.user32.CallWindowProcW(WINPROC, hwnd, msg, wp, lp) def dd_activate(hwnd): """D&Dを有効にする :param int hwnd: 有効にするウィンドウのハンドル :return: None """ ctypes.windll.shell32.DragAcceptFiles(hwnd, True) global WINPROC WINPROC = ctypes.c_void_p( ctypes.windll.user32.GetWindowLongPtrW(hwnd, GWL_WNDPROC)) ctypes.windll.user32.SetWindowLongPtrW(hwnd, GWL_WNDPROC, drop_func)