Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1
    Utente di HTML.it L'avatar di Jey
    Registrato dal
    Jan 2013
    Messaggi
    41

    [Delphi] Eseguire un processo all'interno di un panel

    Salve a tutti, come da titolo, il mio obbiettivo è lanciare un eseguibile dal mio applicativo delphi e fare in modo che esso venga mostrato all'interno di un mio panel.
    Nello specifico il mio obiettivo e di eseguire un browser ( come ad esempio firefox ).
    Ora, questi sono i passaggi che faccio:

    -Creo il processo con create process
    -EnumWindows per trovare le finestre dell'applicativo
    -GetClassName della finestra per trovare la finestra principale ( es. IEFrame per i.e. )
    -SetParent dell'HWND della finestra così trovata

    Ora, il tutto funziona correttamente ma, se provassi ad aprire due volte il mio applicativo delphi, soltanto in uno riesco ad aprire firefox, mentre nell'altro avvio firefox ma fallisco nell'EnumWindows e quindi nella SetParent...

    Suggerimenti?

  2. #2
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    posta la porzione di sorgente

  3. #3
    Utente di HTML.it L'avatar di Jey
    Registrato dal
    Jan 2013
    Messaggi
    41
    Ecco i 2 metodi interessati:

    codice:
    implementation
    
    uses
       Messages,
       Classes,
       Windows,
       SysUtils,
       Generics.Collections;;
    
    var
       piUnitPID                        :  DWORD;
       piUnitMainWindowHandle           :  HWND;
       psUnitWindowClassName            :  string;
    
    function EnumWindowsProc( liHWND: HWND; liParam: integer ): boolean; stdcall;
    var
       liPID                            :  DWORD;
       lacBuffer                        :  array[0..MAX_PATH] of Char;
    begin
       Result                           := true;
       try
          Windows.GetWindowThreadProcessId( liHWND, &liPID );
          if( liPID = piUnitPID ) then
          begin
             Windows.GetClassName( liHWND, @lacBuffer, MAX_PATH );
             if ( SameText( UpperCase( string(lacBuffer) ), UpperCase( psUnitWindowClassName ) ) ) then
             begin
                piUnitMainWindowHandle  := liHWND;
                Result                  := false;
             end;
          end;
       except
       end;
    end;
    
    constructor TMyProcess.Create( const lsProcessPath: string; const lsProcessParams: string; const lsWindowClassName: string; loParentHandle: HWND );
    var
       loStartupInfo                    :  TStartupInfo;
       loPocessInfo                     :  TProcessInformation;
    begin
       try
          FillChar( loStartupInfo, SizeOf( loStartupInfo ), #0 );
          FillChar( loPocessInfo, SizeOf( loPocessInfo ), #0 );
          psWindowClassName             := lsWindowClassName;
          with loStartupInfo do
          begin
             cb                         := SizeOf( TStartupInfo );
             dwFlags                    := STARTF_FORCEONFEEDBACK + STARTF_FORCEOFFFEEDBACK;
             wShowWindow                := SW_HIDE;
          end;
          if( CreateProcess( nil,
                             PChar( lsProcessPath + lsProcessParams + ' '),
                             nil,
                             nil,
                             false,
                             CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
                             nil,
                             nil,
                             loStartupInfo,
                             loPocessInfo ) ) then
          begin
             WaitForInputIdle( loPocessInfo.hProcess, 10000 );
             try
                piPID                   := loPocessInfo.dwProcessId;
                piUnitPID               := piPID;
                psUnitWindowClassName   := psWindowClassName;
                EnumWindows( @EnumWindowsProc , 0 );
                SetParent( piUnitMainWindowHandle, loParentHandle );
             except
             end;
          end;
          CloseHandle( loPocessInfo.hProcess );
          CloseHandle( loPocessInfo.hThread );
       except
       end;
    end;
    Così invece è come io creo il mio oggetto:

    codice:
    loProcess      := TMyProcess.Create( 'C:\Program Files (x86)\Mozilla Firefox\firefox.exe', '', 'MozillaWindowClass', Self.Panel1.Handle );

  4. #4
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Per un approccio del genere ti basta una shellexecute con SW_HIDE, poi con findwindow cerchi l'handle e la setti con Setparent, per poi dare la showwindow, praticamente una decina di righe tutto compreso (in sostanza hai "reinventato" funzioni già nella shellapi, basta che la USEs).

    A parte questo, e a parte il fatto che non mi risulta essere supportato la cosa che vuoi fare (se non per oggetti activex importati, ovvero nella fattispecie come twebbrowser e roba del genere), ma posso sempre sbagliare, il punto è come indentificare i vari programmi.
    - per inciso non sono così sicuro sulla sincronicità dell'avvio del programma, così a "occhio" è da verificare fine inciso -

    La primissima cosa che mi viene in mente è (a parte usare il relativo programmello a supporto di autoit che mostra praticamente tutto di una finestra) enumerare i relativi PID per differenziarli.
    Questo però funziona direi con chrome in versione standard (tanti PID quante finestre, se non diversamente impostato), mentre per firefox no (un unico PID).

    Non mi è quindi chiarissimissimo come ti aspetti di poter visualizzare un singolo processo in più panel di programmi diversi (ammesso che funzioni senza effetti collaterali).
    Potresti provare qualcosa tipo questo
    http://kb.mozillazine.org/Opening_a_...nother_profile

  5. #5
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    In alternativa puoi provare uno stub Ada

  6. #6
    Utente di HTML.it L'avatar di Jey
    Registrato dal
    Jan 2013
    Messaggi
    41
    No il mio obiettivo non è visualizzare lo stesso processo all'interno di panel di applicazioni differenti.
    Praticamente vorrei che il mio applicativo lanciasse un nuovo processo per firefox o altro e lo "intrappolasse" in un suo panel.
    Ogni mio applicativo crea il suo processo e lo intrappola in modo indipendente rispetto agli altri.

    Es.
    x = mio applicativo
    -Eseguo X
    -X avvia firefox e lo introppola nel suo panel
    -Eseguo un altro X
    -Quest'ultimo avvia nuovamente firefox e lo intrappola nel suo panel

    Finchè eseguo una sola volta X tutto funziona, ma la seconda volta X avvia firefox ma senza riuscire ad intrappolarlo.

  7. #7
    Utente di HTML.it L'avatar di Jey
    Registrato dal
    Jan 2013
    Messaggi
    41
    Ho fatto 2 test cercando di capire un passaggio di ciò che mi hai detto.

    1)
    Avvio il mio applicativo, lui avvia firefox, lo intrappola e tutti felici e contenti.
    Ne avvio un altro, lui avvia firefox e non lo intrappola.

    2)
    Dopo aver chiuso tutto, avvio firefox ( non tramite il mio applicativo )
    Avvio il mio applicativo, lui avvia firefox e non lo intrappola.

    Quindi, se ho capito bene ciò che mi hai detto, anche se ho creato un nuovo processo lui si riferisce comunque, in qualche, a quello già avviato facendomi fallire nell'EnumWindows e quindi nella SetParent, giusto?

  8. #8
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Per quanto ne so NON hai avviato un nuovo processo firefox.
    Se fai un tasklist |find /i "firefox" lo vedi bene.

    Qualche dettaglio
    http://blog.httpwatch.com/2009/02/10...process-model/

    Tuttavia non sarei sicurissimo con le ultime versioni di firefox.
    Ad ogni modo prova a usare chrome (come test) che ha un comportamento di default opposto

  9. #9
    Utente di HTML.it L'avatar di Jey
    Registrato dal
    Jan 2013
    Messaggi
    41
    Confermo, di firefox ce n'è soltanto uno
    Chrome ho provato e non si fa intrappolare

    A questo punto mi rimane solo una cosa da chiederti: c'è un modo per fare quello che sto cercando di fare o non è possibile?

  10. #10
    Utente bannato
    Registrato dal
    Dec 2012
    Messaggi
    679
    Originariamente inviato da Jey
    Confermo, di firefox ce n'è soltanto uno
    Chrome ho provato e non si fa intrappolare

    A questo punto mi rimane solo una cosa da chiederti: c'è un modo per fare quello che sto cercando di fare o non è possibile?
    Ti ho risposto sopra: prova con profili firefox diversi lanciati "al volo".
    Questo dovrebbe creare processi firefox diversi.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.