AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Ärger mit Shellexecute

Ein Thema von Delbor · begonnen am 29. Mai 2022 · letzter Beitrag vom 4. Jun 2022
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.340 Beiträge
 
Delphi 12 Athens
 
#1

AW: Ärger mit Shellexecute

  Alt 30. Mai 2022, 14:40
Natürlich nicht.

Du setzt die Platzierung (Position/Placement) über die Position,
aber du setzt nicht den Parent, also die Form in dein Panel.

MSDN-Library durchsuchenSetParent
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.192 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Ärger mit Shellexecute

  Alt 31. Mai 2022, 19:00
Hi zusammen

Im Moment ist vor allem das eine Handle nil(0):
Delphi-Quellcode:
        aWnd:=FindWindow(PChar('Ashampoo PDF'), nil);
          if aWnd<>0 then
          begin
            Winapi.Windows.SetParent(awnd,OfficerAlexMain.tbsAppParent.Handle);
          end;
Ich hab bisher noch weiter gesucht und mit verscchiedenen Codeversionne gearbeitet - wenn aWnd 0 ist, nützt das alles nichts.
Ich habe auch eine
Delphi-Quellcode:
procedure TOfficerAlexMain.FindPaint;
var aWnd : Hwnd;
    WPM : TWindowPlacement;
    Rect : TRect;
begin
  aWnd:=Findwindow('paint.net',nil);
  if aWnd<>0 then begin
    Winapi.Windows.SetParent(awnd,OfficerAlexMain.tbsAppParent.Handle);
    WPM.Length:=SizeOf(WPM);
    GetWindowPlacement(awnd,@WPM);
    Rect.Top :=0;
    Rect.Left :=0;
    Rect.Right :=Panel1.Width;
    Rect.Bottom:=Panel1.Height;
    wpm.rcNormalPosition:=Rect;
    SetWindowPlacement(awnd,@WPM);
    end;
end;
von zwei ähnlichen Prozeduren mal separat als Reaktion auf einen Button nachgebaut:
Delphi-Quellcode:
procedure TOfficerAlexMain.FindPaint;
var aWnd : Hwnd;
    WPM : TWindowPlacement;
    Rect : TRect;
begin
  aWnd:=Findwindow('paint.net',nil);
  if aWnd<>0 then begin
    Winapi.Windows.SetParent(awnd,OfficerAlexMain.tbsAppParent.Handle);
    WPM.Length:=SizeOf(WPM);
    GetWindowPlacement(awnd,@WPM);
    Rect.Top :=0;
    Rect.Left :=0;
    Rect.Right :=Panel1.Width;
    Rect.Bottom:=Panel1.Height;
    wpm.rcNormalPosition:=Rect;
    SetWindowPlacement(awnd,@WPM);
    end;
end;
Hier und in meinen bisherigen Umsetzungen ist die Variable aWnd immer 0, womit der darunter folgende Code nicht ausgeführt wird.

Wieso das?

Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#3

AW: Ärger mit Shellexecute

  Alt 31. Mai 2022, 19:44
Wenn es das Paint.net ist das ich meine ist es normal das du kein Handle (HWND) bekommst
denn dein Class Name stimmt nicht und dieser ändert sich mit jeden neuem Start der Anwendung.
Prüfe den Classnamen einfach mal mit einer Spy Anwendung.

Paint.net vers. 4.3.11

1 Start
WindowsForms10.Window.8.app.0.24cbd2a_r3_ad1
2 Start
WindowsForms10.Window.8.app.0.2428e43_r3_ad1

TIP:
Versuche es einfach mal mit dem Window Title.

Geändert von venice2 (31. Mai 2022 um 19:47 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.656 Beiträge
 
Delphi 12 Athens
 
#4

AW: Ärger mit Shellexecute

  Alt 31. Mai 2022, 19:45
Hast Du es mal mit WinSpy versucht? Damit bekommt man sehr schön heraus, wie man an das Fensterhandle kommt.
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 KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Ärger mit Shellexecute

  Alt 31. Mai 2022, 19:56
Vielleicht hilft dir mein code schnippsel weiter um ans ziel zu gelangen.
Delphi-Quellcode:
type
  TExec = packed record
    Filename : string;
    PID : DWORD;
    WindowHandle : HWND;
  end;

var
  Exec: TExec;

procedure ResetExec;
begin
  Exec.Filename := '';
  Exec.PID := 0;
  Exec.WindowHandle := 0;
end;

function EnumWindowsProc(Wnd : HWND; ProcessID : Cardinal) : Boolean; stdcall;
var
  PID : Cardinal;
begin
  GetWindowThreadProcessId(Wnd, @PID);
  if ProcessID = PID then
    Exec.WindowHandle := Wnd;
  Result := True;
end;

function ExecFile(const AFilename: string): Boolean;
var
  Executable : string;
  Security : TSecurityAttributes;
  ProcessInfo: TProcessInformation;
  StartupInfo: TStartupInfo;
  dummy : HINST;
begin
  Result := False;
  ResetExec;

  if (not FileExists(AFilename)) then
    Exit;

  SetLength(Executable, MAX_PATH);
  dummy := FindExecutable(PChar(AFilename), nil, PChar(Executable));
  if dummy > 32 then
  begin
    SetLength(Executable, StrLen(PChar(Executable)));
    UniqueString(Executable);

    Security.nLength := SizeOf(TSecurityAttributes);
    Security.lpSecurityDescriptor := nil;
    Security.bInheritHandle := False;

    FillChar(StartupInfo, SizeOf(TStartupInfo), #0);
    StartupInfo.cb := SizeOf(TStartupInfo);
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
    StartupInfo.wShowWindow := SW_SHOWNORMAL {SW_HIDE};

    Win32Check(CreateProcess(PChar(Executable), PChar(Format('%s %s', [Executable, AFilename])), @Security, @Security, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, PChar(ExtractFilePath(Executable)), StartupInfo, ProcessInfo));
    try
      WaitForInputIdle(ProcessInfo.hProcess, INFINITE);
      Exec.Filename := Executable;
      Exec.PID := ProcessInfo.dwProcessId;
      EnumWindows(@EnumWindowsProc, LPARAM(Exec.PID));
    finally
      CloseHandle(ProcessInfo.hProcess);
      CloseHandle(ProcessInfo.hThread);
      Result := True;
    end;
  end;
end;
nach dem aufruf steht in globaler variable Exec.WindowHandle was du brauchst. Ist ein Versuch Wert.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.192 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Ärger mit Shellexecute

  Alt 1. Jun 2022, 07:55
Hi zusammen

Ich hab mir gestern abend das von DeddyH vorgeschlagene Wynspy mal 'installiert', aber heute morgen nichts davon vorgefunden, ausser dass mir Windows unter 'Zuletzt neu hinzugefügt' Delphi Alexandria meldet. Das hab ich gestartet und hatte bislang den Eindruck eines gewöhnlichen Delphi-Starts, bin allerdings noch nicht alle Menuepunkte durchgegangen.
Den Code von CodeZwerg werd ich mir mal in eine Unit/Klasse packen.

Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Ärger mit Shellexecute

  Alt 1. Jun 2022, 09:30
Den Code von CodeZwerg werd ich mir mal in eine Unit/Klasse packen.
Bin gespannt was dabei rauskommt, bei meiner Variante ist der ClassName völlig egal da ich über die erzeugte ProcessID das Fensterhandle versuche zu holen.
Diese Methodik funktioniert zu 100% immer zuverlässig solange das "ExecFile" kein "Wrapper" für andere Executables ist (Programm A lädt beim start Programm B oder Fenster wird in DLL erzeugt... etc) bzw solange die ProcessID ein Fenster besitzt.

Wenn Du noch Fragen dazu haben solltest, ich hoffe ich kann Dir weiterhelfen.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.555 Beiträge
 
Delphi 7 Professional
 
#8

AW: Ärger mit Shellexecute

  Alt 1. Jun 2022, 09:50
Muss es unbedingt Ashampo zur Anzeige von PDF-Dateien sein?

Wenn nein: Bei mir ist seit 'ner Weile Sumatra im Einsatz. Klappt so gut, dass es mir nicht mher auffällt, dass ich da "was fremdes" in meine Programme einbette.

Zuerst wird geprüft, ob Sumatra vorhanden ist, wenn ja, wird es genutzt. Sollte es nicht gefunden werden, wird es mit dem AcrobatReader versucht. Den Teil kann man aber auch entfernen, wenn die Nutzung vom Acrobat ausgeschlossen werden soll.

Da ich nur Delphi 7 habe, wirst Du im folgenden Quelltext vermutlich einige Anpassungen vornehmen müssen.

Zuerst die DFM:
Delphi-Quellcode:
object fmPDFVorschau: TfmPDFVorschau
  Left = 476
  Top = 60
  Width = 249
  Height = 138
  Caption = 'PDF-Vorschau'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  KeyPreview = True
  OldCreateOrder = False
  OnCreate = FormCreate
  OnKeyDown = FormKeyDown
  OnResize = FormResize
  OnShow = FormResize
  PixelsPerInch = 96
  TextHeight = 13
  object pnPDF: TPanel
    Left = 0
    Top = 0
    Width = 241
    Height = 111
    Align = alClient
    BevelOuter = bvNone
    TabOrder = 0
  end
end
und dann die dazugehörige Unit:
Delphi-Quellcode:
unit uPDFVorschau;

interface

uses
  AcroPDFLib_TLB,
  Forms,
  Classes,
  Controls,
  ExtCtrls;

type
  TfmPDFVorschau = class(TForm)
    pnPDF: TPanel;
    procedure FormResize(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure FormCreate(Sender: TObject);
  protected
    procedure CreateParams(var Params: TCreateParams) ; override;
  private
    { Private-Deklarationen }
    fAcroPDF : TAcroPDF;
    fPDFFile : String;
    fUseSumatraPDF : Boolean;
  public
    { Public-Deklarationen }
    procedure LoadPDF(APdfFile : String);
    procedure LoadArcoPDF;
    procedure LoadSumatraPdF;
    property PDFFile : String read fPDFFile;
    property UseSumatraPDF : Boolean read fUseSumatraPDF write fUseSumatraPDF default false;
  end;

var
  fmPDFVorschau: TfmPDFVorschau;

implementation

{$R *.dfm}

uses
  Windows,
  SysUtils,
  ShellAPI;

const
  csCaption = 'PDF-Vorschau - %s';

// Eigenen Button in die Taskbar machen, damit man per STRG+TAB zwischen den
// Fenstern wechseln kann. Der eingebettet Acrobat nimmt sich leider das Recht
// heraus alle Tastaturkürzel zu ignorieren, wenn sie vom Programm sind und
// sich selbst so in den Focus zu setzen, dass man nicht per Mausklick ...
// problemlos mit dem Programm arbeiten kann.
procedure TfmPDFVorschau.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  Params.WndParent := 0;
end;

procedure TfmPDFVorschau.FormCreate(Sender: TObject);
begin
  // Das muss ggfls. angepasst werden.
  fUseSumatraPDF := FileExists('.\Lib\SumatraPDF.exe');
end;

procedure TfmPDFVorschau.FormResize(Sender: TObject);
begin
  if not fUseSumatraPDF then begin
    if Assigned(fAcroPDF) then begin
      if fAcroPDF.Visible then begin
        fAcroPDF.LoadFile(fPDFFile);
        fAcroPDF.Update;
      end;
    end;
  end else
  if Assigned(pnPDF) then begin
    pnPDF.Align := alTop;
    Application.ProcessMessages;
    pnPDF.Align := alClient;
  end;
end;

procedure TfmPDFVorschau.LoadPDF(APDFFile : String);
begin
  fPDFFile := APDFFile;
  Caption := Format(csCaption,[ChangeFileExt(ExtractFileName(fPDFFile),'')]);
  case fUseSumatraPDF of
    true : LoadSumatraPDF;
    false : LoadArcoPDF;
  end;
end;

procedure TfmPDFVorschau.LoadArcoPDF;
begin
  Screen.Cursor := crHourGlass;
  if Assigned(pnPDF) then pnPDF.Visible := False;
  if not Assigned(fAcroPDF) then begin
    fAcroPDF := TAcroPDF.Create(Self);
    fAcroPDF.Parent := Self;
    fAcroPDF.Left := 0;
    fAcroPDF.Top := 0;
    fAcroPDF.Width := Width;
    fAcroPDF.Height := Height;
    fAcroPDF.TabStop := False;
    fAcroPDF.Align := alClient;
    fAcroPDF.ParentShowHint := False;
    fAcroPDF.ShowHint := True;
    fAcroPDF.TabOrder := 0;
    fAcroPDF.Visible := True;
  end;
  fAcroPDF.src := fPDFFile;
  fAcroPDF.LoadFile(fPDFFile);
  Screen.Cursor := crDefault;
  Show;
end;

procedure TfmPDFVorschau.LoadSumatraPDF;
var
  sParam : String;
begin
  Screen.Cursor := crHourGlass;
  if Assigned(fAcroPDF) then fAcroPDF.Visible := False;
  // Caption := Format(csCaption,[fPDFFile]);
  // -reuse-instance funktioniert nur, wenn immer die gleiche Datei geladen wird,
  // andernfalls entsteht für jede PDF-Datei eine neue Instanz von SumatraPDF.
  // Die Instanzen von SumatraPDF werden beendet, wenn man das Programm beendet.
  // Bei diesem Vorgehen entsteht aber nur eine Instanz von SumatraPDF.
  pnPDF.Free;
  Sleep(1000); // Warten, bis sich SumatraPDF beendet hat.
  pnPDF := TPanel.Create(Self);
  pnPDF.Parent := Self;
  pnPDF.Left := 0;
  pnPDF.Top := 0;
  pnPDF.Width := Width;
  pnPDF.Height := Height;
  pnPDF.BevelOuter := bvNone;
  pnPDF.TabOrder := 1;
  pnPDF.Align := alClient;
  pnPDF.Visible := True;
  sParam := Format('-lang de -reuse-instance -plugin %d "%s"',[pnPDF.Handle,fPDFFile]);
  ShellExecute(Self.Handle,'open',PAnsiChar('SumatraPDF.exe'),PAnsiChar(sParam),'',sw_normal);
  Screen.Cursor := crDefault;
  Show;
end;

procedure TfmPDFVorschau.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  case key of 27 : Close; end;
end;

end.
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
3.034 Beiträge
 
Delphi 12 Athens
 
#9

AW: Ärger mit Shellexecute

  Alt 1. Jun 2022, 11:06
Hi zusammen

Ich hab mir gestern abend das von DeddyH vorgeschlagene Wynspy mal 'installiert', aber heute morgen nichts davon vorgefunden, ausser dass mir Windows unter 'Zuletzt neu hinzugefügt' Delphi Alexandria meldet. Das hab ich gestartet und hatte bislang den Eindruck eines gewöhnlichen Delphi-Starts, bin allerdings noch nicht alle Menuepunkte durchgegangen.
Den Code von CodeZwerg werd ich mir mal in eine Unit/Klasse packen.

Gruss
Delbor
Ich glaube nicht, das WinSpy was in der Delphi IDE ist.
Das ist denke ich ein separat aufrufbares Programm, welches einem alle handles usw. anzeigt.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.656 Beiträge
 
Delphi 12 Athens
 
#10

AW: Ärger mit Shellexecute

  Alt 1. Jun 2022, 11:31
Einfach auf den Link Klicken, dann sieht man, dass das ein Programm des DP-Mitglieds toms ist
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
Antwort Antwort


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:42 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