38.1 Registry
38.2 Rýpání do registrů
38.3 Domácí úkol
38.4 V další lekci
38.1 Registry
Nevím, jak se to mohlo stát, ale nejspíš jsem vás zapomněl informovat o jedné velmi důležité věci, která v mnohém předčí dříve zmíněné soubory ini. Jsou to právě registry, do kterých si můžeme ukládat různá data a po opětovném zapnutí programu si je z nich zase vyzvednout. Slouží k tomu poměrně jednoduchá sada příkazů. První příkaz je pro zapsání do registru, druhý je pro čtení z registru a třetí je pro mazání hodnoty včetně klíče z registru. První se budu zabývat zápisem do registru. Je to asi logické, abychom pak měli na čem ukazovat čtení a mazání. Zápis tedy vypadá nějak takto:
Call SaveSetting(jmeno_aplikace, sekce, klic, ukladany_retezec)
Voláme funkci, která je dostupná přímo z jazyka VB. Jejími parametry jsou název aplikace, sekce, ve které je klíč, název klíče a hodnota, která se do klíče uloží. V praxi to může vypadat třeba takto:
Call SaveSetting(App.ProductName, "UserInfo", "Uzivateske_jemno", userName)
Call SaveSetting(App.ProductName, "Setting", "Barva pozadí", lngBgColor)
Potom je třeba tato uložená data číst a to takto:
Navratova_hodnota = GetSetting(jmeno_aplikace, sekce, klic, defaultni_hodnota)
Opět předvedu a vysvětlím na příkladě:
retval = GetSetting(App.ProductName, "Setting", "Barva pozadí", RGB(200, 200, 200))
Funkce GetSetting po nás požaduje tři parametry, těmi jsou název aplikace název sekce a název klíče. Poslední čtvrtý parametr je volitelný a tudíž ho zadávat nemusíme, ale jeho zadání je v některých případech více než vhodné, uloží se totiž do proměnné retval, pokud se nějakým nedopatřením potřebný klíč nenalezne. Toho můžeme využít například při prvním spuštění programu. V proměnné retval tedy máme návratovou hodnotu funkce. Hodnoty se mažou pomocí DeleteSetting, ale ta je tak jednoduchá, že se jí ani nebudu zabývat.
Pokud byste měli zájem se štourat do jiných registrů, je to věc mnohem složitější, je potřeba využít API funkce a i kód je „mnohem“ složitější.
38.2 Rýpání do registrů
V prvé řadě budeme potřebovat pár API funkcí. Ty vám ukážu. Bez nich je to, co se chystáme provádět, téměř nemožné:
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Private Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey As Long, ByVal lpValueName As String) As Long
Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long
Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpData As Any, ByVal cbData As Long) As Long
Dále by se snad shodly nějaké konstanty, kterých se využívá. Ale my se jimi prozatím příliš zabývat nebudeme a představíme si je až v průběhu této lekce. Mnozí jste se na tento díl určitě těšili :)
Jelikož pracujeme s existujícími řetězci, začneme dnes čtením hodnot. To je asi nejsložitější, protože prvně musíme zjistit, jakou hodnotu vlastně čteme a podle toho s ní musíme zacházet. Viděl jsem tyto úlohy řešené několika způsoby. Buď složené do jedné funkce nebo do více. Více funkcí by bylo asi pro někoho estetičtější a možná i příjemnější řešení, ale já zvolím metodu první, která spočívá v tom, že se to celé bude skládat z jedné funkce. Tento postup volím proto, aby byla jasná posloupnost toho, co se vykoná a abyste vy nemuseli očima přeskakovat na různé pomocné funkce.
Ještě než se ale pustíme do psaní samotného kódu, rád bych vám řekl něco o práci s registry obecně. Než začneme s jakýmkoliv řetězcem pracovat, je třeba ho otevřít. K tomu se používá výše uvedená API funkce RegOpenKey, která jako své parametry požaduje cestu ke klíči a proměnnou, v níž je uložen výsledek funkce. Ten slouží jako-no, snad se to dá přirovnat k manipulátoru-a pracují s ním ostatní funkce, pomocí níž s hodnotami v klíči pracujeme. Potom až vše dokončíme, je důležité klíč zase uzavřít. Na to se používá výše zmíněná API funkce RegCloseKey. Ta má jediný argument a na jeho místo se dosazuje návratová hodnota funkce RegOpenKey, o které jsem mluvil v souvislosti s tím, že s ní pracují i jiné funkce…
Tato lekce měla být původně o FlexGridu, ale pak jsem si řekl "Nějakej flexgrid, ten počká. Takové registry jsou mnohem zábavnější.", ale to sem nepatří.
…Ještě se na moment vrátím k funkci RegOpenKey, ta je sice dobrá, ale pokud chceme otevřít nějaký klíč, který ještě neexistuje, musíme použít funkci RegCreateKey. Tto by ale neměl být žádný problém, protože je prakticky stejná-teda alespoň co se týká parametrů. Ted již pomalu k onomu kódu. První si představíme nějaké základí konstanty.
Const REG_NONE As Long = 0 ' nic
Const REG_SZ As Long = 1 ' řetězec
Const REG_BINARY As Long = 3 ' binární hodnota
Const REG_DWORD As Long = 4 ' 32-bitové číslo
Tyto slouží k určení druhu hodnoty v klíči. Další sada konstant jsou klíče k jednotlivým sekcím v registrech a to:
Const HKEY_CLASSES_ROOT As Long = &H80000000
Const HKEY_CURRENT_USER As Long = &H80000001
Const HKEY_LOCAL_MACHINE As Long = &H80000002
Const HKEY_USERS As Long = &H80000003
Const HKEY_PERFORMANCE_DATA As Long = &H80000004
Const HKEY_CURRENT_CONFIG As Long = &H80000005
Ty nám poslouží především k zpřehlednění kódu, každému je totiž příjemnější, když v kódu vidí HKEY_CURRENT_USER, než když tak je naprosto nesrozumitelné &H80000001, že?
Teď se již pustíme do zjišťování hodnot klíčů.
Function GetREG(hKey As Long, strPath As String, strValue As String)
Dim hndREG 'deklarace manipulátor klíče
Dim lngTypeHodnoty As Long 'proměnná, ve které se skrývá typ hodnoty
Dim strBuffer As String 'proměnná bufferu
Dim lngVelikostBufferu As Long 'proměnná obsahující velikost bufferu
RegOpenKey hKey, strPath, hndREG 'otevření klice
If RegQueryValueEx(hndREG, strValue, 0, lngTypeHodnoty, ByVal 0, lngVelikostBufferu) = 0 Then
'zjištění typu hodnoty
If lngTypeHodnoty = REG_SZ Then 'Pokud je hodnota řetězce, zpracuje se takto:
strBuffer = String(lngVelikostBufferu, Chr$(0)) 'vytvoříme buffer
If RegQueryValueEx(hndREG, strValue, 0, 0, ByVal strBuffer, lngVelikostBufferu) = 0 Then
GetString = Left$(strBuffer, lngVelikostBufferu - 1) 'do názvu funkce vrátíme hodnotu
' a odebereme poslední nulový znak
End If
ElseIf lngTypeHodnoty = REG_BINARY Or REG_DWORD Then 'Pokud je proměnná binární nebo DWORD, zpracujeme ji úplně jednoduše
Dim strData As Integer
If RegQueryValueEx(hndREG, strValue, 0, 0, strData, lngVelikostBufferu) = 0 Then
GetString = strData
End If
End If
End If
RegCloseKey hndREG 'uzavření klíče
End Function
Vidíte, že už je to mírně složitější, ale po pár pročteních-někomu bude stačit jedno-to pochopíte. Myslím, že jako dostatečné vysvětlení slouží komentáře. Pokud ne, tak pište do Poradny. Teď si ještě ukážeme, s jakými parametry se funkce volá:
x = REG (HKEY_CURRENT_USER, "Console", "FaceName")
To je vše, HKEY_CURRENT_USER používáme jako konstantu zmíněnou výše, Console je cesta ke klíči a FaceName je jméno klíče. Je to jen příklad, ale měl by fungovat. Pokud vám tento zápis vyhodí NoValue!, tak se nedivte, protože tento klíč je dost často prázdný. Je to řetězcová proměnné.
Pokud se potřebujete dostat k editoru registru, určitě už znáte postup-Start >> Spustit >> regedit
Nyní pokud máte zájem pokračovat, můžete se dozvědět, jak hodnotu mazat. K tomu se používá výše zmíněná API funkce:
Private Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey As Long, ByVal lpValueName As String) As Long
Pro tuto API funkci si napíšeme jednoduchou funkci, která ji bude využívat a mazat tak hodnoty z klíčů.
Function DelREG(hKey As Long, strPath As String, strValue As String)
Dim hndREG
RegOpenKey hKey, strPath, hndREG
RegDeleteValue hndREG, strValue
RegCloseKey hndREG
End Sub
Hodnota se maže včetně klíče a funkce se volá tako:
DelREG HKEY_CURRENT_USER, "Console", "FaceName"
Když už jsme klíč smazali, mohli bychom ho znovu nahrát. K tomu se používá API funkce RegCreateKey, která, jak už jsem jednou říkal, má stejné parametry jako funkce RegOpenKey a RegSetValueEx. Viz kód:
Function SaveREG(hKey As Long, strPath As String, strValue As String, strData As String)
Dim hndREG
RegCreateKey hKey, strPath, hndREG
RegSetValueEx hndREG, strValue, 0, REG_SZ, ByVal strData, Len(strData)
RegCloseKey hndREG
End Sub
A volání funkce je jasné:
SaveREG HKEY_CURRENT_USER, "Console", "FaceName", "ukládaný_retězec"
Tímto se dají hodnoty i přepisovat. Toto by bylo o řetězcích, hodnoty jsou velmi podobné, ale na to snad přijdete sami. Určitě je zapotřebí změnit REG_SZ a také Len(strData)
To je vše, o co jsem vás chtěl v této lekci obohatit :) Doufám, že vám to k něčemu bylo a že vám to nějak pomohlo.
38.3 Domácí úkol
Vím, že v takto pokročilé fázi je zadávání úkolů snad i trochu scestné, ale pro ty, které je potřeba popostrčit, je zde takový drobný návrh. Co třeba udělat něco, co nerozvíjí jen schopnosti programovat, ale i schopnosti tvořit a hledat informace? Co třeba program na optimalizaci registrů? S pěkným uživatelským rozhraním a velkými možnostmi? Vy, kteří si myslíte, že jste hodni se takového úkolu zhostit, to berte jako takovou ročníkovou práci. Ale rád bych v tom viděl víc, než znalost práce s registry a checkbuttony, trošku si s tím pohrajte, ať to vypadá jako program a ne jako vtip :)
38.4 V další lekci
Snad se tam probuje již zmiňovaný FlexGrid