WxWidgets : Frame e Window

di il
31 risposte

WxWidgets : Frame e Window

In ambiente CodeBlocks+minGW+wxWidgets C++
credo di aver capito il funzionamento degli eventi con wxFrame
ma sono un pò ribelle di natura, non mi piace wxFrame con barre e controbarre prefissate
vorrei una finestra senza niente da poterci inserire
diversi campi di input (?) da spaziare con il mouse.
Qualche bit-pal mi vuole aiutare ? Grazie

31 Risposte

  • Re: WxWidgets : Frame e Window

    Rileggendo mi rendo conto di essere stato troppo generico.
    In dettaglio : non ho capito come attivare wxWindow e
    neppure come attivare campi di input che non siano voci di menù o di barre varie.
    Ri-grazie per l'attenzione.
  • Re: WxWidgets : Frame e Window

    Hi , bit-pal ,
    sempre nell'intento di capire ( a volte cercare di spiegare significa capire meglio ) :

    - quasi tutte le classi wxWidgets hanno gli stessi 2 parametri iniziali :
    (wxWindow *parent, wxWindowID id, .....
    qual'è la funzione del puntatore parent ? ( non ci sono anche dei figli ? )

    - creando in CodeBlocks un nuovo progetto wxWidgets si ottiene la finestra principale già
    codificata :
    in file .h :
    class MyFrame: public wxFrame {
    public:
    MyFrame(wxWindow* parent,wxWindowID id = -1);

    in file .cpp : MyFrame::MyFrame(wxWindow* parent,wxWindowID id) {
    ………...
    Create( parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize,
    wxDEFAULT_FRAME_STYLE, _T("id"));

    - se cerco di imitare ( #include <wx/window.h>) sostituendo wxFrame con wxWindow per
    gestire una finestra senza bordi e barre varie ottengo una valanga di errori che riesco a diminuire
    ( usando build ) quasi del tutto ma andando a tentoni senza capire quello che faccio
    - perchè a volte vengono richiamati solo i primi 2 parametri e non anche gli altri ?
    - come faccio a scegliere la posizione e la dimensione della finestra ?
    - per casi disperati come me , non ci sono degli esempi per principianti ?
  • Re: WxWidgets : Frame e Window

    Non ho usato wxWidgets, ma in questo genere di librerie il parent di solito è la finestra che contiene quella che stai creando, la quale sarà automaticamente figlia. La posizione dei figli ad esempio è relativa a quella del parent, così come vale anche in caso di ridimensionamento del parent, i figli possono rispondere in un determinato modo a seconda del layaut impostato sul parent.
    Ma può avere anche implicazioni nella gestione degli eventi.
    Ti conviene seguire un manuale o una guida, altrimenti rischi di procedere alla cieca.

    https://www.wxwidgets.org/docs/tutorials
  • Re: WxWidgets : Frame e Window

    Grazie Alexv ,
    ho letto con attenzione il tutorial wsWidgets , ma vengono date per scontate tante nozioni che io , provenendo da un mondo di programmazione anni '80 , non conosco . Tutto ciò di cui stiamo parlando si riferisce a strumenti propedeutici a quello che per me è la vera programmazione : analisi del problema e stesura del codice risolutivo. Capisco l'utilità delle librerie e dell' IDE ma non vedo l'ora di poter padroneggiare quanto mi necessita per poter fare quello che più mi piace .
    Trovo singolare, però , che il tutorial wxWidgets non si preoccupi un pò di più a facilitare la comprensione di procedure che, nel bene e/o nel male , sono state progettate da una o più persone con un dato schema mentale , ma destinate a persone che possono avere una forma-mentis molto diversa.
  • Re: WxWidgets : Frame e Window

    In effetti come spiegazioni lasciano un po' a desiderare e l'ultimo libro risale a 15 anni fa.
    Magari vedi se trovi dei buoni tutorial introduttivi su Youtube e quando cerchi info in merito a un argomento, vedi come influisce il sistema di parenting.
  • Re: WxWidgets : Frame e Window

    Vedi Alexv ti potrà sembrare inverosimile ma ho incominciato a programmare su IBM 5120 con i floppy giganteschi ed ho finito con Olivetti M24 . Con tutte le limitazioni ( soprattutto di memoria ) dell'epoca ho fatto ( e venduto a diversi studi di commercialisti ) un programma gestionale che sfiorava il MB di codice sorgente in multiprogrammazione reale ( con i semafori ) e con data-base incorporato . Questo per dire che non è indispensabile avere strumenti ( librerie e IDE ) sofisticati, anche se possono aiutare naturalmente.
  • Re: WxWidgets : Frame e Window

    Prova Visual Studio, allora. Non saprei in C++ perché non ci faccio la grafica in quel linguaggio, ma in C# la parte grafica te la sbrighi in quattro e quattr'otto e ti puoi concentrare sul programma vero e proprio
  • Re: WxWidgets : Frame e Window

    Concordo con Weierstrass, se vuoi programmare in C/C++, significa che sei in cerca di prestazioni e vuoi padroneggiare la memoria e la CPU approfonditamente. In C/C++ programmi a basso livello usando la console per i test e realizzi una DLL riusabile.
    Invece se hai bisogno delle interfacce grafiche, sotto Win userai C# e VisualStudio, dove svolgi in scioltezza tutte le operazioni che ti permettono di creare un'interfaccia trascinado lo strumento desiderato nel form, C# è adatto per il 99% del codice, e quell'1% che ti impone il C, lo scrivi in C.
    Creare un'applicazione desktop con VisualStudio è agevole e ti mostrerà il vero avanzamento della programmazione.
    Come sai ci sono anche altri sistemi, usando C++ e le librerie o ambienti come GTK, FLTK, QT, ma come hai riscontrato richiedono uno sforzo enorme per l'installazione, configurazione e uso, imponendoti ad usare un linguaggio che non ti aiuta nel maneggiare le stringhe, gli input utente, le liste le dictionary, gli input output su file, la grafica spicciola ecc ecc.
    VSform.gif
    VSform.gif

    Una volta trascinati e posizionati gli strumenti nel form, cliccandoli due volte VS scrive l'evento relativo pronto per essere riempito con il tuo codice.
    Proprio quello che vuoi tu, scrivere il tuo programma, delegando l'IDE per quelle azioni tediose e che niente hanno a che fare con la stesura di un algoritmo o codice che persegue una logica.
    Se vieni dal C, la prima cosa che apprezzerai di VS e C# è la programmazione ad eventi, con il C o la vecchia scuola hai un flusso ininterrotto del codice che scorre impietosamente, o si è fermi in un input, o si sta eseguendo un ciclo.
    Con VS, il codice è sempre fermo in attesa che succeda qualcosa... (il ciclo ancora c'è ma lo gestisce il S.O.) L'utente ha cliccato un bottone, verrà eseguito il codice relativo, l'utente ha scritto in una casella e premuto invio, parte il codice relativo, ad ogni azione (evento) risponde un codice, terminato il quale il programma resta in attesa del prossimo evento.
    Programmare un'applicazione desktop in C, se non ce n'è un vero bisogno è per masochisti, oppure si sta imparando, ma per quello è sufficiente la console.
  • Re: WxWidgets : Frame e Window

    Va beh, alla fine ci si avvale di queste librerie proprio per rendere l'esperienza di programmazione della grafica e degli eventi come avverrebbe in C#, quindi non vedo il motivo di indurlo per forza a cambiare.
    I tool per disegnare poi ci stanno anche per wxwidgets e Qt.
  • Re: WxWidgets : Frame e Window

    Ciao Rubik , come forse ricorderai : la mia prima intenzione era quella di gestire il mouse e gli eventi in modalità console . Poi mi sono detto che una migliore risoluzione non era da scartare, poi mi è venuta una mezza idea di come gestire lo sfondo dello schermo, poi mi sono detto che una moltitudine di gente utilizza le librerie grafiche, non può essere così proibitivo ( anche perché la presentazione di wxWidgets dichiara espressamente la loro facilità di impiego ) . Così mi sono lasciato tentare, senza avere ambizioni di grafica vera e propria , di designing .
    In realtà , volevo riprendere il mio vecchio programma gestionale ( in C sotto Unix AT&T ) aggiungendoci l'uso del mouse e degli eventi . Dopo Basic e turbo Pascal Borland ero approdato al C proprio per la possibilità di gestire direttamente la memoria heap . E siccome , tra le altre cose , sono anche curioso , mi ero chiesto allora come facesse malloc() a gestire il rilascio della memoria , in particolare dove tenesse conto della quantità di memoria abbinata ad un dato indirizzo . Avevo scoperto così che , oltre una certa quantità minima , era possibile sapere dal puntatore la relativa quantità di memoria allocata semplicemente leggendo i 4 bytes precedenti . Comodo !
    Tornando a bomba , sono pochissime le informazioni che intendo usare dell’enorme libreria wxWidgets :
    • la gestione di una finestra nuda , senza annessi , ( credo tipo wxWindow ) di dimensioni più grandi dello schermo reale , da poter scrollare Nord-Sud Est-Ovest
    • le gestione di diversi campi-di-input ( nudi , senza annessi ) da poter ancorare alla finestra di cui sopra , ognuno con l’identificatore univoco per la gestione degli eventi , che non ho ancora identificato nella marea delle classi wxWidgets
    • la gestione I/O
    • la gestione dei files
    che altro ?
    Penso che sarebbe sufficiente la visione di un’implementazione esempio per tutto ciò di cui sopra . Cosa che non ho trovato in wxWidgets .
    Magari qualche lettore generoso vorrà segnalarmi qualche esempio .
    Non credo che scappare dalle difficoltà possa risolvere i problemi , anche perché nuove installazioni e nuove librerie non sono garanzia di no-problem !
    Il mio scopo non è creare qualcosa di utilizzabile fruttando librerie fornitissime che risolvono gran parte dei compiti , ma avere strumenti per trasformare la mia fantasia in qualcosa di funzionante , senza finalità di lucro .
    Infine , non credo/spero di avere problemi con C++ provenendo da un uso approfondito di C .
  • Re: WxWidgets : Frame e Window

    Alexv ha scritto:


    Va beh, alla fine ci si avvale di queste librerie proprio per rendere l'esperienza di programmazione della grafica e degli eventi come avverrebbe in C#, quindi non vedo il motivo di indurlo per forza a cambiare.
    Perché poi si blocca per la complessità dello strumento, come infatti è avvenuto. Che poi siano alternative valide nessuno lo mette in dubbio

    Rosmarino ha scritto:


    Infine, non credo/spero di avere problemi con C++ provenendo da un uso approfondito di C .
    Perché C++ allora, se comunque parti da zero e vuoi solo un linguaggio simile al C? C++ va bene se devi gestire un network adapter con migliaia di byte da smaltire ogni millisecondo, ad esempio.
  • Re: WxWidgets : Frame e Window

    @Alexv Non intendo forzare nessuno a cambiare, davo solo un contributo alla conoscenza e il perché si usa uno o un altro linguaggio, poi dal mio punto di vista che non deve essere per forza condiviso.

    @Rosmarino Non conosco le wxWidgets e non ti posso aiutare, ho sperimentato QT5 che permette la creazione di interfacce multipiattaforma a dir poco fantastiche, usato anche dalle case automobilistiche per la creazione dei nuovi cruscotti interattivi (un pachiderma) e FLTK farraginoso un po' datato ma ancora supportato.
    Resto in ascolto anche io, sono interessato ad una soluzione per gestire un'interfaccia grafica con Il C/C++, con la mia scarsa esperienza per ora ho trovato soluzioni che poi sono risultate obsolete e/o deprecate che risolvevano dei problemi ma poi non funzionavono con win10 o delle librerie aggiuntive indispensabili erano sparite, oppure ide sterminati dove l'installazione configurazione e uso comporta un'impegno equivalente ad imparare a programmare da zero.
    Un link dove trovare come installare ed usare una libreria valida ancora oggi per gestire un'interfaccia senza grandi pretese in C/C++ è gradito.

    Il C++ supporta la sintassi del C, non avrai nessun problema ad usarlo, i nuovi tipi di dato e la gestione della console permette di usare il C++ come un C corredato di qualche comoda istruzione in più. Ma è un uso riduttivo del C++, che invece contempla le classi e la programmazione ad oggetti.

    Programmo in C da pochi mesi per curiosità, di proposito evito il C++ (conosco C# e VB.Net non sento il bisogno del C++), a scopo didattico dalla console sono riuscito a speremere qualcosina in più, per la posizione del mouse ho scritto un programma: il gioco del 15:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <windows.h>
    #include <ctype.h>
    
    /*************************************
    *            GIOCO DEL 15            *
    *  Si gioca in console con il mouse  *
    *  il puzzle è sempre risolvibile    *
    *************************************/
    
    // **** costanti
    const char RigSopra[]={(CHAR)201,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)203,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)203,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)203,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)187,'\0'};
    const char RigheCentro[]={(CHAR)204,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)206,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)206,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)206,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)185,'\0'};
    const char RigSotto[]={(CHAR)200,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)202,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)202,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)202,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)205,(CHAR)188,'\0'};
    // in aControllo, gli indici in base zero del vettore iSequenza che devono essere esplorati, in base alla casella cliccata
    const unsigned int aControllo[16][4]={{1, 4, 0, 0}, {0, 2, 5, 1}, {1, 3, 6, 2}, {2, 7, 3, 3}, {0, 5, 8, 4}, {4, 1, 6, 9}, {5, 2, 7, 10}, {11, 3, 6, 7}, {4, 9, 12, 8}, {8, 5, 10, 13}, {14, 9, 6, 11}, {15, 10, 7, 11}, {8, 13, 12, 12}, {12, 9, 14, 13}, {13, 10, 15, 14}, {14, 11, 15, 15}};
    const char Titolo[]="Gioco del15 CB2021";
    
    // **** pubbliche
    struct {
        unsigned int riga; // base 1
        unsigned int colonna; // base1
        unsigned int casella; // base 0
        unsigned int mosse;
        unsigned int MouseButton; // 1 = tasto sinistro, 2 = tasto destro
        unsigned char iSequenza[16]; // contiene sempre lo stato del gioco
    }GiocoDel15;
    
    // **** prototipi
    int Schermo(HANDLE Cons); // disegna lo schema con i numeri
    int SeqValida(); // 0 = la sequenza non è risolvibile, 1 = la sequenza è risolvibile
    void MenuScelta();
    void GenSequenza(); // genera la sequenza ordinata
    void mescola(HANDLE Cons);
    void TrovaCasella(int x, int y, HANDLE Cons); // aggiorna la struct GiocoDel15 in base alla casella cliccata
    
    int main()
    {
        SetConsoleTitle(Titolo);
        POINT pCoor;
        HWND hwnd=0;
    
        //attende la creazione della finestra per prelevare hwnd
        while (hwnd==0)
            hwnd=FindWindow(NULL, Titolo); // handle della finestra
        //------------------------------------------------------
    
        HANDLE console=GetStdHandle(STD_OUTPUT_HANDLE); // handle del processo
    
        MenuScelta();
        GenSequenza(); // sequenza ordinata
        Schermo(console); // prima visualizzazione schema
    
        while(1){ // loop infinito mouse
            Sleep(50); // lascia la CPU libera, limita i cicli in 1000/50=20 al secondo
            if((GetKeyState(GiocoDel15.MouseButton) & 0x8000) != 0){ // bottone mouse
                GetCursorPos(&pCoor); // coordinate assolute cursore
                ScreenToClient(hwnd, &pCoor); // coordinate relative cursore
                TrovaCasella(pCoor.x, pCoor.y, console); // TrovaCasella modifica la struct GiocoDel15
                if (GiocoDel15.riga!=0 && GiocoDel15.colonna!=0){ // click dentro lo schema
                    for (int i=0; i<4; i++){ // controllo in 4 direzioni predefinite in aControllo
                       if (GiocoDel15.iSequenza[aControllo[GiocoDel15.casella][i]]==0){ // è la casella vuota, swap
                            GiocoDel15.iSequenza[aControllo[GiocoDel15.casella][i]]=GiocoDel15.iSequenza[GiocoDel15.casella]; // scrivo il valore della casella cliccata nella casella vuota
                            GiocoDel15.iSequenza[GiocoDel15.casella]=0; // nella casella cliccata metto zero, lo swap è completo
                            GiocoDel15.mosse++; // incremento le mosse
                            /* per test
                            printf("\n\nCasella = %d", GiocoDel15.casella+1);
                            printf(" Vuota = %d", aControllo[GiocoDel15.casella][i]+1);*/
                            break;
                       }
                    }
                    int risolto=Schermo(console); // aggiorno lo schermo, la funzione restituisce se c'è soluzione
                    printf("\n\n  ");
                    if (risolto==1){
                        SetConsoleTextAttribute(console, 0x0E); // 0xE giallo 0x0 nero
                        printf(" Risolto,");
                        SetConsoleTextAttribute(console, 0x0A); // 0xA verde 0x0 nero
                    }
                    printf(" mosse = %d",GiocoDel15.mosse); // visualizzo le mosse
                }
            Sleep(200); // Ritardo evita doppio click, al massimo vengono rilevati 5 click al secondo
            }
        }
    }
    
    int Schermo(HANDLE Cons){
    
        system("cls");
        int i=0;
        SetConsoleTextAttribute(Cons, 0x0B); // 0xB ciano 0x0 nero
        if (GiocoDel15.MouseButton==1)
            printf("\n   GIOCO DEL15  W7 LBUTTON\n");
        else
            printf("\n   GIOCO DEL15 W10 RBUTTON\n");
    
        printf("\n   ");
    
        // disegno schema con sequenza ***************
        SetConsoleTextAttribute(Cons, 0xCF); // 0xF bianco 0xC rosso
        printf("                       ");
        SetConsoleTextAttribute(Cons, 0x0B); // 0xB ciano 0x0 nero
        printf("\n   ");
        SetConsoleTextAttribute(Cons, 0xCF); // 0xF bianco 0xC rosso
        printf(" %s ",RigSopra);
        for (i=0; i<16; i+=4){
            SetConsoleTextAttribute(Cons, 0x0B); // 0xB ciano 0x0 nero
            printf("\n   ");
            SetConsoleTextAttribute(Cons, 0xCF); // 0xF bianco 0xC rosso
            // il numero zero viene sostituito con gli spazi (casella vuota)
            for (int ind=0; ind<4; ind++){
                printf(" %c ", (CHAR)186);
                if (GiocoDel15.iSequenza[ind+i]==0) printf("  "); else printf("%02d", GiocoDel15.iSequenza[ind+i]);
            }
            printf(" %c ", (CHAR)186);
            SetConsoleTextAttribute(Cons, 0x0B); // 0xB ciano 0x0 nero
            printf("\n   ");
            SetConsoleTextAttribute(Cons, 0xCF); // 0xF bianco 0xC rosso
            if (i==12) printf(" %s ", RigSotto); else printf(" %s ", RigheCentro);
        }
        SetConsoleTextAttribute(Cons, 0x0B); // 0xB ciano 0x0 nero
        printf("\n   ");
        SetConsoleTextAttribute(Cons, 0xCF); // 0xF bianco 0xC rosso
        printf("                       ");
        SetConsoleTextAttribute(Cons, 0x0B); // 0xB ciano 0x0 nero
        printf("\n   ");
        printf("\n    [MESCOLA]     [ESCI]");
        SetConsoleTextAttribute(Cons, 0x0A); // 0xA verde 0x0 nero
        //****************************************
    
        /* per test*/
        printf("\n\n   Sequenza = [");
        for (i=0; i<16; i++){
            printf("%02d", GiocoDel15.iSequenza[i]); // mostra lo stato della sequenza
        }
        printf("]");
    
        if (GiocoDel15.iSequenza[15]==0 ){
            printf(" SeqValida = %d", SeqValida()); // verifica se la sequenza è risolvibile: 1=si, 0=no
        }
    
    
        for (i=0; i<15; i++){
            if (GiocoDel15.iSequenza[i] != i+1) return 0;  // non risolto
        }
        return 1; // risolto
    }
    
    int SeqValida(){ // usata in fase di test
    
        unsigned int coppie = 0;
        for (int i=0; i<15;i++){
            for (int y=i+1; y<15;y++){
                if (GiocoDel15.iSequenza[i] < GiocoDel15.iSequenza[y]) coppie++;
            }
        }
        return coppie%2;
    }
    
    void MenuScelta(){
    
        GiocoDel15.MouseButton=0;
        while(GiocoDel15.MouseButton==0){
            system("cls");
            printf("\n   ***** GIOCO DEL15 *****\n");
            printf("\n   si gioca con il mouse, le coordinate cambiano in base al S.O.\n");
            printf("\n   1) Win 7 tasto sinistro mouse");
            printf("\n   2) Win10 tasto destro mouse\n");
            printf("\n   0) Esci\n");
            printf("\n      Tua scelta : ");
    
            char scelta=getchar();
    
            switch (scelta){
    
            case '1': // Win7
                GiocoDel15.MouseButton = 1; // VX_LBUTTON
                break;
    
            case '2': // Win10
                GiocoDel15.MouseButton = 2; // VX_RBUTTON
                break;
    
            case '0': // esci
                printf("\n");
                exit(0);
            }
        }
    }
    
    void GenSequenza(){
        // riempimento vettore ordinato
        for (int i=0; i<15; i++)GiocoDel15.iSequenza[i]=i+1;
        GiocoDel15.iSequenza[15]=0;
    }
    
    void mescola(HANDLE Cons){
    
        GenSequenza(); // si parte con la sequenza ordinata con zero finale
        // mescolamento vettore
        srand((unsigned) time(NULL)); // init random
    
        for (int i=0; i<30; i++){ // se la sequenza ordinata viene mescolata un numero pari di volte(es 30), è sempre valida
            int ind = rand() % 14 + 1 ; // (1/14), non sposto mai lo zero finale
            unsigned char tmp = GiocoDel15.iSequenza[ind]; // inizio swap
            GiocoDel15.iSequenza[ind] = GiocoDel15.iSequenza[0];
            GiocoDel15.iSequenza[0] = tmp; // fine swap
        }
        GiocoDel15.mosse = 0;
        Schermo(Cons); // visualizzazione
    }
    
    void TrovaCasella(int x, int y, HANDLE Cons){ // controllo coordinate mouse
    
        GiocoDel15.riga = 0; // base 1
        GiocoDel15.colonna = 0; // base 1
        GiocoDel15.casella = 0; // base zero
    
        if (GiocoDel15.MouseButton==1){ // Win7
            if (x>39 && x<73) GiocoDel15.colonna = 1; // casella 0
            if (x>79 && x<113) {GiocoDel15.colonna = 2; GiocoDel15.casella = 1;}
            if (x>119 && x<153) {GiocoDel15.colonna = 3; GiocoDel15.casella = 2;}
            if (x>158 && x<193) {GiocoDel15.colonna = 4; GiocoDel15.casella = 3;}
            if (y>55 && y<76) GiocoDel15.riga = 1;
            if (y>79 && y<100) {GiocoDel15.riga = 2; GiocoDel15.casella +=4;}
            if (y>103 && y<123) {GiocoDel15.riga = 3; GiocoDel15.casella +=8;}
            if (y>129 && y<148) {GiocoDel15.riga = 4; GiocoDel15.casella +=12;}
            if (x>37 && x<100 && y>180 && y<190) mescola(Cons);
            if (x>149 && x<188 && y>180 && y<190) {printf("\n"); exit(0);}
        }
        else{ // Win10
            if (x > 39 && x < 74) GiocoDel15.colonna = 1; // casella 0
            if (x > 78 && x < 112) { GiocoDel15.colonna = 2; GiocoDel15.casella = 1; }
            if (x > 119 && x < 154) { GiocoDel15.colonna = 3; GiocoDel15.casella = 2; }
            if (x > 158 && x < 192) { GiocoDel15.colonna = 4; GiocoDel15.casella = 3; }
            if (y > 76 && y < 103) GiocoDel15.riga = 1;
            if (y > 107 && y < 135) { GiocoDel15.riga = 2; GiocoDel15.casella += 4; }
            if (y > 140 && y < 167) { GiocoDel15.riga = 3; GiocoDel15.casella += 8; }
            if (y > 173 && y < 197) { GiocoDel15.riga = 4; GiocoDel15.casella += 12; }
            if (x > 37 && x < 100 && y>240 && y < 251) mescola(Cons);
            if (x > 149 && x < 188 && y>240 && y < 251) { printf("\n"); exit(0); }
        }
        // printf( "\nPosizione x = %d y = %d rig = %d col = %d cas = %d",x ,y, GiocoDel15.riga, GiocoDel15.colonna, GiocoDel15.casella);
    }
    
    Per la posizione del cursore e i colori, ho scritto un programma che replica alcune istruzioni presenti in alcune versioni della libreria conio.h:
    
    #include <stdio.h>
    #include <windows.h>
    
    /****************************************************************************
       codice che replica le istruzioni:
       gotxy(); textcolor(); textbackground(); clrscr();
       presenti nella libreria <conio.h> del compilatore Borland C/C++ e simili
    
       Didattico direttamente usabile, o adatto a compatibilizzare i codici che usano
       tali istruzioni ma non presenti nella conio.h fornita con i compilatori:
       CGwin, MinGW, MSVC e altri, è sufficiente eseguire le seguenti modifiche:
    
       1) aggiungere le variabili globali: fore, back e handle
       2) aggiungere nel main():  handle=GetStdHandle(STD_OUTPUT_HANDLE);
       3) modificare tutti i cprintf() in printf()
       4) aggiungere le quattro void:
                                  gotxy(int x, int y)
                                  textcolor(int f)
                                  textbackground(int b)
                                  clrscr()
    *****************************************************************************/
    
    int fore = 7; // variabile globale colore primo piano
    int back = 0; // variabile globale colore secondo piano
    HANDLE handle; // variabile globale che contiene l'HANDLE della console
    
    void gotoxy(int x, int y){ // equivalente in Borland C/C++
        COORD cursore; // angolo superiore sinistro = 0,0
        cursore.X=x-1; // i codici Borland usano la base 1
        cursore.Y=y-1; // i codici Borland usano la base 1
        SetConsoleCursorPosition(handle, cursore);
    }
    
    COORD getxy(){ // può far comodo
        CONSOLE_SCREEN_BUFFER_INFO buff;  // buffer info schermo
        GetConsoleScreenBufferInfo(handle, &buff); // lettura info console
        /* info disponibili:
        dwCursorPosition     COORD
        dwMaximumWindowSize  COORD
        dwSize               COORD
        srWindow             SMALL_RECT
        wAttributes          WORD
        */
        return buff.dwCursorPosition; // angolo superiore sinistro = 0,0
    }
    
    void textcolor(int f){ // equivalente in Borland C/C++
        // se f non è compreso tra 0 e 15, i colori ciclano
        fore=f; // right 4 bit
        SetConsoleTextAttribute(handle, fore+back*16);
    }
    
    void textbackground(int b){ // equivalente in Borland C/C++
        // se b non è compreso tra 0 e 15, i colori ciclano
        back=b; // left 4 bit
        SetConsoleTextAttribute(handle, fore+back*16);
    }
    
    void clrscr(){
        system("cls");
    }
    
    // Test routine
    int main(){
    
        handle=GetStdHandle(STD_OUTPUT_HANDLE); // lettura dell'HANDLE
    
        for (int i=0; i<16; i++) printf("foba "); // intestazione fo=foreground, ba=background
    
        for (int ba=0; ba<16; ba++){ // 16 colori di background
            for (int fo=0; fo<16; fo++){ // 16 colori di foreground
                gotoxy(ba*5+1,fo+2); // ogni colore al suo posto
                textcolor(fo); textbackground(ba);
                printf("%02d%02d", fo, ba);
            }
        }
        textcolor(7); textbackground(0); // colori default
        printf("\n");
        COORD cursore=getxy(); // lettura coordinate cursore in base 0
        printf("_<- qui il cursore e' in colonna %d riga %d ", cursore.X, cursore.Y);
        cursore=getxy(); // lettura coordinate cursore in base 0
        printf("_<- qui colonna %d riga %d \n\n", cursore.X, cursore.Y);
        system("pause");
        return 0;
    }
    
    entrambi sono per progetti: console application, scritti in C con Code::Blocks e compilatore GCC. (funzionano anche con progetto console application C++).
    I codici sopra esposti sono frutto del mio primo approcio al C.

    EDIT: concordo con Weierstrass
  • Re: WxWidgets : Frame e Window

    Rubik ha scritto:


    con il C o la vecchia scuola hai un flusso ininterrotto del codice che scorre impietosamente, o si è fermi in un input, o si sta eseguendo un ciclo.
    Ma chi l'ha detto? Questo può capitare finché non si sa come organizzare un codice complesso. In C è molto facile creare un codice orientato agli eventi, anche se non è un linguaggio esplicitamente orientato agli eventi. Meno semplice invece è creare un codice orientato agli oggetti, ma volendo si può fare comunque, costruendo tutto quanto in modo esplicito. Quello che fanno altri linguaggi più evoluti è automatizzare queste operazioni, ma inevitabilmente per farlo nascondono parte del codice mentre il programmatore non sa cosa si muove "sotto il cofano".
  • Re: WxWidgets : Frame e Window

    Rosmarino ha scritto:


    In realtà , volevo riprendere il mio vecchio programma gestionale ( in C sotto Unix AT&T ) aggiungendoci l'uso del mouse e degli eventi

    ...

    Il mio scopo non è creare qualcosa di utilizzabile fruttando librerie fornitissime che risolvono gran parte dei compiti , ma avere strumenti per trasformare la mia fantasia in qualcosa di funzionante , senza finalità di lucro .
    Se hai già un applicativo scritto in C e ci vuoi aggiungere quello che hai appena scritto, perché non consideri di utilizzare le Windows API che nel C sono già native? Non avresti bisogno di alcuna installazione, semplicemente l'header <windows.h> o eventualmente <windowsx.h> o <commctrl.h> se ti servissero anche i Common Controls di Windows.
Devi accedere o registrarti per scrivere nel forum
31 risposte