3

When I use SetWindowLong command to change direction of treeview, popupmenu on its node dose not show. Full Code is here :

Procedure SetWinControlBiDi(Control: TTreeView);
 var
  ExStyle: Longint;
 begin

  ExStyle := GetWindowLong(Control.Handle, GWL_EXSTYLE);

  SetWindowLong(Control.Handle, GWL_EXSTYLE, ExStyle or WS_EX_RTLREADING or WS_EX_RIGHT or WS_EX_LAYOUTRTL or WS_EX_NOINHERITLAYOUT );

 end;


procedure TMainForm.FormShow(Sender: TObject);
 begin

  SetWinControlBiDi(TreeView1);

 end;
j0k
  • 22,600
  • 28
  • 79
  • 90
Ilbeigy
  • 31
  • 2

2 Answers2

3

The standard way to do this is to use the Delphi BiDiMode property. It's best to do it this way so that the VCL is aware that you want right-to-left. You need to change the BiDiMode property on the popup menu too.

Now, the correct way to do this is not to change the properties on the individual components. Doing it that way is laborious and very error prone. Set Application.BiDiMode somewhere in your application's initialization and the change will propagate through to all your components.

For example you can make the change in your application's .dpr file:

Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.BiDiMode := bdRightToLeft;
Application.CreateForm(TMainForm, MainForm);
Application.Run;

You need to make sure that you have not modified any component's BiDiMode or ParentBiDiMode in any .dfm file. If you have simply remove those lines from your .dfm file and that will allow the single application wide Application.BiDiMode setting to control everything.


Your approach of setting GWL_EXSTYLE is problematic. The VCL is in control of that setting and if you do need to change it, doing so in TForm.OnShow will lead to strange bugs. Sometimes windows need to be re-created and when this happens your code to set GWL_EXSTYLE will not run and your tree view will revert to left-to-right. If you do need to modify the window styles then you need to override TWinControl.CreateParams for the component. However, in this case the VCL has direct support for BiDi and that is the best solution.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Special thanks for your reply and you are rights, but this code Application.BiDiMode := bdRightToLeft does not work for some dbtreeview component of third party. Can you show me a proper way to slove popup problem in my approach? – Ilbeigy Jun 24 '11 at 14:50
  • If the popup menu is owned by your app then `Application.BiDiMode` is the solution. If the popup menu is not a VCL component and is created and owned by the 3rd party code then I don't know. You didn't say anything about 3rd party code in your question. You still haven't said what the component is. I can't guess what it is!! I suggest you contact the component vendor. – David Heffernan Jun 24 '11 at 14:53
  • Dear David, my component is TdxDBTreeView from DevExpress Corp. and they formally said their components do not support rtl, so i should use SetWindowLong command to change its direction(Application.BiDiMode has no effect) and in this case popup menu does not popup. – Ilbeigy Jun 24 '11 at 15:46
  • If their components don't support rtl then I don't understand why changing the window style would help. Did devExpress suggest that you change the Window style? If so that sounds odd. Anyway, the place where you should do that, if that is indeed the thing to do, and I don't believe it, is in TdxDBTreeView.CreateParams. Note that you don't call SetWindowLong from there, you just modify Params.ExStyle. Anyway, I think you should be getting support from devExpress to resolve this. Perhaps you need a better vendor that's less LTR-centric. – David Heffernan Jun 24 '11 at 15:52
0

This is an alternative solution to show TPopupMenu In this case

1- Use OnMouseDown Event

2- Write this code to show a TPopupMenu when you click the right mouse button

 var
  pt : TPoint;

  begin
  pt := Mouse.CursorPos;

   if Button = mbRight then
        APopupMenu.Popup(pt.X, pt.Y);

Good luck !

Hadji.A
  • 1
  • 3