Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi [NonVCL] Problem WndProc; Pointer mit Daten füllen (https://www.delphipraxis.net/167129-%5Bnonvcl%5D-problem-wndproc%3B-pointer-mit-daten-fuellen.html)

NickelM 14. Mär 2012 14:56

[NonVCL] Problem WndProc; Pointer mit Daten füllen
 
Hallo zusammen,

Ich bin gerade dabei ein Plugin für TS3 in Delphi zuschreiben. Die Funktionen und so funken nach langen entlich. Nun wollte ich folgendes machen:
- Eigene Window-Message wo ich dem lparam einen PAnsiChar übergebe.
- Die SendMessageA (wegen AnsiChar, da ich einen AniString in UTF-8-Encoding verschicke) von der Plugin-DLL aufrufen und ausgeben.

So also was ich festgestellt habe ist, dass ich irgendwas falsch mache beim füllen der Daten in meiner WndProc. Gibt es irgendeine spezielle Funktion zum Speichern in einen Pointer bei der WndProc oder steh ich einfach aufm Schlauch?

Hier der Code:
Delphi-Quellcode:
//WndProc der Anwendung
function WndMainProc(hWnd: HWND; uMsg: UINT; wParam: wParam; lParam: LParam):
  lresult; stdcall;
var Text : AnsiString;
begin
  Result := 0;
  case uMsg of
  //.....
    WM_MUSIKBOT_PLAY:
    begin
      Text:= UTF8Encode(StreamList.Names[wParam]); //Der Wert existiert
      StrPLCopy(PAnsiChar(lParam),Text,50);
      //Move(Text[1],Pointer(lParam)^,50); //dies hab ich auch versucht geht auch nicht      
    end;
  end;
end;
//Aufruf aus der Plugin-DLL.
var
StreamName : array [0..50] of AnsiChar;
begin
   //SendMessageA(WindowH,WM_GETTEXT,50,Integer(@StreamName)); //Lustig hier ist, das dies geht
  SendMessageA(WindowH,WM_MUSIKBOT_PLAY,0,Integer(@StreamName)); //der wParam wird hier für etwas anderes genutz und das Resultat wird nur für Errors verwendet
  //Ausgeben
end;
Wenn ich mir vorm beenden der Funktion in der WndProc, lParam zu einem PAnsiChar caste,bekomme ich den richtigen Text. Was mach ich falsch? Verstehs net.
Wenn ich eine "fertige" Windows-Message nehme geht es. Also muss es irgendwie an der WndProc liegen.

Gruß
NickelM

Luckie 14. Mär 2012 15:09

AW: [NonVCL] Problem WndProc; Pointer mit Daten füllen
 
Weißt du eigentlich, was du da machst? Die DLL schickt deinem Programm eine Nachricht mit einer Zeichenfolge im LParam. Du empfängst diese Nachricht in deiner WndProc. Dort weißt du den Inhalt des WParam der AnsiString Variable Text zu. Dann kopierst du den Text in den Parameter der WndProc. Zum einen macht das keinen Sinn. Und zum Anderen ist LParam vom Typ DWord. Es wird also mit der Zeichenkette nichts anfangen können.

Aber die Frage ist, was willst du eigentlich machen?

Blup 14. Mär 2012 15:26

AW: [NonVCL] Problem WndProc; Pointer mit Daten füllen
 
Zitat:

Zitat von Luckie (Beitrag 1156561)
Dort weißt du den Inhalt des WParam der AnsiString Variable Text zu.

Da WParam = 0, weist er der Variablen "Text" "StreamList.Names[0]" zu.
Zitat:

Zitat von Luckie (Beitrag 1156561)
Dann kopierst du den Text in den Parameter der WndProc. Zum einen macht das keinen Sinn. Und zum Anderen ist LParam vom Typ DWord. Es wird also mit der Zeichenkette nichts anfangen können.

Da LParam einen Zeiger auf die Variable StreamName beinhalted, überschreibt er so den Inhalt dieser Variable mit dem Inhalt aus "Text".

Edit:
So kann das aber nur innerhalb einer Anwendung funktionieren, da jede Anwendung ihren eigenen Adressraum hat.
Datenaustausch zwischen verschiedenen Anwendungen ist z.B. mit WM_COPYDATA möglich.

NickelM 14. Mär 2012 15:36

AW: [NonVCL] Problem WndProc; Pointer mit Daten füllen
 
@Blup: WParam wird manchmal als Index verwendet, falls er höher ist als 0. Bei 0 leg ich den Index anders fest, aber das ist nicht das Prob, da trotzdem die Variable Text gefüllt wird. Sonst hast du völlig Recht. Nach meiner Kenntniss sollte es funken, aber dies tut es ja nicht :-D.

EDIT: Doffe Frage, kann es sein, das ich erst irgendwie meiner WndProc (z.b. dem Programm) Rechte geben muss um auf den Speicher von der DLL-Variable zuzugreifen? Anscheinend macht die normale WndProc noch irgendwas, um in den Speicherbereich von der Variablen schreiben zukönnen. Oder irre ich da?

NickelM 14. Mär 2012 17:26

AW: [NonVCL] Problem WndProc; Pointer mit Daten füllen
 
Das habe ich mir auch schon gedacht. Aber warum funkt dann
Delphi-Quellcode:
SendMessageA(WindowH,WM_GETTEXT,50,Integer(@StreamName)
?
WindowH wird doch, wie ich Windows kenne, auch ein Pointer auf irgendein Speicher sein. Weil das liesst ja von der anderen Anwendung den Fenster-Titel aus. Oder liegt das in einer Art Globalen Windows Speicher?
Naja, ich versuch mal ob ich das mit WM_COPYDATA irgendwie hinbekomme, was ich möchte.
Würd mich troztdem interessieren warum die oben genannte Zeile funkt. Die müsste eigentlich ja dan auch nicht funktionieren.:gruebel:

himitsu 14. Mär 2012 18:09

AW: [NonVCL] Problem WndProc; Pointer mit Daten füllen
 
Njain, Handle haben nichts mit Pointern zu tun. (auch wenn einige weniger Handle aktuell intern als Pointer verwaltet werden, wie z.B. das Handle von geladenen Modulen, wie DLLs)

Stell die Handle eher als Index in einer Liste vor.

Bei Messages wie WM_TEXT haben die Parameter eine vorgegebene Funktion, bzw. ein definiertes Datenformat, welches Windows kennt.
Demnach kann Windows dort auch den entsprechenden Speicher kopieren, wenn er in ein anderes Programm rüber muß.
Bei WM_COPYDATA wird ebenfalls angegeben wie und wo Daten liegen und Windows kann sich ebenfalls um das Kopieren kümmern.

Ansonsten (vorallem bei eigenen Messages) kann man eben nur Integer übergeben.
Oder Anderes, welches als global eindeutiger Wert darin übergeben werden kann. (z.B. globale Handle)

NickelM 14. Mär 2012 21:28

AW: [NonVCL] Problem WndProc; Pointer mit Daten füllen
 
Hm...also gibt es keine Möglichkeit auser WM_COPYDATA, irgendeine Variable zuerzeugen, egal ob Handle oder Pointer, die ich per SendMessage von der Plugin-DLL an die Anwendung übergeben kann um dort wieder auf meine Daten, die ich irgendwo hinterlegt habe, von 2 verschiedene Anwendungen drauf zugreifen kann?
Ich hab schon viel von Pipes gehört usw. , aber wie gesagt nur gehört. Ob das damit geht, weis ich auch nicht. Hab grad nen bischen mit GlobalAlloc und VirtualAlloc getestet, auch bei GlobalAlloc, den Handle an die andere übergeben, kein Unterschied. Ich werde wohl schauen müssen, ob ich irgendwie eine MessageLoop mit einem "unsichtbaren" Fenster in der DLL erzeuge und hoffen, dass ich dan mit WM_COPYDATA die Daten rüberbekomme.

Gruß
NickelM

himitsu 14. Mär 2012 22:44

AW: [NonVCL] Problem WndProc; Pointer mit Daten füllen
 
'ne Pipe ist wie eine Datei ... also eine Art Dateihandle und da diese Prozessgebunden sind, müßtest du bei Übergabe dieses Handle klonen.
Da der Empfänger den Sender nicht kennt und der Kloner das Recht benitzten muß das gewünschte Handle überhaupt klonen zu dürfen, wäre es vermutlich einfacher das Handle gleich beim Sender zu klonen, passend für den Zielprozess.
Oder MMF (Memory Mapped Files).

Tipp: IPC wäre das Thema, worüber du dich informieren solltest.

Bummi 14. Mär 2012 22:54

AW: [NonVCL] Problem WndProc; Pointer mit Daten füllen
 
falls Du Dich mit Pipes beschäftigen möchtest gibt es von Russell nette freie Komponenten, ich habe sie allerdings mittlerweile massiv erweitert und angepasst, der einzige Links den ich auf die Schnelle finden konnte:

http://r3code.livejournal.com/117012.html
http://micksmix.wordpress.com/2011/0...it-for-delphi/

Luckie 14. Mär 2012 23:00

AW: [NonVCL] Problem WndProc; Pointer mit Daten füllen
 
Zitat:

Zitat von Blup (Beitrag 1156569)
Da LParam einen Zeiger auf die Variable StreamName beinhalted, überschreibt er so den Inhalt dieser Variable mit dem Inhalt aus "Text".

Ja, OK, das stimmt. Aber mich verwirrt, was er damit erreichen will. Ich dachte er wollte an die Zeichenkette kommen, die auf die er im LParam einen Zeiger hat. Das Problem ist, um es noch mal deutlich zu machen, dass Zeiger nicht über Prozessgrenzen gültig sind. Es gibt ausnahmen. Bei WM_TEXT mapped Windows den Speicherbereich in einen Speicherbereich der für beide Prozesse gültig ist, so dass das mit den Zeigern funktioniert. Das sind noch Überbleibsel aus 16-Bit Windows Zeiten, als es noch keine getrennten Speicherbereiche gab. Bei WM_COPYDATA verfährt Windows ähnlich. Allerdings handelt es sich dabei um eine Fensternachricht, so dass zumindest der Empfänger ein Fenster sein muss. Ob auch der Thread von dem die Nachricht verschickt wird zu einem Fenster gehören muss, weiß ich jetzt nicht, aber man könnte es mal probieren, ob es auch ohne Fenster geht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:28 Uhr.
Seite 1 von 2  1 2      

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