![]() |
Re: Text (Pfadangabe) per Windows Message verschicken
ich würd es am Einfachsten so machen ... auf jedenfall mußt du data verschicken, der andere Prozess holt sich dann über diesen globalen Wert in data selber per GlobalLock die Daten in seinen Arbeitsspeicher und kann dann daraus lesen.
Delphi-Quellcode:
PS: hiermit INTEGER(dataptr^) versendest du nur die ersten 4 Byte direkt im Parameter.
Data := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, Size);
try DataPtr := GlobalLock(Data); try CopyMemory(DataPtr, PChar(aText), Size); finally GlobalUnlock(Data); end; SendMessage(aWnd, WM_TSOPLAYFILE, data, 0); finally GlobalFree(Data); end; |
Re: Text (Pfadangabe) per Windows Message verschicken
Ich dachte ich kann die Daten dann in der Message des Empfängers einfach per Pointer auslesen! Muss ich dort auch mit GlobalAlloc arbeiten?
Im Empänger sieht es so aus:
Delphi-Quellcode:
var
MSGFile: PChar; WM_TSOPLAYFILE: begin; MSGFile := PChar(@wParam); MessageBox(0, MSGFile, 'param', MB_OK or MB_ICONWARNING); //mit deinem Code bekomme ich jetzt hier eine endlos lange Message... if FileExists(MSGFile) then begin; PostMessage(HWND_TOPMOST, WM_COMMAND, MAKELONG(IDC_BMPBUTTON2, BN_CLICKED), 0); if Succeeded(CheckFile(MSGFile)) then PostMessage(HWND_TOPMOST, WM_COMMAND, MAKELONG(IDC_BMPBUTTON1, BN_CLICKED), 0) end; end; Wie muss das hier aussehen? Also wie lese ich den Speicher mit GlobalAlloc? Edit: Achja, ist PostMessage in dem Fall nicht besser als SendMessage in deinem Code? @himitsu |
Re: Text (Pfadangabe) per Windows Message verschicken
Einfach so mit einem Pointer geht das nicht ... wie auch, da beide Programme ihren eigenen virtuellen Arbeitsspeicher haben.
Delphi-Quellcode:
mit GloablAlloc wird Speicher außerhalb deiner Anwendung reserviert
DataPtr := GlobalLock(wParam);
try s := PChar(DataPtr); // oder sonstwas finally GlobalUnlock(wParam); end; und mit GlobalLock wird dieser Speicher in den Adreßraum deiner Anwendung verschoben danach mit GlobalUnlock wieder aus dem Adreßraum deiner anwendung entfernt und nun kann sich die andere Anwendung diesen Speicher auch mal in ihren Adreßraum legen und diesen so auslesen. |
Re: Text (Pfadangabe) per Windows Message verschicken
Erstmal danke für deine Erklärung :thumb:
Hab das ganze nun erstmal wieder in eine Funktion gepackt, die es dann auslesen soll (sonnst seh ich bald gar nicht mehr durch^^)
Delphi-Quellcode:
function GetAllocFileName(wParam: WPARAM): PChar;
var DataPtr: Pointer; begin; Result := ''; DataPtr := GlobalLock(wParam); try Result := PChar(DataPtr); // oder sonstwas finally GlobalUnlock(wParam); end; end;
Delphi-Quellcode:
Aber ich bekomme schon wieder nur 3x Cryptisches Zeug angezeigt??
WM_TSOPLAYFILE:
begin; MSGFile := GetAllocFileName(wParam);//PChar(@wParam); MessageBox(0, MSGFile, 'param', MB_OK or MB_ICONWARNING); if FileExists(MSGFile) then begin; PostMessage(HWND_TOPMOST, WM_COMMAND, MAKELONG(IDC_BMPBUTTON2, BN_CLICKED), 0); if Succeeded(CheckFile(MSGFile)) then PostMessage(HWND_TOPMOST, WM_COMMAND, MAKELONG(IDC_BMPBUTTON1, BN_CLICKED), 0) end; end; Das aber ne schwere Geburt mit mir und GlobalAlloc :lol: |
Re: Text (Pfadangabe) per Windows Message verschicken
Zitat:
und das hab ich hier mal ausgenutzt, damit die Speicher reservierung und Freigabe in einer Hand (Programm) bleibt.
Delphi-Quellcode:
da die Speicherverwaltung des Strings aber Delphi übernimmt und PChar intern für einen vorhandenen Speicher sorgt, kann eigentlich keine Exception entstehen (es sei den du hast irgendwo anders ein großes Problem)
Data := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, Size);
If Data <> 0 Then Begin Try DataPtr := GlobalLock(Data); If DataPtr <> nil Then Begin Try CopyMemory(DataPtr, PChar(aText), Size); If SendMessage(aWnd, WM_TSOPLAYFILE, Data, 0) = 0 Then {Fehler}; Finally GlobalUnlock(Data); End; End Else {Fehler}; Finally GlobalFree(Data); End; End Else {Fehler};
Delphi-Quellcode:
und die andere Seite hatte ich ja schon geschrieben
Data := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, Length(aText) + 1);
If Data <> 0 Then Begin DataPtr := GlobalLock(Data); If DataPtr <> nil Then Begin CopyMemory(DataPtr, PChar(aText), Length(aText) + 1); If SendMessage(aWnd, WM_TSOPLAYFILE, Data, 0) = 0 Then {Fehler}; GlobalUnlock(Data); End Else {Fehler}; GlobalFree(Data); End Else {Fehler};
Delphi-Quellcode:
DataPtr := GlobalLock(wParam);
If DataPtr = nil Then Begin Try s := PChar(DataPtr); // oder sonstwas Finally GlobalUnlock(wParam); End; End Else {Fehler}; |
Re: Text (Pfadangabe) per Windows Message verschicken
Zitat:
Eine WindowMessage gilt als empfangen, wenn die WndProc des Empgängers verlassen wurde. Eine Verarbeitung im WndProc ist daher sehr bedenklich, da das andere Programm solange blockiert wird. Besser wäre die Variable im anderen Programm solange gültig zu halten bis eine "Verarbeitung-Beendet" Message zurück kommt. Zitat:
|
Re: Text (Pfadangabe) per Windows Message verschicken
Sorry, ist schon ne Weile her, hatte aber nicht viel Zeit :(
Aufjedenfall habe ich immer noch das Problem, das nichts ankommt, sieht vllt irgendjemand noch nen Fehler?? Ich bin schon tierisch am Verzweifeln :( und das verstehe ich auch nicht so:
Delphi-Quellcode:
Wieso soll der Ptr nil sein?? muss der nicht auf ne Addresse zeigen?
If DataPtr = nil Then Begin
Try s := PChar(DataPtr); // oder sonstwas Finally GlobalUnlock(wParam); End; |
Re: Text (Pfadangabe) per Windows Message verschicken
ups ... <> nil natürlich :oops:
im Fehlerfall liefert GlobalLock ein NIL zurück. |
Re: Text (Pfadangabe) per Windows Message verschicken
OK, aber wenn ich auf ungleichheit Prüfe kommt bei mir der Fehler, also ist GlobalLock fehlgeschlagen, aber wieso??
Meine Funktionen: Senden:
Delphi-Quellcode:
Empfangen:
procedure GlobalAllocFileName(aWnd: HWND; aText: String);
var Data: THandle; DataPtr: Pointer; Size: Integer; oldWND: HWND; begin { Size := Length(aText) + 1; Data := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, Size); try DataPtr := GlobalLock(Data); try CopyMemory(DataPtr, PChar(aText), Size); finally GlobalUnlock(Data); end; SendMessage(aWnd, WM_TSOPLAYFILE, data, 0); finally GlobalFree(Data); end; } Data := GlobalAlloc({GMEM_MOVEABLE or GMEM_DDESHARE}GHND, Length(aText) + 1); If Data <> 0 Then Begin DataPtr := GlobalLock(Data); If DataPtr <> nil Then Begin CopyMemory(DataPtr, PChar(aText), Length(aText) + 1); If SendMessage(aWnd, WM_TSOPLAYFILE, Data, 0) = 0 Then {Fehler} begin MessageBox(0, 'senden fehlgeschlagen', 'fehler', MB_OK or MB_ICONWARNING); GlobalUnlock(Data); end; End Else {Fehler} MessageBox(0, 'dataptr leer', 'fehler', MB_OK or MB_ICONWARNING); GlobalFree(Data); End Else {Fehler} MessageBox(0, 'data leer', 'fehler', MB_OK or MB_ICONWARNING); end;
Delphi-Quellcode:
function GetAllocFileName(wParam: WPARAM): PChar; //wparam ist nicht 0
var DataPtr: Pointer; begin; Result := ''; DataPtr := GlobalLock(wParam); //aber hier gibts nen "nil" ich vermute das hier irgendwo mein Fehler steckt If DataPtr <> nil Then Begin Try Result := PChar(DataPtr); // oder sonstwas MessageBox(0, 'get - pointer nil', 'fehler', MB_OK or MB_ICONWARNING); Finally GlobalUnlock(wParam); End; End Else {Fehler} MessageBox(0, 'get - dataptr leer', 'fehler', MB_OK or MB_ICONWARNING); end; Nachrichtenschleife vom Hauptprogramm:
Delphi-Quellcode:
initialization abschnitt von der Anwendung:
WM_TSOPLAYFILE:
begin; MSGFile := GetAllocFileName(wParam);//PChar(@wParam); MessageBox(0, MSGFile, 'param', MB_OK or MB_ICONWARNING); if FileExists(MSGFile) then begin; PostMessage(HWND_TOPMOST, WM_COMMAND, MAKELONG(IDC_BMPBUTTON2, BN_CLICKED), 0); if Succeeded(CheckFile(MSGFile)) then PostMessage(HWND_TOPMOST, WM_COMMAND, MAKELONG(IDC_BMPBUTTON1, BN_CLICKED), 0) end; Result := 1; end;
Delphi-Quellcode:
initialization
begin; if paramcount > 0 then Param := paramstr(1); tMutex := CreateMutex(nil, True, ClassName); if GetLastError = ERROR_ALREADY_EXISTS then begin; if fileexists(Param) then begin; if (FindWindow(ClassName, AppName) > 0) then GlobalAllocFileName(FindWindow(ClassName, AppName), Param) // PostMessage(FindWindow(ClassName, AppName), WM_TSOPLAYFILE, INTEGER(@Param), 0) end else MessageBox(0, 'The Program is already running.', ClassName, MB_OK or MB_ICONWARNING); Halt; end; end; Sorry für nen bissel viel Code :) |
Re: Text (Pfadangabe) per Windows Message verschicken
Dein Problem derzeit ist, dass der Sender den Speicher noch immer gelockt hat. Du hast derzeit beim Sender folgenden Ablauf:
1. Speicher alloziieren 2. Speicher locken, Pointer holen 3. Speicher befüllen (Pointer beschreiben) 4. Nachricht versenden mit dem Handle von 1. 5. Speicher unlocken 6. Speicher freigeben. Wenn du an Stelle 4. bist, dann empfängt dieser das Handle von 1. und versucht nun ebenfalls mit GlocalLock ein exklusiven Lock zu bekommen, was ihm aber von Windows verwehrt wird, da das Handle derzeit von deinem Sender noch gelockt ist. Also, der korrekte Ablauf sollte anhand der Nummerierung von zuvor wie folgt sein: 1., 2., 3., 5., 4., 6. Also vorher unlocken, nur im ungelockten Zustand kann Windows den speicher virtuell zwischen den Prozessen verschieben. So lange einer den glockt hat, hat er den Finger drauf und Windows ist machtlos. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:57 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