AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Handle von Sub-Fenster anderer Applikation implementieren
Thema durchsuchen
Ansicht
Themen-Optionen

Handle von Sub-Fenster anderer Applikation implementieren

Offene Frage von "torud"
Ein Thema von torud · begonnen am 17. Apr 2010 · letzter Beitrag vom 23. Apr 2010
Antwort Antwort
Seite 1 von 2  1 2      
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#1

Handle von Sub-Fenster anderer Applikation implementieren

  Alt 17. Apr 2010, 13:47
Hallo Wissende,

ich möchte eine andere Application starten und mir das Handle eines der Unter-Forms in den Canvas eines TIMage oder eine TPaintbox zeichnen lassen. Ich weiss, dass das Kollegen mit C# schon gemacht haben.

Wie ich die andere Applikation starte und das Handle des Fenster bekomme, habe ich mir hier im Forum schon zusammen gesucht.

Aber wenn ich dann das erhaltene Handle zuweise bleibt das Image oder die Paintbox leer. Was mache ich da falsch?

Hier mal mein Code:

Delphi-Quellcode:
unit Unit1;

interface

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

type
  PFindWindowStruct = ^TFindWindowStruct;
  TFindWindowStruct = record
    Caption: string;
    ClassName: String;
    WindowHandle: THandle;
end;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Image1: TImage;
    Button1: TButton;
    PaintBox1: TPaintBox;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//sammeln aller infos und schreiben dieser in eine listbox - nur so, zum testen
function EnumWinProc(Wnd: THandle; LParam: LongInt): Boolean; stdcall;
var
 WinCaption : string;
 Len: integer;
begin
 Result := True;
 Len := GetWindowTextLength(Wnd);
 SetLength(WinCaption, Len);
 GetWindowText(Wnd, PChar(WinCaption), Len+1);
 if Trim(WinCaption) <> 'then
   Form1.Listbox1.Items.Add(Format('%.6x : %s', [Wnd, WinCaption]));
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  EnumWindows(@EnumWinProc, 0);
end;

function EnumWindowsProc(hWindow: hWnd; lParam: LongInt): boolean; stdcall;
var lpBuffer: PChar;
    WindowCaptionFound: boolean;
    ClassNameFound: boolean;
begin
  GetMem(lpBuffer, 255);
  result:=true;
  WindowCaptionFound:=false;
  ClassNameFound:=false;
  try
    if GetWindowText(hWindow, lpBuffer,255)>0 then
      if Pos(PFindWindowStruct(lParam).Caption, StrPas(lpBuffer))>0
      then WindowCaptionFound:=true;
    if PFindWindowStruct(lParam).ClassName='then
      ClassNameFound:=true
      else if GetClassName(hWindow, lpBuffer, 255)>0 then
        if Pos(PFindWindowStruct(lParam).ClassName, StrPas(lpBuffer))>0
        then ClassNameFound:=true;
    if (WindowCaptionFound and ClassNameFound) then begin
      PFindWindowStruct(lParam).WindowHandle:=hWindow;
      result:=false;
    end;
  finally
    FreeMem(lpBuffer, sizeof(lpBuffer^));
  end;
end;

function FindAWindow(WinCaption: string; WinClassName: string): THandle;
var WindowInfo: TFindWindowStruct;
begin
  with WindowInfo do begin
    caption := WinCaption;
    className := WinClassName;
    WindowHandle := 0;
    EnumWindows(@EnumWindowsProc, LongInt(@WindowInfo));
    result := WindowHandle;
  end;
end;

//hier wird das fenster gesucht und das handle zugewiesen
procedure TForm1.Button1Click(Sender: TObject);
var TheWindowHandle: THandle;
begin
  TheWindowHandle:=FindAWindow('Renderer', '');
  if TheWindowHandle=0 then
    ShowMessage('Window not found!')
  else
    PaintBox1.Canvas.Handle := (TheWindowHandle);
    PaintBox1.Repaint;

    //ShowWindow(TheWindowHandle, SW_SHOWMINNOACTIVE);

    //hier wird das fenster in den vordergrund geholt
    //allerdings samt des hauptfenstrers der anderen applikation
    //BringWindowToTop(TheWindowHandle); end;

end.
Es ist so, dass ich keine Fehlermeldung erhalte, das Handle wird also korrekt ermittelt.
Ich mache Scheinbar nur noch einen Fehler bei der Übergabe des Handles an die Paintbox, respektive das Image.
Wäre das überhaupt der richtige Weg, oder sollte ich es besser anders machen?
Danke
Tom
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Handle von Sub-Fenster anderer Applikation implementiere

  Alt 17. Apr 2010, 14:00
Zitat von torud:
Hallo Wissende,

ich möchte eine andere Application starten und mir das Handle eines der Unter-Forms in den Canvas eines TIMage oder eine TPaintbox zeichnen lassen.
Der Satz ist Unsinn und ergibt keinen Sinn. Ein Handle kann man nicht zeichnen. Ein Handle ist für Windows nur eine Ziffernfolge, um eine Ressource eindeutig identifizieren zu können.

Ich vermute mal, du willst, die Oberfläche eines Fenster einer anderen Anwendung in eine Paintbox zeichnen.
Delphi-Quellcode:
PaintBox1.Canvas.Handle := (TheWindowHandle);
PaintBox1.Repaint;
Hier weißt du nur dem Canvas der Paintbox ein Handle zu. So geht das nicht. Du musst dir mit MSDN-Library durchsuchenGetDC ein Handle auf das Fenster holen und des dann mit den Zeichenfunktionen (BitBlt, CopyRect, StrechtBlt) auf die Paintbox zeichnen.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#3

Re: Handle von Sub-Fenster anderer Applikation implementiere

  Alt 17. Apr 2010, 14:18
Zitat von Luckie:
Ich vermute mal, du willst, die Oberfläche eines Fenster einer anderen Anwendung in eine Paintbox zeichnen.
Hallo Michael!

Absolut richtig vermutet.

Da ich so was noch nie gemacht habe, kann es schon mal passieren, dass sich falsch ausdrückt und so Mißverständnisse aufkommen.

Ich schaue mal ob ich hier im Forum was zu Deinem Hinweis finde, da mein Englisch leider nicht so doll ist, als dass ich was mit Deinem Link anfangen könnte.

Was ich nicht ganz verstehe ist, dass Du einmal schreibst, dass das mit einem Handle so nicht geht und später schreibst Du dann, dass ich mir mit GetDC ein Handle auf das Fenster holen soll. Ist also das Ergebis über GetDC ein anderes, als das über die FindAWindow-Methode?
Danke
Tom
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: Handle von Sub-Fenster anderer Applikation implementiere

  Alt 17. Apr 2010, 14:20
GetDC holt Dir einen DeviceContext auf die Zeichenfläche des Fensters (also quasi dessen Canvas.Handle).
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#5

Re: Handle von Sub-Fenster anderer Applikation implementiere

  Alt 17. Apr 2010, 14:21
Ja. Zum einem meinte ich, dass mit dem einfachen zu weisen eines Fensterhandles nicht geht und zum anderem brauchst du ein Handle auf den zugehörigen Gerätekontext (Devicecontext), also ein Handle auf die Zeichenfläche des Fensters. Die Eigenschaft Canvas entspricht übrigens dem, was Windows unter einem Gerätekontext versteht.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.540 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: Handle von Sub-Fenster anderer Applikation implementiere

  Alt 17. Apr 2010, 14:31
Hier ein schnell dahingeschludertes Beispiel:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var DC: hDC;
    Wnd: HWnd;
begin
  if ShellExecute(0,'open','calc.exe',nil,nil,SW_SHOW) > 32 then
    begin
      Sleep(500);
      Wnd := FindWindow(nil,'Rechner');
      if Wnd <> 0 then
        begin
          DC := GetDC(Wnd);
          if DC <> 0 then
            begin
              BitBlt(Canvas.Handle,0,0,ClientWidth,ClientHeight,DC,0,0,SRCCOPY);
              ReleaseDC(DC,Wnd);
            end;
        end;
    end;
end;
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#7

Re: Handle von Sub-Fenster anderer Applikation implementiere

  Alt 17. Apr 2010, 14:39
Erstmal vielen Dank für Euren Support und die aufgebrachte Geduld.
Das Beispiel sollte mir sicher helfen den Vorgang zu realisieren und zu verstehen.

Feedback versprochen!
Danke
Tom
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#8

Re: Handle von Sub-Fenster anderer Applikation implementiere

  Alt 17. Apr 2010, 15:38
Also,

grundsätzlich funktioniert der Code schon ganz gut. Es wird zwar zu viel gezeichnet, aber das liegt sicher an den gemachten Angaben im BitBlt.

Ausserdem frage ich mich, wie ich es anstellen soll, dass das zeichnen nicht nur beim Betätigen des Buttons einmalig erfolgt, sondern permanent. Das Beispiel mit dem Rechner finde ich schon ganz gut. Wenn ich also im Rechner eine Rechenopertaion durchführen würde, wäre es klasse, wenn die Aktionen immer alle gezeichnet werden würden.

Ich habe hierzu mal das ReleaseDC(DC,Wnd); aus dem Code entfernt, aber ich bin mir sicher, dass das noch nicht reichen wird. Ich Sollte ich einfach über einen Timer das BitBlt immer wieder aufrufen, oder geht es auch eleganter?
Danke
Tom
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#9

Re: Handle von Sub-Fenster anderer Applikation implementiere

  Alt 17. Apr 2010, 17:08
Nun, wenn etwas in regelmäßigen Intervallen ausgeführt werden soll, dann nimmt man einen Timer.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#10

Re: Handle von Sub-Fenster anderer Applikation implementiere

  Alt 18. Apr 2010, 11:08
Gibt es denn auch die Möglichkeit die Grösse des externen Fensters abzufragen, damit man beim BitBlt auch nur die Grösse zeichnet, die das Fenster hat..?
Danke
Tom
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:54 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