![]() |
WM_COPYDATA macht große Probleme
Hallo,
ich möchte von einem Programm zu einem anderen eine Nachricht senden, doch das funktoniert nicht. Hier mal mein Code:
Delphi-Quellcode:
Warum kommt keine Nachricht an? Wird sie gar nicht erst gesendet? Das Handle (Wnd) zu dem die Nachricht gesendet wird stimmt aber.
//die 2. Anwendung
var Wnd: HWnd; MyCopyDataStruct: TCopyDataStruct; begin // Hier stehen noch andere Teile die ein Semaphore erstellen und das Handle (wnd) abfragen //das funktioniert auch alles nur die Message nicht If ParamStr(1) <> '' then with MyCopyDataStruct do begin dwData:=0; cbData:=Length(PChar(ParamStr(1))) + 1; lpData:=PChar(ParamStr(1)); SendMessage(Wnd, WM_COPYDATA, Application.Handle, Integer(@MyCopyDataStruct)); end; //die 1. Anwedung, die auf die Message eigentlich warten sollte procedure TForm1.WMCOPYDATA(var Msg: TWMCopyData); var sText: array of Char; begin SetLength(sText,Msg.CopyDataStruct.cbData); StrLCopy(PChar(sText), Msg.CopyDataStruct.lpData, Msg.CopyDataStruct.cbData); NewAVObject(PChar(sText)); //Prozedur zu weiteren Verarbeitung end; Ich bin schon seit 3 Tagen am verzweifeln, ich hoffe mir kann jemand helfen. Gruß Mazel |
Re: WM_COPYDATA macht große Probleme
Bist du sicher, dass das auch das Handle des Zielfensters ist?
|
Re: WM_COPYDATA macht große Probleme
Zitat:
Florian |
Re: WM_COPYDATA macht große Probleme
Hi,
es ist das richtige Handle, denn ich habe beim Start der ersten Anwendung mir eine Message zeigen lassen und als die zweite Anwendung getsartet wurde
Delphi-Quellcode:
und
ShowMessage(IntToStr(Application.Handle));
Delphi-Quellcode:
beides mal war es gleich, sonst würde er auch nicht mit SetForegroundWindow(Wnd) die richtige Anwendung nach vorne bringen.
ShowMessage(IntToStr(Wnd));
Aber hier trotzdem der Code (aus einer OneInst):
Delphi-Quellcode:
Gruß
unit OneInst;
interface { Make a call to this procedure in your project source immediately before the first call to CreateForm. That should ensure it is after the Application.Title assignment that can muck up the logic. If you haven't set an application title yet, then do so to ensure this works } uses Windows, Messages, SysUtils, Classes, Controls, Forms; procedure EnsureSingleInstance (MyGUID : string) ; implementation uses WinTypes, WinProcs, Dialogs, UnitConst, Unit1; procedure EnsureSingleInstance (MyGUID : string) ; var Wnd: HWnd; WndClass, WndText: array[0..255] of char; MyCopyDataStruct: TCopyDataStruct; begin {$ifdef Win32} { Try and create a semaphore. If we succeed, then check } { if the semaphore was already present. If it was } { then a previous instance is floating around. } { Note the OS will free the returned semaphore handle } { when the app shuts so we can forget about it } if (CreateSemaphore(nil, 0, 1, PChar(MyGUID)) <> 0) and (GetLastError = Error_Already_Exists) then {$else} if HPrevInst <> 0 then {$endif} begin Wnd := GetWindow(Application.Handle, gw_HWndFirst); while Wnd <> 0 do begin { Look for the other TApplication window out there } if Wnd <> Application.Handle then begin { Check it's definitely got the same class and caption } GetClassName(Wnd, WndClass, Pred(SizeOf(WndClass))); GetWindowText(Wnd, WndText, Succ(Length(Form1.Caption))); if (StrPas(WndClass) = Application.ClassName) and (StrPas(WndText) = Form1.Caption) then begin { This technique is used by the VCL: post } { a message then bring the window to the } { top, before the message gets processed } PostMessage(Wnd, wm_SysCommand, sc_Restore, 0); {$ifdef Win32} If ParamStr(1) <> '' then with MyCopyDataStruct do begin dwData:=WM_COMMUNICATE; cbData:=Length(PChar(ParamStr(1))) + 1; lpData:=PChar(ParamStr(1)); SendMessage(Wnd, WM_COPYDATA, Application.Handle, Integer(@MyCopyDataStruct)); end; SetForegroundWindow(Wnd); {$else} BringWindowToTop(Wnd); {$endif} Halt end end; Wnd := GetWindow(Wnd, gw_HWndNext) end end end; end. Mazel |
Re: WM_COPYDATA macht große Probleme
zeig mal die Definition von TForm1.WMCOPYDATA.
Da muss nämlich noch dazu, dass dies eine "Message-Funktion" ist und auf welche Message diese Funktion horchen soll. z.Bsp.:
Delphi-Quellcode:
und wo hast Du eigentlich die Message WM_MYMESSAGE deklariert?
TForm1 = class (TForm)
... ... private ... procedure WMQUERYENDSESSION (var Msg: TWMQueryEndSession); message WM_QUERYENDSESSION; ... end; ... ... procedure TForm1.WMQUERYENDSESSION (var Msg: TWMQueryEndSession); begin ... ... inherited; end; Und hast Du diese Message auch registriert? |
Re: WM_COPYDATA macht große Probleme
Sorry,
ich habe ich bisschen herum probiert, dort steht jetzt wieder WM_COPYDATA. Wegen der ersten Frage:
Delphi-Quellcode:
Ist in dieser Funktion das inherited notwendig?
private
procedure WMCOPYDATA(var Msg: TWMCopyData); Message WM_COPYDATA; ... ... end; ... ... procedure TForm1.WMCOPYDATA(var Msg: TWMCopyData); var sText: array of Char; begin SetLength(sText,Msg.CopyDataStruct.cbData); StrLCopy(PChar(sText), Msg.CopyDataStruct.lpData, Msg.CopyDataStruct.cbData); NewAVObject(PChar(sText)); end; Gruß Mazel |
Re: WM_COPYDATA macht große Probleme
Gibt es eine andere Möglichkeit um den Parameter von der zweiten Instanz zur ersten zu übertragen?
Gruß Mazel |
Re: WM_COPYDATA macht große Probleme
|
Re: WM_COPYDATA macht große Probleme
Hi,
danke, nur bringt mir das nicht soviel. Ich möchte Nachrichten von einer Instanz (Anwendung) zu einer anderen Senden. Was bedeutet eigentlich das Owner in:
Delphi-Quellcode:
Ich habe 2 Codeschnippsel. Bei einem kommt auch das Owner vor, in dem funktioniert die Parameter übergabe aber da gibt es andere Dinge die mir nciht gefallen und in der anderen kommt das eben nicht vor (die obere).
hWnd := (Owner AS TForm).Handle;
Gruß Mazel |
Re: WM_COPYDATA macht große Probleme
Hi,
wollte das selber mal hinkriegen und dein post hat mir dabei sehr geholfen, nun kann ich dir evtl. helfen: Du solltest beachten, dass du das handle der Form brauchst und nicht das der Application, das sind zwei verschiedene Dinge, in deiner Abfrage vergleichst du nämlich application.handle mit dem Handle an das du senden willst, du musst es aber an die form schicken. Hoffe das löst bei dir auch die Probleme meins funzt jezt so... MFG Flippo |
Re: WM_COPYDATA macht große Probleme
Hi,
ich weis jetzt genau was du meinst. Wenn die 2. Instanz startet, prüft diese, ob es das Programm schonmal gestartet ist, wenn ja ermittele ich ähnlich FindFirst - FindNext ein Handle, welches ich unter Wnd abspeichere. Application.Handle sollte doch das Handle, der aktuellen Instanz (also dieser 2.Instanz) sein. Wenn das gefundene Handle (Wnd) nicht das der 2. Instanz sein sollte überprüfe ich es ob es sich um die 1. Instanz handelt, wenn nicht, bekommt Wnd das nächste Handle. Du kannst ja gerne dein Code mal posten. Gruß Mazel |
Re: WM_COPYDATA macht große Probleme
Hi,
...hmm weiss nicht genau ob du mich da richtig verstanden hast oder ob ich dich jetz falsch verstehe.. mir geht es nicht darum ob das Programm 2 mal geöffnet ist oder nicht, sondern darum das du, wemm du das Programm einmal aufrufst ein Handle für deine Application und eines für deine Form hast... Also nochmal als Quelltext ausgedrückt: application.handle und form1.handle innerhalb des selben Programms, dass auch nur eine Form hat, waren bei mir unterschiedliche Werte und man muss an Form1 senden wenn die Empfangsfunktion unter Form1 deklariert ist... ansonsten mein Code der bei mir funktioniert: Zum Senden:
Delphi-Quellcode:
Zum empfangen:
procedure TForm1.SendMainApp(S:String);
var copyDataStruct : TCopyDataStruct; begin copyDataStruct.dwData := 0; //use it to identify the message contents copyDataStruct.cbData := 1 + Length(s); copyDataStruct.lpData := PChar(s); sendmessage(PH,WM_COPYDATA,application.handle,Integer(@CopyDataStruct)); //PH ist das handle der Form an die ich Sende (form1.handle) end;
Delphi-Quellcode:
procedure WMCopyData(var Msg :TWMCopyData); message WM_COPYDATA;
Delphi-Quellcode:
procedure TForm1.WMCOPYDATA(var Msg: TWMCopyData);
var s,s1:string; i:integer; begin s := PChar(Msg.CopyDataStruct.lpData) ; //msg.Result := 2006; end; |
Re: WM_COPYDATA macht große Probleme
Mhm, ich habe dich schon verstanden. Das sind zwei unterschiedliche Werte.
Wie ermittelts du das Handle der Form1 (PH)? Ich muss das Handle ermitteln da ich die Message an die 1. Instanz senden muss von der 2. Instanz aus. Gruß Mazel |
Re: WM_COPYDATA macht große Probleme
ich habs da recht einfach gehabt, weil ich von einer dll aus sende und das handle von form1 einfach beim laden mitschicke.... aber
![]()
Delphi-Quellcode:
Hoffe das hilft dir weiter...
procedure WMCOPYDATA(var Msg: TWMCopyData);
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:17 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz