将带有C 和Winapi的WM_Dropfiles发送到第三方应用程序

Sending WM_DROPFILES with C++ and WinAPI to third-party application

本文关键字:Dropfiles 应用程序 第三方 WM Winapi      更新时间:2023-10-16

因此,我拼命地试图自动化拖放功能,并将对解决方案的搜索范围缩小到了相当精致的代码块:

// DragAndDrop.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include <Shlobj.h>
#include <tchar.h>

int main(int argc, char* argv[]) {
    for (int i = 0; i <= WM_DROPFILES; i++)
    {
        ChangeWindowMessageFilter (i, MSGFLT_ADD);
    }
    if (HWND hwnd = FindWindow ("OpusApp", NULL)) {
    //HGLOBAL hGlobal = GlobalAlloc (GMEM_FIXED,
    //sizeof ("d:\DragMe.txt") + 2);
    //char *strFile = (char*) GlobalLock
    //(hGlobal);
    //strcpy (strFile, "d:\DragMe.txt");
    //strFile [strlen ("d:\DragMe.txt") +
    //1] = NULL;
    char filename[] = "d:\DragMe.txt";
    POINT point;
    point.x = 480;
    point.y = 480;
    HGLOBAL hMem = GlobalAlloc(GHND, sizeof(DROPFILES) + strlen(filename)+2);
    DROPFILES *dfiles = (DROPFILES*) GlobalLock(hMem);
    if (!dfiles)
    {
        GlobalFree(hMem);
        return NULL;
    }
    dfiles->pFiles = sizeof(DROPFILES);
    dfiles->pt = point;
    dfiles->fNC = TRUE;
    dfiles->fWide = FALSE;
    memcpy(&dfiles[1], filename, strlen(filename));
    GlobalUnlock(hMem);
    printf ("Sending Message...n");
    if (!PostMessage(hwnd, WM_DROPFILES, (WPARAM)hMem, 0)) {
        printf("Error Posting Message!");
        GlobalFree(hMem);
    }
    }
    int temp = 0;
    scanf("&d", temp);
    return 0;
}

...我对我的代码中的任何坏词表示歉意...它们只是用于调试目的。无论如何,以上非常简单,它可以与Microsoft Word,Excel和Notepad一起使用...但是对于许多应用程序,它根本不起作用(SPY 甚至没有记录WM_Dropfiles Message 系统范围/strong>在这些情况下,这很奇怪...)。我什至尝试将代码作为x64或x86编译为问题应用程序,但没有更改...

我觉得我可能正在错误地使用Findwindow(我使用自动捆绑的窗口信息工具来获取窗口类,因为我发现间谍 非常混乱)。在任何情况下,我都会设置赏金,因为我需要解决这个问题。

我将需要使用它的应用程序命名为dantfish,它是Windows 7上的32位应用程序...我需要将视频文件的列表发送到其界面的特定区域(特定窗格),我正在尝试使用上述代码来做到这一点。

有帮助吗?我非常感谢!

ChangeWindowMessageFilter/Ex()不授予您将指定消息发送到其他进程的权利。它授予其他过程(特别是较低的完整性过程),将该消息发送给您的权利。因此,摆脱它,这不会使您受益。

接下来,尝试将带有dfiles->fWide设置的Unicode文件名发送到TRUE,然后查看是否有所作为。一些应用程序不处理ANSI数据。Windows是一个基于Unicode的OS。使用IsWindowUnicode()知道给定的HWND是否期望ANSI或Unicode窗口消息。

最后,某些应用程序根本不实现WM_DROPFILES(它们不调用DragAcceptFiles()或启用WS_EX_ACCEPTFILES)。处理拖动&amp;在现代Windows版本中的首选方法是实现IDropTarget接口,并使用RegisterDragDrop()将其与HWND相关联。没有API可以检索HWND的IDropTarget,但可以手动完成:

(根据讨论的改编:如何为hwnd接收iDroptarget?)

IDropTarget* GetRegisteredDropTargetFromWnd (HWND hWnd) 
{ 
    IUnknown *pBuffer = (IUnknown *) GetProp (hWnd, TEXT("OleDropTargetInterface")); 
    if (pBuffer != NULL) 
    { 
        IDropTarget *pRetVal = NULL; 
        if (SUCCEEDED(pBuffer->QueryInterface(IID_IDropTarget, (void **) &pRetVal)))
            return pRetVal;     
    }
    return NULL; 
}

如果HWND具有IDropTarget,则可以用IDataObject包装DROPFILES数据并将其传递给IDropTarget::Drop()方法。如果Drop()接受数据,请勿发布WM_DROPFILES消息。但是,诀窍是,GetProp()返回的IDropTarget*指针相对于拥有HWND的过程,因此您必须将其元用到您的过程中,否则将代码注入HWND的过程,以实际使用该过程接口指针。

我使用的代码与您的代码几乎相同,并有许多应用程序。我认为您的问题是您使用Findwindow()找到的窗口是 top级窗口,它可能 not 是启用窗口的窗口,可以放入目标应用程序中。某些应用仅使选定的子窗口掉落。问题当然是找到该窗口。我还没有发现任何简单的解决方案解决这个问题。您可以使用EnumChildWindows()递归地枚举顶部窗口中的所有孩子,并尝试识别正确的窗口(即按类,ID,窗口样式或其他参数),但这很粗糙。我使用spyxx,但这也不是一个很好的解决方案。
祝你好运。