Right click(popup menu) does not work when change diretion of treeview with SetWindowLong Command

1.3k Views Asked by At

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;
2

There are 2 best solutions below

4
On

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.

0
On

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 !