gpt4 book ai didi

windows - 更改某些非文本字符的字体时,如何使 TRichEdit 在 Windows 7 上表现得像写字板?

转载 作者:可可西里 更新时间:2023-11-01 11:56:14 25 4
gpt4 key购买 nike

Sertac Akyuz的帮助下,直接原因似乎与\bullet的字符集有关:在我本地化的Windows中,\bullet 通过键入 Alt(0149) 输入总是得到 \fcharset134,并尝试通过 EM_SETCHARFORMAT 更改其字体总是失败(好吧,颜色、大小、样式确实可以会更改但不会更改字体系列名称)。

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

注意:应使用 RichEdit (version >= 4.1)!

注意:RichEdit 版本可以在 MSDN 的 About Rich Edit Controls 找到, Murray Sargent 的 MSDN 博客 RichEdit versionsRichEdit Versions Update to 7.0 .后几页提到 RichEdit 版本高于 4.1。作为测试,我将 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;

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

根据 WikipediaWordPad使用了微软的RichEdit控件,在Windows 95、98和Windows 2000中分别是1.0、2.0和3.0版本。在 Windows XP SP1 及更高版本中,写字板使用 RichEdit 4.1,包括 Windows 7。

假设一个 rtf 文档正在写字板中编辑,包含一个非文本字符 Alt(0149),项目符号点 •。 (或 U+2022)

在Windows 2000 SP4或XP SP2中,该圆点的字体只能采用写字板的默认字体。也就是说,不能在写字板中以交互方式更改该项目符号点的字体。

但是,在 Windows 7 SP1 中,可以通过首先更改为“Arial Unicode MS”,然后无限次更改为任何所需的字体来更改其字体。

Wordpad_1 WordPad_2 WordPad_3

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

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

TRichEdit_1

以交互方式,TRichEdit(Delphi XE、Windows 7)允许将圆点的字体更改为“Arial Unicode MS”。但是,不能进一步在 TRichEdit 中以交互方式更改为其他字体。 TRichEdit_2 TRichEdit_3 TRichEdit_4

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

PS:可能需要多次键入 Alt(0149) 才能在写字板中找到点。按照建议输入 2022 和 Alt+x 总是有效 here .

PS:需要“激活”写字板中的字体,如Why TFontDialog gives less fonts than Screen.Fonts? 的答案中所述

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 控件是否相同。我建议您检查 (Spy++) Spyxx.exe 以确保控件具有相同的类和相同的样式。如果它们相同,我还会再次使用 Spy++ 检查以确保控件接收到相同的消息。我猜控件不一样,或者它们的配置不一样。

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

关于windows - 更改某些非文本字符的字体时,如何使 TRichEdit 在 Windows 7 上表现得像写字板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11312563/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com