Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2007-11

Converting StrLCopy to widestrings

6 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Felipe Monteiro de Carvalho

Hello,

In a LCL code we have:

var
  FileNameBuffer: PChar;
  FileNameWide: WideString;
  FileNameWideBuffer: PWideChar;
  FilterBuffer: WideString;
begin
{$ifdef WindowsUnicodeSupport}
  if UnicodeEnabledOS then
    FileNameWideBuffer := AllocMem(FileNameBufferLen * 2 + 2)
  else
    FileNameBuffer := AllocMem(FileNameBufferLen + 1);
{$else}
  FileNameBuffer := AllocMem(FileNameBufferLen + 1);
{$endif}
.....
  {$ifdef WindowsUnicodeSupport}
    if UnicodeEnabledOS then
    begin
      FileNameWide := UTF8Decode(FileName);
      { StrLCopy is a PChar function, so it won't create a proper 2-byte
        sized ending and we ensure that it's there by cleaning the string }
      FillChar(FileNameWideBuffer^, FileNameBufferLen * 2 + 2, #0);
      StrLCopy(PChar(FileNameWideBuffer),
PChar(PWideChar(FileNameWide)), FileNameBufferLen * 2);
    end
    else
      StrLCopy(FileNameBuffer, PChar(UTF8ToAnsi(FileName)), FileNameBufferLen);
  {$else}
    StrLCopy(FileNameBuffer, PChar(FileName), FileNameBufferLen);
  {$endif}
...
  {$ifdef WindowsUnicodeSupport}
    if UnicodeEnabledOS then
    begin
      lpStrFile := PChar(FileNameWideBuffer);
.....

Which doesn't work. FileName can be, for example: C:\Programs\file.txt

And then the dialog will show only C, as if it would show only the first letter.

The original code uses StrLCopy to copy a PChar with a maximal length. I tryed to manually build a StrLCopy for PWideChar, but it would crash, so I then tryed to improvise an way to use StrLCopy with PWideChar strings

In fact, there are lot's of places on LCL where the helper PChar functions are used. Are there PWideChar equivalents??? It really get's much harder to use PWideChar strings without those helper functions.

thanks,

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Felipe Monteiro de Carvalho

I managed to get it working with:

  {$ifdef WindowsUnicodeSupport}
    if UnicodeEnabledOS then
    begin
      FileNameWide := UTF8Decode(FileName);
      FillChar(FileNameWideBuffer^, FileNameBufferLen * 2 + 2, #0);
      if Length(FileNameWide) > FileNameBufferLen then
       FileNameBufferSize := FileNameBufferLen
      else FileNameBufferSize := Length(FileNameWide);
      Move(FileNameWide[1], FileNameWideBuffer^, FileNameBufferSize * 2);
    end
    else
      StrLCopy(FileNameBuffer, PChar(UTF8ToAnsi(FileName)), FileNameBufferLen);
  {$else}
    StrLCopy(FileNameBuffer, PChar(FileName), FileNameBufferLen);
  {$endif}

But still, the code would be much simpler and shorter if there were PWideChar routines

Felipe Monteiro de Carvalho

Reply by email

Marc Weustink
to Felipe Monteiro de Carvalho: In a LCL code we have: var FileNameBuffer: PChar; FileNameWide: WideString;…
Felipe Monteiro de Carvalho wrote 44 lines
Hello, In a LCL code we have: var FileNameBuffer: PChar; FileNameWide: WideString; FileNameWideBuffer: PWideChar; FilterBuffer: WideString; begin {$ifdef WindowsUnicodeSupport} if UnicodeEnabledOS then FileNameWideBuffer := AllocMem(FileNameBufferLen * 2 + 2) else FileNameBuffer := AllocMem(FileNameBufferLen + 1); {$else} FileNameBuffer := AllocMem(FileNameBufferLen + 1); {$endif} ..... {$ifdef WindowsUnicodeSupport} if UnicodeEnabledOS then begin FileNameWide := UTF8Decode(FileName); { StrLCopy is a PChar function, so it won't create a proper 2-byte sized ending and we ensure that it's there by cleaning the string } FillChar(FileNameWideBuffer^, FileNameBufferLen * 2 + 2, #0); StrLCopy(PChar(FileNameWideBuffer), PChar(PWideChar(FileNameWide)), FileNameBufferLen * 2); end else StrLCopy(FileNameBuffer, PChar(UTF8ToAnsi(FileName)), FileNameBufferLen); {$else} StrLCopy(FileNameBuffer, PChar(FileName), FileNameBufferLen); {$endif} ... {$ifdef WindowsUnicodeSupport} if UnicodeEnabledOS then begin lpStrFile := PChar(FileNameWideBuffer); .....

First question, why is the copying needed ?
Why isn't lpStrFile := PWChar(FileNameWide);
simply enough ?

IMO, you're copying way to much.

Marc

Reply by email

Felipe Monteiro de Carvalho
to Marc Weustink
Marc Weustink wrote 5 lines
First question, why is the copying needed ? Why isn't lpStrFile := PWChar(FileNameWide); simply enough ? IMO, you're copying way to much.

That variable is only valid on the scope of the function, and we need something more permanent.

Felipe Monteiro de Carvalho

Reply by email

Marc Weustink
to Felipe Monteiro de Carvalho
Felipe Monteiro de Carvalho wrote 9 lines
On Nov 17, 2007 1:25 PM, Marc Weustink wrote: > First question, why is the copying needed ? > Why isn't lpStrFile := PWChar(FileNameWide); > simply enough ? > > IMO, you're copying way to much. That variable is only valid on the scope of the function, and we need something more permanent.

I need to review the code in that area, imo it is not needed. anyway when is the allocateed memory freed ?

Marc

Reply by email

Felipe Monteiro de Carvalho
to Marc Weustink
Marc Weustink wrote
I need to review the code in that area, imo it is not needed.

I couldn't make it work without allocating. There is no permanent storage for the data available.

anyway when is the allocateed memory freed ?

I noticed that it's nowhere freed. More parts allocate memory, but it's freed on DestroyHandle. I don't know if windows frees it, probably not.

Also, I don't know if DestroyHandle for dialogs is called always after closing, so there are questions and this may be a point of memory leak.

Felipe Monteiro de Carvalho

Reply by email