I am having one Delphi XE2 Project to check one Hexadecimal Value from Registry Key MyCompanyName\1. If the Hexadecimal Value is 13, then some message will be there else some other message will be there.
So I have defined the following codes:
procedure TMainForm.BitBtn01Click(Sender: TObject);
var
RegistryEntry : TRegistry;
begin
RegistryEntry := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);
RegistryEntry.RootKey := HKEY_LOCAL_MACHINE;
if (RegistryEntry.KeyExists('SOFTWARE\MyCompanyName\1\')) then
begin
if (RegistryEntry.OpenKey('SOFTWARE\MyCompanyName\1\',true)) then
begin
if (RegistryEntry.ReadString('SettingValue') = '0x00000013') then
begin
Memo01.Lines.Add('SettingHexadeciamlValue exist properly')
end
else
begin
Memo01.Lines.Add('SettingHexadeciamlValue does not exist properly')
end;
end
else
begin
if (RegistryEntry.OpenKey('SOFTWARE\MyCompanyName\1\',false)) then
begin
Memo01.Lines.Add('Unable to read RegistryKey ''MyCompanyName''Exiting.......')
end;
end;
end
else
begin
Memo01.Lines.Add('RegistryKey ''MyCompanyName'' does not exist')
end;
end;
After compilation, when I am running the application AsAdministrator, I am getting error mentioning Invalid data type for 'SettingValue'.
These values are integers, not strings, so you should use ReadInteger, not ReadString.
Now, hexadecimal is only a way of presenting an integer to the user, that is, a method of creating a 'textual representation' of the integer. For example, the integer 62 has many different textual representations:
62 (decimal)
LXII (Roman numerals)
3E (hexadecimal)
111110 (binary)
Sextiotvå (Swedish words)
etc.
If you want to display this number in hexadecimal, as the registry editor (regedit.exe) does, you can use the IntToHex function, which creates a hexadecimal textual representation of the argument integer. Example:
var
myvalue: integer;
...
myvalue := ReadInteger('SettingValue');
ShowMessage(IntToHex(myvalue, 8));
Related
First of all I am sorry that I cannot better to describe my problem.
What I have is Word number 65025 which is 0xFE01 or
11111110 00000001 in binary. And I want to pass the value to wstr Word => 11111110 00000001.
I found that using typecast does not work.
And one more question here. If I want to add another number like 10000 => 0x03E8 how to do it. So in the result the widestring should refer to values 0xFE01 0x03E8.
And then, how to retrieve the same numbers from widestring to word back?
var wstr: Widestring;
wo: Word;
begin
wo := 65025;
wstr := Widestring(wo);
wo := 10000;
wstr := wstr + Widestring(wo);
end
Edit:
I'm giving another, simpler example of what I want... If I have word value 49, which is equal to ASCII value 1, then I want the wstr be '1' which is b00110001 in binary terms. I want to copy the bits from word number to the string.
It looks like you want to interpret a word as a UTF-16 code unit. In Unicode Delphi you would use the Chr() function. But I suspect you use an ANSI Delphi. In which case cast to WideChar with WideChar(wo).
You are casting a Word to a WideString. In Delphi, casting usually doesn't convert, so you are simply re-interpreting the value 65025 as a pointer (a WideString is a pointer). But 65025 is not a valid pointer value.
You will have to explicitly convert the Word to a WideString, e.g. with a function like this (untested, but should work):
function WordToBinary(W: Word): WideString;
var
I: Integer;
begin
Result := '0000000000000000';
for I := 0 to 15 do // process bits 0..15
begin
if Odd(W) then
Result[16 - I] := '1';
W := W shr 1;
end;
end;
Now you can do something like:
wo := 65025;
wstr := WordToBinary(wo);
wo := 10000;
wstr := wstr + ' ' + WordToBinary(wo);
For the reverse, you will have to write a function that converts from a WideString to a Word. I'll leave that exercise to you.
Again, you can't cast. You will have to explicitly convert. Both ways.
i want to create a random number in delphi and assign it to file as a file name. I managed to do that but when i click button to generate number it always start with a 0. Any idea how to fix it
procedure TForm1.Button1Click(Sender: TObject);
var
test:integer;
begin
test:= random(8686868686868);
edit1.Text:= inttostr(test);
end;
end.
As user246408 said you should use Randomize to initialize the random number generator with a random value. Also if you want to limit the returned numbers to positive integers, use the predefined MaxInt constant.
The overloaded function System.Random that returns an integer has the following signature:
function Random(const ARange: Integer): Integer;
and returns an integer X which satisfies the formula 0 <= X < ARange.
To prevent a 0 value, you can add a constant of your choise, like
procedure TForm17.Button2Click(Sender: TObject);
const
MinRandomValue = 100000;
var
test:integer;
begin
test:= random(MaxInt-MinRandomValue)+MinRandomValue;
edit1.Text:= inttostr(test);
end;
(MinRandomValue subtracted from MaxInt to prevent overflow)
or, you can use System.Math.RandomRange
test := RandomRange(100000, MaxInt);
Documented here
Your code has 2 problems.
You don't call Randomize, that is why you always get zero as the
first "random" value.
You use too large value 8686868686868 for Random range, it
exceeds 32-bit boundary and equivalent to 2444814356.
if you need just a single "random" value use
procedure TForm1.Button1Click(Sender: TObject);
var
test:integer;
begin
Randomize;
test:= random($7FFFFFFF);
edit1.Text:= inttostr(test);
end;
Consider the following code:
procedure Test;
function d1: Variant;
var
DDt: TDateTime;
begin
DDt := EncodeDate(100,1,1);
Result := DDt;
end;
function d2: Variant;
var
DDt: TDateTime;
begin
DDt := EncodeDate(99,12,31);
Result := DDt;
end;
procedure Writedate(V: Variant);
begin
Writeln(string(V));
end;
var
V: Variant;
begin
V := d1;
Writedate(V);
V := d2;
Writedate(V);
end;
The first call to Writedate will succeed, and the output will be '01-01-0100'. The second call, however, will fail with an 'invalid argument' failure. Inspecting the code, you can see the Variant of the 99-12-31 date has a EVariantInvalidArgError error.
However, if I call FormatDateTime('c', TDateTime(V)) on either TDateTime, they will both succeed. In fact, at any point when the Variant contains a TDateTime, whose date is before 100 CE, the IDE will display a EVariantInvalidArgError when inspecting its value.
It seems odd that the Variant cannot handle the pre-100 CE date, when TDateTime can. Is this a bug in Delphi? I find it being right between 99 and 100 CE to be a bit suspicious.
Variant can contain any date value, as your code demonstrates (assignment V := d2; produces no error).
The error is raised during the conversion to string which the compiler delegates to the OS on Windows platforms. This fails because OLE Automation specifies midnight, 1 January 0100 as the minimum valid OLE Automation date value.
With this code to retrieve the version of the installed MS Word:
uses uses oleauto;
[...]
function TForm2.GetWordVersion:string;
const
wdDoNotSaveChanges = 0;
var
WordApp: OLEVariant;
WordVersion: variant;
begin
Try
WordApp := CreateOLEObject('Word.Application');
WordVersion := WordApp.version;
WordApp.Quit(wdDoNotSaveChanges);
except
on E: Exception do
begin
WordVersion := -1;
end;
End;
Result := wordversion;
end;
I get 140 on my machine, my colleague gets 14. Both are win7/Word2010 but I am in Italy he is in India.
Anyone knows about this?
Why different values?
Thanks
I'm guessing this is a decimal separator issue. Word returns the string '14.0' and then when you convert to integer the period is treated as a positional separator on one machine, and a decimal separator on another.
The solution is to stop converting to integer which I infer that you are doing in code that you have not shown.
I am inferring that from this comment:
I can convert it to string and use the first 2 chars.
Since the code in the question operates on strings, I conclude that other code, not shown in the question, is converting to integer.
I am trying to add following values to
procedure TForm1.FormCreate(Sender: TObject);
var
md: TDictionary<string, string>;
s, v: string;
begin
md := TDictionary<string, string>.Create;
try
s := 'orange';
v := 'fruit';
md.Add(s, v);
s := 'orange ';
v := 'color';
md.Add(s, v);
ShowMessage(IntToStr(md.Count));
finally
md.Free;
end;
end;
I know this is duplicate but if you look at second orange, you can see a space at the end. I think Delphi trims the value but it shouldn't.
Does anyone know solution of this problem?
Thanks,
This code shows a message box containing the number 2 on all known versions of Delphi. That is exactly as is expected and the TDictionary code most certainly does not trim your keys when comparing for equality.