Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Application Handle einer fremden Application bekommen? (https://www.delphipraxis.net/54438-application-handle-einer-fremden-application-bekommen.html)

Angel4585 4. Okt 2005 13:16


Application Handle einer fremden Application bekommen?
 
Hallo,

wir haben hier gerade ein kleines Problem.

Und zwar benötigen wir das Application Handle einer fremden Application, wissen aber nicht wie man das bekommt.

mit FindWindow(nil,'Fremde Application') bekommt man zwar das FensterHandle, das genügt aber in diesem Fall nicht.

Also weis zufällig irgendjemand wie ich an das Application Handle der Fremden Application komme?

Danke schonmal

TheXception 4. Okt 2005 13:22

Re: Application Handle einer fremden Application bekommen?
 
Zitat:

Zitat von Angel4585
mit FindWindow(nil,'Fremde Application') bekommt man zwar das FensterHandle, das genügt aber in diesem Fall nicht.

Also ich glaube zwischen Application.Handle ist genau das gleiche wie ein Handle das man per FindWindow() bekommt.
vllt sagst du kurz was du mit dem handle anstellen willst das der von FindWindow nicht reicht.

Angel4585 4. Okt 2005 13:38

Re: Application Handle einer fremden Application bekommen?
 
OK, also:

Aufgabe ist: Das ein Itemindex einer RadioGroup der einen Anwendung and eine Radiogroup der anderen Anwendung gechickt wird.

Es geht zwar auf der einen Seite mit

Senderanwendung:
Delphi-Quellcode:
SendMessage(ParentHandle,WM_SELECTRADIOBUTTON,RadioGroup.ItemIndex,0);
Empfängeranwendung:
Delphi-Quellcode:
procedure GetItemIndex(var msg: TMessage); message WM_SELECTRADIOBUTTON;
.
.
procedure Ttf_empfang.GetItemIndex(var msg: TMessage);
begin
RadioGroup1.ItemIndex:=msg.WParam;
end;
das FormularHandle übergebe, allerdings habe ich in einem Buch eine andere Möglichkeit gesehn bei der man das ApplicationHandle übergeben muss, was dann so aussieht:

Senderanwendung:
Delphi-Quellcode:
SendMessage(ParentHandle,WM_SELECTRADIOBUTTON,RadioGroup.ItemIndex,0);
Empfängeranwendung:
Delphi-Quellcode:
procedure GetItemIndex(var Msg :TMsg;var Handeled : Boolean);
.
.
procedure Ttf_empfang.GetItemIndex(var Msg :TMsg;var Handeled : Boolean);
begin
case Msg.Message of
 WM_SELECTRADIOBUTTON : RadioGroup1.ItemIndex:=Msg.wParam;
 end;
end;
Delphi-Quellcode:
procedure Ttf_empfang.FormCreate(Sender: TObject);
begin
Application.OnMessage:=GetItemIndex;
end;
so das wars. Bei dem ersten Beispiel brauche ich wie gesagt das Fensterhandle und bei dem zweiten das Application Handle.
Ich weis das ich es ja auch mit dem ersten machen kann, mich würde aber trotzdem interessieren wie ich an ein ApplicationHandle drankommen kann

Olli 4. Okt 2005 14:11

Re: Application Handle einer fremden Application bekommen?
 
Kleiner Tip: TForm <> TApplication ...

Angel4585 4. Okt 2005 14:21

Re: Application Handle einer fremden Application bekommen?
 
Soweit das TForm<>Tapplication ist war ich vor zwei Jahren in der Schule auch schonmal...

Aber das hilft mir bei meinem Problem im moment nicht wirklich weiter.
Ich kann ja nicht
Delphi-Quellcode:
FindWindow('TApplication','Fremde Anwendung');
machen.(Können schon, funzt aber nicht)

Flocke 4. Okt 2005 14:29

Re: Application Handle einer fremden Application bekommen?
 
Du kannst dir doch mit RegisterWindowMessage eine systemweit eindeutige Fenstermeldung generieren und diese dann aus der Senderanwendung "broadcasten", also an alle Fenster schicken (HWND_BROADCAST).

Angel4585 4. Okt 2005 14:35

Re: Application Handle einer fremden Application bekommen?
 
Bekomm ich so das Anwendungs Handle?

Ich glaub wenn ich das schon an alle "Fenster" schicke benötige ich auch das "Fenster" Handle und nicht das Anwendungshandle oder?

Ziel ist es ja aber das Anwendungshandle zu bekommen.

Flocke 4. Okt 2005 14:39

Re: Application Handle einer fremden Application bekommen?
 
Zitat:

Zitat von Angel4585
Bekomm ich so das Anwendungs Handle?

Natürlich nicht!

Zitat:

Zitat von Angel4585
Ich glaub wenn ich das schon an alle "Fenster" schicke benötige ich auch das "Fenster" Handle und nicht das Anwendungshandle oder?

Nein! Du schickst es einmal mit PostMessage an HWND_BROADCAST und Windows schickt es dann für dich an alle Fenster.

Angel4585 4. Okt 2005 14:48

Re: Application Handle einer fremden Application bekommen?
 
Es funzt aber trotzdem nicht, Windows schickt es an alle FensterHandles, Aber die fremde Anwendung wartet auf ihr Applicationhandle.

Vorrausgesetzt :

PostMessage(HWND_BROADCAST,WM_SELECTRADIOBUTTON,rg _nachricht_steuer.ItemIndex,0);
ist richtig. :?:

Flocke 4. Okt 2005 14:55

Re: Application Handle einer fremden Application bekommen?
 
Du solltest NIE eine Meldung, deren Nummer du dir einfach selbst ausgedacht hast, an fremde Fenster schicken (darum mein Vorschlag mit RegisterWindowMessage). HWND_BROADCAST kriegen alle Fenster - wer weiß, wie die die Nummer interpretieren...

Wenn du es verschickst aber in Application.OnMessage Nichts empfängst, dann machst du vielleicht irgendetwas anderes falsch (Konstanten gleich definiert???).

[Nachtrag]

Zitat:

Aber die fremde Anwendung wartet auf ihr Applicationhandle
Was soll das heißen???

Sepp 4. Okt 2005 15:09

Re: Application Handle einer fremden Application bekommen?
 
Hallo

Du könntest es auch über den EXE Namen versuchen sofern der bekannt ist.

In der Jedi Library gibt es in der Unit JCLSYSINFO die nötigen
Funktionen dazu.

1.ProzessID holen

function GetPidFromProcessName(const ProcessName: string): DWORD;

2.Mainwindow handle über die ID suchen.

function GetMainAppWndFromPid(PID: DWORD): HWND;

Du sollest evt. noch testen ob es sich um ein Fensterhandle handelt.

Ist allerdings nicht getestet, sollte aber funktionieren.

Sepp

Angel4585 4. Okt 2005 15:11

Re: Application Handle einer fremden Application bekommen?
 
@Flocke
Also ich hab ne Unit in der die Meldung definiert ist und auf die BEIDE programme zugreifen. Da sollte also nicht das Problem sein.

Zitat:

Zitat:

Zitat:
Aber die fremde Anwendung wartet auf ihr Applicationhandle
Was soll das heißen???
Application.OnMessage wird ja nur ausgeführt wenn die Als "Ziel" Das Handle der Anwendung angegeben wurde. Allerdings ist es ja genau das was mir Fehlt. Mit FindWindow bekomm ich zwar das Handle auf das Fenster, aber nicht das auf die gesamte Application.

Flocke 4. Okt 2005 16:30

Re: Application Handle einer fremden Application bekommen?
 
Zitat:

Zitat von Angel4585
Application.OnMessage wird ja nur ausgeführt wenn die Als "Ziel" Das Handle der Anwendung angegeben wurde. Allerdings ist es ja genau das was mir Fehlt. Mit FindWindow bekomm ich zwar das Handle auf das Fenster, aber nicht das auf die gesamte Application.

Laut Quelltext (Forms.pas) wird Application.OnMessage für jede Meldung ausgeführt, die für deine Anwendung bestimmt ist. In dem TMsg-Parameter steht das Fensterhandle mit drin. Es sollte also klappen, wenn du die Nachricht an irgendein Fenster deiner Anwendung schickst (oder z.B. mit BROADCAST an alle).

Hast du das Ganze denn in der empfangenden Anwendung mal debugged? Oder hast du vielleicht eine Komponente, die Application.OnMessage selbst setzt?

Angel4585 5. Okt 2005 07:27

Re: Application Handle einer fremden Application bekommen?
 
OK:

Senderprogramm:
Delphi-Quellcode:
unit USteuer;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, Spin, UBotschaften,TlHelp32;

type
  Ttf_steuer = class(TForm)
    Btn_starten: TButton;
    Btn_Maximieren: TButton;
    Btn_Minimieren: TButton;
    Btn_Button_druecken: TButton;
    Btn_schliessen: TButton;
    Btn_wiederherstellen: TButton;
    rg_nachricht_steuer: TRadioGroup;
    LHandle: TLabel;
    LBHandle: TLabel;
    LRGHandle: TLabel;
    procedure rg_nachricht_steuerClick(Sender: TObject);
    procedure Btn_wiederherstellenClick(Sender: TObject);
    procedure Btn_Button_drueckenClick(Sender: TObject);
    procedure Btn_MinimierenClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Btn_schliessenClick(Sender: TObject);
    procedure Btn_MaximierenClick(Sender: TObject);
    procedure Btn_startenClick(Sender: TObject);
  private
    ParentHandle : HWND;
    ButtonHandle : HWND;
    RGHandle : HWND;
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  tf_steuer: Ttf_steuer;

implementation

{$R *.dfm}



procedure Ttf_steuer.Btn_startenClick(Sender: TObject);
var
  StartupInfo: TStartupinfo;
  ProcessInfo: TProcessInformation;
begin
//FUNKTIONIERT!!
FillChar(Startupinfo,Sizeof(TStartupinfo),0);
Startupinfo.cb:=Sizeof(TStartupInfo);
if not CreateProcess(nil,'Empfang.exe',nil,nil,false,normal_priority_class,nil,nil, Startupinfo,ProcessInfo)then
 ShowMessage('Anwendung konnte nicht gestartet werden');
end;

procedure Ttf_steuer.Btn_MaximierenClick(Sender: TObject);
begin
//FUNKTIONIERT!!
ParentHandle:=FindWindow(nil,'Empfang');
LHandle.Caption:=IntToStr(ParentHandle);
//Maximieren der Zweiten AW
SendMessage(ParentHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
end;

procedure Ttf_steuer.Btn_schliessenClick(Sender: TObject);
begin
//FUNKTIONIERT!!
ParentHandle:=FindWindow(nil,'Empfang');
LHandle.Caption:=IntToStr(ParentHandle);
SendMessage(ParentHandle,WM_SYSCOMMAND,SC_CLOSE,0);
end;

procedure Ttf_steuer.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Btn_schliessen.Click;
end;

procedure Ttf_steuer.Btn_MinimierenClick(Sender: TObject);
begin
//FUNKTIONIERT!!
ParentHandle:=FindWindow(nil,'Empfang');
LHandle.Caption:=IntToStr(ParentHandle);
//Minimieren der zweiten AW
SendMessage(ParentHandle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
end;

procedure Ttf_steuer.Btn_Button_drueckenClick(Sender: TObject);
begin
//FUNKTIONIERT!!
ParentHandle:=FindWindow(nil,'Empfang');
ButtonHandle:=FindWindowEx(ParentHandle, 0,'TButton',nil);
LBHandle.Caption:=IntToStr(ButtonHandle);
//Button der zweiten AW betätigen
SendMessage(ButtonHandle, BM_CLICK, 0, 0);
end;

procedure Ttf_steuer.Btn_wiederherstellenClick(Sender: TObject);
begin                
ParentHandle:=FindWindow(nil,'Empfang');
LHandle.Caption:=IntToStr(ParentHandle);
//Wiederherstellen der zweiten AW
ShowWindow(ParentHandle,1);
end;

procedure Ttf_steuer.rg_nachricht_steuerClick(Sender: TObject);
begin
ParentHandle:=FindWindow(nil,'Empfang');
PostMessage(HWND_BROADCAST,WM_SELECTRADIOBUTTON,rg_nachricht_steuer.ItemIndex,0);
end;

end.
In der letzten prozedur(rg_nachricht_steuerClick) wird geBROADCASTet mit der Message WM_SELECTRADIOBUTTON und dem "Übergabewert"
rg_nachricht_steuer.ItemIndex(Radiogroup)

Unit mit der Konstanten

Delphi-Quellcode:
unit UBotschaften;

interface
 uses Messages;

 const
 WM_SELECTRADIOBUTTON = (WM_USER+5);
 WM_GETAPPHANDLE = (WM_USER+6);
implementation

end.
hier ist die Message als Konstante Deklariert auf welche Sender und Empfänger zugreifen.


Empfängerprogramm

Delphi-Quellcode:
unit UEmpfang;

interface

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

type
  Ttf_empfang = class(TForm)
    Btn_Empfang: TButton;
    rg_nachricht: TRadioGroup;
    LHandle: TLabel;
    LBHandle: TLabel;
    LRGHandle: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Btn_EmpfangClick(Sender: TObject);
  private
    { Private-Deklarationen }
  protected
    procedure SelectRadioButton(var Msg: TMsg; var Handeled: boolean);
  //  procedure XX(var msg: TMessage); message WM_SELECTRADIOBUTTON;
  public
    { Public-Deklarationen }
  end;

var
  tf_empfang: Ttf_empfang;

implementation

{$R *.dfm}
procedure Ttf_empfang.SelectRadioButton(var Msg : TMsg; var Handeled : boolean);
begin
case Msg.message of
 WM_SELECTRADIOBUTTON : begin
                        beep;
                        rg_nachricht.ItemIndex:=Msg.wParam;
                        end;
 end;
end;

procedure Ttf_empfang.Btn_EmpfangClick(Sender: TObject);
begin
case rg_Nachricht.ItemIndex of
 0:ShowMessage('Nachricht EINS ausgewählt');
 1:ShowMessage('Nachricht ZWEI ausgewählt');
 2:ShowMessage('Nachricht DREI ausgewählt');
 3:ShowMessage('Nachricht VIER ausgewählt');
 4:ShowMessage('Nachricht FÜNF ausgewählt');
 end;
end;

procedure Ttf_empfang.FormCreate(Sender: TObject);
begin
Application.OnMessage:=SelectRadioButton;
end;

{procedure Ttf_empfang.XX(var msg: TMessage);
begin
rg_nachricht.ItemIndex:=msg.WParam;
end; }

end.
Dem Empfänger wird im FormCreate der Application.OnMessage Die prozedur SelectRadioButton zugewiesen,
in welcher auf die gesendete Message abgefragt wird und bei der Bestätigung eben eine Nachricht angezeigt werden sollte. Aber aus irgendwelchen Gründen funktioniert es nicht.

Sag mir einfach wo hier mein Denkfehler liegt:

mit der Prozedur XX im Empfänger funktioniert es.
Ohne, d.h. mit der Zuweisung an Application.OnMessage funktioniert es nicht, was es aber sollte.Warum?

Flocke 5. Okt 2005 08:07

Re: Application Handle einer fremden Application bekommen?
 
Vorab: wie ich schon zwei Mal geschrieben habe, solltest du keine selbsterdachten Meldungsnummern broadcasten. Zur Verdeutlichung:
Delphi-Quellcode:
// Ausgedachte Nummer
const
  WM_SELECTRADIOBUTTON = (WM_USER+5);

// Systemweit eindeutige Nummer
var
  WM_SELECTRADIOBUTTON;

// ... zur Initialisierung:
WM_SELECTRADIOBUTTON := RegisterWindowMessage('WM_SELECTRADIOBUTTON');
Weiter:

eine direkten Fehler kann ich nicht entdecken, bis auf die Ausnahme, dass du in SelectRadioButton nicht auf das Handle der Anwendung bzw. des Hauptfensters prüfst.

Nebenbei: Application.Handle ist auch ein Fensterhandle (sonst könnte man ja keine Nachrichten dort hin schicken), nur eben das des (unsichtbaren) Anwendungsfensters, dessen Titel in der Taskleiste eingeblendet wird.

Das sollte deine Anwendung aber nicht daran hindern, einen Piepton auszugeben. Ist das denn genau der Fehler, dass in SelectRadioButton keine Nachrichten ankommen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:50 Uhr.

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