Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   FindWindow (https://www.delphipraxis.net/191624-findwindow.html)

derseitzer 3. Feb 2017 10:11

FindWindow
 
Hallo Leute,
Ich habe mir 2 Delphi Programme gemacht und möchte nun vom Prog1 das Prog2 steuern.
im Prog1 steht unter anderem dieser Buttonclick:

Code:
procedure TForm1.Button1Click(Sender: TObject);
var
  hWnd: THandle;
  hBtn: THandle;
begin
  hWnd := FindWindow(nil, 'Gesteuert');
  if hWnd <> 0 then
  begin
    hBtn := FindWindowEx(hWnd, 0, nil, 'Button');
    if hBtn <> 0 then
    begin
      SendMessage(hBtn, BM_CLICK, 0, 0);
    end
    else
      ShowMessage(SysErrorMessage(GetLastError));
  end
  else
    ShowMessage(SysErrorMessage(GetLastError));
end;
im Prog2 habe ich aus Testzwecken nur einen Button. Name UND caption des Buttons(eig ja Panel aber egal) ist 'Button' und der Formname von Prog2 UND caption ist "Gesteuert".
Ich bekomme KEINE showmessage, was mich sehr verwirrt.. wenn ich andere Sachen eingeben bekomme ich die showmessage. Das, was passieren soll, wenn ich auf den "Button" klicke, passiert nicht..
Wo liegt denn mein Fehler? :shock:

P.s. Code ist von "Luckie" hier aus der Delphi-Praxis :))

Der schöne Günther 3. Feb 2017 10:25

AW: FindWindow
 
Der Doku zu BM_CLICK nach wäre es eine Idee mal zu schauen ob es daran liegt dass dein "Prog2" wohl nicht aktiv ist. Wie soll in einem nicht-aktiven Fenster auch ein Button gedrückt werden können?

Nur so als Idee...

derseitzer 3. Feb 2017 10:38

AW: FindWindow
 
Hört sich nach einem guten Grund an.. habe mal einen Timer vorgeschaltet, dann die andere Form angeklickt und gewartet.. passiert allerdings auch nichts :( .
Dann muss ich das wohl mit tasten simulationen machen? nicht sehr elegant :|

Also wie es scheint hat es schon jemand hinbekommen mit dem oben genannten befehl sendmessage(....)
http://www.delphipraxis.net/158316-b...anwendung.html

himitsu 3. Feb 2017 11:18

AW: FindWindow
 
Das sind deine Programme, also können/sollen sie sich "intern" unterhalten und garnicht erst versuchen ihre GUI zu misshandeln.

Stichwort: Inter-Process Communication (IPC) -> Pipes/NamedPips, MailSlots, MemoryMappedFiles (MMF), TCP/IP, richtige Messages (MSDN-Library durchsuchenRegisterWindowMessage) uvm.

ZYLAGON 3. Feb 2017 20:04

AW: FindWindow
 
Hallo derseitzer,

ersetze einfach mal
Delphi-Quellcode:
SendMessage(hBtn, BM_CLICK, 0, 0);
durch
Delphi-Quellcode:
SendMessage(hBtn, WM_LBUTTONDOWN, 0, 0);
SendMessage(hBtn, WM_LBUTTONUP, 0, 0);
ZYL

himitsu 4. Feb 2017 01:21

AW: FindWindow
 
Ach ja, Delphi-Fenster sind "Windows" (CreateWindow) und keine "Dialoge" (CreateDialog/CreateDialogIndirect).

BM_CLICK ist aber eine DialogMessage.

Und selbst wenn es ein Dialog wäre, sagt die Hilfe auch noch
Zitat:

Remarks
If the button is in a dialog box and the dialog box is not active, the BM_CLICK message might fail. To ensure success in this situation, call the SetActiveWindow function to activate the dialog box before sending the BM_CLICK message to the button.
Bei Windows verarbeitet das Control (hier der Button) selber seine Klick-Events und bei Dialogs steckt die Event-Behandlung im Dialog (das Hauptfenster)

t.roller 4. Feb 2017 06:35

AW: FindWindow
 
Liste der Anhänge anzeigen (Anzahl: 1)
Statt jedes einzelne Objekt zu suchen, ist es ausreichend, nur das Empfänger-Window zu suchen und dem die Messages zu senden.
Delphi-Quellcode:
SENDER:

var
  Form1: TForm1;
  aWnd : HWND;

const
    WM_MY_MESSAGE = WM_USER + 10; //1034

implementation

{$R *.dfm}

procedure TForm1.bnMINIMIZEClick(Sender: TObject);
begin if aWnd<>0 then Postmessage(aWnd,WM_SYSCOMMAND, SC_MINIMIZE,0); end;

procedure TForm1.bnRESTOREClick(Sender: TObject); // SC_RESTORE
begin
aWnd := FindWindow(NIL, 'WindowProc');
  if aWnd<>0 then
  BEGIN
      Postmessage(aWnd,WM_SYSCOMMAND, SC_RESTORE,0);
      SetForegroundwindow(aWnd);
      SendMessage(aWnd, WM_SYSCOMMAND, SC_RESTORE, aWnd);
  END;
end;

procedure TForm1.Button9Click(Sender: TObject);
begin
SendMessage(aWnd, WM_MY_MESSAGE, 123, 1);
SendMessage(aWnd, WM_MY_MESSAGE, 123, 2);
SendMessage(aWnd, WM_MY_MESSAGE, 123, 3);
SendMessage(aWnd, WM_MY_MESSAGE, 123, 4);
SendMessage(aWnd, WM_MY_MESSAGE, 123, 5);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin aWnd := FindWindow(NIL, 'WindowProc'); end; //sucht Empfänger

procedure TForm1.bnCLOSEClick(Sender: TObject);
begin
if aWnd<>0 then Postmessage(aWnd,WM_SYSCOMMAND,SC_CLOSE,0); //Close Empfänger
Application.Terminate; //Close Sender
end;

end.
//---------------------------------------------------------
EMPFÄNGER:

  protected
    procedure WndProc(var Message: TMessage); override;
  end;

var
  Form1: TForm1;

const
    WM_MY_MESSAGE = WM_USER + 10; //1034

implementation

{$R *.dfm}

procedure TForm1.WndProc(var Message: TMessage);
begin
  inherited;
  case Message.Msg of
    WM_MY_MESSAGE: BEGIN
      case Message.LParam of
      1: PostMessage(Button1.Handle, BM_CLICK, 0, 0);
      2: PostMessage(Button2.Handle, BM_CLICK, 0, 0);
      3: PostMessage(Button3.Handle, BM_CLICK, 0, 0);
      4: PostMessage(Button4.Handle, BM_CLICK, 0, 0);
      5: PostMessage(Button5.Handle, BM_CLICK, 0, 0);
      end;
    END;
  end;
end;

procedure TForm1.bnCLEARClick(Sender: TObject);
begin Memo1.clear; end;

procedure TForm1.Button1Click(Sender: TObject);
begin Memo1.Lines.Add('B1'); end;

procedure TForm1.Button2Click(Sender: TObject);
begin Memo1.Lines.Add('B2'); end;

procedure TForm1.Button3Click(Sender: TObject);
begin Memo1.Lines.Add('B3'); end;

procedure TForm1.Button4Click(Sender: TObject);
begin Memo1.Lines.Add('B4'); end;

procedure TForm1.Button5Click(Sender: TObject);
begin Memo1.Lines.Add('B5'); end;

himitsu 4. Feb 2017 07:39

AW: FindWindow
 
Zu dem Beispiel:
  • Prozessübergreifend keine UserMessages (WM_USER), sondern besser MSDN-Library durchsuchenRegisterWindowMessage verwenden.
    WM_USER sind nur für das eine Objekt, bzw. für diesen Objekt-Typ (Klasse) gültig.
    WM_APP sind global in der Anwendung gültig. (alle Fensterklassen der Anwendung kennen entweder diese ID nicht, oder sie haben hinter der Message-ID die gleiche Funktion liegen)
    Sollte man mal "ausversehn" ein falsches Objekt erwischen und das hat zufällig eine Message mit der gleichen ID, dann passiert wer weiß was und das will niemand.
  • Kein BM_CLICK, wie es schon mehrmals genannt wurde.
  • Und warum greifst du in deinem Code auf die globale Variable Form1 zu? (aus der TForm1-Instanz heraus)

t.roller 4. Feb 2017 07:51

AW: FindWindow
 
Zitat:

Zitat von himitsu (Beitrag 1360797)
Zu dem Beispiel:
...Und warum greifst du in deinem Code auf die globale Variable Form1 zu? (aus der TForm1-Instanz heraus)

Das ist ein typischer Copy&Paste-Fehler aus einem anderen Programm, das parallel in einer anderen IDE liegt. Ich habe es oben geändert.

t.roller 4. Feb 2017 13:08

AW: FindWindow
 
Zitat:

Zitat von himitsu (Beitrag 1360797)
Sollte man mal "ausversehn" ein falsches Objekt erwischen und das hat zufällig eine Message mit der gleichen ID, dann passiert wer weiß was und das will niemand.

Stimmt! Ich habe vor einigen Monaten eine sowjetische "vergessene" Atombombe in der Nähe von Dresden gefunden und versuche seitdem, die richtigen Wparam- und Lparam-Werte herauszufinden.
Das kann noch Jahre dauern...

Luckie 4. Feb 2017 13:58

AW: FindWindow
 
Zitat:

Zitat von himitsu (Beitrag 1360793)
Ach ja, Delphi-Fenster sind "Windows" (CreateWindow) und keine "Dialoge" (CreateDialog/CreateDialogIndirect).

BM_CLICK ist aber eine DialogMessage.

Hä? Das wäre mir neu, dass die Nachricht nur mit Dialogen funktioniert. Im Gegenteil: https://msdn.microsoft.com/de-de/lib...(v=vs.85).aspx

EWeiss 4. Feb 2017 15:44

AW: FindWindow
 
Zitat:

Zitat von Luckie (Beitrag 1360808)
Zitat:

Zitat von himitsu (Beitrag 1360793)
Ach ja, Delphi-Fenster sind "Windows" (CreateWindow) und keine "Dialoge" (CreateDialog/CreateDialogIndirect).

BM_CLICK ist aber eine DialogMessage.

Hä? Das wäre mir neu, dass die Nachricht nur mit Dialogen funktioniert. Im Gegenteil: https://msdn.microsoft.com/de-de/lib...(v=vs.85).aspx

Wo ist das Problem?
Die Aussage von @himitsu ist definitiv nicht korrekt.
Fenster ist Fenster ob Dialog oder Window beides wird letztendlich über CreateWindow erstellt.
Wobei beim erstellen des Dialogs lediglich das Ex angehängt wird.
Die Messagen jedoch sind für alle gleich.

Davon sind natürlich spezielle Konstanten wie für, bsp. ListBoxen ausgeschlossen.

Zitat:

The CreateDialog function uses the CreateWindowEx function to create the dialog box
gruss

Luckie 4. Feb 2017 16:06

AW: FindWindow
 
Hier gibt es kein Problem. Wie du schon sagst, habe ich himitsui nur korrigiert. Aber Dialoge werden nicht mit CreateWindowEx erstellt, wie du behauptest, sondern per Ressource.

EWeiss 4. Feb 2017 16:28

AW: FindWindow
 
Zitat:

Zitat von Luckie (Beitrag 1360810)
Hier gibt es kein Problem. Wie du schon sagst, habe ich himitsui nur korrigiert. Aber Dialoge werden nicht mit CreateWindowEx erstellt, wie du behauptest, sondern per Ressource.

Da muss ich dich leider korrigieren.
https://msdn.microsoft.com/de-de/lib...(v=vs.85).aspx

Entweder ist MS doof oder ich..
Habe es doch deutlich als Quote markiert.
Muss mich aber deshalb jetzt nicht streiten du kannst sie ja über Ressourcen erstellen ich verwende CreateWindowEx ;) btw.. wird diese über CreateDialog aufgerufen.

