Отправка WM_DROPFILES с C ++ и WinAPI в стороннее приложение

Поэтому я отчаянно пытался автоматизировать функциональность перетаскивания, и сузил свой поиск решений до довольно изысканного куска кода:

// 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 общесистемного в этих случаях, что странно …). Я даже пытался скомпилировать код как x64 или x86 для проблемных приложений, но без изменений …

Мне кажется, что я неправильно использую FindWindow (я использую Window Info Tool в комплекте с AutoIT, чтобы получить класс окна, так как Spy ++ довольно запутанный). В любом случае, я назначаю вознаграждение, потому что мне действительно нужно выяснить это.

Приложение, с которым мне нужно будет это использовать, называется Dartfish, и это 32-разрядное приложение в Windows 7 … Мне нужно отправить список видеофайлов в определенную область его интерфейса (определенную панель), и я Я пытаюсь сделать это с помощью приведенного выше кода.

Любая помощь? Я очень ценю это!

1

Решение

ChangeWindowMessageFilter/Ex() не дает вам права отправлять указанное сообщение другим процессам. Он предоставляет другим процессам (в частности, процессам с более низкой целостностью) право отправлять это сообщение вам. Так что избавься от этого, это тебе не выгодно.

Затем попробуйте отправить имена файлов Unicode с помощью dfiles->fWide установите в TRUE и посмотрите, будет ли это иметь значение. Некоторые приложения не обрабатывают данные Ansi. Windows — это ОС на основе Юникода. использование IsWindowUnicode() знать, ожидает ли данный HWND сообщения окна Ansi или Unicode.

Наконец, некоторые приложения просто не реализуют WM_DROPFILES (они не звонят DragAcceptFiles() или включить WS_EX_ACCEPTFILES). Предпочтительный способ обработки перетаскивания&падение в современных версиях Windows заключается в реализации IDropTarget вместо этого, и связать его с HWND, используя RegisterDragDrop(). Там нет 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Вы можете обернуть DROPFILES данные с IDataObject и передать его IDropTarget::Drop() метод. Если Drop() принимает данные, не размещайте WM_DROPFILES сообщение. Однако хитрость в том, что IDropTarget* указатель возвращается GetProp() относится к процессу, которому принадлежит HWND, так что вам придется встроить его в свой процесс или добавить код в процесс HWND, чтобы фактически использовать указатель интерфейса.

0

Другие решения

Я использовал код, почти идентичный вашему, с хорошими результатами во многих приложениях. Я думаю, что ваша проблема в том, что окно, которое вы найдете с помощью FindWindow (), является верхний уровень окно, которое может не быть активным окном для добавления в целевое приложение. Некоторые приложения включают только выбранные дочерние окна для удаления. Проблема, конечно, в том, чтобы найти это окно. Я не нашел простого решения этой проблемы. Вы мог рекурсивно перечислять все дочерние элементы верхнего окна, используя EnumChildWindows () и пытаясь определить правильное окно (то есть по классу, ID, стилю окна или другому параметру), но это брутто. Я использую SpyXX, но это тоже не очень хорошее решение.
Удачи.

0

По вопросам рекламы [email protected]