Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Rhinorhino on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Reading the Registry: numeric values

Status
Not open for further replies.

chpicker

Programmer
Joined
Apr 10, 2001
Messages
1,316
I followed some sample code for reading registry values. For the most part they are pretty simple, I can read any string values I like. However, Binary or DWORD values always return an error code of -106. I cannot find a reference to this error code anywhere in WinError.H and cannot for the life of me imagine what could be wrong. Here is some sample code:
[tt]
set classlib to home()+"ffc\registry" ADDITIVE
oReg=CreateObject("registry")
p_cRegName=""
* Next line returns 0 (ERROR_SUCCESS)
?oReg.GetRegKey("lfFaceName",@p_cRegName,;
"Software\Microsoft\Notepad",oReg.nUserKey)
* Next line prints the value from the registry
?p_cRegName
p_cRegName=0 && Set numeric
* Next line returns -106 (No clue)
?oReg.GetRegKey("lfItalic",@p_cRegName,;
"Software\Microsoft\Notepad",oReg.nUserKey)
* Next line shows value was unchanged
?p_cRegName
[/tt]
You'll notice that I went ahead and set p_cRegName to a numeric value before trying to call it the second time although that is unnecessary.

Anyone know what error -106 is? Is there something special you have to do to retrieve a numeric value?

Ian
 
The -106 error is internal to the registry class. See the registry.h file in the ffc directory.

Why don't you use the following:

hkeycuruser= -2147483647
#DEFINE HKEY_CLASSES_ROOT -2147483648
#DEFINE HKEY_CURRENT_USER -2147483647
#DEFINE HKEY_LOCAL_MACHINE -2147483646
#DEFINE HKEY_USERS -2147483645
set classlib to home()+"ffc\registry" ADDITIVE
oReg=CreateObject("registry")

p_cRegName=""
? oReg.openkey("Software\Microsoft\Notepad",HKEY_USERS,.f.)

? oreg.gekeyvalue("lfFaceName",@p_cRegName)
?p_cRegName

p_cRegName=0 && Set numeric
? oreg.gekeyvalue("lfItalic",@p_cRegName)
?p_cRegName
oRetg.CloseKey()
 
Ok, I tried your code (after fixing the typos--no offense *grin*) and get error -105 ("bad key passed") on both of the GetKeyValue() functions.

Looking up -106 in Registry.H, I find it means "data type for value is not a data string". Well, duh, I'm trying to get a numeric value! LOL

So, does this mean that the class can ONLY work with string data? I can't use it for numeric? Guess I'll just have to use the API functions myself.

Ian
 
Ian

You will be able to read DWORD values without error using WinAPI calls, but the data is indecipherable without conversion. HTH

Chris [pc2]
 
Ian,
I modified the REGISTRY.PRG to be able to access numeric values - I added Get32KeyValue() and GetBinStrKeyValue(). I talked with Randy Brown of MS who wrote the original program, and he said that like the other code provided with VFP, it was never meant to be THE answer to everyones requirements, but simply a starting point / example.

I originally wrote them to demontrate &quot;overloading&quot; classes for our local user group, so I've never actually used them in a real application. I had a demo of reading the &quot;MessageFont&quot; of the HKEY_CURRENT_USER key &quot;Control Panel\desktop\WindowMetrics&quot;. The demo works fine in Win 95 / 98, but fails in NT / 2000 / XP - not because the changes don't work, but because these other OSs store Font data differently (in &quot;double byte&quot; strings <s>).

So, a variant on your code:
#DEFINE HKEY_CURRENT_USER -2147483647 && BITSET(0,31)+1

LOCAL lcRegValue, lcRegfile, lnRetVal, oReg, lnRegValue

lcRegfile = &quot;REGISTRY&quot;
lnRetVal = 0

SET PROCEDURE TO (m.lcRegfile) ADDITIVE
oReg = CreateObject(&quot;Registry&quot;)

lcRegValue = &quot;&quot;
lnRetVal = oReg.GetRegKey(&quot;lfFaceName&quot;,@lcRegValue,;
&quot;Software\Microsoft\Notepad&quot;, HKEY_CURRENT_USER)
? lcRegValue

lnRegValue = 0
lnRetVal = oReg.GetRegKey(&quot;fWrap&quot;,@lnRegValue,;
&quot;Software\Microsoft\Notepad&quot;, HKEY_CURRENT_USER)
? lnRegValue

