|
发表于 2022-3-1 02:36:11
|
显示全部楼层
本帖最后由 人造人 于 2022-3-1 02:43 编辑
现学现卖,耗时4天,^_^
就我所知,目前拖放文件有两种完全不同的方法
一种是通过消息机制,使用 WM_DROPFILES 消息
另一种是通过 com 接口,使用 IDropSource IDataObject IDropTarget 这3个接口
第一种我弄懂了,写了一个C代码
第二种我找不到能用的资料,这方面的资料太少了
而且现在大部分软件已经不使用消息机制了,使用的是 com 接口
下面的代码是C语言版本的,核心原理就是一个全局钩子,在python中我还不知道怎么用全局钩子
如果你使用第一种方法的话,这方面的资料很多,你完全可以参考这个代码,把这个代码修改成python版本的
实在不行,你可以 python + c 呀,全局钩子的部分在 C 中做,就是在 python 中调用一下,这完全没有问题
对于第二种方法,我真的没办法了,这方面的资料真的太少了,^_^
drag.c
- #include <windows.h>
- #include <wchar.h>
- #include <strsafe.h>
- #define BUFF_SIZE 4096
- static TCHAR video_buff[BUFF_SIZE] = TEXT("hello world!");
- static LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
- switch(message) {
- case WM_CREATE: {
- DragAcceptFiles(hwnd, TRUE);
- return 0;
- }
- case WM_DROPFILES: {
- HDROP hdrop = (HDROP)wParam;
- POINT point; DragQueryPoint(hdrop, &point);
- StringCchPrintf(video_buff, BUFF_SIZE, TEXT("point: (%ld, %ld)"), point.x, point.y);
- UINT count = DragQueryFile(hdrop, 0xffffffff, NULL, 0);
- TCHAR filename[MAX_PATH];
- filename[0] = TEXT('\n');
- for(UINT i = 0; i < count; ++i) {
- DragQueryFile(hdrop, i, filename + 1, MAX_PATH - 1);
- StringCchCat(video_buff, BUFF_SIZE, filename);
- }
- DragFinish(hdrop);
- RECT rect;
- GetClientRect(hwnd, &rect);
- InvalidateRect(hwnd, &rect, TRUE);
- return 0;
- }
- case WM_PAINT: {
- PAINTSTRUCT ps;
- HDC hdc = BeginPaint(hwnd, &ps);
- RECT rect; GetClientRect(hwnd, &rect);
- DrawText(hdc, video_buff, -1, &rect, DT_LEFT);
- EndPaint(hwnd, &ps);
- return 0;
- }
- case WM_DESTROY: {
- DragAcceptFiles(hwnd, FALSE);
- PostQuitMessage(0);
- return 0;
- }
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
- const TCHAR szAppName[] = TEXT("MyWindows");
- WNDCLASS wndclass = {0};
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = MainWndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = szAppName;
- if(!RegisterClass(&wndclass)) {
- MessageBox(NULL, TEXT("这个程序需要在 Windows NT 才能执行!"), szAppName, MB_ICONERROR);
- return 0;
- }
- HWND hwnd = CreateWindow(szAppName, TEXT("鱼C工作室"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
- ShowWindow(hwnd, iCmdShow);
- UpdateWindow(hwnd);
- MSG msg;
- while(GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return msg.wParam;
- }
复制代码
common.h
- #ifndef _COMMON_H_
- #define _COMMON_H_
- #include <windows.h>
- typedef struct {
- POINT point;
- UINT count;
- TCHAR path[0][MAX_PATH];
- } shared_t;
- #define SHARED_STRUCT_SIZE(n) (sizeof(shared_t) + n * sizeof(TCHAR [MAX_PATH]))
- #endif
复制代码
hook.c
- #include "common.h"
- static HHOOK hhook;
- static HINSTANCE hinstLib;
- static HWND hwndCaller __attribute((section(TEXT("shared")), shared));
- static void TargetWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
- switch(message) {
- case WM_DROPFILES: {
- HDROP hdrop = (HDROP)wParam;
- UINT count = DragQueryFile(hdrop, 0xffffffff, NULL, 0);
- UINT block_size = SHARED_STRUCT_SIZE(count);
- shared_t *shared = malloc(block_size);
- DragQueryPoint(hdrop, &shared->point);
- shared->count = count;
- for(UINT i = 0; i < shared->count; ++i) {
- DragQueryFile(hdrop, i, shared->path[i], MAX_PATH);
- }
- COPYDATASTRUCT cds = {0, block_size, shared};
- HANDLE hMutex = CreateMutex(NULL, FALSE, TEXT("mutex_hook_dll"));
- WaitForSingleObject(hMutex, INFINITE);
- if(hwndCaller) SendMessage(hwndCaller, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)&cds);
- ReleaseMutex(hMutex);
- free(shared);
- 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(hhook, nCode, wParam, lParam);
- }
- void InstallHook(HWND hwnd) {
- HANDLE hMutex = CreateMutex(NULL, FALSE, TEXT("mutex_hook_dll"));
- WaitForSingleObject(hMutex, INFINITE);
- hwndCaller = hwnd;
- ReleaseMutex(hMutex);
- hhook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, hinstLib, 0);
- }
- void UninstallHook(void) {
- HANDLE hMutex = CreateMutex(NULL, FALSE, TEXT("mutex_hook_dll"));
- WaitForSingleObject(hMutex, INFINITE);
- hwndCaller = NULL;
- ReleaseMutex(hMutex);
- UnhookWindowsHookEx(hhook);
- hhook = NULL;
- }
- BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) {
- switch(reason) {
- case DLL_PROCESS_ATTACH:
- hinstLib = instance;
- break;
- }
- return TRUE;
- }
复制代码
main.c
- #include "common.h"
- #include <wchar.h>
- #include <strsafe.h>
- #define BUFF_SIZE 4096
- static TCHAR video_buff[BUFF_SIZE] = TEXT("hello world!");
- static HINSTANCE hinstLib;
- static LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
- switch(message) {
- case WM_CREATE: {
- hinstLib = LoadLibrary(TEXT("hook.dll"));
- void (*InstallHook)(HWND hwnd) = (void *)GetProcAddress(hinstLib, TEXT("InstallHook"));
- InstallHook(hwnd);
- return 0;
- }
- case WM_PAINT: {
- PAINTSTRUCT ps;
- HDC hdc = BeginPaint(hwnd, &ps);
- RECT rect; GetClientRect(hwnd, &rect);
- DrawText(hdc, video_buff, -1, &rect, DT_LEFT);
- EndPaint(hwnd, &ps);
- return 0;
- }
- case WM_COPYDATA: {
- COPYDATASTRUCT *pcds = (COPYDATASTRUCT *)lParam;
- shared_t *shared = (shared_t *)pcds->lpData;
- StringCchPrintf(video_buff, BUFF_SIZE, TEXT("hwnd: %p\npoint: (%ld, %ld)"), wParam, shared->point.x, shared->point.y);
- for(UINT i = 0; i < shared->count; ++i) {
- StringCchCat(video_buff, BUFF_SIZE, TEXT("\n"));
- StringCchCat(video_buff, BUFF_SIZE, shared->path[i]);
- }
- RECT rect;
- GetClientRect(hwnd, &rect);
- InvalidateRect(hwnd, &rect, TRUE);
- return 0;
- }
- case WM_DESTROY: {
- void (*UninstallHook)(void) = (void *)GetProcAddress(hinstLib, TEXT("UninstallHook"));
- UninstallHook();
- FreeLibrary(hinstLib);
- PostQuitMessage(0);
- return 0;
- }
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
- const TCHAR szAppName[] = TEXT("MyWindows");
- WNDCLASS wndclass = {0};
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = MainWndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = szAppName;
- if(!RegisterClass(&wndclass)) {
- MessageBox(NULL, TEXT("这个程序需要在 Windows NT 才能执行!"), szAppName, MB_ICONERROR);
- return 0;
- }
- HWND hwnd= CreateWindow(szAppName, TEXT("鱼C工作室"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
- ShowWindow(hwnd, iCmdShow);
- UpdateWindow(hwnd);
- MSG msg;
- while(GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return msg.wParam;
- }
复制代码
|
评分
-
查看全部评分
|