Aha! J Quite possibly...
SetLength(sDir, MAX_PATH); ZeroMemory(@sDir[1], MAX_PATH); if Succeeded(SHGetFolderPath(0, CSIDL_Program_Files, 0, 0, PAnsiChar(sDir))) then FW_Path := sDir; Yes, you are setting the string length to MAX_PATH, so any string data with a length of LESS than MAX_PATH will contain null chars after the actual string value as part of the string value data itself! If you inspect the value of sDir it will appear to be correct, because the code displaying the string contents will almost certainly be treating the first NULL it finds as the string terminator, irrespective of the string length you have set, but when you try to combine that string with other strings using the Delphi string handling functions, the explicit LENGTH of the string will be used, not the null terminator: So, building on my previous example: s := ‘hat’#0#0; s := s + ‘ and gloves’; // At this point “s” contains: ‘hat’#0#0’ and gloves” To fix your code you have at least two options: 1) After getting the contents of sDir, call SetLength() again and set the actual length of the string 2) Use a char array in the windows API call and exploit the RTL support for auto conversion of PChars to and from strings I myself would go with the latter. The Windows API is designed to work with “raw” pointers to char arrays – co-ercing functions that *modify* buffer contents to accept Delphi strings makes me nervous (functions that just accept string data without modifying it are a different matter, and I have no trouble simply casting a string to a PChar in those circumstances). J Also, I am guessing from your use of PANSIChar that you are using Delphi 2007 or earlier – this code will fail if/when you move to Delphi 2009 as the SHGetFolderPath() routine in those later versions will expect/require a PWIDEChar param. The easiest way to deal with this is to simply use PChar instead – in D2007< PChar = PANSIChar and in D2009+ PChar = PWideChar. But, to further protect yourself, the ZeroMemory() call should use MAX_PATH * SizeOf(Char) to indicate the number of zero bytes to write (Char can change size depending on Delphi versions). Having said that, I suspect (but am not 100% sure) that the ZeroMemory() call is redundant in this case. Alternatively you could explicitly use the ANSI version of SHGetFolderPath (SHGetFolderPathA) with a PANSIChar, but this is likely to get even messier with the use of String in the Delphi Unicode compatibility arena, since a “String” cannot be typecast as a PANSIChar in D2009+. I also think you may need to +1 on MAX_PATH to allow for the null terminator that the Windows API is most likely to include in any return value. Whew – that’s quite a start to a Monday morning. J hth Jolyon From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On Behalf Of Bob Pawley Sent: Monday, 27 June 2011 08:58 To: 'NZ Borland Developers Group - Delphi List' Subject: Re: [DUG] Variable in String Hi Jolyon I was wondering if my problem is a conflict between how I derive the value of the variable (PAnsiChar). Here is the code for doing that.
_______________________________________________ NZ Borland Developers Group - Delphi mailing list Post: delphi@delphi.org.nz Admin: http://delphi.org.nz/mailman/listinfo/delphi Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: unsubscribe