Hekko
I call GetPrivateProfileString and if the key is empty or not found it would return the default value.
In my case the default value is "0" define as a string
GetPrivateProfileString Returns 0 and GetLastError too
I join the file of my debugging session
Has someone an idea?
It would seem that if the key exist but has no value assigned to it the function returns a null string and GetPrivateProfileString returns 0. >:(
Hi HellOfMice,
Not sure of the issue but here are examples of what I do
RetVal = GetPrivateProfileStringW(L"StartUp", L"ShowSplash", L"0", IniString, 254, p_inifile);
StartUp.Show_Splash = _wtoi(IniString);
RetVal = GetPrivateProfileStringW(L"StartUp", L"EscFileCnt", L"500", IniString, 254, p_inifile);
StartUp.EscFileCnt = _wtoi(IniString);
The value that is returned, when no value is found, is the value in parameter 3, as a string...
There is also GetPrivateProfileIntW if you don't want to mess with _wtoi, it works the same way...
John Z
Hi John,
The case I found is an existing key with no value
mov [rsp + 40],rsi
mov DWORD PTR [rsp + 32],SIZEOF KID_WINDOW.Dlg_Style
lea r9,[rbx].KID_WINDOW.Dlg_Style
lea r8,szZeroString + rip
lea rdx,szRC_Item_0020 + rip
mov rcx,rdi
call GetPrivateProfileString
test eax,eax
jnz @F
lea rcx,[rbx].KID_WINDOW.Dlg_Style
lea rdx,szZeroString + rip
call lstrcpy
;-----------------------------------------------------------------------------------------------------
ALIGN 16
;-----------------------------------------------------------------------------------------------------
@@ :
The only way to solve this case is the one above.
Quote[Dialog Box #3]
ExStyle Present=0
Style Present=1
Caption Present=1
Menu Present=0
Class Present=1
Font Present=1
Number Of Controls=1
Dialog Font Name=MS Shell Dlg
Dialog Font Size=8
Dialog Font Weight=0
Dialog Font Italic=0
Dialog Font Charset=1
Dialog Window X=6
Dialog Window Y=18
Dialog Window Width=195
Dialog Window Height=195
Dialog Menu ID=
Dialog Id=DLG_MAIN
Dialog Style=DS_SHELLFONT|DS_MODALFRAME|DS_3DLOOK|WS_THICKFRAME|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_VISIBLE
Dialog ExStyle=
Dialog Caption=Dialog Program
Dialog Class=DialogClass
Here there is no menu ID and no extended style
They are strings but th string is not found I want "0"
For having this result I must delete the key before or if the string is empty I sound not call WritePrivateProfileString
Thank You John for your help, remarks and ideas.
Philippe
check with GetLastError() if key exists ?
Hi HellOfMice,
It is interesting: I set edited my ini to be:
[Settings]
MaxCards=500
MainLeft=
MainTop=
MainWidth=727
MainHeight=526
DarkMode=0
[Display]
HideTools=
So three entries with no value. Then I just run the program - the window is drawn starting at 0,0.
Even though no value in the ini file. and the default values for the window as shown below are not 0,0
//size parameters from the ini
RetVal = GetPrivateProfileStringW(p_tmp, L"MainLeft", L"10",INIString,200, p_file);
MainForm.left= _wtoi(INIString);
RetVal = GetPrivateProfileStringW(p_tmp, L"MainTop", L"30",INIString,100, p_file);
MainForm.top= _wtoi(INIString);
RetVal = GetPrivateProfileStringW(p_tmp, L"HideTools", L"0", INIString,100,p_file);
StartUp.Hide_Toolbar = _wtoi(INIString);
So in C code it seems to be doing what you are wanting. Key Found, but empty, return 0
Perhaps in C the values are all ZERO when the INIStart structure is created?
So loading a default 0 into the storage of each INI entry might get you where you want to be?
Then if it fails that entry will have the 0.
John Z
If the entry is deleted before, I get the default value.
John, you should check the RetVal value, must contain the number of characters returned
Hi Philippe,
Could you post the complete source code if possible?
Ok VortexThis is the current project
Hi HellOfMice,
Quote from: HellOfMice on December 16, 2024, 02:55:28 PM
John, you should check the RetVal value, must contain the number of characters returned
It really is not useful, at least in my case.
Since I pre-allocate the return string space and set the max-chars equal to or less than that allocation there is no risk of overflow. Tested with no value, tested with huge string - all ok :)
All critical parameters are either TRUE/FALSE or some number N.
NON-Critical text like the user language is limited by max-chars.
MS says -
"If neither lpAppName nor lpKeyName is NULL and the supplied destination buffer is too small to hold the requested string, the string is truncated and followed by a null character, and the return value is equal to nSize minus one."
Even Micro$oft example code ignores the return ....
John Z
"Not everything worthwhile can be measured, and not everything that can be measured is worthwhile."
Steve Hargadon
Hi John,
QuoteRetVal = GetPrivateProfileStringW(p_tmp, L"MainLeft", L"10",INIString,200, p_file);
INIString should be equal to "10"
Is it right?
if no what is the RetVal value
Thank for your help
Philippe
Hi Sir HelloOfMice,
Yes that is correct, If there is no entry in the in file then INIString will be "10",
if there is an entry INIString will be that entry value.
as in
[Settings]
MaxCards=500
MainLeft=503
Then INIString will be "503"
And if there is a MainLeft = but no value the INIString will be "" and result in a 0 as far as I can tell.
John Z
Here is how I used GetPrivateProfileInt, maybe more suitable to your case?
syntax.field1 = GetPrivateProfileInt(L"RenameOptions", L"Field1", Field1_Skip, p_inifile);
if ((syntax.field1 < Field1_Skip) || (syntax.field1 > Field1_FN))
{syntax.field1 = Field1_Skip;}
Hi Cowboy
In that case MainLeft should contain "10".
It should contain the Default Returned string.
This is what is done if the key does not exist
Windows thinks the key has an empty string as a value and returns it
Hi HellOfMice,
I'm confused, what you are saying is what I wrote....so I'm not sure what you are pointing to as an issue??
Maybe I've not enough sleep...
Three cases
1) A specified Key does not exist - result will be the default value specified
2) A specified Key does exist and has a value - result will be that value
3) A specified Key exists but has no value - result will be empty string which converts to 0
which one is in question?
John Z
John Z
Hi John,
I had a normal time in my bed but did not slept very much...
I am ok with all your sentences. I had not understood. Sorry.
Philippe
From MicrosoftQuote[in] lpDefault A default string. If the lpKeyName key cannot be found in the initialization file, GetPrivateProfileString copies the default string to the lpReturnedString buffer.If this parameter is NULL, the default is an empty string, "".Avoid specifying a default string with trailing blank characters. The function inserts a null character in the lpReturnedString buffer to strip any trailing blanks.
They don't say that the returned string has an empty string if lpKeyName has no value after '='
We are in sync! Too little sleep! :(
A default string. If the lpKeyName key cannot be found in the initialization file, GetPrivateProfileString copies the default string to the lpReturnedString buffer.If this parameter is NULL, the default is an empty string, Avoid specifying a default string with trailing blank characters. The function inserts a null character in the lpReturnedString buffer to strip any trailing blanks.
This is case #1 ....
Yes MS never clearly discusses case #3
Cheers,
John Z
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
int __cdecl main(void)
{
char szBuf[260];
DWORD rc = GetPrivateProfileString("Dialog Box #3", "Dialog Menu ID", "0", szBuf, sizeof(szBuf), "./GetPrivate.ini");
DWORD ec = GetLastError();
printf("%d, %d, '%s'\n", ec, rc, szBuf);
rc = GetPrivateProfileString("Dialog Box #3", "Dialog Menu IDs", NULL, szBuf, sizeof(szBuf), "./GetPrivate.ini");
ec = GetLastError();
printf("%d, %d, '%s'\n", ec, rc, szBuf);
return 0;
}
[Dialog Box #3]
Dialog Menu ID=
0, 0, ''
2, 0, ''
Excellent as usual TimoVJL!
John Z