Comment faire pour que TRichEdit se comporte comme WordPad sur Windows 7 en changeant la police pour certains caractères non textuels?
avec l'aide de Sertac Akyuz
, il semble que la raison directe est liée au jeu de caractères de bullet
: dans mes fenêtres localisées, l'entrée bullet
en tapant Alt(0149) obtient toujours fcharset134
, et les tentatives de changer sa police par EM_SETCHARFORMAT
échouent toujours (bien, la couleur, la taille, le style peut effectivement être changé mais pas le nom de famille de la police).
la solution La plus simple est donc d'abord réinitialiser le jeu de caractères et changer la police.
Remarque: RichEdit (version >= 4.1) doit être utilisé!
Note: les versions de RichEdit peuvent être trouvées sur MSDN's à propos de Rich Edit Controls , le blog MSDN de Murray Sargent RichEdit versions et RichEdit Versions Update to 7.0 . Ces dernières pages mentionnaient des versions RichEdit supérieures à 4.1. Comme test, j'ai copié le RICHED20.DLL envoyé avec Office 2010 avec l'application pour Windows 2000, et tout fonctionne comme un charme!
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;
==================================================
selon Wikipedia , WordPad
utilisé la commande RichEdit
de Microsoft, versions 1.0, 2.0 et 3.0 dans Windows 95, 98 et Windows 2000, respectivement. Sous Windows XP SP1 et versions ultérieures, WordPad utilise RichEdit 4.1, y compris Windows 7.
dit un rtf document, en cours d'édition dans WordPad, contient un caractère non textuel Alt(0149), the bullet dot •
. (Ou U+2022)
dans Windows 2000 SP4 ou XP SP2, la police de ce point ne peut prendre que la police par défaut de WordPad. C'est-à-dire qu'on ne peut pas changer de police pour ce point de puce de façon interactive dans WordPad.
cependant, dans Windows 7 SP1, on peut changer sa police par first changing to "Arial Unicode MS"
, puis à n'importe quelle police désirée temps illimités.
de plus, le document WordPad créé en utilisant WordPad dans Windows 7 qui contient différentes polices du point peut être ouvert et visualisé correctement dans WordPad dans Windows 2000 ou XP.
le TRichEdit (Delphi XE, Windows 7) peut également ouvrir et voir le document WordPad créé en utilisant WordPad dans Windows 7 correctement par TRichEdit.Lines.LoadFromFile
.
de manière interactive, le TRichEdit (Delphi XE, Windows 7) permet de changer la police de the bullet dot
en"Arial Unicode MS". Cependant, on ne peut pas aller plus loin pour changer de polices de caractères de façon interactive dans TRichEdit.
je me demande donc (1) la raison du comportement différent de WordPad dans Windows 7, et (2) s'il est possible de faire en sorte que TRichEdit se comporte de la même façon?
PS: on peut avoir besoin de taper Alt(0149) plusieurs fois pour obtenir le point dans WordPad. Taper 2022 et Alt+x fonctionne toujours, comme suggéré ici .
PS: il faut "activer" les polices dans WordPad comme mentionné dans la réponse de pourquoi TFontDialog donne moins de polices que L'écran.Les polices?
PS: on peut toujours changer le point en différentes polices dans Word.
de l'échantillon.rtf (coller dans un fichier texte et ensuite changer l'extension au format rtf à l'utilisation)
{rtf1ansiansicpg936deff0deflang1033deflangfe2052{fonttbl{f0fswissfprq2fcharset134 Arial Unicode MS;}{f1fnilfcharset0 Arial Unicode MS;}{f2fromanfprq2fcharset0 Times New Roman;}{f3fscriptfprq2fcharset0 Comic Sans MS;}{f4fnilfcharset0 Comic Sans MS;}{f5fmodernfprq1fcharset0 Consolas;}{f6fnilfcharset0 Consolas;}{f7fmodernfprq1fcharset0 Lucida Console;}{f8fnilfcharset0 Lucida Console;}{f9fromanfprq2fcharset2 Symbol;}{f10fromanfprq2fcharset0 Symbol;}{f11fnilfcharset134 'cb'ce'cc'e5;}}
{*generator Msftedit 5.41.21.2510;}viewkind4uc1pardnowidctlparsa200sl276slmult1lang2052f0fs22 Arial sample text lang1033f1bulletf2par
bf3 Comic sample text f4bulletf2par
b0f5 Consolas sample text f6bulletf2par
f7 Lucida sample text f8bulletf2par
pardnowidctlparqjlang2052f9 symbl sample text lang1033f10u149?kerning2fs21par
pardsa200sl276slmult1lang2052kerning0f11fs22par
}
uMainForm.dfm pour voir le format des lignes 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 pour voir le format des lignes 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.
1 réponses
une chose à vérifier serait de voir si les contrôles richedit utilisés par WordPad et TRichEdit sont les mêmes. Je vous recommande de vérifier avec (Spy++) Spyxx.exe pour s'assurer que le contrôle de la même classe et le même style. Si elles sont les mêmes, je vérifierais aussi pour m'assurer que les commandes reçoivent les mêmes messages, encore une fois en utilisant Spy++. Je suppose que les commandes ne sont pas les mêmes ou qu'elles ne sont pas configurées de la même manière.
S'ils ne sont pas les mêmes contrôle, alors vous devriez être en mesure d'utiliser le même contrôle que WordPad (en supposant qu'il fait partie de la norme Windows custom controls). Et utilisez Spy++ pour définir le style de la même façon que WordPad est. Aussi, vous pouvez avoir à envoyer les mêmes messages.