Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Registry: Typ ermitteln (https://www.delphipraxis.net/22551-registry-typ-ermitteln.html)

Pseudemys Nelsoni 19. Mai 2004 07:58


Registry: Typ ermitteln
 
moin,

gibt es eine funktion der winapi mit der ich den typ eines keynamens bekomme? bei funktionen wie RegQueryValueEx übergibt man ja den typ, aber ich hab noch keine gesehen mit der man den typ bekommt.
Also mit typ meine ich z.b REG_SZ usw

Phoenix 19. Mai 2004 08:10

Re: Registry: Typ ermitteln
 
Erm... Bei RegQueryValueEx bekommst Du den Typ zurück. Du übergibst ihn nicht.

Alternativ kannst Du auch mit RegEnumValue alle Namen der Values incl. deren Typ zurückgeben lassen.

MathiasSimmack 19. Mai 2004 08:10

Re: Registry: Typ ermitteln
 
Na klar, du übergibst als Typ REG_NONE, und erhältst im Gegenzug dafür den richtigen Typ geliefert. Ich habe dir, @Pseudemys Nelsoni, gestern (?) den Link zu einem DF-Beitrag gegeben, und in den Tutorials wird auch vorgemacht, wie man den Typ ermittelt. Und gerade eben habe ich auch was dazu bei deinem Exception-Beitrag geschrieben.


Edit: Name ergänzt, weil sich Phoenix reingedrängelt hat. ;)

Pseudemys Nelsoni 19. Mai 2004 08:20

Re: Registry: Typ ermitteln
 
Zitat:

Na klar, du übergibst als Typ REG_NONE, und erhältst im Gegenzug dafür den richtigen Typ geliefert.
hallo mathias, mich hat nur das hier stutzig gemacht:

Zitat:

Zitat von PSDK
lpType
[out] Pointer to a variable that receives a code indicating the type of data stored in the specified value. For a list of the possible type codes, see Registry Value Types. The lpType parameter can be NULL if the type code is not required.

also weil da "out" und nicht "in" steht, deswegen wunder ich mich wieso man denn da den typ doch(ß) bekommt.

Muetze1 19. Mai 2004 09:00

Re: Registry: Typ ermitteln
 
Moin!

Zitat:

Zitat von Pseudemys Nelsoni
also weil da "out" und nicht "in" steht, deswegen wunder ich mich wieso man denn da den typ doch(ß) bekommt.

Na die Funktion will einen Zeiger auf einen Speicherplatz haben wo sie die Information ablegen kann. Und sie gibt diese Informationen zurück, daher out. In bedeutet ja, dass die Funktion diesen Parameter beim Aufruf benötigt und dieser "reingegeben" werden muss, out, das dieser "herausgegeben" wird (bzw. zurück gegeben).

MfG
Muetze1

Pseudemys Nelsoni 19. Mai 2004 09:16

Re: Registry: Typ ermitteln
 
ok, dann noch eine frage dazu. Ich habe folgendes(nur das wichtigste daraus) aus den Win32api tut sources von luckie:

Delphi-Quellcode:
function Reg_ReadString(const RootKey: HKEY; const RegVal: string): string;
var
  lpType: DWORD;
begin
  lpType := REG_NONE;

  if(RegQueryValueEx(RootKey,@RegVal[1],nil,@lpType,nil,@cbData) =
       ERROR_SUCCESS) .....

wieso wird lpType denn auf REG_NONE gesetzt wenn die funktion "RegQueryValueEx" sowieso nicht daraus liest?

MathiasSimmack 19. Mai 2004 10:11

Re: Registry: Typ ermitteln
 
Evtl. wäre es ja denkbar, dass das Auslesen des Typs mal nicht klappt. In dem Fall hätte die Variable dann auch keinen Wert. So aber setzt du vorher REG_NONE, und es dürfte/wird beim Vergleich bzw. bei der Typprüfung überhaupt keine Probleme geben.

(btw: Das ist meine Meinung. Sollte die falsch sein, schiebe ich den schwarzen Peter an NicoDE weiter, von dem nämlich die Funktion stammt, durch die ich das allererste Mal Kontakt mit der Registry auf API-Ebene erhielt. ;))

Phoenix 19. Mai 2004 10:46

Re: Registry: Typ ermitteln
 
Ich habe inzwischen eine ziemlich komplette Übersetzung der gesamten Registry-Funktionen für Delphi selber gemacht. Es ist tatsächlich so, das unter ganz widrigen Umständen der Wert von Type undefiniert ist.

Ist er aber initialisiert, so wird er auch nicht geändert - demnach kann man hier dann sauber weiterarbeiten ohne gefahr zu laufen, zufällig einen gültigen Wert drin stehen zu haben, der dann aber nicht passt.

