Newsgroup: it.comp.lang.c++
Titolo: Registry & Vc++

Prima di tutto: Grazie,
secondo,
Si, più o meno il significato di tutte le funzioni lo conosco ( o meglio so
a cosa servono ma non riesco ad usarle...)
Il fatto è che usate come dici tu(ovvero RegOpenKey(key)), il compilatore mi
restituisce:
the function RegOpenKey do not accept 1 value.
ovvero gli mancano dei parametri.
Non per niente la definizione di quella funzione è
 LONG RegOpenKey( HKEY hKey,
 // handle of open key
LPCTSTR lpSubKey,
 // address of name of subkey to open
PHKEY phkResult
 // address of handle of open key
);
a cui vanno sommati altri due o tre parametri se la si usa nella versione
Ex---------
Il mio problema sta proprio qui.
Non riesco a leggere o scrivere nessun valore contenuto nel registry...
in secondo luogo (domanda che mi rendo conto sia veramente scema..) cosa è e
a cosa serve un handle of open key?(veramente, come avrai intuito, non ho
ben chiaro neanche il concetto di Handle...)
Ok mi sembra di aver dato fastidio abbastanza,
ancora grazie,
Francesco Aruta.

ovvero gli mancano dei parametri.
Certo, il nome della sottochiave da aprire e l'indirizzo in cui
porre il risultato -- vorrei anche vedere...!  Sarebbe un po' come
se uno si lamentasse che non gli compila fopen, passandogli il
filename, perche` non passa il secondo parametro (il "mode")...!
Vabbe`, vista la confusione, forse la cosa migliore e` un programmillo
d'esempio.  Ecco un esempietto di quelli che si buttano giu` in 5
minuti, una piccola console application che legge uno specifico
valore (di locazione e nome fissi e predefiniti) dalla registry:
-- taglia regesem.cpp:
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
    HKEY hk = HKEY_LOCAL_MACHINE;	// chiave corrente
    LONG result;			// risultato chiamate API
    // il "percorso" da seguire sotto HKEY_LOCAL_MACHINE:
    const char *chiavi[] = {
        "SOFTWARE", "Microsoft", "Windows", "CurrentVersion",
        0
    };
    // "seguiamo il percorso" con una serie di RegOpenKey:
    for(int i=0; chiavi[i]; ++i) {
        result = RegOpenKey(hk, chiavi[i], &hk);
        if(result == ERROR_SUCCESS)
            cout << "Opened OK: " << chiavi[i] << endl;
        else {
            cout << "Cannot open: " << chiavi[i]<<", err="<<result<< endl;
            return 1;
        }
    }
    // OK, adesso leggiamo uno specifico valore
    const char * valuename = "ProgramFilesDir";	// nome del valore
    DWORD dwType;				// tipo letto
    char buffer[256];				// dati letti
    DWORD bufsize = sizeof(buffer);		// numero byte letti
    // l'operazione di lettura
    result = RegQueryValueEx(hk, valuename, 0, &dwType,
        (unsigned char*)buffer, &bufsize);
    // diagnosi di successo o fallimento
    if(result == ERROR_SUCCESS)
        cout << "Queried OK: "<<valuename<<", "<<bufsize<<" bytes" << endl;
    else {
        cout << "Cannot query: "<<valuename<<", err="<<result<<endl;
        return 2;
    }
    // mostriamo il valore all'utente, se ci e` possibile:
    if(dwType == REG_SZ || dwType == REG_EXPAND_SZ) {
        cout << "Value is string: " << buffer << endl;
    } else if(dwType == REG_MULTI_SZ) {
        cout << "Value is multi-string: " << endl;
        char *p = buffer;
        while(*p) {
            cout << "String: " << p << endl;
            while(*p) ++p;
            ++p;
        }
    } else {
        cout << "Type=" << dwType << "(not string)" << endl;
    }
    return 0;
}
-- fine taglio
E` tutto chiaro sin qui?  E` un poco come "scendere" alla ricerca
di uno specifico file nell'albero dei directory, aprendo l'uno
dopo l'altro i directory in cui e` annidato a partire dalla radice.
Vogliamo leggere il valore:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir
(che spero sia presente su qualsiasi macchina -- comunque, se hai problemi,
usa REGEDIT, o REGEDT32 che sia, sulla tua macchina, per trovare un valore
stringa che _sia_ presente, e cambia le costanti in questo programma per
la prova).
Partiamo da HKEY_LOCAL_MACHINE, una delle quattro "chiavi sempre aperte"
da cui inizia qualsiasi operazione di registry.
Iterando sulle componenti del "percorso", apriamo ciascuna nella "chiave
corrente" (percorso sino a quel punto), sovrascrivendo quest'ultima (piu`
elegante sarebbe aprire su un'altra HKEY, chiamiamola ad esempio hk1,
poi chiudere la precedente hk prima di fare hk=hk1).
Quando arriviamo alla fine del percorso, chiediamo il valore con il
nome che ci interessa.  Qui uso la versione estesa di query per
potere controllare il tipo di dato, "tanto per gradire".
Soluzione poco elegante e` invece quella di fornire un buffer fisso;
come risultato avrei un errore se il valore che m'interessa fosse
piu` lungo del buffer.  Piu` elegante: una prima query cui passi
un "puntatore al buffer" pari a zero, questa ti da SOLO il numero
di byte che servono; poi, una "pb=new char[numbytes]" per allocare
lo spazio che serve, e la ripetizione della query senza piu` il
pericolo di troncamento (infine, ovvio, la "delete[] pb").  Ma
questo e` solo un programmillo d'esempio e puo` permettersi (spero:-)
qualche "scorciatoia" tipo quella del buffer fisso, visto che il
ProgramFilesDir che interessa non dovrebbe essere piu` di 256
caratteri di lunghezza.
OK, vediamo allora quanto questo esempietto puo` essere stato utile
per chiarire i tuoi dubbi sull'accesso alla registry; se questi
discorsi elementari sono chiariti, possiamo magari vedere, se servono,
cose piu` complicate.
Ah, un avvertimento: ***ATTENZIONE***!!! a *scrivere* sulla registry!!!
E` di gran lunga il modo piu` facile per sputtanarsi tutta una
macchina Windows.  Un erroruccio, e BOOM, macchina rovinata!
***IMPORTANTE***: tenere backup frequenti della registry, e un
floppy di reboot/startup di emergenza in grado di recuperare
la registry dai backup...!!!  *Soprattutto* se si sperimenta con
programmetti che scrivono sulla registry, ma sarebbe un'ottima
precauzione in generale.  Di tutto quel che puo` interessare
avere su un backup, la registry e` probabilmente una delle cose
piu` importanti -- c'e` dentro praticamente tutta la configurazione
di macchina, e, se si perde quella, si rischia di dovere ripetere
l'istallazione di *tutto*, ma dico *tutto*...!!!
Alex
--
 ____    Alex Martelli, Bologna, Italia -- email: 
al...@magenta.com
 \SM/___                                 
http://magenta.com/~alex
  \/\bi/     You never know what is enough unless you know what
     \/          is more than enough.

Vabbe`, vista la confusione, forse la cosa migliore e` un programmillo
Grazie mille del programmino spiegato alla perfezione...
( con tutti i tuoi programmi-esempio che trovo sul NG ci si potrebbe
scrivere un ottimo libro ;-)
In realtà racchiude "tutto" quello che dovevo fare con il (la?) registry
ovvero leggere una stringuccia in una chiave che conosco a priori.
AriGrazie,
Francesco Aruta

ovvero leggere una stringuccia in una chiave che conosco a priori.
Beh, si`, e` (per fortuna) l'operazione piu` tipica... l'unica cosa da
verificare (spesso e` ambigua quando qualcuno ti specifica una
chiave nella registry) e` se "l'ultimo livello" sia il nome di un valore
(da passare alla RegQueryValueEx come secondo parametro)
ovvero il nome dell'ultima sottochiave (in questo caso, bisognera`
chiamare RegQueryValueEx con secondo parametro "stringa
vuota", per avere il valore "di default" di quella chiave).
Alex