DEV POSTA
devmail@infomedia.it
A cura di Matteo Baccan

C++: riferimenti incrociati

Date due classi A e B, si vuole che A contenga un puntatore ad un oggetto di tipo B e B contenga un puntatore ad un oggetto di tipo A.
Se la definizione delle classi è fatta all’interno di file header separati, includendo un puntatore dalla classe A alla classe B, questa seconda classe deve essere nota.
Se però si cerca di definire la classe B vi è un errore poiché B contiene un puntatore ad A.
In questo modo si entra in un problema ricorsivo.
Come è possibile risolvere questo problema senza aggirarlo?

Nicolò Fioretti

Risponde Lorenzo Vandoni (vandoni@infomedia.it)

Finché si tratta di puntatori, il problema si risolve semplicemente con una forward declaration. Basta cioè dichiarare la classe A nell’include del file B e viceversa, con questa sintassi:

class A;

In questo modo si indica al compilatore che A è un nome di classe valido e quindi la dichiarazione di un puntatore ad A viene accettato. Il legame con la classe vera e propria viene risolto successivamente.
La cosa non è più vera se invece dei puntatori si mettono come variabili di istanza dei veri e propri oggetti. Se un oggetto A contiene un oggetto B che contiene un oggetto A, si ha una struttura impossibile: in teoria sarebbe necessario uno spazio di memoria infinito per contenerla e si deve quindi ricorrere a una soluzione alternativa, che di solito è appunto quella dei puntatori.


C++: Activex MSChart

Ho sviluppato un'applicazione in Visual C++, relativa al metodo Montecarlo. Ho ottenuto il profitto per cinque prodotti e vorrei rappresentarlo graficamente.
Per tale ragione ho creato una finestra e ho inserito l'ActiveX MSChart. A questo punto non so assolutamente che codice scrivere per generare il grafico. So come farlo in Visual Basic, ma in Visual C++ è differente.
Ho cercato la soluzione sia nei manuali di Visual C++, sia in Internet, ma non ho trovato niente.
Come posso risolvere questo problema?

Giacomo Morosini

Risponde Davide Infantino (infantino@infomedia.it)

In Internet in realtà si trova abbastanza materiale sull'argomento. Per esempio un punto di partenza è http://codeguru.earthweb.com/controls/MSChart.shtml. Naturalmente bisognerà integrare quanto si legge con prove sul campo perché questo controllo ha i suoi problemi, soprattutto perché la documentazione ufficiale non è di buona qualità.
Le fornisco comunque anche una soluzione opensource da valutare: GNU Plot. Volendo esiste anche una versione ActiveX di tale prodotto.


C++ Builder 5: VCL

Ho dei problemi con l'utilizzo delle VCL in C++ Builder 5. Vorrei costruire, all'interno di un oggetto TDBGrid, una lookup list senza derivarla da un dataset secondario. Secondo il manuale per fare questo è necessario: costruire un campo di consultazione da associare al campo di database presente all'interno dell'oggetto TDBGrid; generare un oggetto TLookupList a runtime; inserire all'interno di questo i valori di ricerca utilizzando il metodo TLookupList::Add; assegnare l'oggetto TLookupList alla proprietà LookupList del campo di consultazione costruito con il primo passaggio; assegnare il valore "true" alla proprietà LookupCache del campo di consultazione.
Utilizzando tale procedimento non riesco a costruire il campo di consultazione, in quanto è necessario indicare sempre il nome di un dataset secondario. Inoltre la proprietà LookupList di un campo di consultazione è a sola lettura pertanto ogni tentativo di assegnazione determina un errore di compilazione.
Ho dimenticato qualcosa oppure quanto scritto sul manuale non è corretto?

Claudio Colombo

Risponde Franco Pingiori (pingiori@infomedia.it)

Per ottenere tale risultato, la soluzione più semplice è intervenire sull'oggetto DBGrid. Per aggiungere una drop list ad un campo, durante la stesura del programma, può servirsi dell'Object Inspector. I passi sono: selezionare la proprietà Columns di DBGrid, selezionare il campo al quale vuole associare la drop list, selezionare la proprietà PickList ed aggiungere le stringhe della lista. La PickList è un oggetto TStrings.
Per modificare la drop list durante l'esecuzione, può usare il metodo Add della PickList. Le stringhe da aggiungere possono essere ottenute nel modo che preferisce. Supponendo che la colonna con la lista da aggiornare sia la i-esima della griglia DBGrid1, la funzione potrebbe essere invocata nel modo seguente:

DBGrid1->Columns->Items[i]->PickList->Add("stringa");


ADO: come iniziare

Sono un programmatore ASP e SQL Server 7.0. Ho iniziato, da poco, a programmare con Visual Basic e vorrei realizzare una piccola applicazione che mi permetta di interagire con SQL Server da form Visual Basic. Il problema è che, durante i miei tentativi, non riesco ad utilizzare correttamente l'oggetto ADO, che invece utilizzo correttamente in ASP.
Con ASP utilizzo per la connessione un DNS di sistema chiamato "Scuola" che, tramite ODBC, si interfaccia con la base di dati.
Come posso utilizzare una tecnica simile e memorizzare o visualizzare i dati di SQL Server da Visual Basic?

Aurelio Nisticò

Risponde Davide Infantino (infantino@infomedia.it)

Su Internet esiste parecchia documentazione su ADO.
Per esempio su http://msdn.microsoft.com, se prova a fare una ricerca con le chiavi "ADO AND VB", troverà molta documentazione.
Personalmente però le consiglio di installare SQL Server 2000 Desktop Edition, chiamato anche MSDE, anche se usa SQL Server 7, perché in questo prodotto è presente la documentazione parzialmente tradotta in italiano di SQL Server.
Per molte cose base, l'uso di questa documentazione è intercambiabile con quella di SQL Server 7.
In essa troverà la sezione in inglese: "Building SQL Server Applications" e "ADO and SQL Server Applications", che dovrebbe fare proprio al caso suo.


Turbo Assembler

Dove posso reperire su Internet una versione di Turbo Assembler Borland?

Edoardo Mancini

Risponde Luigi Morelli (morelli@infomedia.it)

Come puoi immaginare, il Turbo Assembler è un prodotto commerciale.
Per quanto ne so, non esistono, al momento, versioni ufficiali gratuite e liberamente scaricabili da Internet, tranne le versioni pirata. Tuttavia è possibile reperire diversi tool assemblatori di pubblico dominio. Di seguito troverai alcuni link di sicuro interesse.

  • http://www.borland.com/borlandcpp/cppcomp/tasmfact.html è la pagina ufficiale di Borland, contiene le ultime informazioni relative a Turbo Assembler, giunto alla versione 5.0 e le patch per assemblare sotto Borland C++Builder.

  • http://www2.dgsys.com/~raymoon/faq/tasm.html è una pagina contenente FAQ (frequently asked questions) relative a Turbo Assembler di Borland.

  • http://www.vasm.org/links.html, su questa pagina sono presenti numerosissimi link relativi al nostro amato linguaggio, compreso il download del volume "The art of Assembly Language Programming" di Randal Hyde. Inoltre sono presenti anche numerosi collegamenti ad assemblatori compatibili e liberamente scaricabili.

  • http://www.emsps.com/oldtools/borasm.htm, in questa pagina appaiono le vecchie versioni del Turbo Assembler, supportate da terze parti. In particolare Turbo Assembler 1.0 viene venduto a $29, mentre la versione 2.0x costa $79. Nella stessa pagina è possibile trovare anche Turbo Debugger e Turbo Profiler.

Versioni limitate di Turbo Assembler possono essere trovate nelle distribuzioni Borland del C++Builder 2.0 e 3.0, ma la versione completa con Debugger e Profiler è una cosa diversa.


Delphi: Paradox

Sto lavorando ad una procedura in Delphi 3, su un database Paradox e mi ritrovo "nei guai" sull'eliminazione dei dati da una tabella.
Ho sempre utilizzato il comando TdTable.EmptyTable ed ha sempre funzionato a meraviglia, purtroppo questa tabella contiene un campo memo e il relativo file .mb.
Quando eseguo EmptyTable su questa tabella lo svuotamento è solo virtuale dato che fisicamente i file .db e .mb continuano ad occupare lo stesso spazio.
Conoscete un metodo per riuscire a svuotare la tabella fisicamente senza doverne cambiare la struttura?

Luca Pompermaier

Risponde Leonardo Fiocchetti (fiocchetti@infomedia.it)

Verificando il codice della versione 5 di Delphi ho visto che Empty table invoca l'API BDE DbiEmptyTable, che effettivamente sembra, stando all'help e dalle prove che ho fatto, svuotare la tabella inclusi eventuali file memo.
Sono pertanto dubbioso in merito ai risultati che hai ottenuto.
Ti consiglierei dapprima di verificare, se hai il codice della VCL a disposizione, quale sia l'implementazione nella versione 3 di Delphi del suddetto metodo.
Siccome ritengo che tale API rispetti comunque i vincoli di integrità del DB, penso che dall'ultima volta che ti ha funzionato forse hai cambiato la struttura del database introducendo qualche vincolo tra alcune tabelle, compresa quella di cui non riesci a fare il pack.


Visual Basic: apertura sportello CD

Sto lavorando da tempo a un software e, tra le sue opzioni, vorrei che l'utente potesse aprire e chiudere lo sportellino del lettore CD.
Nonostante abbia visitato il sito dove lei ha pubblicato il metodo da utilizzare, ho avuto risultati deludenti nelle prove pratiche e mi chiedevo se potesse inviarmi un sorgente d'esempio.

Domenico Mangione

Risponde Davide Infantino (infantino@infomedia.it)

Effettivamente chiudere o aprire lo sportellino con il controllo MCI a volte funziona ed altre volte no. Sul sito Microsoft http://msdn.microsoft.com esistono comunque due esempi per fare questo.
I titoli dei due articoli sono:

HOWTO: Eject Removable Media on Windows 95 (Q168180)
HOWTO: Ejecting Removable Media in Windows NT/Windows 2000 (Q165721)

Purtroppo i due esempi sono in C e vanno quindi "tradotti" in Visual Basic.
La cosa è complessa, ma con una discreta pazienza si può fare. Volendo all'indirizzo http://utenti.tripod.it/papero/art.dllvb.html trova un articolo sul come scrivere DLL in C da utilizzare in Visual Basic.


Java: codice a colori

Vorrei inserire del codice Java all’interno dei file Word della mia tesi. Mi piacerebbe però inserirlo a colori: commenti in grigio chiaro, keyword in blu, stringhe in rosso e così via.
Esistono tool capaci di fare qualcosa del genere?

Giovanni De Martino

Risponde Lorenzo Bettini (lettini@infomedia.it)

Ho scritto e mantengo il programma GNU Source-highlight, che vuole essere una suite di programmi per generare documenti con syntax highlight dei listati scritti in certi linguaggi di programmazione. Al momento, di questo pacchetto fanno parte java2html e cpp2html, rispettivamente per Java e per C/C++. Il file HTML generato può essere inserito in documenti Word in modo abbastanza semplice, soprattutto se hai installato, con Office, la gestione delle pagine HTML. Inoltre puoi personalizzare i colori e lo stile del testo generato. Puoi scaricare il programma all'indirizzo http://www.gnu.org/software/src-highlite/.


Visual C: linkare una libreria

Sto tentando di scrivere un programma in Visual C che controlli la porta MIDI. Su un sito Internet c'è scritto che nel programma occorre includere mmsystem.h e mmreg.h e linkare la libreria winmm.lib.
Io ho incluso la libreria nella finestra del progetto e ho creato un file per verificare che tutto funzionasse nel modo corretto, limitandomi ad inserire le due include:

#include<mmsystem.h>
#include<mmreg.h>
#include<stdio.h>

int main(void)
{
   printf("prova\n");
}

ma compaiono circa 80 errori di compilazione. Cos’ho dimenticato?
Inoltre come faccio a conoscere quali funzioni vengono messe a disposizione dalla libreria winmm.lib?

Rosario Marino

Risponde Davide Infantino (infantino@infomedia.it)

Nel caso specifico un codice funzionante per Visual C potrebbe essere quello riportato sotto. Dico potrebbe perché ci sono varie opzioni del compilatore che bisogna impostare perché funzioni, come l'esclusione del "precompiled header", oppure l’avere aggiunto le librerie giuste nella fase di link.
Per sapere quali funzioni sono presenti in libreria, in questo specifico caso, mi sembra che la soluzione migliore sia avere la documentazione allegata al compilatore Visual C.
Vedrà che le funzioni delle varie librerie sono raggruppate per argomento e sono spiegate in dettaglio. Inoltre c'è sempre l'insieme di tutte le funzioni ordinate alfabeticamente.

#define WIN32_LEAN_AND_MEAN
#define ANSI

#include<windows.h>
#include<mmsystem.h>
#include<mmreg.h>
#include<stdio.h>

int main(int argc, char* argv[])
{
   printf("prova\n");
   return 0;
}


Access: aggiornamento record

Ho scritto un'applicazione in ambiente Access 97 per la gestione degli ordini ed il relativo carico/scarico dal magazzino. Per fare questo ho seguito i consiglio che ho trovato nella serie di articoli su Access pubblicati da DEV. Non riesco però a risolvere un piccolo problema. Se un cliente ci ripensa e chiede che una riga del modulo d'ordine venga cancellata, tutto procede nel modo corretto. Le quantità degli articoli tornano al loro stato di partenza.
Per fare ciò ho scritto del codice legato agli eventi "Eliminazione", memorizza il codice di articolo e la quantità che non si vuole più ordinare, e "Dopo conferma eliminazione", rimette tutto a posto nella tabella dei prodotti. C’è però un problema se è richiesta l'eliminazione di due o più righe contemporaneamente. Il magazzino non viene più aggiornato correttamente: soltanto uno degli articoli non più ordinati torna al suo posto. Questo perché l'evento "Dopo conferma eliminazione" si verifica solo una volta nonostante ci siano più record da cancellare. Come superare questa difficoltà?

Giovanni De Martino

Risponde Lorenzo Vandoni (vandoni@infomedia.it)

L'evento "su eliminazione" (Form_Delete nel codice) viene attivato una volta per ogni record da eliminare. L'evento "dopo conferma eliminazione", invece, viene attivato una volta sola. La soluzione quindi può essere quella di sfruttare il primo evento per memorizzare codici e quantità in un array, invece che in due semplici variabili, e quindi, nell'evento "dopo conferma eliminazione", si potrà scandire l'array per aggiornare tutti gli articoli.