RELEASE oReg
RELEASE PROC (m.lcRegfile)

If you want this &quot;new&quot; version of the REGISTRY.PRG (I last updated it back in 4/99!), just post an email address (obscured if you don't want the page scrapers to add you to more SPAM lists), and I'll send it with some more sample code.

Rick


 
Thanks for all the suggestions, everyone. I found it (surprisingly) easier to just implement the API calls myself.

I just wanted a quick program that I could use to automatically disable Internet Explorer access on my computer while I'm not at work. I programmed a timer that checks every 10 seconds to see if it's within my work hours. If it's not within my normal hours, it enabled the Proxy Server (which points to a bogus address) thus preventing the web browser from being able to access anything. If it is my normal work hours, it disables the proxy.

Working with a DWORD is simple enough: it's just a 4 byte value which you can create using concatenated CHR() functions (least significant byte first). My program is 35 lines and works great. :o)

Rick...I would still be interested in your code. Send it to ianATenigmalakeDOTnet.

(This is the first time I've ever posted that email to a public board...let's see if I start getting spammed now LOL)

Ian
 
Another option is to use regedit.exe

Regedit has a number of command line options to help automate it's use in either batch files or from the command prompt.

regedit.exe [options] [filename]

filename && Import .reg file into the registry
/s && Silent, i.e. hide confirmation box when importing files
/e && Export registry file e.g. regedit /e file.reg HKEY_USERS\.DEFAULT
/L:system && Specify the location of the system.dat to use
/R:user && Specify the location of the user.dat to use
/C && Compress [filename] (Windows 98)

HTH

Chris [pc2]
 
rgbean would you be able to send that code you have to

jesse@2020its.com

i would greatly appreciate that
 
Here are a couple of conversion functions that may be useful:

Code:
FUNCTION  buf2dword (lcBuffer)  
RETURN;  
    Asc(SUBSTR(lcBuffer, 1,1)) + ;  
    Asc(SUBSTR(lcBuffer, 2,1)) * 256 +;  
    Asc(SUBSTR(lcBuffer, 3,1)) * 65536 +;  
    Asc(SUBSTR(lcBuffer, 4,1)) * 16777216  
ENDFUNC 
FUNCTION  buf2word (lcBuffer) 
RETURN Asc(SUBSTR(lcBuffer, 1,1)) + ; 
    Asc(SUBSTR(lcBuffer, 2,1)) * 256
 
thx both of you. Now another question since im a registry newbie. Now that I have a the decimal value i needed and have made my comparsion.

In order to insert this number back into the Dword i must convert it to hex? Am i right?
 
Note: I've updated my 'unofficial' REGISTRY.PRG program to handle reading and writing of dwords and binary strings. I also updated it to know about Win 2000, XP, 98 and ME - even the one supplied with the VFP 8.0 beta doesn't have that!

I've tried to maintain the overloaded nature of the method calls and Randy Brown's, internal philosphies.

If you are interested in a copy (with some test code samples), let me know and I'll either send it to you, or find somewhere I can let you download it from.

Rick
 
Hey Rick, I don't suppose you're interested in making a FAQ out of it.(?) There are a few others interested in reading and writing the registry.

Dave S.
 
Dave,
Normally FAQs are (should be?) all new code, and all I've done is extended a program MS already provides. (The original was 23kb and mine with corrections and 4 new methods, is just 28kb.)

When I talked to Randy Brown at a DevCon a couple years ago about this program, he indicated there was no problem with distributing this kind of update, as long as I left all the copyright info intact and gave credit to those who had previously contributed.

Like I wrote before, if there is enough interest, I'll try and post it on our user group web site, and provide a link to it. (Perhaps that could be the FAQ - a description of the changes and a link.)

I also plan on extending these changes to the Foundation Class - Registry.VCX. The changes are virtually identical, it's just a little different instantiation code to use it vs. the REGISTRY.PRG.

Rick
 
As for converting back from the &quot;decimal&quot; as you put it, into the DWORD format:

* * *
* dword is compatible with LONG
FUNCTION num2word (lnValue)
RETURN Chr(MOD(m.lnValue,256)) + CHR(INT(m.lnValue/256))


Technically, you are not converting from &quot;Hex&quot; to &quot;decimal&quot;... you're converting between DWORD and VFP's internal Numeric type... and back.
 
Just to let you know Rick that updated prog works excellent!! Good work and thanks again! :)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top