* * *

Author Topic: Need some Help for RightToLeft TWinControls  (Read 6149 times)

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Need some Help for RightToLeft TWinControls
« on: June 16, 2012, 05:35:32 pm »
For now at least, this is ONLY for Windows.  Hopefully we can find a way to do this in other OS's, or better still, actually fix the Controls for BiDiMode.  But this is a start in that direction.

I have been experimenting trying to find a way to improve Lazarus support for RightToLeft Languages/Controls.  I have found some interesting things, but of course, there are some very big problems and I am hoping to get some feedback from other 'RightToLeft' programmers.

I can now 'Flip' any TWinControl and with some of them, they seem to work perfectly, others 'sort of' work, and other just don't work at all.

For ANY of this to work, you MUST TURN OFF THEMES!!!  Go to 'Project Options' and there is a checkbox to turn Themes OFF.  Otherwise TWinControl.Canvas becomes totally unusable if you use the method that I have found.  Hopefully this will soon be resolved.  It is already in BugTracker for quite awhile.

The main 'workhorse' is:

Add Windows to the uses statement.

procedure RTLCtrl(ACtrl: TObject);
{ Make TWinControl RightToLeft - Windows ONLY! }
begin
  if ACtrl is TWinControl then
    with ACtrl as TWinControl do begin
      if TWinControl(ACtrl).IsRightToLeft then
        TWinControl(ACtrl).BiDiMode:= bdLeftToRight;  // See Note 1.
      SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE)
        or WS_EX_LEFT
        or WS_EX_RTLREADING
        //or WS_EX_LEFTSCROLLBAR  //See Note 2.
        or WS_EX_LAYOUTRTL
        or WS_EX_NOINHERITLAYOUT);
  end;
end;

I use the TForm.OnShow method to 'Flip' everything.  This is an example:

procedure TForm1.FormShow(Sender: TObject);
begin
  RTLCtrl(Form1);
  RTLCtrl(PageControl1);
  RTLCtrl(TreeView1);
  RTLCtrl(Calendar1);
  RTLCtrl(ShellTreeView1);
  RTLCtrl(HeaderControl1);
  RTLCtrl(ToggleBox1);
  RTLCtrl(StaticText1);
  RTLCtrl(CheckListBox1);
  RTLCtrl(ScrollBox1);
end;


Note 1.  This line looks totally wrong, but without it Controls with vertical Scrollbars stay Right aligned.  I have not figured out a way to solve this yet.

Note 2.  According to MS, this should move vertical ScrollBars to the Left, but I guess they get 'flipped' twice and end up on the Right.
« Last Edit: June 16, 2012, 06:45:40 pm by Avishai »
Lazarus Trunk / fpc 2.6.2 / Win32

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Need some Help for RightToLeft TWinControls
« Reply #1 on: June 16, 2012, 05:58:08 pm »
I added a screen shot of some of my test.  As you can see, some of the things I tested were controls that already have good BiDi support.  I do NOT recommend using the 'Flipping' method for controls that already have BiDi support.  I was only curious :)
Lazarus Trunk / fpc 2.6.2 / Win32

Zaher

  • Hero Member
  • *****
  • Posts: 542
    • parmaja.com
Re: Need some Help for RightToLeft TWinControls
« Reply #2 on: June 16, 2012, 08:59:01 pm »
Hi Avishai

1 - it is called Mirror the controls, in fact i dislike it, because it is mirror the canvas and images inside the control, but we need it because  for some control not supprt RightToLeft in Windows

2 - It is in Windows wedgetset other platforms has its problems like GTK2 or QT, we can add mirror in the Windows Wedgetset without effect other Wedgetsets

Usually TreeView, PageControl, Calender need this mirror, so if you like i can add a mirror to it in the Windows Wedgetset, and you can test the patches.

Best Regard.

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Need some Help for RightToLeft TWinControls
« Reply #3 on: June 16, 2012, 09:16:00 pm »
Hi Zaher,

