|
|
10鱼币
想做一个无窗口后台程序,可以获取指定窗口的拖拽事件,得到拖拽文件路径
(只要是获取拖拽其它窗口的文件,所以窗口组件的拖拽事件self.setAcceptDrops(True)是不适应的)
import win32gui, win32ui, win32con
hwnd = win32gui.FindWindow(None, "Test Dialogs")#获取窗口句柄
win32gui.DragAcceptFiles(hwnd, True) #定义一个窗口句柄接受拖拽
以下找到的示例无效
wnd = win32ui.CreateWindowFromHandle(hwnd)
wnd.HookMessage(self.test, win32con.WM_DROPFILES)
请教有可以实现的方法吗?
谢谢啦!
本帖最后由 hrpzcf 于 2022-3-11 12:13 编辑
看你还没解决,我按照楼上大佬的代码修改了做成模块了,你自己看看吧
(, 下载次数: 6)
下载附件,把里面三个文件解压至你项目里能import 到的地方,用法:
- import time
- from GouZi import *
- def test1():
- # 实例化一个文件拖放事件钩子客户端
- # 当然,你想直接调用dll也行,可导出的函数跟DragHookClient类里的函数同名
- dh = DragHookClient()
- print(f"启用钩子:{dh.HookDrag()}") # 安装拖放事件钩子
- print(f"钩子是否启用:{dh.IsHooked()}") # 检查钩子是否已安装
- count = 0
- while count < 60: # while True:
- count += 1
- if dh.HasNewDropFiles(): # 查询是否有新的拖放事件
- print(dh.GetNewDropFiles()) # 获取新的拖放事件生成的路径列表
- time.sleep(1)
- dh.UnHookDrag() # 程序结束不要忘记卸载钩子
- def test2():
- with DragHookClient() as dh:
- if dh.IsHooked(): # 检查钩子是否已安装
- print("钩子已启用")
- else:
- print("钩子未启用")
- return
- count = 0
- while count < 60: # while True:
- count += 1
- if dh.HasNewDropFiles(): # 查询是否有新的拖放事件
- print(dh.GetNewDropFiles()) # 获取新的拖放事件生成的路径列表
- time.sleep(1)
- if __name__ == "__main__":
- # test1()
- test2()
复制代码
GouZi.py
- import sys
- from ctypes import c_bool, c_wchar_p, windll
- from os import path
- __all__ = ["DragHookClient"]
- if sys.maxsize > 0xFFFFFFFF:
- dllName = "GouZi_vc143_x64.dll"
- else:
- dllName = "GouZi_vc143_x86.dll"
- rootPath = path.dirname(path.realpath(__file__))
- dllFullPath = path.join(rootPath, dllName)
- class DragHookClient:
- """WIN全局文件拖放事件钩子客户端"""
- def __init__(self):
- self.__hook = windll.LoadLibrary(dllFullPath)
- self.__hook.IsHooked.restype = c_bool
- self.__hook.HasNewDropFiles.restype = c_bool
- self.__hook.HookDrag.restype = c_bool
- self.__hook.GetNewDropFiles.restype = c_wchar_p
- def IsHooked(self) -> bool:
- """检查是否已启用全局文件拖放事件钩子"""
- return self.__hook.IsHooked()
- def HasNewDropFiles(self) -> bool:
- """检查是否有新的文件拖放事件"""
- return self.__hook.HasNewDropFiles()
- def UnHookDrag(self) -> None:
- """停止全局文件拖放事件钩子"""
- self.__hook.UnHookDrag()
- def HookDrag(self) -> bool:
- """启用全局文件拖放事件钩子"""
- return self.__hook.HookDrag()
- def GetNewDropFiles(self) -> list:
- """以列表形式返回检测到的全局文件拖放事件的文件路径"""
- string = self.__hook.GetNewDropFiles()
- return [s for s in string.strip().split("\n") if s]
- # def __del__(self) -> None:
- # self.__hook.UnHookDrag()
- def __enter__(self) -> "DragHookClient":
- self.__hook.HookDrag()
- return self
- def __exit__(self, excType, excValue, excTB) -> None:
- self.__hook.UnHookDrag()
复制代码
Hook.c
- #include <Windows.h>
- #include <strsafe.h>
- #define MAX_STRLEN 131072
- #define LOCKER TEXT("j5u7ld6va0b489sj1y3k28r1n3b1")
- #define IDRAGFILE INFINITE
- typedef struct {
- INT len;
- TCHAR str[MAX_STRLEN];
- } cp_t;
- #pragma data_seg("shared")
- static BOOL hasNewDrops = FALSE;
- static cp_t dropedFiles = { 0 };
- static HHOOK hHookHnd = NULL;
- #pragma data_seg()
- #pragma comment(linker, "/section:shared,rws")
- static HINSTANCE hLibInst;
- BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) {
- switch (reason) {
- case DLL_PROCESS_ATTACH:
- hLibInst = instance;
- }
- return TRUE;
- }
- static void TargetWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
- switch (message) {
- case WM_DROPFILES: {
- HDROP hDrop = (HDROP)wParam;
- UINT reqSize = 0;
- TCHAR buffer[MAX_PATH];
- UINT count = DragQueryFile(hDrop, IDRAGFILE, NULL, 0);
- HANDLE hMutex = CreateMutex(NULL, FALSE, LOCKER);
- if (!hMutex) break;
- WaitForSingleObject(hMutex, INFINITE);
- if (!hasNewDrops) {
- hasNewDrops = TRUE;
- dropedFiles.len = 0;
- dropedFiles.str[0] = 0;
- }
- for (UINT i = 0; i < count; ++i) {
- reqSize = DragQueryFile(hDrop, i, NULL, 0);
- if (reqSize >= MAX_PATH)
- continue;
- if (dropedFiles.len + reqSize + 1 >= MAX_STRLEN)
- break;
- DragQueryFile(hDrop, i, buffer, MAX_PATH);
- StringCchCat(dropedFiles.str, MAX_STRLEN, buffer);
- StringCchCat(dropedFiles.str, MAX_STRLEN, TEXT("\n"));
- dropedFiles.len += (reqSize + 1);
- }
- dropedFiles.str[dropedFiles.len] = 0;
- ReleaseMutex(hMutex);
- break;
- }
- }
- }
- static LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) {
- switch (nCode) {
- case HC_ACTION: {
- MSG *pMsg = (MSG *)lParam;
- TargetWndProc(pMsg->hwnd, pMsg->message, pMsg->wParam, pMsg->lParam);
- break;
- }
- }
- return CallNextHookEx(hHookHnd, nCode, wParam, lParam);
- }
- __declspec(dllexport) void UnHookDrag(void) {
- if (hHookHnd)
- UnhookWindowsHookEx(hHookHnd);
- hHookHnd = NULL;
- }
- __declspec(dllexport) BOOL HookDrag(void) {
- if (hHookHnd) return TRUE;
- hHookHnd = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, hLibInst, 0);
- return hHookHnd != NULL;
- }
- __declspec(dllexport) BOOL IsHooked(void) {
- return hHookHnd != NULL;
- }
- __declspec(dllexport) BOOL HasNewDropFiles(void) {
- BOOL newDrops = FALSE;
- if (!IsHooked()) return newDrops;
- HANDLE hMutex = CreateMutex(NULL, FALSE, LOCKER);
- if (!hMutex) return newDrops;
- WaitForSingleObject(hMutex, INFINITE);
- newDrops = hasNewDrops;
- ReleaseMutex(hMutex);
- return newDrops;
- }
- __declspec(dllexport) TCHAR *GetNewDropFiles(void) {
- static TCHAR dropedTemp[MAX_STRLEN];
- dropedTemp[0] = 0;
- if (!IsHooked()) return dropedTemp;
- HANDLE hMutex = CreateMutex(NULL, FALSE, LOCKER);
- if (!hMutex) return dropedTemp;
- WaitForSingleObject(hMutex, INFINITE);
- hasNewDrops = FALSE;
- if (dropedFiles.len > 0) {
- StringCchCopy(dropedTemp, MAX_STRLEN, dropedFiles.str);
- dropedFiles.len = 0;
- dropedFiles.str[0] = 0;
- }
- ReleaseMutex(hMutex);
- return dropedTemp;
- }
复制代码
@人造人
|
|