initialized as well.
project. The app was originally started 5 years ago and shelved because
of technology/bugs in the application. I came in and revamped (updated
our American clients. It has been so popular that they asked me to make
a international version which I am in the final steps of currently.
the MSLU for Windows 98. So I have unfortunately let a few of my
notation that well. The original coder is no longer with the company
and from what I have heard has retired out of the programming field.
I will definetly look into the registry class that you have. I have
in Computer Science. I have currently a BS in CS.
Joseph M. Newcomer wrote:
I've never used MSLU, so I have no idea what its issues might be.
I believe VS2003 will run on Win9x, but I've never tried it.
Error 87 is "Invalid parameter", which means you sent the wrong information to the API
call. Well, probably not *you*, explicitly, but certainly the underlying code of
GetProfileString.
I would not trust GetProfileString as far as I could throw a mainframe, particularly when
complex interactions with MSLU are quite likely involved. Go for the raw registry.
There's probably something happening "under the floor" in GetProfileString where, with
MSLU, it Does Not Play Well With Others. I would suspect a bug somewhere in the
underlying code.
You might look at my Registry class on my MVP Tips site. I use it everywhere.
I am curious why you are so grossly misusing Hungarian Notation; how is that a CString
could start with "n", which is supposed to represent an integer type? Best to avoid this
notation entirely than to use it in confusing and misleading ways.
On 6 Sep 2006 15:01:29 -0700, cmgray74@gmail.com wrote:
Joe and all,
Sorry its a little long;
I did set the breakpoint in Windows XP on RegQueryValueEx and
everything looked ok for the parameters, even the return value was 0
(SUCCESS). So I went and looked at the return value in Windows 98, by
using a Messagebox, I noticed a 87 was being returned. I believe,
please correct me if I am wrong, I am unable to debug this application
actively in Windows 98 as I am using Visual Studio 2003 and the MSLU.
Does Visual Studio 2003 even install on a Win98 Box?
Is there a Debug version of the MSLU out there?
In either case I dug a little deeper and noticed the dwType was not
really necessary as I am sure this function should always return a
string. There are two functions that have been created one for getting
a String and the other for getting a Integer. I set the value as NULL
for the dwtype and it seems to work ok now. I was puzzled by this and
looked deeper and noticed in Windows XP that the value for this once
created was a value other then 0. I am unsure if this was the cause or
not in the Windows 98 machine.
In either case it still does not explain why the following original
code does not consistently work;
#define REGISTRY_SECTION _T("User Profile")
#define REGISTRY_USER_ID _T("User ID")
#define REGISTRY_MSMCODE _T("MSMCode")
CWinApp* pApp = AfxGetApp();
CString nValue4;
nValue4 =
pApp->GetProfileString(REGISTRY_SECTION,REGISTRY_MSMCODE,_T("NO VALUE
RETURNED")); //get the value from the registry
CString strValue;
strValue = pApp->GetProfileString(REGISTRY_SECTION,
REGISTRY_USER_ID,_T("NO VALUE RETURNED"));
The above code will bring values back the first time but not the second
time forward though. The code is in a command to run a dialog so I can
execute the same code countless times easily. This is getting a user
name and an alphabetic id code to display in the dialog. The values I
get are "NO VALUE RETURNED" on the next X number of times after the
first. I am unsure why its having problems, the values going into the
function are PreProcessor Directives and the last is a constant hard
coded string. I have even tried removing the ,_T("NO VALUE RETURNED")
and placed in a NULL and there is no change in behavior just the
returned string is empty in the case of the NULL.
Whats interesting is if I use the following;
CString nValue4;
nValue4 =
theApp.GetProfileString(REGISTRY_SECTION,REGISTRY_MSMCODE,_T("NO VALUE
RETURNED")); //get the value from the registry
CString strValue;
strValue = theApp.GetProfileString(REGISTRY_SECTION,
REGISTRY_USER_ID,_T("NO VALUE RETURNED"));
It seems to works fine no matter how many times I try it.
Also I have even tried my own functions, after I figured out the issue
we discussed earlier;
CString nValue4;
nValue4 = GetRegistryString(REGISTRY_MSMCODE);
CString strValue;
strValue = GetRegistryString(REGISTRY_USER_ID);
The function GetRegistryString is as follows;
CString CAApp::GetRegistryString(CString strKeyName)
{
LONG lRet;
wchar_t szData[1024];
ZeroMemory(szData,2048);
***
No, that's
::ZeroMemory(szData, sizeof(szData));
don't hardwire values if you can avoid it. And I'm not sure I see a reason to zero this
buffer, since it is going to be overwritten anyway.
****
DWORD dwBufLen=1024;
****
No.
dwBufLen = sizeof(szData);
The count should be a byte count, not a character count
*****
HKEY hKey;
lRet = RegOpenKeyEx(HKEY_CURRENT_USER,
_T("Software\\GFS\\TheData\\User Profile\\"), 0,KEY_QUERY_VALUE,
&hKey);
if(lRet != ERROR_SUCCESS)
{
RegCloseKey(hKey);
****
If RegOpenKey did not return STATUS_SUCCESS, the key was not opened, so closing it makes
no sense
****
return _T(""); //if it fails the best thing is to return nothing
}
lRet = RegQueryValueEx(hKey,strKeyName , NULL, NULL,(LPBYTE)szData,
&dwBufLen);
****
Do NOT avoid returning the type! You really, really care that this is REG_SZ. and you
MUST double-check this (the user could have changed the type with regedit. Trust me, it's
happened! The result would be fatal to your code.
****
if(lRet == ERROR_SUCCESS)
{
RegCloseKey(hKey);
return szData;
}
else
{
RegCloseKey(hKey);
return _T("");
}
}
****
Does this code fail? If it does, I would suspect a bug in MSLU, because I don't offhand
see anything wrong here (other than the minor issues, which could ultimately result in
other failure modes, but not an error-87 failure).
****
So with all this said, I have the following questions that I am unsure
of;
Do you see anything wrong with any of the code above? Am I missing
something simple?
When should I use the CWinApp* pApp = AfxGetApp(); followed by the
calls for GetProfileString and GetProfileInt and when should I use the
theApp.GetProfileString(....) calls or my own functions?
Thanks,
Chris
MS Alumni
Joseph M. Newcomer wrote:
Have you set a breakpoint at the RegQueryValueEx call and looked at the parameters? Then
execute it, make sure you see its return code, and look at what it returned. Do this at a
fairly low level (don't do any debug print statements, but look at what the debugger is
telling you just at, and immediately after, the RegQueryValueEx call. This is not a
memory damage issue, but it smells of bad parameters that, for whatever reason, might be
exhbiting different behavior on Win98. Post your few llines of code involved in this, and
the results.
joe
On 5 Sep 2006 16:26:46 -0700, cmgray74@gmail.com wrote:
All,
I have small MFC C++ application, that uses the MSLU, that sits in the
system tray. The application has passed testing in Windows XP, 2000,
2003 but I am seeing an issue in Windows 98 where the registry calls,
using GetProfileString and GetProfileInt, are not returning values
back. I get an empty string or 0 (int) back, instead of the values in
the registry. The longest string is 75 characters in length - A URL.
The numbers do not exceed the decimal 90.
I have tried creating my own functions in the app, using RegOpenKeyEx
and RegQueryValueEx, as well and I get similar results in Windows 98
where in Windows XP it returns the value I expect.
The parameter values going into the functions are populated (at least
form the messagebox tag debugging I have done).
Anyone seen anything like this before? Suggestions?
Am I chasing a memory bug in my app?
Am I missing something simple?
I have tried (on the memory idea)
ASSERT(_heapchk() == _HEAPOK);
all over the app while trying to debug the application in Windows XP
but I am having no luck finding any assertions.
I have even tried;
BOOL CAApp::OnIdle(LONG count)
{
ASSERT(_heapchk() == _HEAPOK);
return CWinApp::OnIdle(count);
}
and let it run overnight (6pm till 8:30am) and still no asserts.
I am not really sure how to proceed.
I have read Joseph NewComer article "Memory Damage Primer " that has
helped me greatly in the last few weeks cleaning up a few issues before
testing (Thanks Joseph!) but I am kinda puzzled by the recent registry
issue.
Thanks for the help,
Chris
MS Alumni
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm