tamaño - ¿Cómo hacer que TRichEdit se comporte como WordPad en Windows 7 al cambiar la fuente de ciertos caracteres que no son de texto?
como cambiar el tamaño de letra en word (1)
Una cosa para comprobar sería ver si los controles richedit utilizados por WordPad y TRichEdit son los mismos. Le recomendaría que consulte con (Spy ++) Spyxx.exe para asegurarse de que el control tenga la misma clase y los mismos estilos. Si son iguales, yo también verificaría para asegurarse de que los controles reciban los mismos mensajes, nuevamente usando Spy ++. Supongo que los controles NO son los mismos o que no están configurados de la misma manera.
Si no tienen el mismo control, entonces debería poder utilizar el mismo control que WordPad (suponiendo que sea parte de los controles personalizados estándar de Windows). Y use Spy ++ para establecer el estilo de la misma manera que WordPad. Además, es posible que también deba enviarle los mismos mensajes.
Con la ayuda de Sertac Akyuz
, parece que la razón directa está relacionada con el conjunto de caracteres de /bullet
: en mi Windows localizado, la entrada de /bullet
escribiendo Alt (0149) siempre obtiene /fcharset134
, e intenta cambiar su fuente a través de EM_SETCHARFORMAT
siempre fallar (bueno, el color, tamaño, estilo puede ser cambiado, pero no el nombre de la fuente).
La solución más simple es, por lo tanto, restablecer primero el juego de caracteres y luego cambiar la fuente.
Nota: ¡RichEdit (versión> = 4.1) debería ser usado!
Nota: las versiones de RichEdit se pueden encontrar en los Controles Rich Edit de MSDN, las versiones RichEdit de MSDN Blog de Murray Sargent y las versiones de RichEdit Update to 7.0 . Las últimas páginas mencionaron versiones de RichEdit superiores a 4.1. Como prueba, copié el RICHED20.DLL con Office 2010 junto con la aplicación a Windows 2000, ¡y todo funciona como un amuleto!
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;
===============================================
Según Wikipedia , WordPad
utilizó el control RichEdit
de Microsoft, las versiones 1.0, 2.0 y 3.0 en Windows 95, 98 y Windows 2000, respectivamente. En Windows XP SP1 y posterior, WordPad utiliza RichEdit 4.1, incluido Windows 7.
Digamos que un documento rtf, editado en WordPad, contiene un carácter no textual Alt (0149), the bullet dot •
. (O U + 2022)
En Windows 2000 SP4 o XP SP2, la fuente de ese punto de viñeta solo puede tomar la fuente predeterminada de WordPad. Es decir, no se puede cambiar la fuente de ese punto de viñeta de forma interactiva en WordPad.
Sin embargo, en Windows 7 SP1, uno podría cambiar su fuente first changing to "Arial Unicode MS"
, y luego a cualquier fuente deseada un número ilimitado de veces.
Además, el documento de WordPad creado con WordPad en Windows 7 que contiene diferentes fuentes del punto se puede abrir y visualizar correctamente en WordPad en Windows 2000 o XP.
El TRichEdit (Delphi XE, Windows 7) también puede abrir y ver correctamente el documento de WordPad creado con WordPad en Windows 7 mediante TRichEdit.Lines.LoadFromFile
.
Interactivamente, el TRichEdit (Delphi XE, Windows 7) permite que the bullet dot
fuente del the bullet dot
del the bullet dot
sea cambiada a "Arial Unicode MS". Sin embargo, no se puede ir más lejos para cambiar a otras fuentes interactivamente en TRichEdit.
Por lo tanto, me pregunto (1) la razón del comportamiento diferente de WordPad en Windows 7, y (2) si es posible hacer que TRichEdit se comporte de la misma manera.
PD: Es posible que se necesite el tipo Alt (0149) varias veces para obtener el punto en WordPad. Escribir 2022 y Alt + x siempre funciona, como se sugiere here .
PD: hay que "activar" las fuentes en WordPad como se menciona en la respuesta de ¿Por qué TFontDialog da menos fuentes que Screen.Fonts?
PD: siempre se puede cambiar el punto a diferentes fuentes en Word.
sample.rtf (pegue en un archivo de texto plano y luego cambie la extensión a rtf para usar)
{/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 para ver el formato de las líneas de 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 para ver el formato de las líneas de 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.