Newsgroup: it.comp.appl.access
Titolo: Non mi funziona FindWindowEx con la classe "AfxFrameOrView42"

Faccio riferimento al mio tread del 22/09 "keybd_event senza 'pause' "
e mi rivolgo quindi ad Alex per fargli presenti le difficoltà in cui
sono incorso:
Ho scaricato da VbAccelerator il programmino "SimpleWinSpy" che mi
indica le classi delle finestre sotto il puntatore del mouse.
Usando la classe che mi indica relativa alla finestra pricipale della
mia applicazione esterna per trovare l'handle con la funzione
FindWindow ho un risultato positivo. Però non c'è stato verso di
trovare l'handle della finestra figlia, ho provato e riprovato. Uso la
funzione FindWindowsEx e la classe che mi indica SimpleWinSpy, ma il
risultato è sempre un handle 0. Ho provato anche a usare classi di
finestre "limitrofe", niente.
Riporto il codice che ho messo in un modulo di Access:
Private Declare Function FindWindowEx Lib "user32" _
    Alias "FindWindowExA" (ByVal hWnd1 As Long, _
    ByVal hWnd2 As Long, ByVal lpsz1 As String, _
    ByVal lpsz2 As String) As Long
Function HandChild(HanPrin As Long, sClass As String) As Long
    HandChild = FindWindowEx(HanPrin, 0&, sClass, vbNullString)
End Function
Come classe della finestra figlia ho usato:
"AfxFrameOrView42" dovrebbe essere questa ma ho provato anche:
"Afx:400000:0:10011:1100059:0"
"SysHeader32"
La classe della finestra principale è la seguente:
"Afx:400000:8:10011:0:840499"

 ha scritto nel messaggio
news:1159887213....@k70g2000cwa.googlegroups.com...





La chiamata è giusta, io uso questa che è esattamente come la tua:
FindWindowEx(MasterHWND, 0&, "Classname", vbNullString)
Purtroppo non posso provare quello che dici, ma penso che le possibilità di
errore siano 2:
1)Passi il ClassName errato, io uso SPY++ di VisualStudio ma immagino sia
equivalente a quello da te usato.
2)Stai recuperando l'Handle sbagliato dalla tua Applicazione.
Se questa ha una struttura del tipo MDI+CHILD ovviamente l'handle da passare
come Principale non è quello dell'Applicazione ma quello della MDI, un pò
come per ACCESS.
Access è strutturato così:
Applicazione--->Application.hWndAccessApp
     MDI_AREA(Quella in Grigione di sfondo per capirci) ha un'Handle diverso
          Forms.Hwnd (non popup)
             Controls
Forms(Popup)
In realtà se approfondisci con uno SPY ti accorgi che la stessa Form ha 4 o
più Handle(Cornice di maschera, la CaptionBar, le varie Section...)
Ora con SPY++ si riesce a capire a che livello ci si trova con la
determinazione dell'Handle poichè mette in EVIDENZa con un rettangolo
colorato(nero) il contorno dell'oggetto di cui si stà ricavando l'Handle e
restituisce l'Handle del PARENT, quindi se ti sei ricavato l'Handle
confrontali e vedi se stai lavorando correttamente.
Purtroppo non c'è altro metodo, ti risparmio l'ENUMERAZIONE delle
WindowsChild.....
Ciao
@Alex
-- 
@Alex (Alessandro Baraldi)
---------------------------------------------------------------------------
http://www.sitocomune.com/
http://www.alessandrobaraldi.it
---------------------------------------------------------------------------

ALESSANDRO Baraldi ha scritto:


