![]() |
Demo für ShellExtension - brauche noch Hilfe
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,
ich möchte gern eine Demo für eine Shellextension erstellen, also eine DLL, die wiederum ein Testprogramm aufruft, dem mehrere, markierte, Dateien gleichzeitig, also als Liste, übergeben werden können. Nach viel gehampel mit dem Delphi beiliegenden Demo und viel Suche, bin ich, denke ich, schon mal auf dem richtigen Weg. Aber ich habe, im Moment, zwei fragen: 1. kann man ein TstringList-Objekt via WM_COPYDATA übergeben? 2. kann man das finden des Handles, an das die Messag egeschickt wird, eleganter lösen?
Delphi-Quellcode:
Wer das ganze schonmal testen will, bitte, erstmal, die dll mittels regsvr32 registrieren, und dann auf eine, oder mehrere, .pas-Dateien klicken.
// beim Sender:
function TContextMenu.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; function EnumWindowsProc(hWnd: HWND; lParam: LPARAM): BOOL; stdcall; begin TList(lParam).Add(Pointer(hWnd)); Result := True; end; var SI: TStartupInfo; PI: TProcessInformation; List: TList; ProcessId: DWORD; AppHWnd: HWND; I: Integer; cds: TCopyDataStruct; begin Result := E_FAIL; // Make sure we are not being called by an application if (HiWord(Integer(lpici.lpVerb)) <> 0) then begin Exit; end; // Make sure we aren't being passed an invalid argument number if (LoWord(lpici.lpVerb) <> 0) then begin Result := E_INVALIDARG; Exit; end; AppHWnd := 0; FillChar(SI, SizeOf(TStartupInfo), 0); SI.cb := SizeOf(TStartupInfo); SI.dwFlags := STARTF_USESHOWWINDOW; SI.wShowWindow := lpici.nShow; if CreateProcess( nil, // Application name pChar(GetCompilerPath), // commandline nil, nil, False, 0, nil, nil, SI, PI) then begin WaitForInputIdle(PI.hProcess, INFINITE); CloseHandle(PI.hProcess); CloseHandle(PI.hThread); List := TList.Create; try if EnumWindows(@EnumWindowsProc, Longint(List)) then begin for I := 0 to List.Count - 1 do if GetWindowThreadProcessId(HWND(List.Items[I]), @ProcessId) <> 0 then if ProcessId = PI.dwProcessId then begin AppHWnd := HWND(List.Items[I]); Break; end; if IsWindow(AppHWnd) then begin cds.dwData := 0; cds.cbData := SizeOf (fFileNames); cds.lpData := @fFileNames; SendMessage (AppHwnd, WM_COPYDATA, longint(AppHwnd), longint(@cds)); end; end; finally List.Free; end; result := NOERROR; end else ShowMessage ('Something wrong!'); end; // beim empfänger procedure TMainForm.WMCOPYDATA(var Msg: TWMCopyData); var l: tStringList; i: integer; begin Memo1.Lines.Add ('copy data called!'); l := TStringList(msg.CopyDataStruct.LPData); for i := 0 to l.count -1 do Memo1.Lines.Add (l[i]); end; Viele Grüße Marco |
Re: Demo für ShellExtension - brauche noch Hilfe
Objekte kannst du per WM_COPYDATA nicht ohne ziemich viel Gehampel verschicken. Bei der TStringList genügt es aber, wenn du einfach den ganzen String verschickst, also alle Einträge der Stringliste mit Zeilenumbrüchen zusammengehängt (Eigenschaft Text). Auf der Empfangsseite kannst du dann einfach die Eigenschaft Text einer neuen Liste auf den empfangenen String setzen.
Bezüglich der zweiten Frage: Ich würde einfach mit RegisterWindowMessage eine eigene Nachricht registrieren und dann mit HWND_BROADCAST an alle Fenster schicken. |
Re: Demo für ShellExtension - brauche noch Hilfe
Zitat:
Viele Grüße Marco |
Re: Demo für ShellExtension - brauche noch Hilfe
Der Punkt an RegisterWindowMessage ist doch, dass der gleiche String den gleichen Rückgabewert erzeugt. In beiden Programmen rufst du also RegisterWindowMessage('Meine Shellextension') auf und erhältst den gleichen Nachrichtencode.
Diese Nachricht kannst du nutzen, um aus deinem Zielprogramm ein Handle an das Senderprogramm zu schicken, sodass das Senderprogramm wiederum WM_COPYDATA schicken kann. Startest du eigentlich immer das Zielprogramm selbst? Dann kannst du doch gleich über die Kommandozeile gehen: Einfach direkt den String oder aber ein Fensterhandle bzw. Pipehandle übergeben. Man muss es sich ja nicht unnötig schwierig machen. Edit: In der DLL ist es natürlich etwas schwierig mit RegisterWindowMessage, da dafür ein Fenster und eine Nachrichtenschleife nötig sind. Mal wieder zu kurz gedacht. |
Re: Demo für ShellExtension - brauche noch Hilfe
Hallo zusammen,
Dank eurer Hilfe gibt’s jetzt eine Lauffähige Version, siehe 1. Post. Ich habe das Demo insofern erweitert, als daß jetzt nur noch eine Instanz auf einmal laufen darf. aber: Meine Anwendung wird von der DLL gestartet – stellt fest, daß sie schon läuft, und beendet sich gleich wieder. Eigentlich würde die DLL gern die Message, wo sich die zu kopierenden Daten befinden, also WM_COPYDATA noch an mein Programm schicken, aber das ist schon weg. *lach Ich stehe, gedanklich, im moment ein bißchen auf dem Schlauch. Kann mir da mal bitte jemand runterhelfen? Muß ich das Handle der ersten Instanz rauskriegen, oder wie? hä? Viele Grüße Marco |
Re: Demo für ShellExtension - brauche noch Hilfe
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Zusammen,
so. Jetzt ist sie fertig, lauffähig und enthält, soweit ich sehen kann, keine Fehler mehr. Die Unit InstanceManager Autor: Evan Simpson - esimpson@eramp.net Veröffentlicht in ![]() ist hier, allerdings in veränderter Form zum Einsatz gekommen. Das Testprogramm kann direkt mit Kommandozeile gefüttert werden, auch Parameter wie „ich bin ein Dateiname.doc“ funktionieren, oder, mittels kontextmenü, über die beigefügte DLL zur Shell Extension. Wer Fragen, Anregungen, Verbesserungsvorschläge hat, immer her damit. Und jetzt wünsche ich allen, die das nie finden konnten, viel Spaß damit! Viele Grüße Marco |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz