Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Enviar KEY a ventana externa (No puedo econtrar mi error) (https://www.clubdelphi.com/foros/showthread.php?t=94146)

MaxiDucoli 25-08-2019 22:18:37

Enviar KEY a ventana externa (No puedo econtrar mi error)
 
Hola Foro.
Estoy teniendo un problema con un programa (en realidad son varios que se ejecutan) que no puedo solucionar.
Les paso a explicar:

Tengo 2 aplicaciones, con la primera inicio, esa aplicación ejecuta con una función que encontré por ahí que se llama EjecutaYEsperar (ejecuta un programa externo y espera que te termine) unos programas, ese anda bien ejecuta lo que necesito al principio (Un video tipo presetación, un programa llamado FMEDIA.EXE que en el título del programa pone la ruta del ejecutable en mi caso D:\RetroLife\tools\Fmedia\fmedia.exe) y ese programa queda de fondo pasando música, lanza el programa principal que es un programa externo que no hice yo (EmulationStation) y ahí queda todo en armonía.

Una vez en EmulationStation y con la música de fondo funcionando (fmedia abierto y minimizado) tengo que ejecutar desde EmulationStation (que es un front-end laucher de emuladores) otra aplicación hecha por mi que lo que hace es en realidad lanzar los emuladores en vez de EmulationStation.
O sea que dirijo EmulationStation hacia mi aplicacion y después por medio de parámetros mi aplicacion los lee y hace lo que quiero (Bueno, eso en teoría por que acá empieza mi problema).

Lo que debería hacer mi segunda aplicación es antes de lanzar el emulador, PAUSAR la música de fondo que está tocando FMEDIA, para eso lo que trato de hacer es capturar el HANDLE de FMEDIA (Lo busco mediane un función y lo encuentra) y con ese HANDLE enviarle a la ventan de FMEDIA la simulación de la tecla ESPACIO.


Pero acá está mi problema. Lo hace con un emulador, pero con dos emuladores no lo hace.
Les dejo el código para ver si me pueden ayudar,
Solo dejo el código de mi lanzador que se llama RLExecutor.exe y de la función con la cual busco el HANDLE mediante el nombre parcial de la ventana de FMEDIA.
Muchas gracias.

RETROLIFE EXECUTOR:

Código Delphi [-]
unit RetroLifeExecutor;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, JvComponentBase, MisFunciones,
  JvTrayIcon, JvBackgrounds,ShellApi, strutils;

type
  TFrmExecutor = class(TForm)
    JvBackground1: TJvBackground;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
           procedure LoadIMG (Splash : TJvBackGround;Ruta:String);
//           procedure EjecutarEmu(EMU,ROM : string);
           function CrearLineaDeComando(EMU,ROM: string) : string;
  end;

var
  FrmExecutor: TFrmExecutor;
  NewDrive,CMDLN : string;
  Contador : integer;
 //  UnProceso: TProcess;

  CONST IMGS : string = '\RetroLife\LaunchIMGS\';

  CONST RETROARCH : string = '\RetroLife\emulators\retroarch\retroarch.exe';

  CONST PS2EMU : String = '\RetroLife\emulators\ps2\pcsx2.exe';

  CONST WIIUEMU : String = '\RetroLife\emulators\wiiu\Cemu.exe';

  CONST CORE : string = '\RetroLife\emulators\retroarch\cores\';

  CONST EMUS : Array [0 .. 54] of string = ('3do'{4DO},'3ds'{CITRA},'atari2600'{STELLA},
  'atari5200','atari7800','atarijaguar','atarilynx','atomiswave','colecovision',
  'dreamcast','fbalphaCPS1','fbalphaCPS2','fba_libretro','fds','gamecube','gamegear','gb','gba','gbc',  'genesis','gw',
  'intellivision','mame2003','mame2003plus','mastersystem','megadrive','n64','naomi','nds','neogeo',
  'nes','ngp','ngpc','pcengine','pcenginecd','pcfx','prboom','ps2','psp','psx',
  'saturn','sega32x','segacd','sg-1000','snes','supergrafx','tg16','tg16cd',
  'wii','wonderswan','wonderswancolor','streets','vectrex','virtualboy','WIIU');

  CONST CORES : Array [0.. 54] of String = ('4do'+'_libretro.dll','citra'+'_libretro.dll',
  'stella'+'_libretro.dll','atari800'+'_libretro.dll','prosystem'+'_libretro.dll',
  'virtualjaguar'+'_libretro.dll','handy'+'_libretro.dll','flycast'+'_libretro.dll',
  'bluemsx'+'_libretro.dll','flycast'+'_libretro.dll','fbalpha2012_cps1'+'_libretro.dll',
  'fbalpha2012_cps2'+'_libretro.dll','fbalpha2012'+'_libretro.dll',
  'nestopia'+'_libretro.dll','dolphin'+'_libretro.dll','genesis_plus_gx'+'_libretro.dll',
  'gambatte'+'_libretro.dll','vba_next'+'_libretro.dll','gambatte'+'_libretro.dll',
  'genesis_plus_gx'+'_libretro.dll','gw'+'_libretro.dll','freeintv'+'_libretro.dll',
  'mame2003'+'_libretro.dll','mame2003_plus'+'_libretro.dll','genesis_plus_gx'+'_libretro.dll',
  'genesis_plus_gx'+'_libretro.dll','mupen64plus_next'+'_libretro.dll','flycast'+'_libretro.dll',
  'desmume'+'_libretro.dll','fbalpha2012_neogeo'+'_libretro.dll','nestopia'+'_libretro.dll',
  'mednafen_ngp'+'_libretro.dll','mednafen_ngp'+'_libretro.dll','mednafen_pce_fast'+'_libretro.dll',
  'mednafen_pce_fast'+'_libretro.dll','mednafen_pcfx'+'_libretro.dll','prboom'+'_libretro.dll',
  'play'+'_libretro.dll','ppsspp'+'_libretro.dll','mednafen_psx'+'_libretro.dll',
  'yabasanshiro'+'_libretro.dll','picodrive'+'_libretro.dll','genesis_plus_gx'+'_libretro.dll',
  'gearsystem'+'_libretro.dll','snes9x'+'_libretro.dll','mednafen_supergrafx'+'_libretro.dll',
  'mednafen_pce_fast'+'_libretro.dll','mednafen_pce_fast'+'_libretro.dll',
  'dolphin'+'_libretro.dll','mednafen_wswan'+'_libretro.dll','mednafen_wswan'+'_libretro.dll',
  'genesis_plus_gx'+'_libretro.dll','vecx'+'_libretro.dll','mednafen_vb'+'_libretro.dll','CMEU');

 implementation



{$R *.dfm}

//uses dprocess;

function TFrmExecutor.CrearLineaDeComando(EMU,ROM : string) : string;
var
EMULATOR,CMD,EMUDIR, PS2EMU,WIIUEMU : string;
i : integer;
begin
EMUDIR := '\' + EMU + '\';
Result :='';
NewDrive := ExtractFileDrive(application.ExeName);
//EMULATOR := NewDrive + RETROARCH;
CMD :='-L "' + NewDrive + CORE;

  if AnsiContainsText(ROM,EMUDIR) then
begin
  for i := 0 to Length(EMUS) -1 do
      begin
        if UpperCase(EMUS[i]) = UpperCase(EMU) then
        begin
        CMD := CMD + CORES[i] + '" ' +  ' "' + ROM + '"';
        CMD := AnsiReplaceText(CMD,'\\','\');
        CMD := AnsiReplaceText(CMD,'..\',NewDrive + '\');

        if EMU = 'PS2' then
          begin
          CMD := '--fullscreen --nogui "' + ROM + '"';
          CMD := AnsiReplaceText(CMD,'\\','\');
          CMD := AnsiReplaceText(CMD,'..\',NewDrive + '\');

        end;

            if EMU = 'WIIU' then
              begin
              CMD := '-f -g "' + ROM + '"';
              CMD := AnsiReplaceText(CMD,'\\','\');
              CMD := AnsiReplaceText(CMD,'..\',NewDrive + '\');
              end;

        Result := CMD;
       end;
  end;
      if Result <> '' then  Result := Result;
end;


end;

procedure TFrmExecutor.FormClose(Sender: TObject; var Action: TCloseAction);
var
J : HWND;
begin
//H := FindWindowExtd('RetroArch');
J := FindWindowExtd('fmedia');

//if (True)I then


      if IsWindow(J) then
          begin
          PostMessage(J,WM_KEYDOWN, VK_SPACE, 0);
      end;

end;

procedure TFrmExecutor.FormCreate(Sender: TObject);
begin
SetCursorPos(-1,-1);
Contador :=0;
NewDrive := ExtractFileDrive(Application.ExeName);
//CMD := NewDrive + RETROARCH + NewDrive + CORE + ParamStr(1) + ' ' + ParamStr(2);
FrmExecutor.Height := Screen.Height;
FrmExecutor.Width := Screen.Width;
LoadIMG(JVBackGround1, NewDrive + IMGS + ParamStr(1) +  '.jpg');
CMDLN := CrearLineaDeComando(paramStr(1),ParamStr(2));
end;

procedure TFrmExecutor.LoadIMG (Splash : TJvBackGround;Ruta:String);
begin
 Splash.Image.Picture.LoadFromFile(ruta);
end;

procedure TFrmExecutor.Timer1Timer(Sender: TObject);
var
i :cardinal;
s: String;
H,J, N : HWND;
begin
Inc(Contador);

if Contador = 3 then
begin

        if ParamStr(1) = 'PS2' then
          begin
          S := NewDrive +  PS2EMU;
        end else
            begin
            if ParamStr(1) = 'WIIU' then
            begin
            S := NewDrive +  WIIUEMU;
            end else
                begin
                S := NewDrive + RETROARCH;
                end;
        end;



//i:= ShellExecute(0,nil,PWideChar(s),PWideChar(CMDLN),nil,SW_HIDE);
//keybd_event(VK_SPACE,

//H := FindWindowExtd('Cemu');
J := FindWindowExtd('\fmedia\');
//N := FindWindowExtd('PCSX2');
  if (IsWindow(J)) then
  begin
        PostMessage(J, WM_KEYDOWN, VK_SPACE, 0);
        if EjecutarYEsperar(s + ' ' +  CMDLN,SW_HIDE) = 0 then
              begin
              Timer1.Enabled := False;
              //ShowMessage(IntToStr(i));
              Close;


              end else
                  begin
//if (IsWindow (H))  then SetWindowPos(H, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE);
//J := FindWindowByTitle('ffplay.exe');
//if ISWindow(J) then SendMessage(J,WM_KEYDOWN, VK_SPACE, 0);
                  contador := 0;
                  Timer1.Enabled := False;
                   end;
  end; // IsWindow(J)
  end; // contador

  end; // procedure

end.

FUNCION QUE ME DEVUELVE EL HANDLE DE FMEDIA.

Código Delphi [-]
function FindWindowExtd(partialTitle: string): HWND;
var
  hWndTemp: hWnd;
  iLenText: Integer;
  cTitletemp: array [0..254] of Char;
  sTitleTemp: string;
begin
  hWndTemp := FindWindow(nil, nil);
  while hWndTemp <> 0 do begin
    iLenText := GetWindowText(hWndTemp, cTitletemp, 255);
    sTitleTemp := cTitletemp;
    sTitleTemp := UpperCase(copy( sTitleTemp, 1, iLenText));
    partialTitle := UpperCase(partialTitle);
    if pos( partialTitle, sTitleTemp ) <> 0 then
      Break;
    hWndTemp := GetWindow(hWndTemp, GW_HWNDNEXT);
  end;
  result := hWndTemp;
end;

escafandra 26-08-2019 01:54:40

Para simular la pulsación de una tecla no debe hacerse enviando mensajes sino simulando de verdad. Hay dos formas, la antigua y obsoleta y la moderna. La primera se basa en la API keybd_event y la segunda se basa en API SendImput. Tienes un ejemplo del primer caso aquí y del segundo, aqui. Ambos están en este hilo: ¿Cómo simular de "verdad" las teclas SHIFT+TAB?

Ten en cuenta que algunas aplicaciones requieren tener el foco para ser sensibles a la pulsación del teclado. En este caso tendrás que dárselo con SetFocus


Saludos.


La franja horaria es GMT +2. Ahora son las 17:12:25.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi