Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Alte Instanz über CmdLine aktivieren\starten (https://www.delphipraxis.net/192847-alte-instanz-ueber-cmdline-aktivieren%5Cstarten.html)

EWeiss 24. Mai 2017 18:52


Alte Instanz über CmdLine aktivieren\starten
 
Ich möchte ein Movie starten wenn meine Anwendung schon aktiv ist.

Ist sie es nicht stellt es kein Problem dar.
Delphi-Quellcode:
      // Commandline Parameter auswerten
      StartParams := '';
      ValidExt := false;
      for Params := 1 to ParamCount do
        StartParams := StartParams + ' ' + ParamStr(Params);

      if length(StartParams) > 0 then
      begin
        try
          Ext := Split(VIDEOEXT, ';');
          Extension := Lowercase(ExtractFileExt(StartParams));

          for IntI := 0 to High(Ext) do
          begin
            if (Ext[IntI] = Extension) then
            begin
              ValidExt := true;
              break;
            end;
          end;
        finally
          if ValidExt then
          begin
            RunMediaFile(PWideChar(StartParams));
            SKAERO_InvalidateRect(MainHandle, false);

            ShowWindow(MovieHandle, SW_SHOW);

            btnPlay.Enabled := false;
            btnPause.Enabled := true;
          end;
        end;
      end;
Wenn die Anwendung startet erstelle ich vorher den Mutex um einen Neustart zu verhindern.
Delphi-Quellcode:
initialization

hMutex := CreateMutex(nil, true, 'KVPlayer');
if GetLastError = ERROR_ALREADY_EXISTS then
  Halt;

finalization

if hMutex <> 0 then
  CloseHandle(hMutex)
Wie kann ich den jetzt umgehen wenn ich mit DragDrop ein Movie auf mein Anwendungsicon ziehe während die Anwendung aktiv ist.
Es soll aber keine zweite Instanz gestartet werden.

gruss

SneakyBagels 24. Mai 2017 19:07

AW: Alte Instanz über CmdLine aktivieren\starten
 
Sobald dein Programm merkt, es gibt schon eine Instanz dann musst du deiner bereits existierenden Instanz über SendMessage die Daten schicken die du schicken willst. z.B. den Pfad zum Film.
In der existierenden Instanz kannst du dann mit
Delphi-Quellcode:
procedure WMCopyDataEx(var msg: TWMCopyData); message WM_COPYDATA;
die Daten abfragen.

Die sind dann in
Delphi-Quellcode:
msg.CopyDataStruct.lpData
drin.

Schicken mit
Delphi-Quellcode:
       var
        aCopyData: TCopyDataStruct;
        hExistingInstance: THandle;

       hExistingInstance := FindWindow(PWideChar('fensterclass'), nil);

       pName := PWideChar('pfad zum film');
       aCopyData.dwData := 0;
       aCopyData.cbData := (StrLen(pName) + 1) * SizeOf(Char);
       aCopyData.lpData := pName;

       SendMessage(hExistingInstance, WM_COPYDATA, 0, Integer(@aCopyData));

EWeiss 24. Mai 2017 19:16

AW: Alte Instanz über CmdLine aktivieren\starten
 
Ich habe die Funktion jetzt ausgelagert.

Delphi-Quellcode:
      // Commandline Parameter auswerten
      if ParamCount > 0 then
        ExecuteCmdLine;
Bei initialization habe ich versucht den Mutex umzuleiten allerdings kracht es dann.
Dürfte aber doch eigentlich nicht oder?

Delphi-Quellcode:
initialization
if GetLastError = ERROR_ALREADY_EXISTS then
begin
  if ParamCount > 0 then
    ExecuteCmdLine
  else
    Halt;
end;
Zitat:

Schicken mit
Schicken tue ich die Datei über DragDrop.

Und starte die EXE mit
Delphi-Quellcode:
          ShellExecute(0, 'open', PWideChar(gS[nObjectID].ShellTo), PWideChar(sCmdLine), PWideChar
              (gS[nObjectID].WorkDir), gS[nObjectID].ShowCmd)
Ich versuch mal was anderes..

gruss

himitsu 24. Mai 2017 19:38

AW: Alte Instanz über CmdLine aktivieren\starten
 
Du willst also dein Singleton mehrmals haben ... dann bau einfach den Code für das SingleInstance aus. :stupid:
Oder bau ein, dass es bei einem bestimmten Parameter nichts prüft. :zwinker:



Zitat:

Delphi-Quellcode:
// Commandline Parameter auswerten
StartParams := '';
ValidExt := false;
for Params := 1 to ParamCount do
  StartParams := StartParams + ' ' + ParamStr(Params);

if length(StartParams) > 0 then
begin
  try
    Ext := Split(VIDEOEXT, ';');
    Extension := Lowercase(ExtractFileExt(StartParams));

    for IntI := 0 to High(Ext) do
    begin
      if (Ext[IntI] = Extension) then
      begin
        ValidExt := true;
        break;
      end;
    end;
  finally
    if ValidExt then
    begin
      RunMediaFile(PWideChar(StartParams));
      SKAERO_InvalidateRect(MainHandle, false);

      ShowWindow(MovieHandle, SW_SHOW);

      btnPlay.Enabled := false;
      btnPause.Enabled := true;
    end;
  end;
end;

Delphi-Quellcode:
// Commandline Parameter auswerten
if ParamCount > 0 then
begin
  ValidExt := false;
  Ext := SplitString(VIDEOEXT, ';');
  Extension := Lowercase(ExtractFileExt(ParamStr(ParamCount))); //Extension := Lowercase(ExtractFileExt(GetCommandLine));

  for IntI := 0 to High(Ext) do
  begin
    if (Ext[IntI] = Extension) then
    begin
      ValidExt := true;
      break;
    end;
  end;
  if ValidExt then
  begin
    RunMediaFile(PChar(GetCommandLine));
    SKAERO_InvalidateRect(MainHandle, false);

    ...
Delphi-Quellcode:
// Commandline Parameter auswerten
if ParamCount > 0 then
begin
  Ext := SplitString(VIDEOEXT, ';');
  Extension := ExtractFileExt(ParamStr(ParamCount)); //Extension := ExtractFileExt(GetCommandLine);
  if AnsiMatchText(Extension, Ext) then
  begin
    RunMediaFile(PChar(GetCommandLine));
    SKAERO_InvalidateRect(MainHandle, false);

    ...
* Delphi-Referenz durchsuchenSplittString
* Delphi-Referenz durchsuchenMatchText
* ParamStr enthält keine " mehr, womit es hoffentlich schön knallt, wenn aus
Delphi-Quellcode:
deine.exe "pfad mit lerzeich.en"
zu
Delphi-Quellcode:
deine.exe pfad mit lerzeich.en
wird
* wenn wenn du nur die Endung des letzten Parameters haben willst, warum nimmst du den dann nicht?

200 Byte gespart, 80% der Codezeilen weg und dafür nur bissl nicht ganz funktionierenden und "doppelten" Code entfernt :D

EWeiss 24. Mai 2017 19:42

AW: Alte Instanz über CmdLine aktivieren\starten
 
nop geht so nicht es starten zwei Instanzen.

initialization

Delphi-Quellcode:
hMutex := CreateMutex(nil, true, 'KVPlayer');
if GetLastError = ERROR_ALREADY_EXISTS then
begin
  if ParamCount > 0 then
    SendMessageW(MainHandle, WM_COMMANDLINE, 0, 0)
  end
  else
    Halt;
end;
sorry!
Es bringt mir nichts wenn du versuchst meinen Code zu optimieren ich weiß schon warum ich lowercase verwende.
Wenn mir jemand das Extension als MP4 anstelle von mp4 oder Mp4 schickt dann benötige ich das lowercase...

Die Extension sind als lowercase definiert wenn ich den übergebenen string nicht vorher zuschneide so das er passt wird das Extension nicht gefunden.
Zitat:

SplittString
MatchText
benötige ich auch nicht. Ich mache das auf meine weise.

Zitat:

und dafür nur bissl nicht ganz funktionierenden
Er funktioniert sonst würde mein Video nicht abspielen oder?
Wie immer es führen viele Wege nach Köln.

gruss

CCRDude 24. Mai 2017 19:49

AW: Alte Instanz über CmdLine aktivieren\starten
 
Warum das else vor dem Halt? Die zweite Instanz muss sich doch auch dann beenden, wenn sie der ersten Instanz etwas übergeben hat...

EWeiss 24. Mai 2017 19:52

AW: Alte Instanz über CmdLine aktivieren\starten
 
Zitat:

Zitat von CCRDude (Beitrag 1372681)
Warum das else vor dem Halt? Die zweite Instanz muss sich doch auch dann beenden, wenn sie der ersten Instanz etwas übergeben hat...

Berechtigt. ;)
Danke werde es mal prüfen.

gruss

EWeiss 24. Mai 2017 21:18

AW: Alte Instanz über CmdLine aktivieren\starten
 
Zitat:

wenn wenn du nur die Endung des letzten Parameters haben willst, warum nimmst du den dann nicht?
Ganz einfach..
Was ist denn der letzte Parameter von der Endung "F:\Mov\Das doppelte Lottchen.mp4"
Und du bist sicher das "Lottchen.mp4" dann abgespielt werden kann? :wink:

@SneakyBagels Danke!
Habe deinen Beitrag etwas angepasst damit funktioniert das soweit.

Delphi-Quellcode:
initialization

hMutex := CreateMutex(nil, true, 'KVPlayer');
if GetLastError = ERROR_ALREADY_EXISTS then
begin
  if ParamCount > 0 then
  begin
    MainHandle := FindWindow('KVIDEOPLAYER', nil);
    pName := PWideChar(ParamStr(ParamCount));
    CopyDataStruct.dwData := 0;
    CopyDataStruct.cbData := (StrLen(pName) + 1) * SizeOf(Char);
    CopyDataStruct.lpData := pName;

    SendMessage(MainHandle, WM_COPYDATA, 0, Integer(@CopyDataStruct));
  end;

  Halt;
end;
Delphi-Quellcode:
    WM_COPYDATA:
      begin
        CopyDataStruct := pointer(Lp);
        ExecuteCmdLine(CopyDataStruct.lpData);
      end;
Delphi-Quellcode:
procedure ExecuteCmdLine(Title: Pointer);
var
  Ext: TSplitStrArray;
  Extension: string;
  ValidExt: Bool;
  IntI: integer;
  pTitle: PWideChar;
begin

  ValidExt := false;
  pTitle := Title;

  if Length(pTitle) > 0 then
  begin
    try
      Ext := Split(VIDEOEXT, ';');
      Extension := Lowercase(ExtractFileExt(pTitle));

      for IntI := 0 to High(Ext) do
      begin
        if (Ext[IntI] = Extension) then
        begin
          ValidExt := true;
          break;
        end;
      end;
    finally
      if ValidExt then
      begin
        if KVideo_HasOverlayImage then
          KVideo_UpdateOverlayImage(0);
       
        RunMediaFile(PWideChar(pTitle));
        SKAERO_InvalidateRect(MainHandle, false);

        ShowWindow(MovieHandle, SW_SHOW);

        btnPlay.Enabled := false;
        btnPause.Enabled := true;
      end;
    end;
  end;
end;
Das ganze ist für die LaunchBar OverTheTaskBar damit wenn ich dort ein Movie auf mein KVideoPlayer Icon ziehe das Video abspielt.

gruss

SneakyBagels 24. Mai 2017 22:40

AW: Alte Instanz über CmdLine aktivieren\starten
 
Bitte sehr. Meine Lösung ist einfach und funktioniert wunderbar.

EWeiss 25. Mai 2017 07:29

AW: Alte Instanz über CmdLine aktivieren\starten
 
Zitat:

Zitat von SneakyBagels (Beitrag 1372704)
Bitte sehr. Meine Lösung ist einfach und funktioniert wunderbar.

:thumb:
Ich wollte es mit einem Ein Zeiler versuchen aber das geht nicht weil der String ohne ihn vorher zu kopieren zwischenzeitlich verloren geht.

gruss


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