Need Help with using CString to read string registry keys
-
Hey guys, I'm new to using MFC and to programming in general. I'm having great difficulty with Using CString to read off reg_sz values from the registry. I keep getting this Debug assertion after i leave the function i have these registry reads in Program: MyApp File: dbgheap.c Line:1011 Expression:_CrltsValidHeapPinter(pUserData) exception 03h in my MyApp.exe heres the function snippet: DWORD dwType =0, dwSize=256; ......... ....... float ftemp; for(int i=0; i<6 ;i++) { //open key ...... RegQueryValueEx(tempKey,"Label", NULL, &dwType,(BYTE*) RegRead.GetBuffer(256), &dwSize); RegRead.ReleaseBuffer(); //convert string to float value ftemp=atof(LPCTSTR(RegRead)); m_sClass->Function(i,ftemp,value); ....... m_sClass->Function1(i,ftemp,value,value2); } Once i leave the function this loop is contained in, the compiler throws that degug assertion. If i remove all references to this operation i dont get the assertion. Therefore i assume im using CString wrong somehow. Am i? What is the proper way to make the registry read then? Background: I am trying to retrieve a float value i wrote to the registry as a REG_SZ and then use it. This may be a stupid question but it's not to someone new at this. I appreciate any help :confused: "DWORD my man!"
-
Hey guys, I'm new to using MFC and to programming in general. I'm having great difficulty with Using CString to read off reg_sz values from the registry. I keep getting this Debug assertion after i leave the function i have these registry reads in Program: MyApp File: dbgheap.c Line:1011 Expression:_CrltsValidHeapPinter(pUserData) exception 03h in my MyApp.exe heres the function snippet: DWORD dwType =0, dwSize=256; ......... ....... float ftemp; for(int i=0; i<6 ;i++) { //open key ...... RegQueryValueEx(tempKey,"Label", NULL, &dwType,(BYTE*) RegRead.GetBuffer(256), &dwSize); RegRead.ReleaseBuffer(); //convert string to float value ftemp=atof(LPCTSTR(RegRead)); m_sClass->Function(i,ftemp,value); ....... m_sClass->Function1(i,ftemp,value,value2); } Once i leave the function this loop is contained in, the compiler throws that degug assertion. If i remove all references to this operation i dont get the assertion. Therefore i assume im using CString wrong somehow. Am i? What is the proper way to make the registry read then? Background: I am trying to retrieve a float value i wrote to the registry as a REG_SZ and then use it. This may be a stupid question but it's not to someone new at this. I appreciate any help :confused: "DWORD my man!"
I've been programming in MFC since 1994, and I never directly modify the CString buffer, it just seems wrong to me. Why not just use a character array? What do you gain by futzing around in CString's underwear? ie: char buffer[256]; /* or */ char buffer = new char[dwSize]; RegQueryValueEx(tempKey,"Label", NULL, &dwType,buffer, &dwSize); ftemp=atof(buffer); delete buffer; // (if 'new' was used) Having said that, I wasn't able to duplicate your error, and your use of CString seems correct. There is a very thin registry wrapper class in ATL called CRegKey. It saves you a little trouble. Here is my test of your problem, using both CRegKey and your direct api calls:
#include <stdio.h> #include <afx.h> #include <atlbase.h> void Function1(float f) { printf("ftemp: %f\n",f); } #define USE_CREGKEY void main(int argc, char* argv[]) { DWORD dwType =0, dwSize=256; float ftemp; CString RegRead; #ifdef USE_CREGKEY CRegKey myKey; //open key LONG result = myKey.Open(HKEY_CURRENT_USER,"deleteThisKey",KEY_READ); ASSERT(result == ERROR_SUCCESS); for(int i=0; i<6 ;i++) { result = myKey.QueryValue(RegRead.GetBuffer(dwSize), "Label", &dwSize ); ASSERT(result == ERROR_SUCCESS); RegRead.ReleaseBuffer(); //convert string to float value ftemp=(float)atof(LPCTSTR(RegRead)); } #else HKEY tempKey; //open key RegOpenKeyEx( HKEY_CURRENT_USER,// handle to open key "deleteThisKey", // subkey name 0, // reserved KEY_READ, // security access mask &tempKey // handle to open key ); for(int i=0; i<6 ;i++) { ::RegQueryValueEx(tempKey,"Label", NULL, &dwType,(BYTE*) RegRead.GetBuffer(256), &dwSize); RegRead.ReleaseBuffer(); //convert string to float value ftemp=(float)atof(LPCTSTR(RegRead)); } #endif Function1(ftemp); }
When I use the registry, I like to use Sam Blackburn's WFC utility classes. He has a CString aware class called CRegistry that should be included in MFC. Even if you don't use the classes, Sam has done a super job of giving us great windows/MFC code to use as examples. http://www.samblackburn.com/wfc/ I'm sorry I couldn't pinpoint your problem, but I hope this helps. Jim :confused: PS: Be sure you close tempKey with RegCloseKey(tempKey) when you are done with it. CRegKey does that for you. -
I've been programming in MFC since 1994, and I never directly modify the CString buffer, it just seems wrong to me. Why not just use a character array? What do you gain by futzing around in CString's underwear? ie: char buffer[256]; /* or */ char buffer = new char[dwSize]; RegQueryValueEx(tempKey,"Label", NULL, &dwType,buffer, &dwSize); ftemp=atof(buffer); delete buffer; // (if 'new' was used) Having said that, I wasn't able to duplicate your error, and your use of CString seems correct. There is a very thin registry wrapper class in ATL called CRegKey. It saves you a little trouble. Here is my test of your problem, using both CRegKey and your direct api calls:
#include <stdio.h> #include <afx.h> #include <atlbase.h> void Function1(float f) { printf("ftemp: %f\n",f); } #define USE_CREGKEY void main(int argc, char* argv[]) { DWORD dwType =0, dwSize=256; float ftemp; CString RegRead; #ifdef USE_CREGKEY CRegKey myKey; //open key LONG result = myKey.Open(HKEY_CURRENT_USER,"deleteThisKey",KEY_READ); ASSERT(result == ERROR_SUCCESS); for(int i=0; i<6 ;i++) { result = myKey.QueryValue(RegRead.GetBuffer(dwSize), "Label", &dwSize ); ASSERT(result == ERROR_SUCCESS); RegRead.ReleaseBuffer(); //convert string to float value ftemp=(float)atof(LPCTSTR(RegRead)); } #else HKEY tempKey; //open key RegOpenKeyEx( HKEY_CURRENT_USER,// handle to open key "deleteThisKey", // subkey name 0, // reserved KEY_READ, // security access mask &tempKey // handle to open key ); for(int i=0; i<6 ;i++) { ::RegQueryValueEx(tempKey,"Label", NULL, &dwType,(BYTE*) RegRead.GetBuffer(256), &dwSize); RegRead.ReleaseBuffer(); //convert string to float value ftemp=(float)atof(LPCTSTR(RegRead)); } #endif Function1(ftemp); }
When I use the registry, I like to use Sam Blackburn's WFC utility classes. He has a CString aware class called CRegistry that should be included in MFC. Even if you don't use the classes, Sam has done a super job of giving us great windows/MFC code to use as examples. http://www.samblackburn.com/wfc/ I'm sorry I couldn't pinpoint your problem, but I hope this helps. Jim :confused: PS: Be sure you close tempKey with RegCloseKey(tempKey) when you are done with it. CRegKey does that for you.Jim thank you for all your help and effort. I took your advice and used a good old character array and my problem magically went away. Lol, it is still bugging me though as to why that debug assertion ig getting thrown...lol i'll play around with it once i meet my deadline. Thank You once again! :-D "DWORD my man!"
-
Jim thank you for all your help and effort. I took your advice and used a good old character array and my problem magically went away. Lol, it is still bugging me though as to why that debug assertion ig getting thrown...lol i'll play around with it once i meet my deadline. Thank You once again! :-D "DWORD my man!"
Is the application UNICODE? If so then there might be some problems with: RegQueryValueEx(tempKey,"Label", NULL, &dwType,(BYTE*) RegRead.GetBuffer(256), &dwSize); if this IS unicode then GetBuffer(256) will return 512 bytes (256 wchar_t) meaning your dwSize parameter is incorrect. Another possible problem would be if the RegQueryValueEx is appending a terminating NULL. Try calling RegRead.ReleaseBuffer(-1) instead.