Question about make text with bullets and Underlined on the RichEdit.

Peter Kiers
Peter Kiers used Ask the Experts™
on
Hi,

I have asked how to make text bold,italic,underlined,bullets,numbering on the Richedit.
I have received code that works like a clock. I have a question about the bullets and
the numbering. To explain my problem its best to do it with pictures.
In picture2 I use the code I have received that I have put in the code-section.
You see that when the cursor is on the second line it begins at the beginning of the line.
With the second picture 2 use the Delphi example RichEdit. And you see that the text of
the second line begins not at the beginning but begins at the beginning of the first line.
What do I have to do, or to change to make my code as the first picture.

Who knows the answer?

peter

unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ADODB, ComCtrls, StdCtrls, ImgList, ExtCtrls, OleCtrls, SHDocVw,
  ToolWin, DBCtrls;
 
type
  TNumberingFormat = (nfNone=0, nfBullets=1, nfNumbers=2, nfLowerLetters=3, nfUpperLetters=4, nfLowerNumerals=5, nfUpperNumerals=6);
  
  TForm1 = class(TForm)
    ImageList1: TImageList;
    ToolBar1: TToolBar;
    RichEdit1: TRichEdit;
    BoldBtn: TToolButton;
    ItalicBtn: TToolButton;
    UnderlineBtn: TToolButton;
    BulletBtn: TToolButton;
    NumberBtn: TToolButton;
    procedure NumberBtnClick(Sender: TObject);
    procedure BulletBtnClick(Sender: TObject);
    procedure RichEdit1SelectionChange(Sender: TObject);
    procedure ItalicBtnClick(Sender: TObject);
    procedure BoldBtnClick(Sender: TObject);
    procedure UnderlineBtnClick(Sender: TObject);
    procedure RichEdit1KeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
  private
    { Private declarations }
 
  public
    { Public declarations }
    Procedure RefreshButtonsState;
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
Uses RichEdit;
 
(*---------------------------------------------------*)
procedure TForm1.ItalicBtnClick(Sender: TObject);
begin
  if fsItalic in RichEdit1.SelAttributes.Style then begin
    RichEdit1.SelAttributes.Style := RichEdit1.SelAttributes.Style - [fsItalic];
    ItalicBtn.Down := False;
  end else begin
    RichEdit1.SelAttributes.Style := RichEdit1.SelAttributes.Style + [fsItalic];
    ItalicBtn.Down := True;
  end;
end;
(*---------------------------------------------------*)
Procedure SetRichEditNumbering(ARichEdit : TRichEdit; NumberingFormat : TNumberingFormat);
var aParaformat : TParaFormat2;
begin
  Fillchar(aParaformat, SizeOf(aParaformat), 0);
  aParaformat.cbSize := SizeOf(aParaformat);
  aParaformat.dwMask := PFM_NUMBERING or PFM_TABSTOPS or PFM_NUMBERINGSTYLE 
or PFM_NUMBERINGSTART;  // NEW
  aParaformat.wNumbering := Integer(NumberingFormat);
  aParaformat.wNumberingStyle := $200;
  aParaformat.wNumberingStart := 1; // NEW
  if NumberingFormat <> nfNone then
    aParaformat.cTabCount := 1;
  SendMessage(ARichEdit.Handle, EM_SETPARAFORMAT, 0, Integer(Addr(aParaformat)));
end;
(*---------------------------------------------------*)
Function GetRichEditNumbering(ARichEdit : TRichedit) : TNumberingFormat;
var aParaformat : TParaFormat2;
begin
  Fillchar(aParaformat, SizeOf(aParaformat), 0);
  aParaformat.cbSize := SizeOf(aParaformat);
  SendMessage(ARichEdit.Handle, EM_GETPARAFORMAT, 0, Integer(Addr(aParaformat)));
  Result := TNumberingFormat(aParaformat.wNumbering);
end;
(*---------------------------------------------------*)
Procedure SetRichEditBullets(ARichEdit : TRichEdit; Active : Boolean);
var aParaformat : TParaFormat2;
begin
  Fillchar(aParaformat, SizeOf(aParaformat), 0);
  aParaformat.cbSize := SizeOf(aParaformat);
  aParaformat.dwMask := PFM_NUMBERING or PFM_TABSTOPS;
  if Active then begin
    aParaformat.wNumbering := PFN_BULLET;
    aParaformat.cTabCount := 1;
  end;
  SendMessage(ARichEdit.Handle, EM_SETPARAFORMAT, 0, Integer(Addr(aParaformat)));
end;
(*---------------------------------------------------*)
Function GetRichEditBullets(ARichEdit : TRichedit) : Boolean;
var aParaformat : TParaFormat2;
begin
  Fillchar(aParaformat, SizeOf(aParaformat), 0);
  aParaformat.cbSize := SizeOf(aParaformat);
  SendMessage(ARichEdit.Handle, EM_GETPARAFORMAT, 0, Integer(Addr(aParaformat)));
  Result := (aParaformat.wNumbering and PFN_BULLET) <> 0;
