AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Text (Pfadangabe) per Windows Message verschicken
Thema durchsuchen
Ansicht
Themen-Optionen

Text (Pfadangabe) per Windows Message verschicken

Ein Thema von lbccaleb · begonnen am 7. Mai 2009 · letzter Beitrag vom 17. Mai 2009
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.052 Beiträge
 
Delphi 12 Athens
 
#11

Re: Text (Pfadangabe) per Windows Message verschicken

  Alt 8. Mai 2009, 10:17
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:
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;
PS: hiermit INTEGER(dataptr^) versendest du nur die ersten 4 Byte direkt im Parameter.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von lbccaleb
lbccaleb

Registriert seit: 25. Mai 2006
Ort: Rostock / Bremen
2.037 Beiträge
 
Delphi 7 Enterprise
 
#12

Re: Text (Pfadangabe) per Windows Message verschicken

  Alt 8. Mai 2009, 14:22
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
Martin
MFG Caleb
TheSmallOne (MediaPlayer)
Die Dinge werden berechenbar, wenn man die Natur einer Sache durchschaut hat (Blade)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.052 Beiträge
 
Delphi 12 Athens
 
#13

Re: Text (Pfadangabe) per Windows Message verschicken

  Alt 8. Mai 2009, 14:31
Einfach so mit einem Pointer geht das nicht ... wie auch, da beide Programme ihren eigenen virtuellen Arbeitsspeicher haben.


Delphi-Quellcode:
DataPtr := GlobalLock(wParam);
try
  s := PChar(DataPtr); // oder sonstwas
finally
  GlobalUnlock(wParam);
end;
mit GloablAlloc wird Speicher außerhalb deiner Anwendung reserviert
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.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von lbccaleb
lbccaleb

Registriert seit: 25. Mai 2006
Ort: Rostock / Bremen
2.037 Beiträge
 
Delphi 7 Enterprise
 
#14

Re: Text (Pfadangabe) per Windows Message verschicken

  Alt 8. Mai 2009, 14:44
Erstmal danke für deine Erklärung

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:
    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;
Aber ich bekomme schon wieder nur 3x Cryptisches Zeug angezeigt??

Das aber ne schwere Geburt mit mir und GlobalAlloc
Martin
MFG Caleb
TheSmallOne (MediaPlayer)
Die Dinge werden berechenbar, wenn man die Natur einer Sache durchschaut hat (Blade)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.052 Beiträge
 
Delphi 12 Athens
 
#15

Re: Text (Pfadangabe) per Windows Message verschicken

  Alt 8. Mai 2009, 14:49
Zitat von lbccaleb:
Achja, ist PostMessage in dem Fall nicht besser als SendMessage in deinem Code?
nee, SendMessage wertet, bis das andere Programm fertig ist
und das hab ich hier mal ausgenutzt, damit die Speicher reservierung und Freigabe in einer Hand (Programm) bleibt.

Delphi-Quellcode:
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};
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)
Delphi-Quellcode:
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};
und die andere Seite hatte ich ja schon geschrieben
Delphi-Quellcode:
DataPtr := GlobalLock(wParam);
If DataPtr = nil Then Begin
  Try
    s := PChar(DataPtr); // oder sonstwas
  Finally
    GlobalUnlock(wParam);
  End;
End Else {Fehler};
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Tyrael Y.

Registriert seit: 28. Jul 2003
Ort: Stuttgart
1.093 Beiträge
 
Delphi 2007 Professional
 
#16

Re: Text (Pfadangabe) per Windows Message verschicken

  Alt 8. Mai 2009, 15:07
Zitat von himitsu:
nee, SendMessage wertet, bis das andere Programm fertig ist
und das hab ich hier mal ausgenutzt, damit die Speicher reservierung und Freigabe in einer Hand (Programm) bleibt.
SendMessage wartet auf den Empfang der WindowMessage.
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:
Programm_A -> Daten -> Programm B
Programm_A hält Variable im Speicher
ProgrammB Verarbeitung();
ProgrammB -> Nachricht über Ende -> Programm A gibt Variable frei
Levent Yildirim
Erzeugung von Icons aus Bildern:IconLev
  Mit Zitat antworten Zitat
Benutzerbild von lbccaleb
lbccaleb

Registriert seit: 25. Mai 2006
Ort: Rostock / Bremen
2.037 Beiträge
 
Delphi 7 Enterprise
 
#17

Re: Text (Pfadangabe) per Windows Message verschicken

  Alt 16. Mai 2009, 19:18
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:
If DataPtr = nil Then Begin
  Try
    s := PChar(DataPtr); // oder sonstwas
  Finally
    GlobalUnlock(wParam);
  End;
Wieso soll der Ptr nil sein?? muss der nicht auf ne Addresse zeigen?
Martin
MFG Caleb
TheSmallOne (MediaPlayer)
Die Dinge werden berechenbar, wenn man die Natur einer Sache durchschaut hat (Blade)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.052 Beiträge
 
Delphi 12 Athens
 
#18

Re: Text (Pfadangabe) per Windows Message verschicken

  Alt 16. Mai 2009, 19:24
ups ... <> nil natürlich

im Fehlerfall liefert GlobalLock ein NIL zurück.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von lbccaleb
lbccaleb

Registriert seit: 25. Mai 2006
Ort: Rostock / Bremen
2.037 Beiträge
 
Delphi 7 Enterprise
 
#19

Re: Text (Pfadangabe) per Windows Message verschicken

  Alt 16. Mai 2009, 19:31
OK, aber wenn ich auf ungleichheit Prüfe kommt bei mir der Fehler, also ist GlobalLock fehlgeschlagen, aber wieso??


Meine Funktionen:

Senden:
Delphi-Quellcode:
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;
Empfangen:
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:
    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;
initialization abschnitt von der Anwendung:
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
Martin
MFG Caleb
TheSmallOne (MediaPlayer)
Die Dinge werden berechenbar, wenn man die Natur einer Sache durchschaut hat (Blade)
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#20

Re: Text (Pfadangabe) per Windows Message verschicken

  Alt 17. Mai 2009, 01:03
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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:25 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz