RichEdit problem on dbcs system
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?
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?
This discussion has been closed.
Comments
multiple versions of these RichEd dll's which exhibit different behavior.
Cheers,
Jim Bennett
Digital Metaphors
http://www.digital-metaphors.com
info@digital-metaphors.com