NicoDE 19. Mai 2004 11:03

Re: Registry: Typ ermitteln
 
Zitat:

Zitat von MathiasSimmack
(btw: Das ist meine Meinung. Sollte die falsch sein, schiebe ich den schwarzen Peter an NicoDE weiter, von dem nämlich die Funktion stammt ;))

Ich habe zu oft erlebt, dass Funktionen bei nicht initialisierten Werten, deren Inhalt laut Dokumentation ignoriert werden sollte, nicht das tun was man erwartet hat.
Ist also einfach eine alte Angewohnheit, die ich, trotz teilweiser Sinnlosigkeit bzw. dem Anschein von Verfolgungswahn, nicht geneigt bin wieder abzulegen :)
(es kann unter Win9x zu einem Crash kommen, wenn man TLVItems nicht mit Nullen füllt, obwohl die Werte laut Flags ignoriert werden sollten... um nur ein Beispiel zu nennen)

MathiasSimmack 19. Mai 2004 11:54

Re: Registry: Typ ermitteln
 
@Nico, Phoenix: Also war meine Vermutung richtig. ;)

Pseudemys Nelsoni 19. Mai 2004 16:21

Re: Registry: Typ ermitteln
 
wäre dieser code hier denn in ordnung?

Delphi-Quellcode:
function ReadRegFromAPI(const Key: HKEY; Path, lpValueName: string): string;
var
  KeyH    : HKEY;
  lpType,
  lpcbData,
  lpData  : DWORD;
  bRes    : boolean;
begin
  Result := '';
  if RegOpenKeyEx(Key, PAnsiChar(Path), 0, KEY_READ, KeyH) = ERROR_SUCCESS then
  try
    lpType := REG_NONE;
    lpcbData := 0;
    bRes := false;
    if RegQueryValueEx(KeyH, PAnsiChar(lpValueName), nil, @lpType, nil, @lpcbData) = ERROR_SUCCESS then
    case lpType of
      REG_SZ, REG_EXPAND_SZ:
        begin
          SetLength(Result, lpcbData + 1);
          bRes := RegQueryValueEx(KeyH, PAnsiChar(lpValueName), nil, @lpType, @Result[1], @lpcbData) = ERROR_SUCCESS;
        end;
      REG_DWORD:
        begin
          bRes := RegQueryValueEx(KeyH, PAnsiChar(lpValueName), nil, @lpType, @lpData, @lpcbData) = ERROR_SUCCESS;
          Result := string(lpData);
        end;
    end;
  finally
    if not bRes then
      MessageBox(0, 'Fehler aufgetreten', '!', 0);
    RegCloseKey(Key);
  end;
end;

und wieso muss ich bei einem string auf das erste byte zeigen? also [1] ? bei einem integer sind es doch auch 4 bytes, wieso muss ich da nicht [1] angeben?

Chewie 19. Mai 2004 16:30

Re: Registry: Typ ermitteln
 
Die Funktion erwartet einen Zeiger auf ein Zeichen. String[1] ist dein erstes Zeichen, und mit @String[1] lieferst du einen Zeiger auf das erste Zeichen.

MathiasSimmack 19. Mai 2004 16:40

Re: Registry: Typ ermitteln
 
Mitnichten erwartet die Funktion einen Zeiger auf ein Zeichen. Tatsächlich erwartet sie einen Zeiger auf einen Puffer, der die gewünschten Daten aufnehmen soll. Im Fall eines REG_SZ/REG_EXPAND_SZ ist das entweder ein pchar, ein "array of char" oder eben ein String.
Und da hängt es dann eben vom Typ ab. Da ein String im 0. Zeichen die Länge hat, muss man eben die [1] separat angeben.

Es kann aber auch ein DWORD sein, dann wäre es eben ein Zeiger auf die DWORD-Variable, so wie das Pseudemys Nelson auch gemacht hat. Nur wäre
Delphi-Quellcode:
Result := inttostr(lpData);
wohl sinnvoller als
Zitat:

Delphi-Quellcode:
Result := string(lpData);

;)

Pseudemys Nelsoni 19. Mai 2004 16:51

Re: Registry: Typ ermitteln
 
hallo chewie/mathias, danke für die erklärung :)

2 Fragen stellen sich aber wieder mal :thuimb:

also zur ersten...

ich glaube das "SetLength(Result, lpcbData + 1);" von mir falsch war, denn selbst mit "SetLength(Result, lpcbData - 2);" bekomme ich noch das richtige Ergebnis! oder täusch ich mich da? habs jedenfalls getestet und die showmessage zeigte den gesamten string an.

zur zweiten...

mathias, ich arbeite ohne die vcl, da ich eine dll schreibe, sollte nicht all zu gross werden :\
hast du da noch ne andere idee?


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:11 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz