在更改某些非文本字符的字体时,如何使TRichEdit在Windows 7上的行为类似于写字板?

Sertac Akyuz的帮助下,似乎直接原因与\bullet的字符集有关:在我本地化的Windows中,通过键入Alt(0149)input的\bullet总是获得\fcharset134 ,并总是尝试通过EM_SETCHARFORMAT改变其字体不好(颜色,大小,风格确实可以改变,但不是字体名称)。

最简单的解决方法是首先重置字符集,然后更改字体。

注意:应该使用RichEdit (版本> = 4.1)

注意:RichEdit版本可以在MSDN 关于Rich Edit Controls ,Murray Sargent的MSDN博客RichEdit版本和RichEdit版本更新到7.0中find 。 后面的页面提到RichEdit版本高于4.1。 作为一个testing,我将Office 2010中的RICHED20.DLL与应用程序一起复制到Windows 2000,一切都像一个魅力!

 procedure TMainForm.ButtonFontClick(Sender: TObject); var format: TCharFormat2; begin if dlgFontCdxTxt.Execute then begin FillChar(format, sizeof(format), 0); format.cbSize:= Sizeof(format); format.dwMask:= CFM_CHARSET; format.bCharSet := 1; // or 0; redtTextBlock.Perform(EM_SETCHARFORMAT, SCF_SELECTION, Integer(@format)); FillChar(format, sizeof(format), 0); format.cbSize:= Sizeof(format); format.dwMask:= CFM_FACE; StrPLCopy(format.szFaceName, dlgFontCdxTxt.Font.Name, High(format.szFaceName)); redtTextBlock.Perform(EM_SETCHARFORMAT, SCF_SELECTION, Integer(@format)); end; redtTextBlock.SetFocus; end; 

==================================================

根据维基百科 , WordPad分别在Windows 95,98和Windows 2000中使用微软的RichEdit控件, RichEdit和3.0版本。 在Windows XP SP1和更高版本中,写字板使用RichEdit 4.1,包括Windows 7。

假设在写字板中编辑的rtf文档包含非文本字符Alt(0149), the bullet dot • 。 (或U + 2022)

在Windows 2000 SP4或XP SP2中,该子弹点的字体只能采用写字板的默认字体。 也就是说,WordPad中不能交互地改变那个圆点的字体。

但是,在Windows 7 SP1中,可以first changing to "Arial Unicode MS" ,然后再更改为任何所需的字体次数。

Wordpad_1WordPad_2WordPad_3

此外,使用Windows 7中写字板创build的包含不同字体的写字板文档,可以在Windows 2000或XP中的写字板中正确打开和查看。

TRichEdit(Delphi XE,Windows 7)也可以通过TRichEdit.Lines.LoadFromFile正确打开并查看使用写字板在Windows 7中创build的写字板文档。

TRichEdit_1

TRichEdit(Delphi XE,Windows 7) the bullet dot交互方式the bullet dot的字体更改为“Arial Unicode MS”。 但是,在TRichEdit中不能进一步转换为其他字体。 TRichEdit_2TRichEdit_3TRichEdit_4

因此,我想知道(1)在Windows 7中写字板的不同行为的原因,(2)是否有可能使TRichEdit行为相似?

PS:可能需要多次inputAlt(0149)才能在写字板中find点。 正如这里所build议的,键入2022和Alt + x总是有效。

PS:一个需要“激活”写字板中的字体, 为什么TFontDialog的字体比Screen.Fontsless?

PS:人们可以随时在Word中将点改为不同的字体。

