Czy przeciąganie (drag & drop) można wykonać programowo?
Swego czasu na grupach dyskusyjnych ktoś zapytał, jak można wykonać drag & drop programowo. Chodziło o program, do którego
okienka trzeba było przeciągnąć plik. Googlając natknąłem się na komunikat WM_DROPFILES, który można wysłać do okna programu
i w ten sposób spowodować, że zachowa się on tak, jakby zostały na jego okno przeciągnięte pliki. Działa to np. z Notatnikiem.
Niestety jednak WM_DROPFILES jest metodą dosyć starą i rzadko działa. Większość wpółczesnych programów pod Windows
do obsługi przeciągania używa przeciągania OLE, które wymaga aby kursor został przesunięty i znalazł się na oknem
będącym odbiorcą przeciąganych danych. Trzeba by więc programowo przesuwać kursor myszy a praktycznie zawsze
chcielibyśmy tego uniknąć. Tak więc wychodzi na to, że programowo, bez machania kursorem można zrobić tylko
przeciąganie i upuszczanie starego typu. Poniżej wklejam przykładowy kod źródłowy do przeciągania
pliku, podanego jako parametr wywołania, do okna Notatnika:
#include <windows.h>
#include <iostream>
#include <shlobj.h>
using namespace std;
int main(int argc, char ** argv) {
if (argc!=2) {
cerr << "wrong number of parameters!" << endl;
return 1;
}
char file[MAX_PATH];
GetFullPathName(argv[1], MAX_PATH, file, NULL);
cout << file << endl;
DROPFILES s;
s.pFiles = sizeof(s);
s.pt.x = 1;
s.pt.y = 1;
s.fNC = false;
s.fWide = false;
HGLOBAL hDrop;
BYTE * p;
hDrop = GlobalAlloc(GHND, sizeof(s) + strlen(file) + 2);
p = (BYTE*)GlobalLock(hDrop);
CopyMemory(p, &s, sizeof(s));
CopyMemory(p + sizeof(s), argv[1], strlen(file)+1);
GlobalUnlock(p);
PostMessage(FindWindow("Notepad", NULL), WM_DROPFILES, (WPARAM)hDrop, NULL);
return 0;
}