Zitat:

The CreateDialog function uses the CreateWindowEx function to create the dialog box. CreateDialog then sends a WM_INITDIALOG message, bla, bla
gruss

Luckie 4. Feb 2017 20:42

AW: FindWindow
 
Richtig. Aber mit CreateWindowEx kann man auch ganz "normale" Fenster erstellen. Wenn ich CreateWindowEx verwende dann bekomme ich ein normales Fenster. Heißt im Umkehrschluss, dass Dialoge auch nur normale Fenster sind, die aber vom DialogMenager gesteuert werden.

EWeiss 4. Feb 2017 21:21

AW: FindWindow
 
Zitat:

Zitat von Luckie (Beitrag 1360820)
Richtig. Aber mit CreateWindowEx kann man auch ganz "normale" Fenster erstellen. Wenn ich CreateWindowEx verwende dann bekomme ich ein normales Fenster. Heißt im Umkehrschluss, dass Dialoge auch nur normale Fenster sind, die aber vom DialogMenager gesteuert werden.

Korrekt.

gruss

himitsu 4. Feb 2017 21:36

AW: FindWindow
 
Hab mich von dem "the button's parent window to receive a BN_CLICKED notification code" verleiten lassen.

Luckie 4. Feb 2017 21:39

AW: FindWindow
 
