jjzjj

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

coder 2023-11-09 原文

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”,然后无限次更改为任何所需的字体来更改其字体。

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

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

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

因此,我想知道 (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/

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

  1. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

    如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

  2. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  3. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  4. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  5. ruby - Capistrano 3 在任务中更改 ssh_options - 2

    我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe

  6. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  7. ruby - 更改 ActiveRecord 中对象的类 - 2

    假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。

  8. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  9. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  10. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

随机推荐