end;
(*---------------------------------------------------*)
procedure TForm1.NumberBtnClick(Sender: TObject);
begin
  if GetRichEditNumbering(RichEdit1) = nfNumbers
    then SetRichEditNumbering(RichEdit1, nfNone)
    else SetRichEditNumbering(RichEdit1, nfNumbers);
  RefreshButtonsState;
end;
(*---------------------------------------------------*)
procedure TForm1.RefreshButtonsState;
begin
  BoldBtn.Down := (fsBold in RichEdit1.SelAttributes.Style);
  ItalicBtn.Down := (fsItalic in RichEdit1.SelAttributes.Style);
  UnderlineBtn.Down := (fsUnderline in RichEdit1.SelAttributes.Style);
  BulletBtn.Down := (GetRichEditNumbering(RichEdit1) = nfBullets);
  NumberBtn.Down := (GetRichEditNumbering(RichEdit1) = nfNumbers);
end;
(*---------------------------------------------------*)
procedure TForm1.RichEdit1SelectionChange(Sender: TObject);
begin
  RefreshButtonsState;
end;
(*---------------------------------------------------*)
procedure TForm1.UnderlineBtnClick(Sender: TObject);
begin
  if fsUnderline in RichEdit1.SelAttributes.Style then begin
    RichEdit1.SelAttributes.Style := RichEdit1.SelAttributes.Style - [fsUnderline];
    UnderlineBtn.Down := False;
  end else begin
    RichEdit1.SelAttributes.Style := RichEdit1.SelAttributes.Style + [fsUnderline];
    UnderlineBtn.Down := True;
  end;
end;
(*---------------------------------------------------*)
procedure TForm1.BoldBtnClick(Sender: TObject);
begin
  if fsBold in RichEdit1.SelAttributes.Style then begin
    RichEdit1.SelAttributes.Style := RichEdit1.SelAttributes.Style - [fsBold];
    BoldBtn.Down := False;
  end else begin
    RichEdit1.SelAttributes.Style := RichEdit1.SelAttributes.Style + [fsBold];
    BoldBtn.Down := True;
  end;
end;
(*---------------------------------------------------*)
procedure TForm1.BulletBtnClick(Sender: TObject);
begin
  if GetRichEditNumbering(RichEdit1) = nfBullets
    then SetRichEditNumbering(RichEdit1, nfNone)
    else SetRichEditNumbering(RichEdit1, nfBullets);
  RefreshButtonsState;
end;
(*---------------------------------------------------*)
end.

Open in new window

Pictrure1.jpg
Picture2.jpg
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Emmanuel PASQUIERFreelance Project Manager
Top Expert 2010

Commented:
You should check this, I might be wring but it seems that :
in picture1, all the TestTest... are in a same line without return
in picture2, there is a return at the en of first line (difficult to say because you cut the image)

also, the bullet is a paragraph parameter, so you should be sure that all your text belongs to the same paragraph.
Peter KiersOperator

Author

Commented:
The first picture is how I want it. The second picture is how I have it.

P.
Emmanuel PASQUIERFreelance Project Manager
Top Expert 2010

Commented:
Yes, I got this. Can you try with a little less Test so that we can actually see where line returns are ?
JavaScript Best Practices

Save hours in development time and avoid common mistakes by learning the best practices to use for JavaScript.

Peter KiersOperator

Author

Commented:
working on it
Peter KiersOperator

Author

Commented:
I don't exactly know what to leave out. But I shorten it.
Peter.
Uses RichEdit;
 
 
Procedure SetRichEditNumbering(ARichEdit : TRichEdit; NumberingFormat : TNumberingFormat);
var aParaformat : TParaFormat2;
begin
  Fillchar(aParaformat, SizeOf(aParaformat), 0);
  aParaformat.cbSize := SizeOf(aParaformat);
  aParaformat.dwMask := PFM_NUMBERING or PFM_TABSTOPS or PFM_NUMBERINGSTYLE 
or PFM_NUMBERINGSTART;  // NEW
  aParaformat.wNumbering := Integer(NumberingFormat);
  aParaformat.wNumberingStyle := $200;
  aParaformat.wNumberingStart := 1; // NEW
  if NumberingFormat <> nfNone then
    aParaformat.cTabCount := 1;
  SendMessage(ARichEdit.Handle, EM_SETPARAFORMAT, 0, Integer(Addr(aParaformat)));
end;
(*---------------------------------------------------*)
Function GetRichEditNumbering(ARichEdit : TRichedit) : TNumberingFormat;
var aParaformat : TParaFormat2;
begin
  Fillchar(aParaformat, SizeOf(aParaformat), 0);
  aParaformat.cbSize := SizeOf(aParaformat);
  SendMessage(ARichEdit.Handle, EM_GETPARAFORMAT, 0, Integer(Addr(aParaformat)));
  Result := TNumberingFormat(aParaformat.wNumbering);
end;
(*---------------------------------------------------*)
Procedure SetRichEditBullets(ARichEdit : TRichEdit; Active : Boolean);
var aParaformat : TParaFormat2;
begin
  Fillchar(aParaformat, SizeOf(aParaformat), 0);
  aParaformat.cbSize := SizeOf(aParaformat);
  aParaformat.dwMask := PFM_NUMBERING or PFM_TABSTOPS;
  if Active then begin
    aParaformat.wNumbering := PFN_BULLET;
    aParaformat.cTabCount := 1;
  end;
  SendMessage(ARichEdit.Handle, EM_SETPARAFORMAT, 0, Integer(Addr(aParaformat)));
end;
(*---------------------------------------------------*)
Function GetRichEditBullets(ARichEdit : TRichedit) : Boolean;
var aParaformat : TParaFormat2;
begin
  Fillchar(aParaformat, SizeOf(aParaformat), 0);
  aParaformat.cbSize := SizeOf(aParaformat);
  SendMessage(ARichEdit.Handle, EM_GETPARAFORMAT, 0, Integer(Addr(aParaformat)));
  Result := (aParaformat.wNumbering and PFN_BULLET) <> 0;
end;
(*---------------------------------------------------*)
procedure TForm1.NumberBtnClick(Sender: TObject);
begin
  if GetRichEditNumbering(RichEdit1) = nfNumbers
    then SetRichEditNumbering(RichEdit1, nfNone)
    else SetRichEditNumbering(RichEdit1, nfNumbers);
  RefreshButtonsState;
end;
(*---------------------------------------------------*)
procedure TForm1.RefreshButtonsState;
begin
//  BoldBtn.Down := (fsBold in RichEdit1.SelAttributes.Style);
//  ItalicBtn.Down := (fsItalic in RichEdit1.SelAttributes.Style);
//  UnderlineBtn.Down := (fsUnderline in RichEdit1.SelAttributes.Style);
  BulletBtn.Down := (GetRichEditNumbering(RichEdit1) = nfBullets);
  NumberBtn.Down := (GetRichEditNumbering(RichEdit1) = nfNumbers);
end;
(*---------------------------------------------------*)
procedure TForm1.RichEdit1SelectionChange(Sender: TObject);
begin
  RefreshButtonsState;
end;
(*---------------------------------------------------*)
procedure TForm1.BulletBtnClick(Sender: TObject);
begin
  if GetRichEditNumbering(RichEdit1) = nfBullets
    then SetRichEditNumbering(RichEdit1, nfNone)
    else SetRichEditNumbering(RichEdit1, nfBullets);
  RefreshButtonsState;
end;
(*---------------------------------------------------*)
end.

Open in new window

Emmanuel PASQUIERFreelance Project Manager
Top Expert 2010

Commented:
erh... that is not the source code I would have liked shorten, it's the TestTestTest... lines in the edit of both applications captured image
Peter KiersOperator

Author

Commented:
Is this better.

P.
Voorbeeld1.jpg
Voorbeeld2.jpg
Emmanuel PASQUIERFreelance Project Manager
Top Expert 2010

Commented:
Yes. This eliminates the ret line possible factor
It seems that an offset is defined for the paragraph in the 2nd app. Even in the first line the space between the bullet and text is not the same.
There is most certainly another parameter that could be used in the EM_SETPARAFORMAT
Emmanuel PASQUIERFreelance Project Manager
Top Expert 2010

Commented:
Use this I think :

dxOffset
    Indentation of the second and subsequent lines, relative to the indentation of the first line, in twips. The first line is indented if this member is negative or outdented if this member is positive. To use this member, set the PFM_OFFSET flag in the dwMask member

For all your next problems about RichEdit (not that we don't like points), refer to MSDN
http://msdn.microsoft.com/en-us/library/bb787942%28VS.85%29.aspx
Peter KiersOperator

Author

Commented:
More help needed I can't do this on my own.

Peter
Freelance Project Manager
Top Expert 2010
Commented:
in Procedure SetRichEditBullets(ARichEdit : TRichEdit; Active : Boolean);

aParaformat.dwMask := PFM_NUMBERING or PFM_TABSTOPS or PFM_OFFSET ;
aParaformat.dxOffset := 0; // I believe this should be what you want : alignment with the first line text

dxOffset is expressed in Twips, which is such a funny measure that I'll let you see for yourself in wikipedia if you are interested : http://en.wikipedia.org/wiki/Twip
Try with values like +/-100 to see what you get
Peter KiersOperator

Author

Commented:
thanks for the info.

Peter Kiers

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial