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