Autor Beitrag
hazelnoot
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
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)
BeitragVerfasst: 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:
ausblenden Delphi-Quelltext
1:
if Self.BraetAndernEineBratwurst then Self.HasBratwurstBratGeraet := true;					
hazelnoot Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: 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?

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
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)
BeitragVerfasst: Do 03.08.06 15:47 
also...
TWndMethod ist die Methode, die dann auf die empfangenen Nachrichten reagieren wird.
Deklariert in Classes:
ausblenden Delphi-Quelltext
1:
  TWndMethod = procedure(var Message: TMessage) of object;					

das heißt du schreibst eine Methode, die von der Signatur so aussieht:
ausblenden 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:
ausblenden Delphi-Quelltext
1:
if Self.BraetAndernEineBratwurst then Self.HasBratwurstBratGeraet := true;					
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: 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:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: 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:
ausblenden volle Höhe 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:
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:
ausblenden volle Höhe 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:
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;
    //procedure PrintMsg;
  end;


implementation

var
  WM_SHUTDOWN_THREADS: Cardinal;

{ TTestThread }

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;
  //Synchronize(PrintMsg);
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
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)
BeitragVerfasst: 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:
ausblenden Delphi-Quelltext
1:
if Self.BraetAndernEineBratwurst then Self.HasBratwurstBratGeraet := true;					
hazelnoot Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: Fr 04.08.06 08:52 
danke fuer deine promte antwort!

also ich hab das nun probiert:
meine neue sendmessage im sender:
ausblenden Delphi-Quelltext
1:
SendMessage(FindWindow('FWinHandle'nil), WM_COPYDATA, 1, Longint(@data));					


das FWinHandle deswegen wiel im empfaenger das handle so heisst:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
constructor TTestThread.Create;
begin
  FSignalShutdown := False;
  FWinHandle := AllocateHWND(WndProc); //hier wird der handler angelegt!!
  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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
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)
BeitragVerfasst: 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:
ausblenden Delphi-Quelltext
1:
if Self.BraetAndernEineBratwurst then Self.HasBratwurstBratGeraet := true;					
hazelnoot Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
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)
BeitragVerfasst: 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.

ausblenden 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:

ausblenden Delphi-Quelltext
1:
TWMCopyData(Message).CopyDataStruct					

_________________
Wer andern eine Bratwurst brät, der hat ein Bratwurst-Brat-Gerät, oder anders:
ausblenden Delphi-Quelltext
1:
if Self.BraetAndernEineBratwurst then Self.HasBratwurstBratGeraet := true;					
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: 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:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
const
  sWndTitle = 'MyReceiver';

FWinHandle := AllocateHWND(WndProc); //hier wird der handler angelegt!!
SendMessage(FWinHandle, WM_SETTEXT, 0, Integer(Pointer(sWndTitle))); // Fenster-Titel ändern

Im Sender:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: Fr 04.08.06 11:00 
hoi!

ich hab das nun so gemacht:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: 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..
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: Fr 04.08.06 11:27 
super danke es funkt!!!