Einzelnen Beitrag anzeigen

Partikelecho

Registriert seit: 2. Dez 2011
14 Beiträge
 
Delphi 6 Enterprise
 
#4

AW: Nach BringToFront wieder über Tasten navigieren?

  Alt 14. Apr 2012, 17:58
@Dalai:
Ein fremdes Programm bzw. das Hauptfenster von diesem.

@shmia:
Das macht Sinn, guter Vorschlag. Es geht auch "nur" darum in der anderen Anwendung ein paar Klicks zu machen und anschließend mit den Pfeiltasten in meiner kleinen Anwendung ein paar Buttons auszulösen. Praktisch wäre es z.B. auch, wenn die andere Anwendung durch Auslösen einer Taste wieder zu meiner Anwendung springt - dann hätte man selbst die Kontrolle, wann man wieder was in der kleinen App machen möchte.

Aber erstmal eins nach dem andern. Ich habe jetzt im Delphi-Treff eine Funktion gefunden, mit der ich nach Fenstername oder einem Teil davon ODER nach dem Klassennamen eines Fensters suchen kann. Ein Editor hat z.B. im Titel immer " - Editor" stehen, so könnte ich dieses Fenster dann finden. Vorausgesetzt natürlich, es gibt nicht noch ein weiteres.

Delphi-Treff: Handle auf ein Fenster einer anderen Anwendung bekommen:
http://www.delphi-treff.de/tipps/sys...dung-bekommen/

Ich hab jetzt ne Weile gebastelt und habs geschafft die Codes vom Delphi-Treff so gut es geht lazarus-konform bzw. 64-bit konform zu machen.

Delphi-Quellcode:
unit MainForm;

{$mode objfpc}{$H+}

interface

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

type
  PFindWindowStruct = ^TFindWindowStruct;
  TFindWindowStruct = record
    Caption: string;
    ClassName: String;
    WindowHandle: THandle;
  end;
type
  Tfrm_main = class(TForm)
    // Buttons, Labels, ...
    Timer1: TTimer;
    procedure FormActivate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure FormShow(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    // restliche Prozeduren
  private
    FExtWinHandle: THandle;
    { private declarations }
  public
    { public declarations }
  end;

var
  frm_main: Tfrm_main;
  function FindAWindow(WinCaption: String; WinClassName: String): THandle;
  function EnumWindowsProc(hWindow: hWnd; lParam: PtrInt): Bool; stdcall;

implementation

{$R *.lfm}

{ Tfrm_main }

//------------------------------------------------------------------------------

procedure Tfrm_main.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case Key of
  37: // Aktion für VK_LEFT;
  40: // Aktion für VK_DOWN;
  39: // Aktion für VK_RIGHT;
  38: // Aktion für VK_UP;;
  end;
end;

//------------------------------------------------------------------------------

procedure Tfrm_main.FormActivate(Sender: TObject);
begin
  FExtWinHandle := 0;
end;

//------------------------------------------------------------------------------

function EnumWindowsProc(hWindow: hWnd; lParam: PtrInt): Bool; 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, PtrInt(@WindowInfo));
    Result := WindowHandle;
  end;
end;

//------------------------------------------------------------------------------

procedure Tfrm_main.Timer1Timer(Sender: TObject);
var
  FMyHandle: THandle;
begin
  FMyHandle := FindAWindow('- Editor', '');
  if GetForeGroundWindow <> Handle then
  begin
    if FExtWinHandle = 0 then
      FExtWinHandle := GetForeGroundWindow;
    if FExtWinHandle = FMyHandle then
    begin
      BringToFront;
      {if frm_main.WindowState = wsMinimized then
        frm_main.WindowState := wsNormal;
      if not frm_main.Active then
        SetActiveWindow(Application.MainForm.Handle);
      if not frm_main.Focused then
        Application.MainForm.SetFocus;
      SetForegroundWindow(Application.MainForm.Handle);}

    end;
  end;
end;
- Der Timer überprüft im Moment dauerhaft, ob ein Fenster mit dem Namen oder Teilnamen " - Editor" vorhanden ist und führt dann BringToFront aus - Wie wird das Fenster nun so nach vorn gehoben, dass ich es wieder mit den Maustasten bedienen kann?
- Neben BringToFront habe ich auch SetForegroundWindow(Application.MainForm.Handle) bzw. SetActiveWindow(Application.MainForm.Handle), SetFocus, Activate, etc. versucht. Das Fenster kommt nicht vor.

weitere Infos:
- Das Fenster wird nicht minimiert (Stellt euch 2 Notepads vor, die sich teilweise überlappen und man dann eins anklickt -> das andere liegt dann dahinter)
- Das Fenster hat BorderStyle bsDialog und FormStyle fsNormal
- die ganzen im Vordergrund bleiben Geschichten hab ich raus genommen

Geändert von Partikelecho (15. Apr 2012 um 16:04 Uhr)
  Mit Zitat antworten Zitat