Lazarus

Programming => General => Topic started by: Avishai on June 16, 2012, 05:35:32 pm

Title: Need some Help for RightToLeft TWinControls
Post by: Avishai 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.
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Avishai 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 :)
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Zaher 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.
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Avishai 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).
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Avishai 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;
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Avishai 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;
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Avishai 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;
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Zaher 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.
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Avishai 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.
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Zaher on June 30, 2012, 08:35:59 pm
I design also in Right, in Delphi and Lazarus, then using FlipControl when choosing English Language.
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Avishai on June 30, 2012, 08:37:19 pm
Oh. I see.  I will have to try that.
Title: Re: Need some Help for RightToLeft TWinControls
Post by: majid.ebru 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
Title: Re: Need some Help for RightToLeft TWinControls
Post by: majid.ebru 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 ?

Title: Re: Need some Help for RightToLeft TWinControls
Post by: Zaher on June 20, 2017, 01:28:28 am
Windows Version?
Title: Re: Need some Help for RightToLeft TWinControls
Post by: majid.ebru on June 20, 2017, 03:29:04 am
PC 1:
windows xp

PC 2:
Windows 7
Title: Re: Need some Help for RightToLeft TWinControls
Post by: majid.ebru on June 21, 2017, 09:45:24 pm
have any idea?!
 :'( :'(
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Zaher on June 22, 2017, 11:44:35 pm
I tested it in Windows 8.1 same problem, For that I don't trust with Mirroring for RTL since win98 and above, now i am right for not trusting.

You need a native TreeView component and ask developers to add RTL support.
Title: Re: Need some Help for RightToLeft TWinControls
Post by: majid.ebru on June 23, 2017, 01:33:38 am
Thank you
Title: Re: Need some Help for RightToLeft TWinControls
Post by: majid.ebru on July 07, 2017, 02:22:49 pm
Hi again

i use windows 7-64x.
.
i install VirtualBox (https://www.virtualbox.org/) then i install lazarus.
.
(1)then run my project -> but doesn't work and doesn't show True treeview.
.
i go to start -> control panel -> regional -> language(2sec tabs) -> and tick "install file for complex script  and right to left ...."
.
(2)then run my project -> but doesn't work and doesn't show True treeview.
.
then i go start -> control panel -> regional -> advanced(3th tabs)-> "code page conversion tables "
.
i this page i tick all "Arabic" and "Hebrew"
.
(3)then run my project ->  it works correctly and show True TreeView !?!?!?!?  :o %) :o %)
.
.
.
wowooooooooo
.
.
.
Now i can't find that setting(code page conversion tables) in windows 7.
.
do you know where it is??
.
.
.
i forgot.
when i compile my program in true view -> then it work correctly in all computer ?
can anyone help me?

thankyou
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Zaher on July 07, 2017, 05:53:50 pm
i dont understand First try was in Windows 7+64?

now "Now i can't find that setting(code page conversion tables) in windows 7."

Title: Re: Need some Help for RightToLeft TWinControls
Post by: majid.ebru on July 07, 2017, 07:47:05 pm
Hi

at first time i try and make project in windows XP and it works (at work place).

then i try it in windows 7-64x and it doesn't work(at home)

then in windows 7-64x i install virtual box and i install windows xp and  i change some setting in regional .

and in this new windows it work correctly .
.
.
.
.
"Now i can't find that setting(code page conversion tables) in windows 7."


i can't find too.

where is it???
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Zaher on July 07, 2017, 07:50:49 pm
But in virtual box u used Windows XP, is it? same problem, our problem started from Windows7
Here in Windows 8.1 i have the same problem
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Zaher on July 07, 2017, 08:09:45 pm
I tested it in Delphi Xe5 it is work fine in my windows 8.1
So the problem is in Lazaurs, now i have a task to check why.
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Zaher on July 07, 2017, 08:52:04 pm
Yes it is a bug in Lazarus, I am working on it, it is related to DoubleBuffered and Themes

\lazarus\lcl\interfaces\win32\win32callback.inc line 599

Code: [Select]
  useDoubleBuffer := (ControlDC = 0) and (lWinControl.DoubleBuffered or ThemeServices.ThemesEnabled);

I need help from Lazarus core developers to understand why it force to be DoubleBuffered if ThemesEnabled is true?
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Zaher on July 07, 2017, 08:54:39 pm
This controls should not be double buffered, or at least do not make internal mirror by using "WindowOrg"
Title: Re: Need some Help for RightToLeft TWinControls
Post by: majid.ebru on July 07, 2017, 10:52:55 pm
But in virtual box u used Windows XP, is it? same problem,

Yes
in virtual Box i use Windows XP and i have NO problem

our problem started from Windows7
Here in Windows 8.1 i have the same problem

Yes
our problem in windows 7 (or higher version)
.
Thank you very much  @Zaher for try to solve this problem
 :-* :-*
Title: Re: Need some Help for RightToLeft TWinControls
Post by: majid.ebru on February 18, 2018, 02:29:11 pm
Yes it is a bug in Lazarus, I am working on it, it is related to DoubleBuffered and Themes

\lazarus\lcl\interfaces\win32\win32callback.inc line 599

Code: [Select]
  useDoubleBuffer := (ControlDC = 0) and (lWinControl.DoubleBuffered or ThemeServices.ThemesEnabled);

I need help from Lazarus core developers to understand why it force to be DoubleBuffered if ThemesEnabled is true?

Hi and so sorry i post again

i upgraded to Lazarus 1.8 and i have problem.

when i use :
Code: Pascal  [Select][+][-]
  1. useDoubleBuffer := False;
  2.  
treeview set Right to Left correctly.

but i have flicker when i click or change object.

how can i change code like this:
Code: Pascal  [Select][+][-]
  1. If ( --->  ?!?! Sender is TTreeView ?!?! "I dont Know what i wirte here "   <----  ) then useDoubleBuffer := False
  2. else useDoubleBuffer := True;
  3.  
  4.  

thank you
Title: Re: Need some Help for RightToLeft TWinControls
Post by: Zaher on February 18, 2018, 03:18:06 pm
It is bug in Lazaurs, Lazaurs maintain the mirroring in complex way that I can't understand it, so i can't fix it by my self.
You can report a bug in Lazaurs bug tracker.
Title: Re: Need some Help for RightToLeft TWinControls
Post by: wp on February 18, 2018, 05:37:28 pm
The doublebuffering machinery for Windows has been reworked a few days ago. Please test Lazarus trunk.
Title: Re: Need some Help for RightToLeft TWinControls
Post by: engkin on February 21, 2018, 07:47:54 pm
As wp had mentioned, fixed in r57267 (https://svn.freepascal.org/cgi-bin/viewvc.cgi?view=revision&root=lazarus&revision=57267). Learned about it from this bug report (https://bugs.freepascal.org/view.php?id=33123).
Title: Re: Need some Help for RightToLeft TWinControls
Post by: majid.ebru on February 22, 2018, 11:01:38 am
r57267 (https://svn.freepascal.org/cgi-bin/viewvc.cgi?view=revision&root=lazarus&revision=57267)

how can i use this r57267 file

i download it and replace to "win32callback.inc" .

but i have error
Title: Re: Need some Help for RightToLeft TWinControls
Post by: wp on February 22, 2018, 11:13:26 am
No. The changes are a several places and probably depend also on other changes made earlier. The only way to use this is to install the developer version of Lazarus ("trunk"). Use fpcupdeluxe for easiest installation.
Title: Re: Need some Help for RightToLeft TWinControls
Post by: engkin on February 23, 2018, 04:36:56 am
r57267 (https://svn.freepascal.org/cgi-bin/viewvc.cgi?view=revision&root=lazarus&revision=57267)

how can i use this r57267 file

i download it and replace to "win32callback.inc" .

but i have error

The proper way is to follow wp's advice and use the trunk. But in this specific case you can try to change your original win32callback.inc code in one specific line from:
Code: Pascal  [Select][+][-]
  1.   useDoubleBuffer := (ControlDC = 0) and (lWinControl.DoubleBuffered or ThemeServices.ThemesEnabled);

to:
Code: Pascal  [Select][+][-]
  1.   useDoubleBuffer := (ControlDC = 0) and lWinControl.DoubleBuffered;

as shown in the diff. of this revision (https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/lcl/interfaces/win32/win32callback.inc?root=lazarus&r1=57267&r2=57266&pathrev=57267)
Title: Re: Need some Help for RightToLeft TWinControls
Post by: majid.ebru on March 04, 2018, 08:41:47 am
Hi

i changed but it doesn't work!!
Title: Re: Need some Help for RightToLeft TWinControls
Post by: engkin on March 04, 2018, 02:21:32 pm
What does not work?
Why not?
Title: Re: Need some Help for RightToLeft TWinControls
Post by: majid.ebru on March 06, 2018, 03:47:50 pm
Hi

i change my original win32callback.inc code to :

Code: Pascal  [Select][+][-]
  1. useDoubleBuffer := (ControlDC = 0) and lWinControl.DoubleBuffered;

but my object(tpagecontrol) doesn't change to RighttoLeft
TinyPortal © 2005-2018