/ Forside / Teknologi / Udvikling / Delphi/Pascal / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Delphi/Pascal
#NavnPoint
oldwiking 603
jrossing 525
rpje 520
EXTERMINA.. 500
gandalf 460
gubi 270
DJ_Puden 250
PARKENSS 230
technet 210
10  jdjespers.. 200
SendMessage / PostMessage
Fra : Michael


Dato : 16-08-03 22:21

Delphi 4


Hvordan for jeg sendt en tekst fra et program til et andet (egne
programmer).

Jeg har kigget lidt på noget SendMessage og PostMessage, men det blev jeg
nu ikke særlig klog af, så hvis der er nogen af jer der har et lille
eksempel eller et godt link ville jeg blive møj glad.


/md



 
 
Harald (16-08-2003)
Kommentar
Fra : Harald


Dato : 16-08-03 23:14

"Michael" <michael@mhcdan.dk> skrev i en meddelelse
news:3f3ea083$0$32501$edfadb0f@dread16.news.tele.dk...
> Delphi 4
>
>
> Hvordan for jeg sendt en tekst fra et program til et andet (egne
> programmer).
>
> Jeg har kigget lidt på noget SendMessage og PostMessage, men det blev jeg
> nu ikke særlig klog af, så hvis der er nogen af jer der har et lille
> eksempel eller et godt link ville jeg blive møj glad.

Er de 2 programmer på samme PC eller skal teksten en tur over nettet?

Men hvis det er på samme PC så prøv at kikke på WM_COPYDATA, den er hurtig
og let at bruge.

/HK



Pølle (17-08-2003)
Kommentar
Fra : Pølle


Dato : 17-08-03 08:37


Fra HELP til D4
"OnMessage"

The following code handles a custom message that the application sends to
itself when a file is ready for reading.

const
WM_FILEREADY = WM_USER + 2000;

procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := AppMessage;
end;

procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
if Msg.message = WM_FILEREADY then
begin
Memo1.Lines.LoadFromFile(StrPas(PChar(Msg.lParam)));
Handled := True;
end;
{ for all other messages, Handled remains False }
{ so that other message handlers can respond }
end;


"Michael" <michael@mhcdan.dk> skrev i en meddelelse
news:3f3ea083$0$32501$edfadb0f@dread16.news.tele.dk...
> Delphi 4
>
>
> Hvordan for jeg sendt en tekst fra et program til et andet (egne
> programmer).
>
> Jeg har kigget lidt på noget SendMessage og PostMessage, men det blev jeg
> nu ikke særlig klog af, så hvis der er nogen af jer der har et lille
> eksempel eller et godt link ville jeg blive møj glad.
>
>
> /md
>
>



Klaus Petersen (17-08-2003)
Kommentar
Fra : Klaus Petersen


Dato : 17-08-03 10:37

> Hvordan for jeg sendt en tekst fra et program til et andet (egne
> programmer).

SendMessage og PostMessage virker ikke på den måde, som du nok regner med,
for det er ikke tekst meddelser, der er tale om her.

De meddelser, der sendes med SendMessage kunne f.eks. være en besked om at
musen har flyttet sig indenfor vinduet.

Skal man sende tekstmeddelser mellem applikationer, skal der noget specielt
til, da det ene program ikke har adgang til det andets program's hukommelse.

Det kan man løse f.eks. ved at lave noget "delt hukommelse", som begge
programmer har adgang til. Det er formindtlig den hurtigste metode selvom
der ikke er mærkbar hastigheds forskel på de forskellige metoder jeg nævner
her.

En anden måde er via. WM_COPYDATA meddelsen, som Harald også nævner.

Det er en meddelse, som indeholder en pointer til noget hukommelse, som
f.eks. kunne være en tekststreng.

Jeg har lavet et lille chat program til demonstration af WM_COPYDATA og
hvordan man kan sende tekst mellem programmerne. Programmet vil du nok synes
er ret kompliceret, men bare spørg hvis du er i tvivl om noget.

Det skal lige siges at chat programmet ikke er fejlfrit (den crasher f.eks.
efter at vist brugeren en klage over at for mange instanser er aktive).

På programmets form er en TRichEdit og en TEdit - Opret de 2 komponenter og
erstat koden med denne (bemærk rækkefølgen af instruktionerne):

<kode start>

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
RichEdit1: TRichEdit;
procedure FormCreate(Sender: TObject);
procedure Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormDestroy(Sender: TObject);
protected
procedure WndProc(var Message: TMessage); override;
private
applicationID : byte;

{ Private declarations }
chatwnds : tlist;

procedure FindChatWindows;
procedure SendChatMessage ( text : string );
procedure DisposeChatWndsList;

public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.WndProc(var Message: TMessage);
var
cds : PCopyDataStruct; // pointer til en copydatastruct structure
farve : tcolor;
begin;
// Besvarelse af det "hemmelige" 1024 spørgsmål
if ( ( Message.Msg = WM_USER ) and ( Message.WParam = 1024 ) ) then begin;
Message.Result := 17082003;
exit;
end;

if ( Message.Msg = WM_COPYDATA ) then begin;
cds := PCopyDataStruct (Message.LParam);

if not (cds^.dwData = 17082003 ) then exit; // Magic ID

if (cds^.cbData > 0) then begin;
farve := $ffffff;

case byte (pchar (cds^.lpData) [0]) of
1 : farve := $ffaaaa;
2 : farve := $00ff00;
3 : farve := $0000ff;
4 : farve := $ff00ff;
5 : farve := $ffff00;
6 : farve := $ffffff;
7 : farve := $aaaaaa;
8 : farve := $aaaa00; // Nu gider jeg ikke at definere flere farver
// men det kan du sagtens selv gøre hvis du
vil
end;

RichEdit1.SelStart := -1;
RichEdit1.SelAttributes.Color := farve;
RichEdit1.SelAttributes.Name := 'Verdana';
RichEdit1.SelAttributes.Style := [];
RichEdit1.SelAttributes.Size := 12;
RichEdit1.Lines.Insert ( 0, pchar (cds^.lpData)+1 );

RichEdit1.SelStart := 0;
RichEdit1.SelLength := cds^.cbData - 2;
RichEdit1.SelAttributes.Color := farve;
end;

exit;
end;

inherited;
end;

procedure TForm1.SendChatMessage ( text : string );
var
tekst : pchar;
cds : PCopyDataStruct;
bufsize : cardinal;
wndhandle : ^hwnd;
count : integer;
begin;
count := 0;

while ( count < self.chatwnds.Count ) do begin;
bufsize := length (text) + 2;
getmem ( tekst, bufsize );
tekst [0] := char ( self.applicationID );
strpcopy ( tekst+1, text );

new (cds);
cds^.dwData := 17082003; // Magic ID
cds^.lpData := tekst; // Pointer til tekst
cds^.cbData := bufsize; // Buffer størrelse

wndhandle := self.chatwnds.Items [count];

SendMessage ( wndhandle^, WM_COPYDATA, form1.Handle, integer (cds) );

freemem ( cds^.lpData, cds^.cbData );

inc (count);
end;

end;

function EnumCallBack ( wndhandle : hwnd; lparam : cardinal ) : boolean;
stdcall;
var
chatwnds : tlist;
buf : array [0..511] of char;
handleptr : ^hwnd;
cnt : integer;
begin;
chatwnds := tlist (lparam);

cnt := GetClassName ( wndhandle, buf, 512 );

if ( (cnt > 0 ) and ( buf = 'TForm1' ) ) then begin;
// Når du ændrer navnet (ikke caption!)
// på din form virker programmet ikke
// længere med mindre du ændrer TForm1
til
// det nye navn

// Potentielt vindue fundet

if ( SendMessage ( wndhandle, WM_USER, 1024, 0 ) = 17082003 ) then begin;
// chat vindue fundet
new ( handleptr );
handleptr^ := wndhandle;
chatwnds.Add( handleptr );
end;
end;

result := true;
end;

procedure TForm1.DisposeChatWndsList;
var
handleptr : ^hwnd;
count : integer;
begin;
count := 0;
while ( count < self.chatwnds.Count ) do begin;
handleptr := self.chatwnds.Items [count];
dispose ( handleptr );
inc (count);
end;
end;

procedure TForm1.FindChatWindows;
begin;
DisposeChatWndsList;

self.chatwnds.Clear;

EnumWindows ( @EnumCallBack, longint (self.chatwnds) );
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
richedit1.Clear;
richedit1.Color := clBlack;

edit1.Text := '';
self.chatwnds := tlist.Create;

FindChatWindows;
applicationID := self.chatwnds.Count;

if (applicationID > 8) then begin;
MessageDlg ( 'Der er for mange chat programmer kørende!', MTERROR, [mbok],
0);
application.Destroy;
end;

end;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin

if key=13 then begin;
findchatwindows;
sendchatmessage ( edit1.Text );
edit1.Text := '';
end;

end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
DisposeChatWndsList;
self.chatwnds.Destroy;
end;

end.

<kode slut>

Håber du kan bruge det til noget.

mvh.
Klaus.



Michael (19-08-2003)
Kommentar
Fra : Michael


Dato : 19-08-03 20:15

Kanon tak skal I ha'.

Jeg har gjort brug af Klaus' eksempel og det virker sgu'.
Nu skal jeg bare lige ha fundet ud hvad der er hvad.

/md



Michael (19-08-2003)
Kommentar
Fra : Michael


Dato : 19-08-03 20:42

Hej Klaus,

Jeg har liget et lille spørgsmål.
Hvad mener du med det hemmelige 1024 spørgsmål? Jeg har prøvede at lure
joken (hvis det er sådan en) men kan sgu' ikke rigtig fange den

> begin;
> // Besvarelse af det "hemmelige" 1024 spørgsmål
> if ( ( Message.Msg = WM_USER ) and ( Message.WParam = 1024 ) ) then
begin;
> Message.Result := 17082003;
> exit;
> end;


/md



Klaus Petersen (20-08-2003)
Kommentar
Fra : Klaus Petersen


Dato : 20-08-03 00:05

> Jeg har liget et lille spørgsmål.
> Hvad mener du med det hemmelige 1024 spørgsmål? Jeg har prøvede at lure
> joken (hvis det er sådan en) men kan sgu' ikke rigtig fange den

Det er rigtig nok en lille joke (een af de nørdede måske nok )

Grunden til at jeg har opfundet et hemmeligt 1024 spørgsmål er, at når
programmet søger efter chat vinduer (mere præcist, instanser af programmet
dvs. mulige modtagere af chat meddelsen), vil den også finde vinduet i selve
Delphi, hvis du har projektet åbent - men det er ikke et rigtigt chat
vindue, da programmet jo ikke kører og derfor ikke modtager og afsender chat
meddelser.

For at teste, om vinduet tilhører en kørende instans af programmet (altså er
en rigtig modtager) sender jeg en brugerdefineret besked (WM_USER) til den
med værdien 1024 som wparam - det kunne for så vidt være hvilket som helst
tal. Modtageren skal herefter "besvare" beskeden med den rigtige returværdi
(17082003 i dette tilfælde).

I øvrigt kan jeg lige til sidst tilføje, at i tilfælde, hvor det ikke er en
rigtig modtager, vil modtageren formindtlig returnere FALSE, som en
indikation af, at meddelsen ikke er forstået - FALSE oversættes til værdien
0 og vil derfor være et forkert svar på "spørgsmålet".

Så spørgsmålet er noget i retning af ... " Hvis jeg siger 1024 ... hvad
siger du så?" hvor de rigtige program kender svaret og de forkerte ikke gør


> > // Besvarelse af det "hemmelige" 1024 spørgsmål
> > if ( ( Message.Msg = WM_USER ) and ( Message.WParam = 1024 ) ) then
> begin;
> > Message.Result := 17082003;
> > exit;
> > end;
>



Harald (17-08-2003)
Kommentar
Fra : Harald


Dato : 17-08-03 15:11

"Michael" <michael@mhcdan.dk> skrev i en meddelelse
news:3f3ea083$0$32501$edfadb0f@dread16.news.tele.dk...
> Delphi 4
>
>
> Hvordan for jeg sendt en tekst fra et program til et andet (egne
> programmer).

Her er et lille chat program jeg har lavet der viser bruget af WM_COPYDATA,
programmet er meget simpelt og virker kun med 2 programmer startet af
gangen.

På en form putter du følgende:
En TEdit // Edit1
En TMemo // Memo1
En TEdit // Edit2
En TButton // Button1

for at teste programmet gør du følgende:
Start programmet 2 gange, i Edit1 indtaster du et navn i hvert vindue,
indtast nu en tekst i Edit2 og tryk på knappen.

------------------------

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Memo1: TMemo;
Edit2: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
procedure ModtagData(var m : TMessage); message WM_COPYDATA;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.ModtagData(var m : TMessage);
var
CopyDataStruct : TCopyDataStruct;
begin
CopyDataStruct:=PCopyDataStruct(m.lParam)^;
memo1.Lines.Add(pchar(CopyDataStruct.lpData));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
CopyDataStruct : TCopyDataStruct;
SendToHandle : THandle;
Temp : string;
begin
{ de næste par linier er noget fusk det ved jeg godt,
med det er jo kun en demo
}
temp:=Caption;
caption:=''; // for at undgå at programmet bare finder sig selv
SendToHandle:=FindWindow(nil, PChar(Temp));
Caption:=Temp;
if SendToHandle<>0 then
begin
Temp:=Edit1.text+': '+Edit2.Text;
CopyDataStruct.dwData:=0;
CopyDataStruct.cbData:=length(Temp)+1;
CopyDataStruct.lpData:=pointer(Temp);
SendMessage(SendToHandle, WM_COPYDATA, 1, lparam(@CopyDataStruct));
memo1.Lines.Add(Temp);
end;
end;

end.

------------------

Mvh
HK



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408924
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste