Recent

Author Topic: Windows Registry  (Read 14217 times)

jma_sp

  • Full Member
  • ***
  • Posts: 150
  • El conocimiento si ocupa lugar.
Windows Registry
« on: March 30, 2016, 11:50:03 am »
Hello, i have a doubt:

I need to read a windows registry entry of type REG_SZ and display it in a control of type label correctly.

I can read the value but when i aasign the value, by example:

label1.caption :=Registro.ReadString('Cadena_acentuada_español');

Original value in 'Cadena_acentuada_español' = 'í'    // (vocal acentuada)
But value obtained in label '?'
I have tried with:
labe1.font.charset := UNICODE; and label1.font.charset := ANSI_CHARSET; but same result.

There is some property that i can use for Spanish ?
« Last Edit: March 30, 2016, 12:51:48 pm by jma_sp »
Devuan Beowulf 3.0( JWM/ROX/iDesk) - Puppy Linux,  Haiku OS,.ReactOS 0.4.xx  - FreeDos .

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: Windows Registry
« Reply #1 on: March 30, 2016, 12:05:34 pm »
which versions of laz and fpc?
Specialize a type, not a var.

jma_sp

  • Full Member
  • ***
  • Posts: 150
  • El conocimiento si ocupa lugar.
Re: Windows Registry
« Reply #2 on: March 30, 2016, 12:40:57 pm »
Helo Thaddy,

Lazarus Versión: 1.6
FPC Version: 3.0.0
Revision SVN: 51630
i386-win32-win32/win64

The operating systems are all in spanish (Spain) and the Lazarus installation is in spanish.

Also i have tried with: OEM_CHARSET same result (I have Spanish Modern Sort)



« Last Edit: March 30, 2016, 01:10:55 pm by jma_sp »
Devuan Beowulf 3.0( JWM/ROX/iDesk) - Puppy Linux,  Haiku OS,.ReactOS 0.4.xx  - FreeDos .

balazsszekely

  • Guest
Re: Windows Registry
« Reply #3 on: March 30, 2016, 02:39:20 pm »
@jma_sp
Try this:

Code: Pascal  [Select][+][-]
  1. uses windows, jwawinreg;
  2.  
  3. function RegistryReadString(const ARootKey: HKEY; AKeyName, AStringValue: WideString): WideString;
  4. var
  5.   lpKey: HKEY;
  6.   lpSize: DWORD;
  7.   lptype: DWORD;
  8.   lpWs: WideString;
  9. begin
  10.   Result := '';
  11.   lpKey := 0;
  12.   if RegOpenKeyExW(ARootKey, PWideChar(AKeyName), 0, KEY_READ, lpKey) = ERROR_SUCCESS then
  13.   begin
  14.     lpType := 0;
  15.     lpSize := 0;
  16.     if RegQueryValueExW(lpKey, PWideChar(AStringValue), nil, @lpType, nil, @lpSize) = ERROR_SUCCESS then
  17.     begin
  18.       if lpType in [REG_SZ, REG_EXPAND_SZ] then
  19.       begin
  20.         SetLength(lpWs, lpSize);
  21.         if RegQueryValueExW(lpKey, PWideChar(AStringValue), nil, @lpType, PByte(lpWs), @lpSize) = ERROR_SUCCESS then
  22.         begin
  23.           SetLength(lpWs, StrLen(PWideChar(lpWs)));
  24.           Result := lpWs;
  25.         end;
  26.       end;
  27.       RegCloseKey(lpKey);
  28.     end;
  29.   end;
  30. end;
  31.  
  32. procedure TForm1.Button1Click(Sender: TObject);
  33. var
  34.   KeyName: String;
  35.   StringValue: String;
  36.   Res: WideString;
  37. begin
  38.   //replace HKEY_CURRENT_USER, KeyName and StringValue with the appropriate values
  39.   KeyName := 'Software\Test';
  40.   StringValue := 'Cadena_acentuada_español';
  41.   Res := RegistryReadString(HKEY_CURRENT_USER, WideString(KeyName), WideString(StringValue));
  42.   if Res <> '' then
  43.    Label1.Caption := String(Res);
  44. end;

wp

  • Hero Member
  • *****
  • Posts: 11857
Re: Windows Registry
« Reply #4 on: March 30, 2016, 03:47:47 pm »
In my Win7, the key 'HKEY_CURRENT_USER\Identities", item "Last Username'', has the value 'Hauptidentität', and I used it for testing because of the contained non-standard character.

After some playing around I came to this solution which returns the umlaut correctly:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   reg: TRegistry;
  4.   s: String;
  5. begin
  6.   reg := TRegistry.Create(KEY_READ);
  7.   reg.RootKey := HKEY_CURRENT_USER;
  8.   if reg.OpenKeyReadOnly('Identities') then
  9.   begin
  10.     if reg.ValueExists('Last Username') then
  11.     begin
  12.       s := reg.ReadString('Last Username');  // Returns the string in the system codepage
  13.       ShowMessage( WinCPToUTF8(s) );         // Converts the string to utf8
  14.     end else
  15.       ShowMessage('Does not exist');
  16.     reg.CloseKey;
  17.   end;
  18.   reg.Free;
  19. end;

This code runs equally well with Laz 1.4.4 (old strings) and 1.6/trunk (new strings). 
« Last Edit: March 30, 2016, 04:53:13 pm by wp »

jma_sp

  • Full Member
  • ***
  • Posts: 150
  • El conocimiento si ocupa lugar.
Re: Windows Registry
« Reply #5 on: March 30, 2016, 04:07:25 pm »
Hello GetMen, i have applied this piece of code and it works ok, it returned values correctly.

Then, may be the warp of tregistry need an actualization instead to ude windows call directly?

Including a property to indicate the specific language or get automátically from registry locales?

Now i have to test the wp solution.

Thanks.
Devuan Beowulf 3.0( JWM/ROX/iDesk) - Puppy Linux,  Haiku OS,.ReactOS 0.4.xx  - FreeDos .

jma_sp

  • Full Member
  • ***
  • Posts: 150
  • El conocimiento si ocupa lugar.
Re: Windows Registry
« Reply #6 on: March 30, 2016, 04:27:26 pm »
Hello WP I have been reading this:

http://wiki.freepascal.org/Better_Unicode_Support_in_Lazarus

Also works OK.

For WinCPToUTF8 to work i have been added the unit LAZUTF8 to the uses clause.

Thanks for all, both solutions works correctly, last most pascalized.  :)
« Last Edit: March 30, 2016, 04:30:54 pm by jma_sp »
Devuan Beowulf 3.0( JWM/ROX/iDesk) - Puppy Linux,  Haiku OS,.ReactOS 0.4.xx  - FreeDos .

balazsszekely

  • Guest
Re: Windows Registry
« Reply #7 on: March 30, 2016, 05:20:20 pm »
Yes, @wp solution is more elegant, I wonder though what would happen in case of widestring? I guess that should also work. 

wp

  • Hero Member
  • *****
  • Posts: 11857
Re: Windows Registry
« Reply #8 on: March 30, 2016, 05:36:39 pm »
You mean something like this:
Code: Pascal  [Select][+][-]
  1. var
  2.   ws: widestring;
  3.   ...
  4.    ws := reg.ReadString('Last Username');
  5.    ShowMessage( ws );
  6.  
No - this is not working. I have the feeling that TRegistry is not yet ready for the new strings.

balazsszekely

  • Guest
Re: Windows Registry
« Reply #9 on: March 30, 2016, 05:41:15 pm »
Quote
@wp
you mean something like this
Code: Pascal  [Select][+][-]
  1. :
  2. var
  3.   ws: widestring;
  4.   ...
  5.    ws := reg.ReadString('Last Username');
  6.    ShowMessage( ws );
Yes. For example if "Last Username" is an UTF-16 encoded string in registry? In this case, your code would return the correct value?

wp

  • Hero Member
  • *****
  • Posts: 11857
Re: Windows Registry
« Reply #10 on: March 30, 2016, 05:45:59 pm »
I don't know how it is encoded internally, its type is displayed as REG_SZ by RegEdit.

balazsszekely

  • Guest
Re: Windows Registry
« Reply #11 on: March 30, 2016, 06:10:34 pm »
According to the Microsoft documentation(https://msdn.microsoft.com/en-us/library/windows/desktop/ms724884%28v=vs.85%29.aspx):
Quote
REG_SZ = A null-terminated string. This will be either a Unicode or an ANSI string, depending on whether you use the Unicode or ANSI functions.
It can be UTF16.

PS: It's not working with UTF16.
« Last Edit: March 30, 2016, 06:41:48 pm by GetMem »

wp

  • Hero Member
  • *****
  • Posts: 11857
Re: Windows Registry
« Reply #12 on: March 30, 2016, 07:03:27 pm »
Which TRegistry code did you use, the one with WinCPToUTF8 or the one with widestring?

ChrisF

  • Hero Member
  • *****
  • Posts: 542
Re: Windows Registry
« Reply #13 on: March 30, 2016, 08:02:52 pm »

It's a Unicode string if you use the Unicode Windows API: like RegQueryValueExW, for instance, as in your sample code.

But the FCL (i.e. fcl-registry) still only uses the Ansi Windows APIs for the Windows registry, even with FPC 3.0.


*** Edit ***
And there is also currently no widestring version for the FCL registry.

I guess the following list is still a 'valid' exhaustive list of the current progress for the unicode support in the RTL/FCL:
http://wiki.freepascal.org/FPC_Unicode_support#RTL_changes

*** Edit2 ***
(Rereading my former answer, I feel it's a bit imprecise and could be wrongly interpreted)

In the Unicode versions of Windows, strings are always stored internally in a wide format ("UTF-16") in the Windows registry (keys or values). These wide strings are converted internally by Windows to/from Ansi strings when Ansi Windows APIs are used.

Which is always the case currently for the FCL...
« Last Edit: March 30, 2016, 09:33:17 pm by ChrisF »

balazsszekely

  • Guest
Re: Windows Registry
« Reply #14 on: March 30, 2016, 10:17:37 pm »
Quote
@wp
Which TRegistry code did you use, the one with WinCPToUTF8 or the one with widestring?
The one with widestring.

Quote
@ChrisF
And there is also currently no widestring version for the FCL registry
True! In my opinion this should be changed to widestring.

Quote
These wide strings are converted internally by Windows to/from Ansi strings when Ansi Windows APIs are used.
Unfortunately the conversion is not always possible. I would stay with the widestring version.
« Last Edit: March 30, 2016, 10:21:15 pm by GetMem »

 

TinyPortal © 2005-2018