Sign in Join

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

Mailing lists / fpc-pascal / 2007-11

Help making code unicode capable

10 messages · 5 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,

I have a small piece of code on LCL which I have found hard to convert to unicode:

      lpStrFilter := StrAlloc(Length(Filter)+1);
      StrPCopy(lpStrFilter, Filter);

on win32wsdialogs.pp

lpStrFilter is a member on the LPOPENFILENAME winapi structure.

Having a win9x version is trivial, but having a version where we put a PWideChar into lpStrFilter looks hard...

      lpStrFilter := StrAlloc(Length(Filter)+1);
      StrPCopy(lpStrFilter, Utf8ToAnsi(Filter));

I tryed this as unicode version:

      lpStrFilter := PChar(PWideChar(Utf8Decode(Filter)));

But it crashes the dialog when it is closed... I don't know what exactly is happening here, or why the original code manually alocated memory and then copyed the string, instead of just copying, so I'm lost about solving this.

thanks,

Felipe Monteiro de Carvalho
Jonas Maebe
to Felipe Monteiro de Carvalho
Felipe Monteiro de Carvalho wrote 13 lines
Having a win9x version is trivial, but having a version where we put a PWideChar into lpStrFilter looks hard... lpStrFilter := StrAlloc(Length(Filter)+1); StrPCopy(lpStrFilter, Utf8ToAnsi(Filter)); I tryed this as unicode version: lpStrFilter := PChar(PWideChar(Utf8Decode(Filter))); But it crashes the dialog when it is closed... I don't know what exactly is happening here, or why the original code manually alocated memory and then copyed the string, instead of just copying,

Maybe because Filter may already have disappeared/freed by the time the dialog is closed? (and for some reason it may still need that text at that time)

Jonas

Marco van de Voort
to Jonas Maebe
Show quoted text 19 lines
On 10 Nov 2007, at 15:08, Felipe Monteiro de Carvalho wrote: > Having a win9x version is trivial, but having a version where we put a > PWideChar into lpStrFilter looks hard... > > lpStrFilter := StrAlloc(Length(Filter)+1); > StrPCopy(lpStrFilter, Utf8ToAnsi(Filter)); > > I tryed this as unicode version: > > lpStrFilter := PChar(PWideChar(Utf8Decode(Filter))); > > But it crashes the dialog when it is closed... I don't know what > exactly is happening here, or why the original code manually alocated > memory and then copyed the string, instead of just copying, Maybe because Filter may already have disappeared/freed by the time the dialog is closed? (and for some reason it may still need that text at that time)

utf8decode returns string I assume?. I think it is that tempstring that is lost.

Moreover, the first piece of code assumes that
length(filter)>=length(utf8toansi(filter))

I think that is ok in general, but I would assign the result of utf8toansi to a local string first, because even if a shortcut abusing temps works, that will be more comprehensive.

Jonas Maebe
to Felipe Monteiro de Carvalho
Felipe Monteiro de Carvalho wrote
> utf8decode returns string I assume? It returns WideString. Is there a function to manually alloc a widestring like StrAlloc?

Assign it to a variable of the type widestring. If you cannot this variable in scope the whole time, you have to allocate enough memory (length(widestring)*2+2) and copy the contents (including the terminating zero) to the allocated memory block.

Jonas

Felipe Monteiro de Carvalho
to Jonas Maebe

Thanks, I arrived at this:

var
  FilterBuffer: WideString;
...
      FilterBuffer := Utf8Decode(Filter);
      lpStrFilter := GetMem(Length(FilterBuffer) * 2 + 2);
      Move(FilterBuffer, lpStrFilter, Length(FilterBuffer) * 2 + 2);

But now it crashes when loading the dialog =/

any ideas?

thanks,

Felipe Monteiro de Carvalho
Mattias Gaertner
to Felipe Monteiro de Carvalho
Show quoted text 13 lines
Thanks, I arrived at this: var FilterBuffer: WideString; ... FilterBuffer := Utf8Decode(Filter); lpStrFilter := GetMem(Length(FilterBuffer) * 2 + 2); Move(FilterBuffer, lpStrFilter, Length(FilterBuffer) * 2 + 2); But now it crashes when loading the dialog =/ any ideas?
       Move(FilterBuffer[0], lpStrFilter^, Length(FilterBuffer) * 2 +
2);

Mattias

Felipe Monteiro de Carvalho
to Mattias Gaertner
Mattias Gaertner wrote
Move(FilterBuffer[0], lpStrFilter^, Length(FilterBuffer) * 2 + 2);

The compiler wisely doesn't allow accessing [0], but:

      Move(FilterBuffer[1], lpStrFilter^, Length(FilterBuffer) * 2 + 2);

Seams to work perfectly =)

thanks,

Felipe Monteiro de Carvalho
Marc Weustink
to Felipe Monteiro de Carvalho: I have a small piece of code on LCL which I have found hard to convert to unicode:…
Felipe Monteiro de Carvalho wrote 7 lines
Hello, I have a small piece of code on LCL which I have found hard to convert to unicode: lpStrFilter := StrAlloc(Length(Filter)+1); StrPCopy(lpStrFilter, Filter);

There is a big chance that this is an inheritence of the pre 1.0 fpc times. At that time Casting a string to a PChar didn't work reliable, so all in all cases where you now would use PChar(S) these constructs where used.
I think in this case you now simply can use a sting (or widestring)

Marc

Marc Weustink
to Mattias Gaertner: On Sat, 10 Nov 2007 15:44:54 +0100 Move(FilterBuffer[0], lpStrFilter^,…
Mattias Gaertner wrote 20 lines
On Sat, 10 Nov 2007 15:44:54 +0100 "Felipe Monteiro de Carvalho" wrote: > Thanks, I arrived at this: > > var > FilterBuffer: WideString; > ... > > FilterBuffer := Utf8Decode(Filter); > lpStrFilter := GetMem(Length(FilterBuffer) * 2 + 2); > Move(FilterBuffer, lpStrFilter, Length(FilterBuffer) * 2 + 2); > > But now it crashes when loading the dialog =/ > > any ideas? Move(FilterBuffer[0], lpStrFilter^, Length(FilterBuffer) * 2 + 2);
See my other mail, I think that lpStrFilter := PWChar(FilterBuffer)
should work here. No need for a temp buffer.

Marc