Autor |
Beitrag |
hazelnoot
      
Beiträge: 27
|
Verfasst: Do 03.08.06 14:13
hi!
wie kann ich eine message von einem programm in ein anderes schicken? OHNE gui? wie geht das danke!
mfg hazelnoot
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 03.08.06 14:36
Um Window Messages zu verschicken, musst dein Empfänger mindestens ein solches Window haben. Das muss nicht zwangsläufig ein sichtbares Fenster sein, aber das Handle eines solchen benötigst Du ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
hazelnoot 
      
Beiträge: 27
|
Verfasst: Do 03.08.06 14:58
wie bekomm ich so ein handle hin ohne einer form? wie mache ich das...?
danke fuer eure hilfe mfg
hazelnoot!
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Do 03.08.06 15:16
Am einfachsten geht das mit der Funktion AllocateHWnd. Für Details siehe Delphi-Hilfe...
Gruß, Motzi
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
hazelnoot 
      
Beiträge: 27
|
Verfasst: Do 03.08.06 15:25
koennt ihr mir nicht einen beispielcode zeigen wie sowas funken koennte?
mit window handle erstellen ohne form!!!!
bidde bidde
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Do 03.08.06 15:30
Ich hab dir doch eh schon eine Funktion genannt. Mit der geht das mit einem einfachen Aufruf und Details findest du wie gesagt in der Delphi-Hilfe. Ein bisschen mehr Eigentinitiative könntest du schon an den Tag legen..
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
ManniTwo
      
Beiträge: 46
Win XP SP III, Ubuntu 8.04, Debian 5.0
Delphi 5 Pro; Delphi 2005; C++,C# (VS 2005); Java, Ruby (Eclipse)
|
Verfasst: Do 03.08.06 15:33
aus Interesse hab ich mal bei AllocateHWND nachgeschaut und in meiner Delphi-Hilfe (2005) hab ich es auch nicht gefunden, deshalb hier noch ein Link mit etwas Beispiel-Code, du musst nur ein paar Worte englisch verstehen, aber ich denke das ist machbar
delphi.about.com/od/...lapi/l/aa093003b.htm
_________________ Wer andern eine Bratwurst brät, der hat ein Bratwurst-Brat-Gerät, oder anders:
Delphi-Quelltext 1:
| if Self.BraetAndernEineBratwurst then Self.HasBratwurstBratGeraet := true; |
|
|
hazelnoot 
      
Beiträge: 27
|
Verfasst: Do 03.08.06 15:38
aber ich versteh eins nicht waenn ich mit der funktion ein neues HWND erzeuge wie kann ich dann dieses zur kommunikation hernehmen? wie muss ich es einrichten damit ich das handle dann angeben kann beim sender der message?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| unit Unit1;
interface uses Classes, Graphics, Controls, Forms, Dialogs, Windows, StdCtrls, ExtCtrls;
type testClass = class(TObject) windowHandle : HWND;
procedure createHandle(); procedure doZeugs(Sender: TObject); end;
implementation procedure testClass.createHandle(); begin windowHandle := AllocateHWnd(doZeugs); end;
procedure testClass.doZeugs(Sender: TObject); begin
end; end. |
soweit bin ich schon aber ich weis einfach nicht was ein TWndMethod ist was ich der AllocateHWnd mitgeben soll... weis jemand was das fuer ein argument ist... waenn dann das argument dann stimmt kann ich das windowHandle dann beim sender angeben? oder muss ich dann nochwas machen?
danke fuer eure hilfe
mfg hazelnoot!
|
|
ManniTwo
      
Beiträge: 46
Win XP SP III, Ubuntu 8.04, Debian 5.0
Delphi 5 Pro; Delphi 2005; C++,C# (VS 2005); Java, Ruby (Eclipse)
|
Verfasst: Do 03.08.06 15:47
also...
TWndMethod ist die Methode, die dann auf die empfangenen Nachrichten reagieren wird.
Deklariert in Classes:
Delphi-Quelltext 1:
| TWndMethod = procedure(var Message: TMessage) of object; |
das heißt du schreibst eine Methode, die von der Signatur so aussieht:
Delphi-Quelltext 1:
| procedure WindowsMessagesReceiver(var Message: TMesssage); |
und die reagiert dann auf die eintrudelnden Messages, aber nicht wie sonst nur auf bestimmte, sondern (siehe Quelle von dem Link vorhin)
Zitat: |
This procedure is called for each and every Windows message, so we need to filter out only those that are interesting[...] For all other messages that are not handled by our application remember to call the default Windows procedure. Even if this is not so important for our non-visible non-interactive window it is a good practice and missing this step may yield to unpredictable behaviors. |
_________________ Wer andern eine Bratwurst brät, der hat ein Bratwurst-Brat-Gerät, oder anders:
Delphi-Quelltext 1:
| if Self.BraetAndernEineBratwurst then Self.HasBratwurstBratGeraet := true; |
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Do 03.08.06 16:45
Ok, mein Fehler.. in der Delphi2005-Hilfe steht nichts zu dieser Funktion (hab auch gerade nachgeschaut). Ich hab vorher nur in der D6-Hilfe geschaut und da findet man folgendes:
Zitat: | Delphi-Quelltext 1:
| function AllocateHWnd(Method: TWndMethod): HWND; |
Description
Call AllocateHWnd to create a window that is not associated with a windowed control. Typically, this method is used to create non-visual windows that respond to messages but that do not appear in the user interface. For example, the TTimer component uses this method to create a window that responds to timer messages from Windows.
The Method parameter specifies the window procedure that the generated window uses to respond to messages.
AllocateHWnd returns the handle of the newly created window.
Note: Use the DeallocateHWnd procedure to free windows that are created using AllocateHWnd. |
TWndMethod ist ein Methodenzeiger, wie das mit diesem funktioniert hat ja schon ManniTwo erklärt...
Gruß, Motzi
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
hazelnoot 
      
Beiträge: 27
|
Verfasst: Fr 04.08.06 08:10
hi!
danke fuer eure hilfe hat mir extrem geholfen!!!! ich habe nur ein weiteres problem:
mein code bis jetzt:
der sender:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
| program Sender;
{$APPTYPE CONSOLE}
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
var data : TCopyDataStruct; test : PChar; wnd: HWND;
begin while True do begin Writeln('Um zu senden Durecken Sie enter'); Readln; Write('Sende...');
test := 'C:\Dokumente und Einstellungen\Sickinger\Desktop\Sockutil\UdpSockUtil.pas';
data.dwData := 0; data.cbData := strlen(test) + 1; data.lpData := test;
SendMessage(wnd_broadcast, WM_COPYDATA, 1, Longint(@data));
Writeln('OK'); end; end. |
und der empfaenger:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60:
| unit Unit4;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TTestThread = class(TThread) private FSignalShutdown: boolean; FWinHandle: HWND; protected procedure Execute; override; procedure WndProc(var msg: TMessage); public constructor Create; destructor Destroy; override; end;
implementation
var WM_SHUTDOWN_THREADS: Cardinal;
constructor TTestThread.Create; begin FSignalShutdown := False; FWinHandle := AllocateHWND(WndProc); inherited Create(False); end;
destructor TTestThread.Destroy; begin DeallocateHWnd(FWinHandle); inherited; end;
procedure TTestThread.Execute; begin FreeOnTerminate := True; while NOT FSignalShutdown do begin Application.HandleMessage; end; end;
procedure TTestThread.WndProc(var msg: TMessage); begin Writeln('halloasdfasdfasfdasdfadsaf'); end;
end. |
waenn ich dieses ausführe dann kommt im thread zwar die message 'halloasdfasdfasfdasdfadsaf' an, aber ich will nicht 'C:\Dokumente und Einstellungen\Sickinger\Desktop\Sockutil\UdpSockUtil.pas' einnen pfad angeben muessen ich will einen normalen text senden!!!! weiters wie kann ich den thread/windowHandler eindeutig identifizieren? mit SendMessage(wnd_broadcast, WM_COPYDATA, 1,Longint(@data)); funkt das nicht! was muss ich machen damit ein text an den thread geschickt wird und damit ich den thread eindeutig identifizieren kann!!!
danke!
|
|
ManniTwo
      
