Home General
New Blog Posts: Merging Reports - Part 1 and Part 2

RichEdit problem on dbcs system

edited February 2002 in General
Last time i get a 'Invalid Pointer operation' error in tppRichText
component , when the componet set stretch to true.
( I enter some Chinese Character)

And later i use

ppRegisterRichEditClass( tRichEdit );

to avoid the error , No error on Win2K system but having some Win 98/ME
System have infinite loop result.

I try to find out why the error occur only on Win98/ME ?

Finally , i found out that following.

On D5 ComCtrls.Pas;

function TCustomRichEdit.GetSelLength: Integer;
var
CharRange: TCharRange;
begin
SendMessage(Handle, EM_EXGETSEL, 0, Longint(@CharRange));
Result := CharRange.cpMax - CharRange.cpMin;
end;

function TCustomRichEdit.GetSelText: string;
var
Length: Integer;
begin
SetLength(Result, GetSelLength + 1);
Length := SendMessage(Handle, EM_GETSELTEXT, 0, Longint(PChar(Result)));
SetLength(Result, Length);
end;

On Line 'SetLength(Result, GetSelLength + 1); ' , it use GetSelLength to
determine the length need to allocate string length. But in RichEd20.DLL ,
its will return no. of 'character' not byte count. In Westen country , there
are no error occur. But if in DBCS sytsem , those return value will be short
than expect , so the

Length := SendMessage(Handle, EM_GETSELTEXT, 0, Longint(PChar(Result)));

e.g. 'a' will return 1 , but enter 1 Chinese Character , it also return 1
instead of 2.

have't enough space to return value . Error occur.


Below is the modify code i use :

unit PccRichEdit;

interface

Uses StdCtrls,ComCtrls,Controls,Messages,Windows,RichEdit,ppDrwCmd;


Const
EM_GETTEXTLENGTHEX = WM_USER + 95;

const
GTL_DEFAULT = 0; { do the default (return # of
}
GTL_USECRLF = 1; { compute answer using CRLFs for
paragraphs }
GTL_PRECISE = 2; { compute a precise
}
GTL_CLOSE = 4; { fast computation of a "close"
r }
GTL_NUMCHARS = 8; { return the number of
}
GTL_NUMBYTES = 16; { return the number of
}

{ EM_GETTEXTLENGTHEX info; this struct is passed in the wparam of the msg }

type
TGetTextLengthEx = record
flags: DWORD; { flags (see GTL_XXX defines) }
codepage: UINT; { code page for translation }
end;


Type

TppPccRichEdit = class(TppRichEdit)
private

protected
function GetSelText: string; override;

end; {class, TppRichEdit}

implementation

function TppPccRichEdit.GetSelText: string;
Var
TextLenEx: TGetTextLengthEx;
MaxLength , Length: Integer;
begin
with TextLenEx do begin
flags := GTL_NUMBYTES or GTL_CLOSE or GTL_USECRLF ;
codepage := CP_ACP;
end;
MaxLength := Perform(EM_GETTEXTLENGTHEX, WParam(@TextLenEx), 0);
if MaxLength = 0 then
begin
Result := '';
exit;
end;
SetLength(Result, MaxLength);
Length := SendMessage(Handle, EM_GETSELTEXT, 0, Longint(PChar(Result)));
SetLength(Result, Length);
end;

initialization
ppRegisterRichEditClass( tppPccRichEdit );

finalization
ppUnRegisterRichEditClass( tppPccRichEdit );

end.

This time seens everything OK .

Or someone else have another idea?

Comments

This discussion has been closed.