Delphi: TRichEdit text in a system language other than the standard non-Unicode, like String (ANSI)

So here is the setting:

  • Create a new Delphi 7 application with the TRichEdit control. We are talking about non-Unicode applications here.
  • Set the new input language to Windows' Regional and Language Options, which has a different encoding from the default encoding of your language for a non-Unicode program - for example, Greek.
  • Add a button to the application and in your OnClick handler add Button1.Caption := RichEdit1.Text; and set its Font.Charset to the encoding of the newly installed input language ( GREEK_CHARSET , if we stick to this example).
  • Launch the application, switch to the new (Greek) input language, enter a few letters in RichEdit and click the button - now the button now has characters ???? instead of greek characters.

  • Now, if you set your default language for programs other than Unicode in Greek (requires a restart of Windows), this problem will disappear - Greek characters will display correctly. Set your default language for programs other than Unicode to what it was before, and the problem is there again.

So, I would suggest that TRichEdit works with Unicode internally, since changing its Font.Charset value does not change anything - RichEdit correctly accepts any installed input language and if you installed two different non-Latin languages ​​that use different character sets (Greek / GREEK_CHARSET / and Russian / RUSSIAN_CHARSET / for example), he would accept them both without changing his Font.Charset.

I would also suggest that when you get the value TRIMEdit .Text (or .Lines[i] ), it will convert its Unicode inner text to ANSI, based on the standard Windws language for non-Unicode programs.

In addition, assigning a .Text value to WideString or UnicodeString also does not work properly (the text is again in ???? instead of the correct characters), this is not only when you assign its String (AnsiString).

So here is the question:

I want to be able to convert RichEdit text to String (ANSI) correctly, based on the character set of my choice, instead of the default default language for programs other than Unicode. How can i do this? I would prefer a solution that is not related to third-party components, but, of course, if this is not possible, everything will be done.

Thanks!

PS: Switching to Delphi 2009 or later is not an acceptable solution.

+4
source share
1 answer

Send the base edit window EM_GETTEXTEX . You pass a GETTEXTEX struct that indicates the code page.

So, something like this will pull the text into a UTF-16 WideString :

 function GetRichEditText(RichEdit: TRichEdit): WideString; var GetTextLengthEx: TGetTextLengthEx; GetTextEx: TGetTextEx; Len: Integer; begin GetTextLengthEx.flags := GTL_DEFAULT; GetTextLengthEx.codepage := 1200; Len := SendMessage(RichEdit.Handle, EM_GETTEXTLENGTHEX, WPARAM(@GetTextLengthEx), 0); if Len=E_INVALIDARG then raise Exception.Create('EM_GETTEXTLENGTHEX failed'); SetLength(Result, Len); if Len=0 then exit; GetTextEx.cb := (Length(Result)+1)*SizeOf(WideChar); GetTextEx.flags := GTL_DEFAULT; GetTextEx.codepage := 1200; GetTextEx.lpDefaultChar := nil; GetTextEx.lpUsedDefChar := nil; SendMessage(RichEdit.Handle, EM_GETTEXTEX, WPARAM(@GetTextEx), LPARAM(PWideChar(Result))); end; 

Then you can convert this UTF-16 string to any code page that you like. If you prefer to pull it out on a specific code page directly, do the following:

 function GetRichEditText(RichEdit: TRichEdit; AnsiCodePage: UINT): AnsiString; var GetTextLengthEx: TGetTextLengthEx; GetTextEx: TGetTextEx; Len: Integer; begin GetTextLengthEx.flags := GTL_DEFAULT; GetTextLengthEx.codepage := AnsiCodePage; Len := SendMessage(RichEdit.Handle, EM_GETTEXTLENGTHEX, WPARAM(@GetTextLengthEx), 0); if Len=E_INVALIDARG then raise Exception.Create('EM_GETTEXTLENGTHEX failed'); SetLength(Result, Len); if Len=0 then exit; GetTextEx.cb := (Length(Result)+1)*SizeOf(AnsiChar); GetTextEx.flags := GTL_DEFAULT; GetTextEx.codepage := AnsiCodePage; GetTextEx.lpDefaultChar := nil; GetTextEx.lpUsedDefChar := nil; SendMessage(RichEdit.Handle, EM_GETTEXTEX, WPARAM(@GetTextEx), LPARAM(PWideChar(Result))); end; 
+5
source

All Articles