Oppure

Loading
09/10/15 17:11
ZioCrocifisso
Quell'operazione col for si può anche fare in-place, e poi eventualmente riallocare se è necessario. Se bisogna rimuovere un solo elemento, limitarsi a modificare l'array già esistente è più veloce che allocarne uno nuovo solo per risparmiare qualche byte.
Ultima modifica effettuata da ZioCrocifisso 09/10/15 17:12
aaa
09/10/15 18:29
pierotofy
Si hai ragione.

In place si potrebbe fare:

int j = 0;
for (int i = 0; i < totEl; i++){
    if (*pp[i] != NULL) {
        pp[j++] = pp[i];
    }
}
 
// j è la nuova dimensione dell'array
 
return pp;
Il mio blog: piero.dev
10/10/15 19:49
AldoBaldo
Grazie per i molti consigli.

Il vettore è per forza di cose "piccolino", perché si tratta di immagini che dovrebbero costituire un doppio buffer dello schermo, uno per l'offscreen del primo piano, l'altro per un secondo offscreen dal quale prelevare i dati per le cancellature (la "gomma";). Ipotizzando per le LIM il caso più comune di 1024*768 pixel di risoluzione, ogni elemento della lista verrebbe a pesare (indirettamente, perché un HBITMAP è giusto un puntatore di 4 byte) circa 1024*768*4*2 byte, ovvero circa 6 megabytes. Nei miei "piani" c'è l'idea di implementare un numero massimo di elementi che si aggirerà tra gli 8 e i 16 (non ho ancora deciso; valuterò con delle prove d'uso pratico sul campo per vedere quale può essere un tetto realisticamente utile).

Siccome si scambia la posizione degli HBITMAP senza movimentare le immagini vere e proprie, la velocità non credo proprio sia problema, particolarmente con così pochi elementi. Molto gradita invece la semplicità del procedimento, perché non voglio correre il rischio di perdermi in complicazioni che faticherei a gestire.

Detto questo, credo che ricorrerò a uno dei due metodi proposti da Piero, probabilmente il secondo. Farò qualche esperimento, quindi tornerò a dirvi com'è andata e quale codice avrò effettivamente "adottato".

Per ora, grazie di nuovo.
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
10/10/15 21:19
AldoBaldo
Ho inserito il metodo di compattazione come membro privato della mia classe PAGINE, con questo prototipo:

int CompattaArrayHBITMAP();

Il metodo compatta due array “paralleli” che esistono come proprietà HBITMAP *pp (primi piani) e HBITMAP *sf (sfondi) della classe, quindi restituisce il numero degli HBITMAP non NULL rilevati e compattati in testa a ciascun vettore (il valore di ritorno viene sfruttato come indicatore del numero delle pagine disponibili nella classe, immagazzinandolo in una proprietà int totPag).

LÂ’implementazione finale, dovendo gestire due array in parallelo, è un poco diversa da quella che mi ha suggerito Piero, ma ne segue strettamente la logica:

int PAGINE::CompattaArrayHBITMAP() {
    int i, j;

    for( i=j=0; i<maxPag; ++i ) {
        if( pp[i] != NULL ) {
            pp[j] = pp[i];
            sf[j] = sf[i];
            ++j;
        }
    }

    for( i=j; i<maxPag; ++i )
        pp[i] = sf[i] = NULL;

    return j; // la quantita' degli HBITMAP
              // non NULL in testa agli array
}


Il metodo viene impiegato esclusivamente dal metodo pubblico bool elimina_pagina( int indice ); che elimina la pagina allÂ’indice richiesto (se esiste e purché non sia lÂ’ultima disponibile):

bool PAGINE::elimina_pagina( int indice ) {
    if( indice > -1 && indice < totPag && totPag > 1 ) {

        if( indice == iPag ) // si sta eliminando la pagina correntemente selezionata?
            { SelectObject( dc_pp, pp_orig ); SelectObject( dc_sf, sf_orig ); }

        DeleteObject( pp[indice] );  pp[indice] = NULL;
        DeleteObject( sf[indice] );  sf[indice] = NULL;

        totPag = CompattaArrayHBITMAP();

        seleziona_pagina( indice<iPag ? --iPag : iPag );

        return true;
    }

    return false;
}


Confrontando il procedimento suggerito da Piero con quello che avevo escogitato in proprio sono giunto alla conclusione che quando mÂ’è venuto in mente quellÂ’arzigogolo dovevo avere mangiato troppa peperonata (la cattiva digestione genera mostri!). In effetti la soluzione era molto più semplice di quel che mÂ’era parso lì per lì, ma per qualche ragione (la peperonata, credo) mi si era incriccato il cervello. Pirla! Meno male che cÂ’è pierotofy.it... :)
Ultima modifica effettuata da AldoBaldo 11/10/15 10:14
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.