OK, haben wir es jetzt? Gut. Prost. :cheers:

derseitzer 7. Feb 2017 11:58

AW: FindWindow
 
Vielen Dank Leute für eure Hilfe!!
Vorallem danke t.roller.. der Code hat mir extrem geholfen!
Nun noch eine Frage, da ich dies nun geschafft hätte dank euch :) wenn ich in ein edit oder memo feld schreiben möchte (von delphi programm 1 in ein anderes programm 2), wie würde das funktionieren?
Viele Dank nochmal :)

derseitzer 7. Feb 2017 12:05

AW: FindWindow
 
Ok ich habe es selbst rausgefunden: antwort: mit wm_settext :)

himitsu 7. Feb 2017 13:03

AW: FindWindow
 
Zitat:

Zitat von derseitzer (Beitrag 1361016)
Ok ich habe es selbst rausgefunden: antwort: mit wm_settext :)

MSDN-Library durchsuchenSetWindowText

derseitzer 7. Feb 2017 13:36

AW: FindWindow
 
Danke!:) und wenn ich nicht die form.caption ändern möchte sondern in ein edit feld schreiben will oder ein memo feld?:/

EWeiss 7. Feb 2017 16:24

AW: FindWindow
 
Zitat:

Zitat von derseitzer (Beitrag 1361022)
Danke!:) und wenn ich nicht die form.caption ändern möchte sondern in ein edit feld schreiben will oder ein memo feld?:/

Neue Frage neuer Thread.

gruss

himitsu 7. Feb 2017 23:50

AW: FindWindow
 
Lies mal die Beschreibung zu der genannten WinAPI. :roll:

Für Windows™ sind alle Controls nur Windows ... also Forms, Edits, Buttons, usw.
Rate mal, warum alle mit MSDN-Library durchsuchenCreateWindow/MSDN-Library durchsuchenCreateWindowEx erstellt werden. :stupid:

derseitzer 8. Feb 2017 08:47

AW: FindWindow
 
Vielen Dank, habe es nun vertsanden;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:49 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