2013-01-09 11 views
6

Próbowałem zaakceptować pliki, które są przeciągane i upuszczane do formularza z Eksploratora plików, ale to nie działa. Moja obsługa WM_DROPFILES nigdy nie jest wywoływana. Używam systemu Windows 8, jeśli to robi jakąkolwiek różnicę.Przeciąganie i upuszczanie plików do postaci Delphi nie działa

Oto prosty przykład tego, co robię (mam tylko TMemo w formularzu):

type 
    TForm1 = class(TForm) 
    Memo1: TMemo; 
    private 
    { Private declarations } 
    procedure WMDROPFILES(var msg : TWMDropFiles) ; message WM_DROPFILES; 
    procedure CreateWnd; override; 
    procedure DestroyWnd; override; 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

{ TForm1 } 

procedure TForm1.CreateWnd; 
begin 
    inherited; 
    DragAcceptFiles(Handle, True); 

end; 

procedure TForm1.DestroyWnd; 
begin 
    inherited; 
    DragAcceptFiles(Handle, false); 

end; 

procedure TForm1.WMDROPFILES(var msg: TWMDropFiles); 
var 
    i, fileCount: integer; 
    fileName: array[0..MAX_PATH] of char; 
begin 
    fileCount:=DragQueryFile(msg.Drop, $FFFFFFFF, fileName, MAX_PATH); 
    for i := 0 to fileCount - 1 do 
    begin 
    DragQueryFile(msg.Drop, i, fileName, MAX_PATH); 
    Memo1.Lines.Add(fileName); 
    end; 
    DragFinish(msg.Drop); 
end; 
+0

Przetestowałem Twój kod i działa. Windows 7, Delphi XE. Zamieniłem tylko linie w 'DestroyWnd', ale nie powinno to mieć znaczenia - działa zgodnie z oczekiwaniami. – kludg

+2

Duplikat: http://stackoverflow.com/questions/13482304/why-doesnt-my-form-receive-wm-dropfiles-when-files-are-dropped-on-it –

+4

@Serg: kolejność w 'DestroyWnd () 'ma znaczenie. 'DragAcceptFiles()' musi być wywołany przed 'odziedziczonym', ponieważ' dziedziczony' faktycznie zniszczy 'HWND'. Przy następnym odczytaniu 'Handle' po zniszczeniu, nowy' HWND' jest tworzony przez 'CreateWnd()'. Jeśli kolejność jest cofnięta, wynikiem końcowym będzie, że 'DragAcceptFiles (FALSE)' zostanie wywołany jako ostatni, wyłączając funkcję Przeciągnij i upuść. –

Odpowiedz

17

Najprawdopodobniej używasz aplikacji podwyższone. Prawdopodobnie dlatego, że używasz podniesionego Delphi. W systemie Vista i nowszych procesach o niskich uprawnieniach nie można wysyłać komunikatów do procesów o wyższych uprawnieniach. Ten MSDN blog wyjaśnia więcej.

Jeśli używasz swojego IDE Delphi podniesionego, proszę, przestań. Bardzo rzadko jest to potrzebne w przypadku standardowego tworzenia aplikacji desktopowych.


Jak Remy wskazuje, twoja DestroyWnd jest niepoprawna. Niszczycie uchwyt okna przed wywołaniem DragAcceptFiles. Po prostu odwróć zamówienie. Osobiście użyłbym WindowHandle zarówno w CreateWnd jak i DestroyWnd. Właściwość Handle tworzy uchwyt okna, jeśli nie jest ona przypisana, i dlatego maskuje takie błędy.

procedure TForm1.CreateWnd; 
begin 
    inherited; 
    DragAcceptFiles(WindowHandle, True); 
end; 

procedure TForm1.DestroyWnd; 
begin 
    DragAcceptFiles(WindowHandle, false); 
    inherited; 
end; 
+0

To było prawdopodobnie to. Dzięki stary :) –

Powiązane problemy