PDA

View Full Version : [Win32] Interagire con altri programmi


TonyManero
05-12-2007, 09:11
Salve a tutti.
Eccomi con un nuovo quesito e con la certezza che saprete indicarmi la strada giusta! :)


Devo realizzare un'applicazione che mi vada a cliccare sul pulsante "Avanti" di un altra applicazione.

In altre parole...

C'è un setup che sta installando un programma. La mia applicazione, nel momento in cui il setup si blocca spettando che si clicchi su "Avanti", deve cliccare sul pulsante autonomamente per evitare che ci debba essere una persona presente a cliccare fisicamente sul tasto "Avanti"!


Secondo voi devo seguire la strada di ricavare l' Handler del pulsante e pio inviargli un click o è più conveniente memorizzare la posizione del pulsante, portare il mouse lì e inviare un click?

Altri suggerimenti?

Grazie!:D

cionci
05-12-2007, 10:08
Direi che ti conviene fare un FindWindow, cercare la finestra ed a quel punto calcolarti la posizione del pulsante rispetto all'angolo in basso a destra della finestra ed eseguire lì il click.
Così è quasi infallibile ;)

TonyManero
05-12-2007, 11:19
Direi che ti conviene fare un FindWindow, cercare la finestra ed a quel punto calcolarti la posizione del pulsante rispetto all'angolo in basso a destra della finestra ed eseguire lì il click.
Così è quasi infallibile ;)

Penso anch'io... ma intendi calcolare tramite programma chiedendo a win la posizione del pulsante rispetto al form in cui è contenuto... o guardare la posizione a occhio e poi inserirla nel programma?

cionci
05-12-2007, 11:31
Anche guardarla ad occhio...certo chiederla a Windows sarebbe meglio, ma dovrebbe funzionare comunque.

lovaz
05-12-2007, 11:41
Se il tasto avanti e' selezionato potrebbe bastare inviare un return

TonyManero
05-12-2007, 12:08
Se il tasto avanti e' selezionato potrebbe bastare inviare un return


Purtroppo no... e comunque volevo fare una cosa generale da riciclare poi anche per altre applicazioni...

lovaz
05-12-2007, 12:10
E mandare dei tab finche' il pulsante non viene selezionato?

TonyManero
05-12-2007, 15:15
Aggiornamento:

Ho trovato la finestra. ho trovato le coordinate del pulsante, mi ci sono spostaso sopra col puntatore tramite SetCursorPos... ma NON RIESCO E DIRE AL MOUSE DI CLICCARE!!!!! Come diavolo si fa???? :mad: :D

cionci
05-12-2007, 15:25
http://msdn2.microsoft.com/en-us/library/ms646260.aspx

Devi dare due mouse_event...uno con la pressione ed uno con il rilascio.

TonyManero
05-12-2007, 15:37
http://msdn2.microsoft.com/en-us/library/ms646260.aspx

Devi dare due mouse_event...uno con la pressione ed uno con il rilascio.


Thanx! Programma finito... :D ;)

TonyManero
06-12-2007, 09:23
HELP! :D

Il programma funziona benissimo ma volevo ottimizzarlo meglio. In particolare riesco a spostarmi alle coordinate del pulsante e simulare un click... qauindi la cosa funziona.

Il problema è che però, così facendo, non controllo in nessun modo se l'azione ha avuto successo... e in verità manco so se quando il programma ha cliccato il pulsante era lì veramente!

Quindi prima di far partire il tutto volevo fare una EnumWindow, trovare la finestra con la Caption del pulsante per verificare che possa avviare la procedura di "click".

Il problema è che la EnumWindow mi scandisce solo le finestre "principali" e non mi vede la classe Button....

Come posso scandire tutte le finestre e sottofinestre?

O in alternativa, come posso, trovata la finestra giusta, scandire tutte le sue sottofinestre?

Grazie! :D

TonyManero
07-12-2007, 09:12
C'è qualcosa che mi sfugge.... il codice è questo:



#define STRICT
#include <vcl.h>
#pragma hdrstop
#include <FileCtrl.hpp>
#include <dir.h>
#include <stdio.h>
#include <windows.h>
#include <winuser.h>
#include <string.h>
#include <shellapi.h>
#include <iostream>

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;



//Funzione per troare il pulsante una volta trovato il Form

int __stdcall CALLBACK TrovaPulsante(HWND hWnd2, LPARAM lParam2)
{
char buffer2[15];
char risp;
risp=GetWindowText(hWnd2,buffer2,15);


//controllo che sia il pulsante "Chiudi"

if((buffer2[0]=='C')|| //ci sono degli OR perchè se metto degli AND
(buffer2[1]=='h')|| //inspiegabilmente non funziona!!!!!?????
(buffer2[2]=='i')||
(buffer2[3]=='u')||
(buffer2[4]=='d')||
(buffer2[5]=='i'))
{
ShowMessage("TROVATO!!!!!!");
}
}



//funzione per trovare il Form che contiene il pulsante

int __stdcall CALLBACK TrovaFinestra(HWND hWnd, LPARAM lParam)
{
char buffer[10];
char risp;

risp=GetClassName(hWnd,buffer,10);

//Controllo che sia il form "TForm1"

if((buffer[0]=='T')&&
(buffer[1]=='F')&&
(buffer[2]=='o')&&
(buffer[3]=='r')&&
(buffer[4]=='m')&&
(buffer[5]=='1'))

{
//E' il Form che cerco quaindi procedo nella ricerca del pulsante
EnumChildWindows(hWnd,TrovaPulsante,0L);
}
}



Queste sono le due funzioni che uso... una per trovare la finestra ed una per trovare il pulsante (figlio) dentro quella finestra.
Lancio tutto tramite

EnumWindows(TrovaFinestra,0L);

Mi fa delle cose stranissime:

1. Il fatto degli AND e OR come da commento

2. Il buffer2 se messo a 10 o 20 o 100 da risultato completamente diversi!!!!

3. Così come è il programma ora mi dice "TROVATO!!!!!!!" undici volte....

Qualcuno vede dove sbaglio? :(

71104
07-12-2007, 11:25
scusa ma perché anziché comparare carattere per carattere non usi lstrcmp (http://msdn2.microsoft.com/en-us/library/ms647488.aspx)? :D

TonyManero
07-12-2007, 12:08
scusa ma perché anziché comparare carattere per carattere non usi lstrcmp (http://msdn2.microsoft.com/en-us/library/ms647488.aspx)? :D


Perchè nella fretta (cosa che mi accompagna purtroppo SEMPRE) ho messo il primo metodo funzionante... terrò presente il tuo consiglio! ;)

f@bio80
07-12-2007, 14:26
HELP! :D
Il problema è che la EnumWindow mi scandisce solo le finestre "principali" e non mi vede la classe Button....

Come posso scandire tutte le finestre e sottofinestre?

O in alternativa, come posso, trovata la finestra giusta, scandire tutte le sue sottofinestre?

Grazie! :D

enumchildwindows :D

TonyManero
07-12-2007, 17:11
Penso che programmare sotto Win32 sia la cosa più frustrante del mondo!

Premesso questo... dalle prove fatte su inserisco un "ritardo" nel punto in cui ho scritto " //controllo che sia il pulsante "Chiudi"" funziona tutto! Può essere un problema di tempi???? E' come se senza un ritardo non faccia in tempo a caricare la variabile buffer2....

TonyManero
07-12-2007, 17:23
Penso che programmare sotto Win32 sia la cosa più frustrante del mondo!

Premesso questo... dalle prove fatte su inserisco un "ritardo" nel punto in cui ho scritto " //controllo che sia il pulsante "Chiudi"" funziona tutto! Può essere un problema di tempi???? E' come se senza un ritardo non faccia in tempo a caricare la variabile buffer2....


Usando per creare un ritardo una ShowMessage("pippo") la cosa funziona... se come ritardo ci metto una Sleep(500) NO!!!!

Qualcuno ci capisce qualcosa?????? :mbe:

ficofico
08-12-2007, 19:13
io non ci capisco niente di programmazione, però queste cose le faccio con autoit-v3. ti crei un bel file exe con il programma e poi dici alla tua applicazione di far partire l'exe. Non è proprio così semplice ovviamente, però con 4 o 5 righe di codice te la cavi

TonyManero
10-12-2007, 12:29
io non ci capisco niente di programmazione, però queste cose le faccio con autoit-v3. ti crei un bel file exe con il programma e poi dici alla tua applicazione di far partire l'exe. Non è proprio così semplice ovviamente, però con 4 o 5 righe di codice te la cavi

Azz... potentissimo! :eek:

Effettivamente fa tutto quello di cui avevi bisogno! :D

Mi rimane però la curiosità su cosa sbaglio nel mio programma... :)