Beiträge: 46
Win XP SP III, Ubuntu 8.04, Debian 5.0
Delphi 5 Pro; Delphi 2005; C++,C# (VS 2005); Java, Ruby (Eclipse)
|
Verfasst: Fr 04.08.06 08:40
toll....super antwort hatte ich geschrieben mit Zitaten und so  , aber ich habe wohl zu lange gebraucht, da wollte er beim absenden, dass ich mich wieder einlogge und dann war die nachricht weg....naja, egal also nochma kurz:
dass 'hallo....' ankommt wundert nicht, denn das ist ja fest verdrahtet im Client-Code, muss also gar nicht ankommen. Du musst den Msg-Parameter auswerten.
Du kannst statt der Pfadangabe einen anderen Text schreiben.
Identifikation erfolgt durch das Handle, den ersten Parameter bei SendMessage.
Vielleicht einfach mit FindWindow versuchen das entsprechende Handle zu bekommen
_________________ Wer andern eine Bratwurst brät, der hat ein Bratwurst-Brat-Gerät, oder anders:
Delphi-Quelltext 1:
| if Self.BraetAndernEineBratwurst then Self.HasBratwurstBratGeraet := true; |
|
|
hazelnoot 
      
Beiträge: 27
|
Verfasst: Fr 04.08.06 08:52
danke fuer deine promte antwort!
also ich hab das nun probiert:
meine neue sendmessage im sender:
Delphi-Quelltext 1:
| SendMessage(FindWindow('FWinHandle', nil), WM_COPYDATA, 1, Longint(@data)); |
das FWinHandle deswegen wiel im empfaenger das handle so heisst:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| constructor TTestThread.Create; begin FSignalShutdown := False; FWinHandle := AllocateHWND(WndProc); inherited Create(False); end; |
es kommt aber nichts an! ich hab schon 100 andere sachen statt FWinHandle probiert auch den klassennamen usw es will einfach nicht funken! stimmt der parameter WM_COPYDATA? es muss auch nicht eine struktur sein es wuerde auch schon reichen einen einfachen text zu senden!
danke fuer eure geduld  !
mfg hazelnoot!
|
|
ManniTwo
      
Beiträge: 46
Win XP SP III, Ubuntu 8.04, Debian 5.0
Delphi 5 Pro; Delphi 2005; C++,C# (VS 2005); Java, Ruby (Eclipse)
|
Verfasst: Fr 04.08.06 09:48
Wenn man mit AllocateHWND diese "Pseudo-Fenster" erzeugt, registriert Delphi als Klassennamen 'TPUtilWindow'. Ich hab keine Ahnung wieso, jedenfalls habe ich es bei mir durchdebuggt und wenn du FindWindow('TPUtilWindow', nil) übergibst dann sollte es klappen.
[Edit] ich nehme alles zurück, da findet er dann auch ein Handle, wenn der Receiver nicht läuft. Sorry, langsam weiß ich auch net mehr...hab auch leider net die Zeit nach ner Lösung zu suchen...vielleicht am WE oder vielleicht hat bis dahin jemand anders eine gute Lösung für dein Problem[/Edit]
_________________ Wer andern eine Bratwurst brät, der hat ein Bratwurst-Brat-Gerät, oder anders:
Delphi-Quelltext 1:
| if Self.BraetAndernEineBratwurst then Self.HasBratwurstBratGeraet := true; |
|
|
hazelnoot 
      
Beiträge: 27
|
Verfasst: Fr 04.08.06 10:06
hi!
super das funkt!!
is ja egal ob er dann auch ein handle findet!!
weisst du zufaellig noch wie man dann aus "procedure TTestThread.WndProc(var msg: TMessage);" die message die ich uebergeben habe parst? das waer noch ideal dann wuerds perfekt sein!!!
danke nochmal hazelnoot!
|
|
ManniTwo
      
