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.

Wordpad_1 WordPad_2 WordPad_3

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 .

TRichEdit_1

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. TRichEdit_2 TRichEdit_3 TRichEdit_4

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.
52
demandé sur Community 2012-07-03 17:59:45

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.

1
répondu Tommy Hui 2013-09-20 06:12:54