I have some code that compiles fine with D7 but fails with D2010. Obviously it is an Unicode issue:
The compile error is: E2251 Ambiguous overloaded call to 'StrPas'
Here is the whole procedure:
procedure GetVersionInfo;
type
PLangCharSetInfo = ^TLangCharSetInfo;
TLangCharSetInfo = record
Lang: Word;
CharSet: Word;
end;
var
FileName: array [0..260] of Char;
SubBlock: array [0..255] of Char;
VerHandle: Cardinal;
Size: Word;
Buffer: Pointer;
Data: Pointer;
DataLen: LongWord;
LangCharSetInfo: PLangCharSetInfo;
LangCharSetString: string;
begin
LabelComments.Caption := 'No version information for this program is available!';
{Get size and allocate buffer for VerInfo}
if GetModuleFileName(hInstance, FileName, SizeOf(FileName)) > 0 then
begin
Size := GetFileVersionInfoSize(FileName, VerHandle);
if Size > 0 then
begin
GetMem(Buffer, Size);
try
if GetFileVersionInfo(FileName, VerHandle, Size, Buffer) then
begin
{Query first language and that language blocks version info}
if VerQueryValue(Buffer, '\VarFileInfo\Translation', Pointer(LangCharSetInfo), DataLen) then
begin
LangCharSetString := IntToHex(LangCharSetInfo^.Lang, 4) +
IntToHex(LangCharSetInfo^.CharSet, 4);
if VerQueryValue(Buffer, StrPCopy(SubBlock, '\StringFileInfo\' + LangCharSetString + '\ProductName'), Data, DataLen) then
begin
LabelProductName.Caption := StrPas(Data);
Caption := LabelProductName.Caption;
end;
if VerQueryValue(Buffer, StrPCopy(SubBlock, '\StringFileInfo\' + LangCharSetString + '\FileVersion'), Data, DataLen) then
LabelVersion.Caption := StrPas(Data);
if VerQueryValue(Buffer, StrPCopy(SubBlock, '\StringFileInfo\' + LangCharSetString + '\LegalCopyright'), Data, DataLen) then
LabelCopyright.Caption := StrPas(Data);
if VerQueryValue(Buffer, StrPCopy(SubBlock, '\StringFileInfo\' + LangCharSetString + '\Comments'), Data, DataLen) then
LabelComments.Caption := StrPas(Data);
end;
end;
finally
FreeMem(Buffer, Size);
end;
end
end;
end;
The doc for StrPas says
function StrPas(const Str: PAnsiChar): AnsiString; overload;
This function is provided fasor backwards compatibility only. To convert a null-terminated string to an AnsiString or native Delphi language string, use a typecast or an signment.
So the question is should I remove all calls to StrPas ? The only way I make this to compile is to do a hardcast to PAnsi char like:
LabelProductName.Caption := StrPas(PAnsiChar(Data));
StrPas has not been required since Delphi 1, since they changed the Delphi compiler to convert the string correctly without a function call. See: http://coding.derkeiler.com/Archive/Delphi/borland.public.delphi.language.objectpascal/2004-01/1793.html
So just assign it, as follows:
LabelProductName.Caption := PAnsiChar(Data);
And yes, you should remove all calls to StrPas. It can't help and can only get you in trouble in D2010.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With