Beiträge: 46
Win XP SP III, Ubuntu 8.04, Debian 5.0
Delphi 5 Pro; Delphi 2005; C++,C# (VS 2005); Java, Ruby (Eclipse)
|
Verfasst: Fr 04.08.06 10:42
also grundsätzlich erhälst du ja eine TMessage
und da kommst du sicherlich über Message.lparam wieder an die Daten heran, die du da reingesteckt hast, dann musst du das da natürlich umständlich herauspulen,
ich könnte mir vorstellen, hab es aber nicht getestet, dass du die Message auch als TWMCopyData casten kannst, denn du hast ja eine WM_COPYDATA verschickt.
Delphi-Quelltext 1: 2: 3: 4: 5:
| TWMCopyData = packed record Msg: Cardinal; From: HWND; CopyDataStruct: PCopyDataStruct; Result: Longint; |
Dann kämst du ganz leicht wieder an deine CopyDataStruct und daraus über lpdata wieder an deinen text, also:
Delphi-Quelltext 1:
| TWMCopyData(Message).CopyDataStruct |
_________________ Wer andern eine Bratwurst brät, der hat ein Bratwurst-Brat-Gerät, oder anders:
Delphi-Quelltext 1:
| if Self.BraetAndernEineBratwurst then Self.HasBratwurstBratGeraet := true; |
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Fr 04.08.06 10:51
1) wozu der Thread? Die VCL ist nicht thread-safe und man sollte niemals eine Form innerhalb eines Threads (der nicht der primäre Thread ist) erzeugen und/oder benutzen!
2) es ist nicht egal ob er auch ein Fenster findet wenn dein Receiver nicht läuft, denn das bedeutet, dass es in deinem System dann mehrere Fenster mit demselben Klassennamen gibt, und in so einem Fall ist nicht vorhersehbar welches Fensterhandle FindWindow zurückliefert. Es kannt also sein, dass obwohl dein Receiver läuft, dein Sender ein falsches Fensterhandle erhält, von einem Fenster das mit der WM_COPYDATA Message nichts anfangen kann.
Mein Lösungsvorschlag - im Receiver:
Delphi-Quelltext 1: 2: 3: 4: 5:
| const sWndTitle = 'MyReceiver';
FWinHandle := AllocateHWND(WndProc); SendMessage(FWinHandle, WM_SETTEXT, 0, Integer(Pointer(sWndTitle))); |
Im Sender:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| var wnd: HWND;
wnd := FindWindow('TPUtilWindow', 'MyReceiver'); if wnd <> 0 then SendMessage(wnd, WM_COPYDATA, 1, Longint(@data)); |
Gruß, Motzi
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
hazelnoot 
      
Beiträge: 27
|
Verfasst: Fr 04.08.06 11:00
hoi!
ich hab das nun so gemacht:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TTestThread.WndProc(var msg: TMessage); var data : PCopyDataStruct; begin
data := TWMCopyData(msg).CopyDataStruct;
Writeln('out:', String(data.lpData));
end; |
aber da kommt nach out nix mehr woran kann das liegen den typecast hab ich doch richtig gemacht oder?
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Fr 04.08.06 11:07
Deine WndProc wird für JEDE Message die an dein Fenster geschickt wird aufgerufen (und solche gibt es seeehr viele)! Du musst also ausfiltern auf welche du reagieren willst und welche nicht..
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TTestThread.WndProc(var msg: TMessage); begin if msg.Msg = WM_COPYDATA then Writeln('out:', PChar(PCopyDataStruct(msg.lParam)^.lpData)); end; |
Außerdem solltest du die Punkte beachten die ich in meinem vorherigen Posting angesprochen habe...
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
hazelnoot 
      
Beiträge: 27
|
Verfasst: Fr 04.08.06 11:27
|
|
|