[Risolto] Passaggio anomalo di un puntatore a struct a più funzioni

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
Avatar utente
dyrkpw
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 369
Iscrizione: sabato 22 marzo 2008, 12:59

[Risolto] Passaggio anomalo di un puntatore a struct a più funzioni

Messaggio da dyrkpw »

Sto scrivendo un programmino in c con le librerie gtk.
È il classico programmino per cliccare programmaticamente su una certa finestra, un certo bottone a scelta dell' utente affinchè..accada qualcosa  ;D

Problema : senza entrare troppo nei dettagli...il programmino ha una finestra principale con un bottone. Quando questo viene cliccato la finestra passa automaticamente in icona e appare una finestra popup trasparente che risponde al click dell' utente; in questo modo l'utente ha modo di scegliere dove cliccare,  vedendo il desktop o la finestra aperta in primo piano, e poter cliccare ad esempio sulla "x" senza chiudere effettivamente la relativa finestra.

Al click corrisponde la chiusura della finestra trasparente e la massimizzazione della finestra principale del programmino.

Ci sono varie funzioni che permettono tutto ciò....il problema principale è che g_signal_connect() è una maledettissima funzione che permette il passaggio di un solo parametro alla funzione invocata, quindi per comodità ho dovuto creare una struct dedicata alle coordinate e ad altri piccoli dettagli del programmino.

La struct è dichiarata in main(), viene passata ad una funzione che a sua volta la passa ad un' altra ed infine da questa viene passata ad un' altra ancora.
Giunta all' ultima funzione, si comporta in modo anomalo : l'indirizzo che la struct ha in main() non corrisponde all' indirizzo che ha qui....e stranissimamente , dopo il click, i valori tornano normali.

Questa è la porzione di codice incriminata....è da un po' che ci sbatto la testa ma con scarsi risultati. che devo fare? >:(

Codice: Seleziona tutto


#include <stdio.h>
#include <stdlib.h>
#include <gtk\gtk.h>


typedef struct _coordinate
  {
    int x;
    int y;

    char *mouse_coords_text;

    GtkWidget *mouse_coords_label;

  }
  Coordinate;



gboolean delete_event (GtkWidget *window, GdkEvent *event, gpointer data);

void deiconify_after ( GtkWidget *button, GtkWindow *window);

void movimento(GtkWidget *window, Coordinate *where);

void destroy(GtkWidget *window, gpointer data);

void dove (Coordinate *where);




void dove_clickare( Coordinate *where);

void via ( GtkButton *i, GtkWidget *window);




int main( int argc, char *argv[] )
   {

    Coordinate coords;

    gtk_init(&argc, &argv);



      char m_c_txt[] = " coord x coord ";
      coords.mouse_coords_text = m_c_txt;




     printf("\n\nIndirizzo di coords in main() : %x \n\n", &coords );
     printf("\n\nValore di coord.mouse_coord_text in main() : %s \n\n" , coords.mouse_coords_text );




     dove_clickare(&coords);


   gtk_main();


  return 0;

   }




void destroy(GtkWidget *window, gpointer data)
  {
    gtk_main_quit();
  }



gboolean delete_event (GtkWidget *window, GdkEvent *event, gpointer data)
  {

   return FALSE;

  }


VERIFICA CHE LE VARIABILI DENTRO MAIN ESISTANO ANCHE DOPO L'INVOCAZIONE DI GTK_MAIN_QUIT


void dove_clickare( Coordinate *where)
   {

       printf("\n\n Indirizzo di where in dove_clickare() : %x \n\n", where);
       printf("\n\n Valore di where->mouse.. in dove_clickare(): %s \n\n", where->mouse_coords_text);

        GtkWidget *window;
       GtkWidget *button;


       window = gtk_window_new(GTK_WINDOW_POPUP);
                gtk_window_set_opacity( GTK_WINDOW(window), 0.4 );
                gtk_window_maximize( GTK_WINDOW(window) );



       button = gtk_button_new();

       gtk_container_add( GTK_CONTAINER(window), button );



     gtk_widget_set_events(GTK_WIDGET(button), GDK_POINTER_MOTION_MASK );


     gtk_widget_show_all( GTK_WIDGET(window) );





     g_signal_connect( G_OBJECT(button), "motion-notify-event", G_CALLBACK(movimento), where );
     g_signal_connect( G_OBJECT(button), "clicked", G_CALLBACK(movimento), where); // nel caso il puntatore non venga mai spostato, bisogna cmq caricarne le coordinate
     g_signal_connect_after( G_OBJECT(button), "clicked", G_CALLBACK(via), window );







    return;

  }


void movimento(GtkWidget *window, Coordinate *where)
  {

     printf("\n\n Indirizzo di where in movimento() : %x \n\n", where);

     printf("\n\n Valore di where->mouse.. in movimento(): %s \n\n", where->mouse_coords_text);

    //dove(where);


    //gtk_widget_set_tooltip_text( GTK_WIDGET(window), where->mouse_coords_text );




    //gtk_label_set_text( where->mouse_coords_label , where->mouse_coords_text );

    return;
  }


void via ( GtkButton *button, GtkWidget *window) // Nasconde la finestra opaca e esce da gtk_main().
  {                                              // Non necessita di rileggere le coordinate in quanto sono già lette da movimento().

 gtk_main_quit();
  printf("\n\n Esco da via() \n\n");


  return;

}










void dove (Coordinate *where) // Ricava le coordinate del cursore e le salva sia come coordinate numeriche che testuali
  {

    printf("\n\n Indirizzo contenuto nel puntatore : %x \n\n", where->mouse_coords_text);
    printf("Entro\n\n%s\n\n", where->mouse_coords_text );


   printf("\n\n%s\n\n", where->mouse_coords_text );

  return;


 }

P.S il programma l'ho scritto con code::blocks su windows (purtroppo è destinato a winzoz), non so se dià qualche problema su linux.
Ultima modifica di dyrkpw il mercoledì 8 dicembre 2010, 11:59, modificato 1 volta in totale.
io sono ciò che sono non solo per merito di ciò che siamo tutti:
Io non sono te, tu non sei me, ma entrambi siano noi.
Avatar utente
dyrkpw
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 369
Iscrizione: sabato 22 marzo 2008, 12:59

Re: Passaggio anomalo di un puntatore a struct a più funzioni

Messaggio da dyrkpw »