sample.rtf(粘贴到纯文本文件中,然后将扩展名更改为rtf以使用)

 {\rtf1\ansi\ansicpg936\deff0\deflang1033\deflangfe2052{\fonttbl{\f0\fswiss\fprq2\fcharset134 Arial Unicode MS;}{\f1\fnil\fcharset0 Arial Unicode MS;}{\f2\froman\fprq2\fcharset0 Times New Roman;}{\f3\fscript\fprq2\fcharset0 Comic Sans MS;}{\f4\fnil\fcharset0 Comic Sans MS;}{\f5\fmodern\fprq1\fcharset0 Consolas;}{\f6\fnil\fcharset0 Consolas;}{\f7\fmodern\fprq1\fcharset0 Lucida Console;}{\f8\fnil\fcharset0 Lucida Console;}{\f9\froman\fprq2\fcharset2 Symbol;}{\f10\froman\fprq2\fcharset0 Symbol;}{\f11\fnil\fcharset134 \'cb\'ce\'cc\'e5;}} {\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\nowidctlpar\sa200\sl276\slmult1\lang2052\f0\fs22 Arial sample text \lang1033\f1\bullet\f2\par \b\f3 Comic sample text \f4\bullet\f2\par \b0\f5 Consolas sample text \f6\bullet\f2\par \f7 Lucida sample text \f8\bullet\f2\par \pard\nowidctlpar\qj\lang2052\f9 symbl sample text \lang1033\f10\u149?\kerning2\fs21\par \pard\sa200\sl276\slmult1\lang2052\kerning0\f11\fs22\par } 

uMainForm.dfm查看TRichEdit的格式

 object MainForm: TMainForm Left = 0 Top = 0 Caption = 'MainForm' ClientHeight = 362 ClientWidth = 637 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 object pnlBtn: TPanel Left = 0 Top = 0 Width = 637 Height = 57 Align = alTop Caption = 'pnlBtn' TabOrder = 0 object Button1: TButton Left = 240 Top = 14 Width = 137 Height = 31 Caption = 'Analyze Rich Edit' TabOrder = 0 OnClick = Button1Click end end object pnlClient: TPanel Left = 0 Top = 57 Width = 637 Height = 305 Align = alClient Caption = 'pnlClient' TabOrder = 1 object redtTextBlock: TRichEdit Left = 1 Top = 1 Width = 225 Height = 303 Align = alLeft Font.Charset = GB2312_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] Lines.Strings = ( 'redt1') ParentFont = False TabOrder = 0 end object mmo1: TMemo Left = 226 Top = 1 Width = 410 Height = 303 Align = alClient Lines.Strings = ( 'mmo1') TabOrder = 1 end end object Button2: TButton Left = 36 Top = 14 Width = 171 Height = 31 Caption = 'Font...' TabOrder = 2 OnClick = Button2Click end object dlgFontCdxTxt: TFontDialog Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] Left = 480 Top = 16 end end 

uMainForm.pas查看TRichEdit的格式

 unit uMainForm; interface uses Contnrs, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls; type TCdxmlStyle = class public FontName: string; Str: string; end; TCdxmlText = class public Styles: TObjectList; constructor Create; end; TMainForm = class(TForm) redtTextBlock: TRichEdit; mmo1: TMemo; pnlBtn: TPanel; pnlClient: TPanel; Button1: TButton; Button2: TButton; dlgFontCdxTxt: TFontDialog; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } procedure TestLoadFromFile; procedure AnalyzeRichEdit; public { Public declarations } end; var MainForm: TMainForm; implementation {$R *.dfm} uses RichEdit, StrUtils; { TCdxmlText } constructor TCdxmlText.Create; begin Styles := TObjectList.Create; end; var l_HiddenRichEdit: TRichEdit; { TMainForm } procedure TMainForm.FormCreate(Sender: TObject); begin TestLoadFromFile; AnalyzeRichEdit; end; procedure TMainForm.Button2Click(Sender: TObject); var format: TCharFormat2; begin if dlgFontCdxTxt.Execute then begin FillChar(format, sizeof(format), 0); format.cbSize:= Sizeof(format); format.dwMask:= CFM_FACE; StrPLCopy(format.szFaceName, dlgFontCdxTxt.Font.Name, High(format.szFaceName)); redtTextBlock.Perform(EM_SETCHARFORMAT, SCF_SELECTION, Integer(@format)); end; redtTextBlock.SetFocus; end; procedure TMainForm.Button1Click(Sender: TObject); begin AnalyzeRichEdit; end; procedure TMainForm.TestLoadFromFile; begin redtTextBlock.Clear; redtTextBlock.Lines.LoadFromFile('sample.rtf'); end; procedure TMainForm.AnalyzeRichEdit; var l_MemStream: TMemoryStream; l_Format: TCharFormat2; I, J: Integer; l_CdxmlStyle, l_CdxmlStyleWorker: TCdxmlStyle; l_StyleFont: string; l_CdxmlText: TCdxmlText; begin l_CdxmlStyle := nil; l_CdxmlStyleWorker := nil; mmo1.Clear; l_MemStream := TMemoryStream.Create; redtTextBlock.Lines.SaveToStream(l_MemStream); l_MemStream.Seek(0, soFromBeginning); l_HiddenRichEdit.Lines.LoadFromStream(l_MemStream); l_CdxmlText := TCdxmlText.Create; for I := 0 to Length(TrimRight(l_HiddenRichEdit.Text)) - 1 do begin l_CdxmlStyleWorker := TCdxmlStyle.Create; FillChar(l_Format, sizeof(l_Format), 0); l_Format.cbSize:= Sizeof(l_Format); l_Format.dwMask:= CFM_FACE; l_HiddenRichEdit.SelStart := I; l_HiddenRichEdit.SelLength := 1; l_HiddenRichEdit.Perform(EM_GETCHARFORMAT, SCF_SELECTION, Integer(@l_Format)); l_CdxmlStyleWorker.FontName := l_Format.szFaceName; l_CdxmlStyleWorker.Str := AnsiReplaceStr(l_HiddenRichEdit.SelText, #13, #13#10); if l_CdxmlStyle = nil then begin l_CdxmlText.Styles.Add(l_CdxmlStyleWorker); l_CdxmlStyle := l_CdxmlStyleWorker; end else if (l_CdxmlStyleWorker.FontName <> l_CdxmlStyle.FontName ) then begin l_CdxmlText.Styles.Add(l_CdxmlStyleWorker); l_CdxmlStyle := l_CdxmlStyleWorker; end else begin l_CdxmlStyle.Str := l_CdxmlStyle.Str + l_CdxmlStyleWorker.Str; end; end; for I := 0 to l_CdxmlText.Styles.Count - 1 do begin l_CdxmlStyle := TCdxmlStyle(l_CdxmlText.Styles[I]); mmo1.Lines.Add(l_CdxmlStyle.Str + ':' + l_CdxmlStyle.FontName); end; end; initialization l_HiddenRichEdit := TRichEdit.CreateParented(HWND_MESSAGE); end. 

有一件事要检查是否写字板和TRichEdit使用的RichEdit控件是相同的。 我build议你检查(Spy ++)Spyxx.exe,以确保控件具有相同的类和相同的样式。 如果他们是相同的,我会然后检查,以确保控件接收到相同的消息,再次使用Spy ++。 我猜测,控件是不一样的,或者他们没有configuration相同。

如果他们不是相同的控制,那么你应该能够使用与写字板相同的控制(假设它是标准的Windows自定义控件的一部分)。 并使用Spy ++设置样式与写字板相同的方式。 另外,您可能还需要发送相同的消息。

Interesting Posts