Ciao Alex,
adesso ti scriverò un mezzo papiro, scusami ma sono intrippato duro,
non riesco a cavarci le penne! Dopo la tua illuminante spiegazione mi
sono messo a girovagare per la rete, e girovagando ho trovato un
programmino simile al tuo SPY++ (Non chiedemi il link, l'ho
dimenticato, si chiama WndInf13, se vuoi posso fartelo avere, è
carino). Ti fornisce l'handle delle finestre, la classe, fa un disegno
della sua posizione rispetto alla finestra principale e riporta
l'albero gerarchico delle classi. Cominciamo con i problemi, uno è
questo: se io riavvio il computer, la classe della finestra principale,
e anche di una delle finestre figlie cambia. In particolare cambia la
parte finale. Ad esempio una volta è Afx:400000:8:10011:0:70257 e la
volta successiva Afx:400000:8:10011:0:2033b.
Ho provato a passagli direttamente l'handle di quella che credevo
essere la finestra che mi interessava (quello mostrato da WndInf13
quando selezionavo con il mouse una riga da copiare). Niente, stringa
vuota.
Ho provato a percorrere l'albero delle finestre passandogli ogni volta
la classe. Niente, ogni volta la stringa non era quella che mi
interessava.
Infine ho provato con EnumChildWindows ed EnumChildProc e ho riportato
il testo di tutte le finestre figlie. Niente, nessuna finestra aveva il
testo giusto. (Se vuoi ti posto anche il codice ma sono quasi sicuro di
aver fatto bene, mi capita di avere degli svarioni, soprattutto
ultimamente, ma ho controllato più volte).
A questo punto mi sono arreso: evidentemente la finestra in questione
ha delle protezioni che la rendono irraggiungibile via codice.
Io tornerei quindi alla mia soluzione iniziale, quella orribile con le
'pause' del mio trade iniziale (22/09: "keybd_event senza 'pause'").
Infatti più o meno funziona, è un po' lenta ma mi posso accontentare.
Il problema più grosso è che non riesco a farla funzionare su altri
computer che non siano il mio. E' molto strano, su tutti gli altri si
'pianta' non riesce a passare da un'applicazione all'altra o a
effettuare il copia/incolla, anche se metto delle pause lunghissime
(sono arrivato a 5 secondi). Vabbè che sono computer meno performanti,
ma non così tanto meno, e non mi pare che gli chieda di fare delle
cose così impegnative!
Puoi dirmi ancora qualcosa? Scusa ancora l'estenuante lunghezza del
post, ma almeno ti ho detto tutto!
Come sempre grazie,
Pileggi

Pileggi ha scritto:

Normalmente l'applicazione cambia Hwdn ogni volta che viene aperta dopo
essere stata
terminata, ma i Child teoricamente dovrebbero mantenere un Handle
fisso.
Il ogni caso quello che risolverebbe il problema è il ClassName, il
codice che mi riporti
non è un ClassName, almeno io non ho mai visto ClassName di quel
tipo...
Hai provato a fare il Test con lo SPY su Access ...?
Vedi se trovi il ClassName della MDI che a memoria è "MDIClient",
delle ListBox e delle Combo, che hanno Classe anche se non hanno il
focus(ma non hanno l'handle finchè non hanno il focus)...!
Oppure prova su Notepad:
' Find Notepad's handle
Dim hWndNotepad As Long
hWndNotepad = FindWindow("Notepad", vbNullString)
' Find the handle of the textbox, within the Notepad window
Dim hWndTextbox As Long
hWndTextbox = FindWindowEx(hWndNotepad, 0&, "Edit", vbNullString)
In questo caso l'area Bianca di Notepad è un semplice Controllo di
tipo testo che
ha il ClassName="Edit".....!
Fai qualche prova per capire come devi interpretare i dati dello SPY,
penso sia quello il
problema, purtroppo non avendo Flash non posso darti più assistenza.
@Alex

Alessandro Baraldi ha scritto:

Ciao Alex,
nei casi che mi ha indicato lo SPY funziona bene, avevo controllato:
ClassName principale del Notepad: Notepad
finestra figlia: Edit
finestra interna di Access: MDIClient
Non potrebbe essere che il motivo sia che il programma ha delle
protezioni che rendono variabile il ClassName e occulta alle chiamate
API la finestra che contiene i dati? Comunque non ti preoccupare.
Grazie della disponibilità e dell'aiuto!
Ciao,
Pileggi

 Pileggi
Sinceramente non saprei cosa dire....
@Alex