Sürüklenen dosyanın sürüklendiği bileşene göre işlem yapmak

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
YeniCevizci
Üye
Mesajlar: 35
Kayıt: 24 Tem 2004 09:49

Sürüklenen dosyanın sürüklendiği bileşene göre işlem yapmak

Mesaj gönderen YeniCevizci »

Merhaba,

Form üzerine sürüklenen dosyalarla ilgili işlem yaptırmak için şu kodları temel alıyordum:

Kod: Tümünü seç

uses ShellApi;

procedure TForm1.FormCreate(Sender: TObject);
begin
  DragAcceptFiles(Form1.Handle, true);
  Application.OnMessage := AppMessage;
end;

procedure TForm1.AppMessage(var Msg: Tmsg; var Handled: Boolean);
const
   BufferLength : DWORD = 511;
var
   DroppedFilename   : string;
   FileIndex         : DWORD;
   NumDroppedFiles   : DWORD;
   pDroppedFilename  : array [0..511] of Char;
   DroppedFileLength : DWORD;
begin
   if Msg.message = WM_DROPFILES then
   begin
     FileIndex := $FFFFFFFF;
     NumDroppedFiles := DragQueryFile(Msg.WParam, FileIndex,
                                      pDroppedFilename, BufferLength);
     Memo1.Lines.Clear;
     for FileIndex := 0 to (NumDroppedFiles - 1) do
     begin
       DroppedFileLength := DragQueryFile(Msg.WParam, FileIndex,
                                          pDroppedFilename,
                                          BufferLength);
       DroppedFilename := StrPas(pDroppedFilename);
       Memo1.Lines.Add(pDroppedFilename);
     end;
     DragFinish(Msg.WParam);
     Handled := true;
   end;
end;
Sorum ise şu:

Diyelim ki form üzerinde 4 farklı bileşen var. Herhangi birinin üzerine bir dosya sürüklendiğinde, her bileşenin değişik işler yaptırmak için ne yapmalıyım?

Mesela Listbox1 üzerine sürüklendiğinde farklı bir işlem, memo1 üzerine sürüklendiğinde farklı bir işlem yapmasını istiyorum.

Teşekkürler.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

Merhaba...

- Belki daha basit bir yolu vardır ama ben TümeVarım metodunu tercih ettim. Eksik yönlerini de biraz ilüzyon ile çözüme ulaştırdık... :lol: (İlüzyon nerede diye sorarsan, Windowed Control olmayan nesneleri pencerelendirme)

- Şimdi; dışardan form üzerine kabul ettiğin dosya/dosyaların hangileri olduğunu bulduğun kod örneğinde de gördüğün üzere DragQueryFile ile alabildiğini anlamışsındır.

:arrow: Peki mouse ile hangi noktaya bırakıldığını tespit edip edemeyeceğini merak ettin mi :?: Etmediysen bile şimdi ediyorsundur, cevabı :idea: DragQueryPoint komutudur...

:arrow: Şimdi gelen dosya/dosyaların bırakıldığı Mouse Koordinatını TPoint olarak bulduğumuza göre geriye ne kalıyor, bu koordinatlarda hangi nesnemiz var :?: 'ı bulmak... :o

:arrow: Sırası gelmişken unutulmaması gereken nokta ClientToScreen fonksiyonu ile bu TPoint değerinin Form üzerindeki koordinat tipine dönüştürülmesini sağlayıp öyle kontrole sokmalısın. :idea:

:arrow: FindVCLWindow komutu da burada yardımımıza yetişiyor... :idea: Bir anlamda verdiğin TPoint'deki nesnenin gölgesi halini alıyor... Geriye dosyaların kabul göreceği nesnelerin seçimi kalıyor. Ben en çok TAG değerleri vererek kullanmayı seviyorum ve sana da tavsiye ediyorum...

:?: Demişsin ki formda 4 farklı nesne var. Sen şimdi bu nesnelerin TAG'ına birer rakam ata ve FindVCLWindow ile bulduğun nesnenin bu TAG numarasına göre basit bir CASE içinde değer aktarımını yap... :idea:

:arrow: Yine sırası gelmişken, FindVCLWindow ile sadece Windowed Control özelliği olan nesneleri bulabiliyor. TImage TLabel gibi bu özellikten yoksun nesne/nesneler varsa bunları basit bir TPanel içine al ve bu Panel'i Image nesnesi kabul edecek şekilde stratejini belirle...
:idea:

:arrow: Sıra ürüne geldi. Aşağıda senin için bir örnek hazırladım. 1 TMemo, 1 TEdit ve (TPanel içine alınmış) 1 TImage olmak üzere 3 farklı nesne var. Resim drag/drop edilirse TImage'e resim olarak load ediliyor. Bir dizi dosya seçilirse memo haricindekiler sadece ilk sıradakini değerlendiriyor. :wink:

:idea: Bahsetmeye çalıştığım noktaları kavrarsan benzeri tekniği sıkıştığın her yerde kullanabilirsin... :wink: Ben öyle yapıyorum...

Kod: Tümünü seç

procedure TForm1.AppMessage(var Msg: Tmsg; var Handled: Boolean);
const
   BufferLength : DWORD = 511;
var
   xPoint            : TPoint;
   DroppedFilename   : string;
   FileIndex         : DWORD;
   NumDroppedFiles   : DWORD;
   pDroppedFilename  : array [0..511] of Char;
