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;
}