TTreeView
4.08.1999
  • Przeciąganie plików z Windows Explorera do TTreeView.

       Wiele profesjonalnych programów pozwala na przeciąganie plików z Windows Explorera do aplikacji. To jedna z największych zalet Windows, że pozwala na łatwe i intuicyjne manipulowanie obiektami (tutaj plikami) bez użycia klawiatury. Zaimplementowanie tej funkcji jest całkiem proste.

       Kiedy użytkownik upuści plik (lub grupę plików) na kontrolkę, Windows wysyła komunikat WM_DROPFILES do tej kontrolki. Kontrolka musi użyć parametrów tego komunikatu i kilku funkcji API, żeby dowiedzieć się ile plików zostało przeciągniętych i jakie są to pliki. W celu realizacji naszego celu dla TreeView, musimy nadpisać metodę WindowProc tej kontrolki. W tej funkcji musimy przechwytywać komunikat WM_DROPFILES i odpowiednio go przetworzyć. Pamiętaj aby dołączyć Shellapi.h do pliku nagłówkowego.

//w pliku nagłókowym:
#include <Shellapi.h>
//----------------------------------------------------
class TForm1 : public TForm
{

__published:	// IDE-managed Components
 TTreeView *TreeView1;
 void __fastcall FormClose(TObject *Sender, TCloseAction &Action);

private:
  Controls::TWndMethod OldTreeViewWP; 
  void __fastcall NewTreeViewWP(TMessage &Msg);
 // User declarations

public:		// User declarations
        __fastcall TForm1(TComponent* Owner);
};

//w pliku źródłowym:
//---------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
    //włączamy d&d dla TreeView
    DragAcceptFiles(TreeView1->Handle, true);

    //zapamiętujemy starą procedurę WindowProc
    OldTreeViewWP = TreeView1->WindowProc;

    //przypisujemy nową procedurę WindowProc
    TreeView1->WindowProc = NewTreeViewWP;

}
//----------------------------------------------------

void __fastcall TForm1::FormClose(TObject *Sender,
                                     TCloseAction &Action)
{
    //przywracamy dawną procedurę WindowProc
    TreeView1->WindowProc = OldTreeViewWP;

    //wyłączamy d&d dla TreeView
    DragAcceptFiles(TreeView1->Handle, false);

}
//----------------------------------------------------
void __fastcall TForm1::NewTreeViewWP(TMessage &Msg)
{
  if (Msg.Msg == WM_DROPFILES)
 {
  //znajdujemy punkt i węzeł upuszczenia
  POINT P;
  DragQueryPoint((HDROP)Msg.WParam, &P);
  TTreeNode *DropNode = TreeView1->GetNodeAt(P.x, P.y);

  //ile plików zostanie upuszczonych
 int num_files = DragQueryFile((HDROP)Msg.WParam, 0xFFFFFFFF,
                                      (LPSTR)NULL, NULL);
 char FileName[MAX_PATH];

 TreeView1->Items->BeginUpdate();
 for (int index = 0; index < num_files; index++)
  {
   //pobieramy nazwę pliku
   DragQueryFile((HDROP)Msg.WParam, index, FileName, MAX_PATH);

   //dodajemy do TreeView
   TreeView1->Items->Add(DropNode, FileName);

  }
  TreeView1->Items->EndUpdate();

  DragFinish((HDROP)Msg.WParam);
  Msg.Result = 0;
 }
 OldTreeViewWP(Msg);
}