begin
   if Msg.message = WM_DROPFILES then
   begin
     FileIndex := $FFFFFFFF;
     DragQueryPoint(Msg.wParam, xPoint);
     NumDroppedFiles := DragQueryFile(Msg.WParam, FileIndex,
                                      pDroppedFilename, BufferLength);
     Case FindVCLWindow(ClientToScreen(xPoint)).Tag of
     1: begin // Image olan TPanel
          DragQueryFile(Msg.WParam, 0, pDroppedFilename, BufferLength);
          Image1.Picture.LoadFromFile(StrPas(pDroppedFilename));
        end;
     2: begin // TEdit
          DragQueryFile(Msg.WParam, 0, pDroppedFilename, BufferLength);
          Edit1.Text := StrPas(pDroppedFilename);
        end;
     3: begin // TMemo
          Memo1.Lines.Clear;
          for FileIndex := 0 to (NumDroppedFiles - 1) do
          begin
            DragQueryFile( Msg.WParam,
                           FileIndex,
                           pDroppedFilename,
                           BufferLength );
            DroppedFilename := StrPas(pDroppedFilename);
            Memo1.Lines.Add(Format('(%d,%d) Dosya Adı :%s', [xPoint.X, xPoint.Y, pDroppedFilename]));
          end;
        end;
     end; // Case
     DragFinish(Msg.WParam);
     Handled := true;
   end;
end;
8) Çalışmalarında başarılar... Forum adına güzel bir soru ve örnek teşkil etti...
Resim
Resim ....Resim
YeniCevizci
Üye
Mesajlar: 35
Kayıt: 24 Tem 2004 09:49

Mesaj gönderen YeniCevizci »

Harikasınız!

Tam istediğim gibi, çok teşekkürler!

Ben şimdi biraz daha çalışayım anlattıklarınızı... :)
kocaV
Üye
Mesajlar: 15
Kayıt: 21 Tem 2017 01:10

Re: Sürüklenen dosyanın sürüklendiği bileşene göre işlem yapmak

Mesaj gönderen kocaV »

merhaba,
forumda arama yaptığımda benim sorunuma en yakın çözümü bu konuda olduğunu düşündüğümden konunun devamı niteliğinde buraya yazıyorum...

runtime oluşturduğum panel ve image nesnelerine, dışarıdan (windows expoler) drag drop ile resim yüklemek istiyorum.

form üzerine panel ve image nesnelerini oluştururken isimlerine 1,2,3..... şeklinde sıra ile rakam ekliyorum.
ayrıca panelleri oluştururken tag özelliğine de aynı sayıyı tanımlıyorum. Programın çalışması esnasında üzerine resim sürüklenen panelin tag numarasını alıp, aynı numaralı timage nesnesi ile görüntülemek istiyorum ama resmi panelin üzerine sürükleyince "access violation at address.." diye devam eden hatayı alıyorum.
tag numarasını ve sürüklenen resmin adresini listboxa attığımda normal görünüyorlar.

Kod: Tümünü seç

DragQueryPoint(Msg.wParam, xPoint);
 NameLen:= DragQueryFile(hDrop, I, nil, 0) + 1;
SetLength(S, NameLen);
DragQueryFile(hDrop, I, Pointer(S), NameLen);
hno:= FindVCLWindow(ClientToScreen(xPoint)).Tag;

 Timage(FindComponent('Resima' + inttostr(hno))).Picture.LoadFromFile(S); //Buraya S yerine bilgisayarımdan bir resim adresi de girsem aynı hatayı veriyor. Sanırım image componentini bulamıyorum....
İmage nesnesine veya üzerinde bulunduğu panele sürüklenen resmi nasıl görüntüleyebilirim?

Bir de timage nesnesi, tasarım aşamasında iken png resimleri görüntüleyebilirken, çalışma esnasında png türünü görüntülemiyor (jpg adresi verilince görüntülüyor) Bu konuda ne yapabilirim?
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: Sürüklenen dosyanın sürüklendiği bileşene göre işlem yapmak

Mesaj gönderen ertank »

Merhaba,

Sorunuzun daha iyi anlaşılması adına;
-Kullandığınız Delphi sürümü nedir?
-Uygulamanızın görüntüsünü paylaşabilir misiniz?
kocaV
Üye
Mesajlar: 15
Kayıt: 21 Tem 2017 01:10

Re: Sürüklenen dosyanın sürüklendiği bileşene göre işlem yapmak

Mesaj gönderen kocaV »

dün uğraşırken ve araştırırken sorunu çözdüm, faydalanan olabilir düşüncesi ile buraya ekliyorum. (Yapılan işlemlerin mantığı bir üstteki mesajımda bulunmaktadır.)
begin
hDrop:= Msg.wParam;
DragQueryPoint(hdrop, xPoint);
DragQueryFile(Msg.WParam, 0, pDroppedFilename, BufferLength);
hno:= FindVCLWindow(ClientToScreen(xPoint)).Tag;
myimage := ((form1.FindComponent('Resima' + inttostr(hno))) As TImage);
myimage.Picture.LoadFromFile(StrPas(pDroppedFilename));
DragFinish(hDrop);
end;

png sorumun cevabını da buldum, usese pngimage ekleyince artık png formatını da görüntüleyebiliyor timage nesnesi.
Cevapla