I think you should judge if it is ready for the Windows Widgetset.  You have been with Lazarus much longer than I have.  I will be happy to help test.  There is an advantage to mirroring the Canvas.  You do not need to reset the anchors to the right plus you can say Component.Left:= 10 and it will be 10 from the Right Side.  But I am with you, I dislike it too.  I just don't have a better answer and if it can get some more RightToLeft Controls for now, then I think we need it.  Someday maybe all controls will support RightToLeft (I hope).
Lazarus Trunk / fpc 2.6.2 / Win32

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Need some Help for RightToLeft TWinControls
« Reply #4 on: June 16, 2012, 09:26:41 pm »
This code puts it back to LeftToRight:

procedure LTRCtrl(ACtrl: TObject);
{ Make TWinControl LeftToRight - Windows ONLY! }
begin
  if ACtrl is TWinControl then
    with ACtrl as TWinControl do begin
      if TWinControl(ACtrl).IsRightToLeft then
        TWinControl(ACtrl).BiDiMode:= bdLeftToRight;
      SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE)
        and WS_EX_LEFT
        and WS_EX_RTLREADING
        //and WS_EX_LEFTSCROLLBAR
        and WS_EX_LAYOUTRTL
        and WS_EX_NOINHERITLAYOUT);
  end;
end;
Lazarus Trunk / fpc 2.6.2 / Win32

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Need some Help for RightToLeft TWinControls
« Reply #5 on: June 18, 2012, 02:56:17 pm »
I modified the code a bit.  Some things work better if you set BiDiMode:= bdRightToLeft and others work better if it is bdLeftToRight.


procedure TForm1.RTLCtrl(ACtrl: TObject; RTL: Boolean);
{ Make TWinControl RightToLeft - Windows ONLY! }
begin
  if ACtrl is TWinControl then
    with ACtrl as TWinControl do begin
      SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE)
        or WS_EX_LEFT or WS_EX_RTLREADING {or WS_EX_LEFTSCROLLBAR}
        or WS_EX_LAYOUTRTL or WS_EX_NOINHERITLAYOUT);
      if not RTL then
        BiDiMode:= bdLeftToRight
      else
        BiDiMode:= bdRightToLeft;
  end;
end;
Lazarus Trunk / fpc 2.6.2 / Win32

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Need some Help for RightToLeft TWinControls
« Reply #6 on: June 30, 2012, 05:19:28 pm »
RightToLeft programmers might find this useful.

{===== SetRight - Set TControl to the Right & Anchor Right =====}

procedure SetRight(Sender: TObject; Right: Integer);
begin
  if (Sender is TControl) then begin
    with TControl(Sender) Do begin
      Try
        Left:= Parent.Width-Width-Right;
        Anchors:= [akTop,akRight];
      finally

      end;
    end;
  end;
end;
Lazarus Trunk / fpc 2.6.2 / Win32

Zaher

  • Hero Member
  • *****
  • Posts: 542
    • parmaja.com
Re: Need some Help for RightToLeft TWinControls
« Reply #7 on: June 30, 2012, 07:23:29 pm »
Hi, Avishai
You not need this function SetRight
You can use FlipChildren look at
procedure TWinControl.DoFlipChildren;
it is already flip the anchors and positions.

For other functions above, i am not busy this days, but we have no minds to work on any things, search about Syria.

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Need some Help for RightToLeft TWinControls
« Reply #8 on: June 30, 2012, 08:00:23 pm »
Zaher,

I understand about Syria.  It makes me very sad.  so much trouble :(

I know about FlipChildren, but I like to design Right.  I don't like to design Left and then FlipChildren.  But thank you for your comment :)

I put controls 'about' where I want them and then use 'SetRight' to make it precise.

As always, it's good to hear from you.  Please stay safe.
Lazarus Trunk / fpc 2.6.2 / Win32

Zaher

  • Hero Member
  • *****
  • Posts: 542
    • parmaja.com
Re: Need some Help for RightToLeft TWinControls
« Reply #9 on: June 30, 2012, 08:35:59 pm »
I design also in Right, in Delphi and Lazarus, then using FlipControl when choosing English Language.

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Need some Help for RightToLeft TWinControls
« Reply #10 on: June 30, 2012, 08:37:19 pm »
Oh. I see.  I will have to try that.
Lazarus Trunk / fpc 2.6.2 / Win32

majid.ebru

  • Sr. Member
  • ****
  • Posts: 267
Re: Need some Help for RightToLeft TWinControls
« Reply #11 on: June 18, 2017, 03:50:56 pm »
For now at least, this is ONLY for Windows.  Hopefully we can find a way to do this in other OS's, or better still, actually fix the Controls for BiDiMode.  But this is a start in that direction.

I have been experimenting trying to find a way to improve Lazarus support for RightToLeft Languages/Controls.  I have found some interesting things, but of course, there are some very big problems and I am hoping to get some feedback from other 'RightToLeft' programmers.

I can now 'Flip' any TWinControl and with some of them, they seem to work perfectly, others 'sort of' work, and other just don't work at all.

For ANY of this to work, you MUST TURN OFF THEMES!!!  Go to 'Project Options' and there is a checkbox to turn Themes OFF.  Otherwise TWinControl.Canvas becomes totally unusable if you use the method that I have found.  Hopefully this will soon be resolved.  It is already in BugTracker for quite awhile.

The main 'workhorse' is:

Add Windows to the uses statement.

procedure RTLCtrl(ACtrl: TObject);
{ Make TWinControl RightToLeft - Windows ONLY! }
begin
  if ACtrl is TWinControl then
    with ACtrl as TWinControl do begin
      if TWinControl(ACtrl).IsRightToLeft then
        TWinControl(ACtrl).BiDiMode:= bdLeftToRight;  // See Note 1.
      SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE)
        or WS_EX_LEFT
        or WS_EX_RTLREADING
        //or WS_EX_LEFTSCROLLBAR  //See Note 2.
        or WS_EX_LAYOUTRTL
        or WS_EX_NOINHERITLAYOUT);
  end;
end;

I use the TForm.OnShow method to 'Flip' everything.  This is an example:

procedure TForm1.FormShow(Sender: TObject);
begin
  RTLCtrl(Form1);
  RTLCtrl(PageControl1);
  RTLCtrl(TreeView1);
  RTLCtrl(Calendar1);
  RTLCtrl(ShellTreeView1);
  RTLCtrl(HeaderControl1);
  RTLCtrl(ToggleBox1);
  RTLCtrl(StaticText1);
  RTLCtrl(CheckListBox1);
  RTLCtrl(ScrollBox1);
end;


Note 1.  This line looks totally wrong, but without it Controls with vertical Scrollbars stay Right aligned.  I have not figured out a way to solve this yet.

Note 2.  According to MS, this should move vertical ScrollBars to the Left, but I guess they get 'flipped' twice and end up on the Right.

Hi and sorry
.
i use this code and work corerctly.
.
thank you

majid.ebru

  • Sr. Member
  • ****
  • Posts: 267
Re: Need some Help for RightToLeft TWinControls
« Reply #12 on: June 19, 2017, 11:43:36 pm »
Hi
.
Why????
.
i use this code for treeview.
.
at first time evrey thing ok but when compile it in an other PC , text of treeview flip horizontal
.
why my text flip horizontal ?

« Last Edit: June 19, 2017, 11:46:30 pm by majid.ebru »

Zaher

  • Hero Member
  • *****
  • Posts: 542
    • parmaja.com
Re: Need some Help for RightToLeft TWinControls
« Reply #13 on: June 20, 2017, 01:28:28 am »
Windows Version?

majid.ebru

  • Sr. Member
  • ****
  • Posts: 267
Re: Need some Help for RightToLeft TWinControls
« Reply #14 on: June 20, 2017, 03:29:04 am »
PC 1:
windows xp

PC 2:
Windows 7

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus