Newsgroup: it.comp.lang.delphi
Titolo: Riferimenti multipli a stessa finestra

Salve a tutto il NG.
Qualcuno mi sa dire come ottenere tramite l'handle di una applicazione 
il riferimento alla sua finestra principale ?
Es: eseguo più volte una applicazione (non di mia progettazione) con
shellexecuteEx, e ottengo l'handle che punta al processo di pertineza,
ma l'handle della finestra principale di ogni processo come lo ottengo?
Mi serve per inviare messaggi distinti ad ogni finestra aperta.
 grazie a chi mi vorrà rispondere.
saluti g.devil.
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

il riferimento alla sua finestra principale ?
Dovrebbe essere abbastanza semplice.
Posto che le unit siano tutte dichiarate nel file principale, devi in 
ogni unit secondaria inserire il riferimento di essa in questo modo:
unit uCitta; //unit secondaria
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, 
Forms,
  Dialogs, uTabelle, dxExEdtr, DB, QExport, QExportXLS, QExportDialog,
  Menus, kbmMemTable, kbmMemBinaryStreamFormat, ExtCtrls, IBDatabase,
  IBCustomDataSet, dxCntner, dxTL, dxDBCtrl, dxDBGrid, DBCtrls, ComCtrls,
  ToolWin, dxDBTLCl, dxGrClEx;
type
  TfCitta = class(TfTabella)
    tTabellaOID: TIntegerField;
    tTabellaDESCRIZIONE: TIBStringField;
    tTabellaOID_PROV: TIntegerField;
    tTabellaPROVINCIA: TStringField;
    dxDBGrid1OID: TdxDBGridMaskColumn;
    dxDBGrid1DESCRIZIONE: TdxDBGridMaskColumn;
    dxDBGrid1OID_PROV: TdxDBGridMaskColumn;
    dxDBGrid1PROVINCIA: TdxDBGridExtLookupColumn;
    procedure tTabellaCalcFields(DataSet: TDataSet);
    procedure dxDBGrid1PROVINCIACloseUp(Sender: TObject; var Text: 
String;
      var Accept: Boolean);
    procedure dxDBGrid1PROVINCIAPopup(Sender: TObject;
      const EditText: String);
    procedure tTabellaAfterDelete(DataSet: TDataSet);
    procedure tTabellaAfterPost(DataSet: TDataSet);
    procedure tTabellaBeforeDelete(DataSet: TDataSet);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  fCitta: TfCitta;
implementation
uses udmMatia, udmLookup, Matia, Filter, uModListe; //qui vengono 
inserite le uniti ereditabili, puoi accedere a metodi, proprietà, 
oggetti, e quant'altro appartengano a queste unit.
{$R *.dfm}
Ti ho riportato il codice dove la unit principale deve essere dichiarata.
Per usare i riferimenti di tale unit principale devi scrivere poi in 
questo modo:
Matia: è il nome della unit principale
fMatia: è il nome della form
Messaggio: è il nome della variabile contenuta nella unit principale 
oppure può essere il nome di una procedura o di un componente
La si usa in questo modo:
fMatia.Messaggio1
Non sto a postarti tutto il codice perchè sarebbe troppo lungo, però se 
vuoi capirre come usare al meglio una variabile o un modulo dichiarato 
nella unit secondaria, ti consiglio di scaricare un mio esempio che si 
trova nel mio sito nella sezione programmi in delphi.
Spero de esserti stato utile.
Comunque per richieste sono disponibile all'indirizzo skype 
massimiliano.monti.78 o al cellulare che è sempre acceso apposta per 
questo motivo.
Per iscritto magari mi dilungo o a causa della mia velocità nello 
scrivere posso commettere degli errori che a voce difficilmente commetto.
Poi via sckype posso mandarti al meglio qualche piccolo esempio.
Massimiliano Monti
Cel: 
+39 - 335 - 8477278
Mail: 
massimili...@matia.it
Url: 
http://www.multimodo.com/mmjstudio/
--- posted by geoForum on 
http://www.delphiedintorni.it

 
Grazie per la risposta .. ma forse non mi sono spiegato bene:
l'applicazione in questione è un eseguibile esterno, che possiede
solo una finestra principale, e che NON ho scritto io, e che deve 
essere eseguito più volte contemporaneamente.
Di questo eseguibile devo ottenere handle diversi, riferentesi alla 
relativa finestra.
Ovviamente il nome applicazione sarà sempre lo stesso, e anche la 
caption della relativa finestra.
saluti G.devil


Meaculpa, avevo capito diversamente
Ti posto un mio codice che fa sě che tu non possa aprire n volte lo 
stesso programma.
  private
    { Private declarations }
  public
    { Public declarations }
    LogOk: Boolean;
    Menu: String;
    NumeroLicenza: String;
    sHardwareID: String;
    One: TmxOneInstance; //Variabile che gestisce l'istanza
    giorno, mese, anno, data_blocco: String;
  end;
var
  fLog: TfLog;
implementation
uses udmMatia, uModPsw, udmLookup, Matia, uModChiesa, uLicenza, uStart;
{$R *.dfm}
procedure TfLog.FormCreate(Sender: TObject);
begin
   NumeroLicenza:=dmLookup.Reg_R('','Licenza');
   if (dmLookup.Reg_R('','Seriale')='') and (dmLookup.Reg_R('','Licenza')
='') then
   begin
     with TfLicenza.Create(nil) do
     begin
       showmodal;
       release;
     end;
   end;
   // Formati
   ShortDateFormat:='dd/mm/yy';
   LongDateFormat:='dd mmm yy';
   //Gestisce l'istanza, impedisce che il programma sia aperto n volte.
   One:=TmxOneInstance.Create(nil);
   if dmLookup.Reg_R( '', 'MultiInstance' )<>'Yes' then
      One.Check( 'IBHILKIA' );
   LogOk:=False;
   dxData.Date:=Date;
   dmMatia.Data:=Date;
end;
Se il tuo programma ha da qualche parte una cosa del genere basta 
eliminare la multistanza e puoi aprire n volte il programma.
massimili...@matia.it
Skype: massimiliano.monti.78
Ab. 
+39.0323.831011
C. 
+39.335.8477278
http:/


 saluti g.devil.
Tempo fa avevo lo stesso quesito ma non ho trovato risposta, cosi' sono 
ricorso al classico EnumWindows(@CercaLeMain);
Col codice sotto ottieni tutte le form aperte dal nome (tuacaption).
function CercaLeMain(H: THandle; lP: lParam): Bool; StdCall;
var st: String; Style, n: DWord; s: array[0..MAX_PATH] of Char;
begin
Result:=True;
if H<>0 then
   begin
   Style:=GetWindowLong(H, GWL_STYLE);
   n:=GetWindowTextLength(H);
   // s: Stringa null terminate, ottieni il "caption" della form
   if n>0 then
       GetWindowText(H, s, n+1)
   else
       s[0]:=#0;
    // Filtra le Wind. delle Applicazioni che ti interessano
    if Upper(StrPas(s))='TUACAPTION' then
        // E' una main form  ...
    end;
end;
Ciao Giorgio 

 Ciao Giorgio
ciao
    g.devil



FindWindowEx cerchi tutte le finestre di classe della tua app esterna.
Ti basta così o vuoi trovare proprio quella del processo che hai creato?
In questo caso:
GetWindowThreadProcessId
Tra le altre cose ottieni anche l'ID del processo, lo confronti con l'ID del 
processo che hai creato e hai trovato la finestra che gli appartiene.
Vedi la guida di Win32 oppure affidati a msdn.

 Vedi la guida di Win32 oppure affidati a msdn.
Grazie mille... mi metto alla ricerca e faccio le prove del caso.
 G.Devil


 l'andle della sua finestra principale.
Forse non hai fatto caso che nel codice che ti ho postato hai a disposizione
anche l'handle delle varie finestre (variabile H),
ed era quanto chiedevi. Se per mezzo della caption filtri le form
principali, ottieni i loro handle memorizzando le varie H ad esempio in un
array.
Ciao Giorgio

 Ciao G.Devil


 Vedi la guida di Win32 oppure affidati a msdn.
Dove Sbaglio??????
var
  numFinestra:integer;
  tabClass:array[0..1000]of string;
  tabTesto:array[0..1000] of string;
  tabHandle:array[0..1000] of HWND;
  PID : DWord;
function EnumWindowsCallback(hWnd: HWND; lParam: LPARAM): BOOL;
Var Testo:array[0..250]of Char;
    Classe:array[0..250]of Char;
begin
  inc(numFinestra);
  GetWindowText(hWnd,Testo,SizeOf(Testo));
  GetClassName(hWnd,Classe,SizeOf(Classe));
  tabHandle[numFinestra]:=hWnd;
  tabTesto[numFinestra]:=string(Testo);
  tabClass[numFinestra]:=string(Classe);
  if numFinestra<1000 then
     result:=true
  else
     result:=false;
// perchč l'enumerazione non si arresti, ed EnumWindow
// continui a chiamare EnumWindowsCallback per le altre finestre
end;
Function GetHandleFinestra(
          IDProcesso: THandle) : HWND;
//IDprocesso č l'handle del processo creato con shellexecuteEx
var i : word;
begin
   Result := 0;
   numFinestra:=-1;
   EnumWindows(@EnumWindowsCallback,0); 
// EnumWindows Chiama EnumWindowsCallback per ogni Processo attivo
   for i:=0 to numFinestra do
   Begin
    GetWindowThreadProcessID(tabHandle[i],@PID); 
{ottengo il PID della finestra interessata}
    If IDProcesso = PID Then
      Begin
         Result := tabHandle[I];
         Break;
      End;
   End;
Grazie in anticipo
G.Devil


      End;
Fai confusione tra Id e HANDLE del processo che crei. L'id è una cosa 
l'handle un'altra.
Fai così, dimentica GetWindowThreadProcessId.
Invece:
Usa HInstance della tua struttura StartupInfo e confrontalo con
GetWindowLong(HandleFinestra,GWL_HInstance)
Comunque se scrivi...
Function GetMyAppWindow(myHInstance: dword): THandle;
var
Child: THandle;
Begin
Child:= 0;
Repeat
Child:= FindWindowEx(0, Child, 'ClasseFinestra', nil);
If (Child<>0) and (GetWindowLong(Child, gwl_hinstance)=myHInstance) Then 
break;
Until Child=0;
Result:= Child;
End;
Te la cavi con queste poche righe. (scritte al volo qui. se li usi correggi 
gli eventuali errori)

 
Scusa .. sarň sicuramente io che non capisco, ma il codice sopra, 
non mi funziona poichč, il valore do myHInstance (Restituito da 
ShellExecuteEx alla variabile SEI.hInstApp) č sempre diverso dal
valore reso da GetWindowLong.
Se vorrai avere la pazienza di farmi un esempio dettagliato di quali 
valori utilizzare, e come ottenerli, te ne sarei veramente grato.
grazie ancora 


 Scusa .. sarò sicuramente io che non capisco, ma il...
Figurati, è difficile per queste cose comunicare via e-mail senza poter 
intervenire direttamente.
Andiamo per ordine: qual'è il nome della classe della finestra principale 
del programma che lanci?
Ciao

 wrote in message
news:444930ab$0$18289$
4faf...@reader1.news.tin.it
Il nome è "C:\Programmi\Gest\TheGest.Exe"
Grazie per la tua disponibilità



Come immaginavo. :-)
Sbagli perché quello non è il nome della classe, ma il nome del file.
Ora come posso spiegarti cos'è un nome di classe?
Quando lanci quella applicazione esterna si apre una finestra, l'oggetto che 
compone quella finestra è istanziato da una ben determinata classe. Ecco, 
quella determinata classe ha un nome che dovresti passare a FindWindowEx, 
altrimenti non ti trova nulla.
Io non so proprio come voi vedenti (io sono non vedente) fate a esplorare le 
finestre e se riuscite in modo semplice ad ottenerne alcuni dati, come il 
nome di classe. Magari qualcuno ti saprà indicare qualche software che fa al 
tuo caso.
Ciao

 Ciao
ciao Gdevil;


 Comunque la classe è "THintWindow"
?
Scusami, ma la main form di quella applicazione che lanci ha come classe il 
nome THintWindow, ossia un nome simile all'aiuto interno usato per i 
controlli?
Mi posti la function da me postata che hai modificato per le tue esigenze?
Ciao

 wrote in message
news:444a2b16$0$29728$
4faf...@reader2.news.tin.it
cut
  Dopo qualche giorno di sbattimento, e questa ultima notte 
  insonne sono riuscito a ottenere il quanto... :).
 
  .....anche grazie al tuo aiuto.
  Grazie per la tua disponibilità
 
 Ciao
  G.Devil



Bene. Non sei riuscito solo ad ottenere ciň che volevi. In questi casi 
credimi la cosa piů utile che si guadagna č quel tassello di esperienza in 
piů.
Ciao