>:(
io sono ciò che sono non solo per merito di ciò che siamo tutti:
Io non sono te, tu non sei me, ma entrambi siano noi.
Avatar utente
Glaëdr
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 327
Iscrizione: sabato 8 novembre 2008, 18:33
Località: Lecce
Contatti:

Re: Passaggio anomalo di un puntatore a struct a più funzioni

Messaggio da Glaëdr »

Io mi sono arreso con le gtk+, e sono felicemente passato alle gtkmm, dove basta un sigc::bind e ci metti quello che vuoi...non c'è una funzione simile anche nella versione C? (anche se lo trovo difficile senza overloading)
"mai fidarti di un computer che non puoi gettare dalla finestra."
Steve Wozniack
camilla112
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 267
Iscrizione: mercoledì 13 gennaio 2010, 13:04

Re: Passaggio anomalo di un puntatore a struct a più funzioni

Messaggio da camilla112 »

Con le librerie gtk esiste l'evento button_press che ti restituisce automaticamente le coordinate del punto di click.

Non so quanto pratico sia tu di gtk, ma quando crei l'interfaccia aggiungi il controllo dell'evento con

Codice: Seleziona tutto

gtk_widget_set_events (tuo_widget, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
e lo colleghi al callback col signal_connect.

Poi nella funzione che chiama hai tra i parametri:

event->x (coordinata x del click)
event->Y (coordinata y del click)
event->button (che vale 1, 2 o 3 a seconda di quale tasto è stato premuto!)

spero ti sia di aiuto!
Avatar utente
dyrkpw
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 369
Iscrizione: sabato 22 marzo 2008, 12:59

Re: Passaggio anomalo di un puntatore a struct a più funzioni

Messaggio da dyrkpw »

Glaëdr ha scritto: Io mi sono arreso con le gtk+, e sono felicemente passato alle gtkmm, dove basta un sigc::bind e ci metti quello che vuoi...non c'è una funzione simile anche nella versione C? (anche se lo trovo difficile senza overloading)

Che io sappia no, ma non sono proprio un mostro di gtk  :)
io sono ciò che sono non solo per merito di ciò che siamo tutti:
Io non sono te, tu non sei me, ma entrambi siano noi.
Avatar utente
dyrkpw
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 369
Iscrizione: sabato 22 marzo 2008, 12:59

Re: Passaggio anomalo di un puntatore a struct a più funzioni

Messaggio da dyrkpw »

camilla112 ha scritto: Con le librerie gtk esiste l'evento button_press che ti restituisce automaticamente le coordinate del punto di click.

Non so quanto pratico sia tu di gtk, ma quando crei l'interfaccia aggiungi il controllo dell'evento con

Codice: Seleziona tutto

gtk_widget_set_events (tuo_widget, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
e lo colleghi al callback col signal_connect.

Poi nella funzione che chiama hai tra i parametri:

event->x (coordinata x del click)
event->Y (coordinata y del click)
event->button (che vale 1, 2 o 3 a seconda di quale tasto è stato premuto!)

spero ti sia di aiuto!

Non lo sapevo, ora provo ad implementare in questo modo :)...anche se mi *rode* che il programmino non funzioni, sebbene almeno a logica (mia) funzioni -.-
io sono ciò che sono non solo per merito di ciò che siamo tutti:
Io non sono te, tu non sei me, ma entrambi siano noi.
Avatar utente
dyrkpw
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 369
Iscrizione: sabato 22 marzo 2008, 12:59

Re: Passaggio anomalo di un puntatore a struct a più funzioni

Messaggio da dyrkpw »

Ultimo up prima di rinunciare
io sono ciò che sono non solo per merito di ciò che siamo tutti:
Io non sono te, tu non sei me, ma entrambi siano noi.
Avatar utente
crisixk
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1402
Iscrizione: domenica 17 maggio 2009, 1:15
Località: Pontedera - Pisa
Contatti:

Re: Passaggio anomalo di un puntatore a struct a più funzioni

Messaggio da crisixk »

dyrkpw ha scritto: Ultimo up prima di rinunciare
rinunciare? Perché?  (bad)

allora, ecco il codice:

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>


typedef struct _coordinate
  {
    int x;
    int y;

    char *mouse_coords_text;

    GtkWidget *mouse_coords_label;

  }
  Coordinate;


    void
    movimento ( GtkWidget      *button,
                GdkEventMotion *event,
                gpointer        where );

    void
    movimento2 ( GtkWidget      *button,
                 gpointer        where );

void dove_clickare( Coordinate *where);

void via ( GtkWidget *button, GtkWidget *window);




int main( int argc, char *argv[] )
   {

    Coordinate coords;

    gtk_init(&argc, &argv);


      char m_c_txt[] = " coord x coord ";
      coords.mouse_coords_text = m_c_txt;


     printf("\n\nIndirizzo di coords in main() : %p \n\n", &coords );
     printf("\n\nValore di coord.mouse_coord_text in main() : %s \n\n" , coords.mouse_coords_text );


     dove_clickare(&coords);


   gtk_main();


  return 0;

   }



void dove_clickare( Coordinate *where)
   {

       printf("\n\n Indirizzo di where in dove_clickare() : %p \n\n", where);
       printf("\n\n Valore di where->mouse.. in dove_clickare(): %s \n\n", where->mouse_coords_text);

        GtkWidget *window;
       GtkWidget *button;


       window = gtk_window_new(GTK_WINDOW_POPUP);

                gtk_window_set_opacity( GTK_WINDOW(window), 0.4 );
                gtk_window_maximize( GTK_WINDOW(window) );


       button = gtk_button_new();

       printf("\n\n Indirizzo di window in dove_clickare() : %p \n\n", window);
       printf("\n\n Indirizzo di button in dove_clickare() : %p \n\n", button);

       gtk_container_add( GTK_CONTAINER(window), button );


     gtk_widget_set_events(GTK_WIDGET(button), GDK_POINTER_MOTION_MASK );


     gtk_widget_show_all( GTK_WIDGET(window) );


     g_signal_connect( G_OBJECT(button), "motion-notify-event", G_CALLBACK(movimento), where );

     g_signal_connect( G_OBJECT(button), "clicked", G_CALLBACK(movimento2), where);

     g_signal_connect_after( G_OBJECT(button), "clicked", G_CALLBACK(via), window );

    return;

  }


    void
    movimento ( GtkWidget      *button,
                GdkEventMotion *event,
                gpointer        where )
  {
     printf("\n\n Indirizzo di button in movimento() : %p \n\n", button);
     printf("\n\n Indirizzo di where in movimento() : %p \n\n", where);
     printf("\n\n Indirizzo di event in movimento() : %p \n\n", event);

     printf("\n\n Valore di where->mouse.. in movimento(): %s \n\n", ((Coordinate*)where)->mouse_coords_text);

    return;
  }

    void
    movimento2 ( GtkWidget      *button,
                 gpointer        where )
  {
     printf("\n\n Indirizzo di button in movimento2() : %p \n\n", button);
     printf("\n\n Indirizzo di where in movimento2() : %p \n\n", where);

     printf("\n\n Valore di where->mouse.. in movimento2(): %s \n\n", ((Coordinate*)where)->mouse_coords_text);

    return;
  }

void via ( GtkWidget *button, GtkWidget *window)
  {

       printf("\n\n Indirizzo di window in via() : %p \n\n", window);
       printf("\n\n Indirizzo di button in via() : %p \n\n", button);

    gtk_main_quit();
    printf("\n\n Esco da via() \n\n");

  return;

}

Hai fatto molta confusione con il passaggio degli argomenti alle funzioni CallBack ...

Quando "crei" una funzione di Callback per un determinato evento, devi considerare l'evento ..
ad esempio:

il segnale "motion-notify-event" vorrebbe una Callback di questo genere:

Codice: Seleziona tutto

gboolean            user_function                      (GtkWidget      *widget,
                                                        GdkEventMotion *event,
                                                        gpointer        user_data)      : Run Last
invece tu usi:

Codice: Seleziona tutto

void movimento(GtkWidget *window, Coordinate *where);
è evidente che manca un parametro ..
per tanto alla tua funzione viene passato come argomento where, non l'indirizzo di where, ma l'indirizzo event ... che cambia sempre perchè il mouse lo muovi sempre ... ecco che non torna ...

per tanto ho modificato così:

Codice: Seleziona tutto

    void
    movimento ( GtkWidget      *button,
                GdkEventMotion *event,
                gpointer        where )
come vedi, il primo parametro non è window, ma button, dato che il segnale non viene da window .. puoi costatarlo guardando gli indirizzi del code che ti ho postato.

Guardalo attentamente, perchè hai fatto casini con gli argomenti ^^


Infine ho creato una seconda funzione di movimento ... indovina perché  :o


per ulteriori info:
http://library.gnome.org/devel/gtk-tuto ... /x159.html
The function specified in the third argument is called a "callback function", and should generally be of the form

void callback_func( GtkWidget *widget,
                    ... /* other signal arguments */
                    gpointer  callback_data );
where the first argument will be a pointer to the widget that emitted the signal, and the last a pointer to the data given as the last argument to the g_signal_connect() function as shown above.

Note that the above form for a signal callback function declaration is only a general guide, as some widget specific signals generate different calling parameters.
buon lavoro con il programmino ...  (b2b)
Avvolte cio' che si crea per facilitarci la vita, ci libera dal ragionare ed insieme ci imprigiona in una sorta di limbo nel quale la coscienza è solo un limite, uno spreco di risorse e tempo. Cosa fa' la mia mano ?
... s'impara un passo alla volta ...
Avatar utente
dyrkpw
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 369
Iscrizione: sabato 22 marzo 2008, 12:59

Re: Passaggio anomalo di un puntatore a struct a più funzioni

Messaggio da dyrkpw »

crisixk ha scritto:
dyrkpw ha scritto: Ultimo up prima di rinunciare
rinunciare? Perché?  (bad)

allora, ecco il codice:

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>


typedef struct _coordinate
  {
    int x;
    int y;

    char *mouse_coords_text;

    GtkWidget *mouse_coords_label;

  }
  Coordinate;


    void
    movimento ( GtkWidget      *button,
                GdkEventMotion *event,
                gpointer        where );

    void
    movimento2 ( GtkWidget      *button,
                 gpointer        where );

void dove_clickare( Coordinate *where);

void via ( GtkWidget *button, GtkWidget *window);




int main( int argc, char *argv[] )
   {

    Coordinate coords;

    gtk_init(&argc, &argv);


      char m_c_txt[] = " coord x coord ";
      coords.mouse_coords_text = m_c_txt;


     printf("\n\nIndirizzo di coords in main() : %p \n\n", &coords );
     printf("\n\nValore di coord.mouse_coord_text in main() : %s \n\n" , coords.mouse_coords_text );


     dove_clickare(&coords);


   gtk_main();


  return 0;

   }



void dove_clickare( Coordinate *where)
   {

       printf("\n\n Indirizzo di where in dove_clickare() : %p \n\n", where);
       printf("\n\n Valore di where->mouse.. in dove_clickare(): %s \n\n", where->mouse_coords_text);

        GtkWidget *window;
       GtkWidget *button;


       window = gtk_window_new(GTK_WINDOW_POPUP);

                gtk_window_set_opacity( GTK_WINDOW(window), 0.4 );
                gtk_window_maximize( GTK_WINDOW(window) );


       button = gtk_button_new();

       printf("\n\n Indirizzo di window in dove_clickare() : %p \n\n", window);
       printf("\n\n Indirizzo di button in dove_clickare() : %p \n\n", button);

       gtk_container_add( GTK_CONTAINER(window), button );


     gtk_widget_set_events(GTK_WIDGET(button), GDK_POINTER_MOTION_MASK );


     gtk_widget_show_all( GTK_WIDGET(window) );


     g_signal_connect( G_OBJECT(button), "motion-notify-event", G_CALLBACK(movimento), where );

     g_signal_connect( G_OBJECT(button), "clicked", G_CALLBACK(movimento2), where);

     g_signal_connect_after( G_OBJECT(button), "clicked", G_CALLBACK(via), window );

    return;

  }


    void
    movimento ( GtkWidget      *button,
                GdkEventMotion *event,
                gpointer        where )
  {
     printf("\n\n Indirizzo di button in movimento() : %p \n\n", button);
     printf("\n\n Indirizzo di where in movimento() : %p \n\n", where);
     printf("\n\n Indirizzo di event in movimento() : %p \n\n", event);

     printf("\n\n Valore di where->mouse.. in movimento(): %s \n\n", ((Coordinate*)where)->mouse_coords_text);

    return;
  }

    void
    movimento2 ( GtkWidget      *button,
                 gpointer        where )
  {
     printf("\n\n Indirizzo di button in movimento2() : %p \n\n", button);
     printf("\n\n Indirizzo di where in movimento2() : %p \n\n", where);

     printf("\n\n Valore di where->mouse.. in movimento2(): %s \n\n", ((Coordinate*)where)->mouse_coords_text);

    return;
  }

void via ( GtkWidget *button, GtkWidget *window)
  {

       printf("\n\n Indirizzo di window in via() : %p \n\n", window);
       printf("\n\n Indirizzo di button in via() : %p \n\n", button);

    gtk_main_quit();
    printf("\n\n Esco da via() \n\n");

  return;

}

Hai fatto molta confusione con il passaggio degli argomenti alle funzioni CallBack ...

Quando "crei" una funzione di Callback per un determinato evento, devi considerare l'evento ..
ad esempio:

il segnale "motion-notify-event" vorrebbe una Callback di questo genere:

Codice: Seleziona tutto

gboolean            user_function                      (GtkWidget      *widget,
                                                        GdkEventMotion *event,
                                                        gpointer        user_data)      : Run Last
invece tu usi:

Codice: Seleziona tutto

void movimento(GtkWidget *window, Coordinate *where);
è evidente che manca un parametro ..
per tanto alla tua funzione viene passato come argomento where, non l'indirizzo di where, ma l'indirizzo event ... che cambia sempre perchè il mouse lo muovi sempre ... ecco che non torna ...

per tanto ho modificato così:

Codice: Seleziona tutto

    void
    movimento ( GtkWidget      *button,
                GdkEventMotion *event,
                gpointer        where )
come vedi, il primo parametro non è window, ma button, dato che il segnale non viene da window .. puoi costatarlo guardando gli indirizzi del code che ti ho postato.

Guardalo attentamente, perchè hai fatto casini con gli argomenti ^^


Infine ho creato una seconda funzione di movimento ... indovina perché  :o


per ulteriori info:
http://library.gnome.org/devel/gtk-tuto ... /x159.html
The function specified in the third argument is called a "callback function", and should generally be of the form

void callback_func( GtkWidget *widget,
                    ... /* other signal arguments */
                    gpointer   callback_data );
where the first argument will be a pointer to the widget that emitted the signal, and the last a pointer to the data given as the last argument to the g_signal_connect() function as shown above.

Note that the above form for a signal callback function declaration is only a general guide, as some widget specific signals generate different calling parameters.
buon lavoro con il programmino ...  (b2b)

Grazie  ;D
Avevo sempre usato meccanicamente void per le funzioni invocate da g_signal_connect*(), ed evidentemente non sapevo nulla riguardo alle impostazioni dei parametri :)
io sono ciò che sono non solo per merito di ciò che siamo tutti:
Io non sono te, tu non sei me, ma entrambi siano noi.
Avatar utente
crisixk
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1402
Iscrizione: domenica 17 maggio 2009, 1:15
Località: Pontedera - Pisa
Contatti:

Re: [Risolto] Passaggio anomalo di un puntatore a struct a più funzioni

Messaggio da crisixk »

di niente  :D

di solito i problemi relativi alle GTK che incontro nel forum derivano soltanto da una difficoltà nel "capire" le informazioni date dalla manualistica ... l'inglese non aiuta e il manuale prevede una certa preparazione di base ..

buon lavoro  ;)
Avvolte cio' che si crea per facilitarci la vita, ci libera dal ragionare ed insieme ci imprigiona in una sorta di limbo nel quale la coscienza è solo un limite, uno spreco di risorse e tempo. Cosa fa' la mia mano ?
... s'impara un passo alla volta ...
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 5 ospiti