Delphi の TToolBar 上でPopupMenuの表示位置下にあるコントロールを取得

 Delphi の TToolBar 上でPopupMenuの表示位置下にあるコントロールを取得
今回は TToolBar 上に TToolButton.Style を tbsButton と tbsSeparator で配置したもの

TToolBar には、指定位置のコントロールを取得する ScreenToClient があるのだが、tbsSeparator のコントロール上で取得しても nil しか返ってこない
  1. procedure TForm1.PopupMenuItem1Click(Sender: TObject);  
  2. var  
  3.     Point: TPoint;  
  4.     Ctrl: TControl;  
  5. begin  
  6.     if (Sender is TMenuItem) then begin  
  7.         Point := ToolBar1.ScreenToClient(TPopupMenu(TMenuItem(Sender).GetParentMenu).PopupPoint);  
  8.           
  9.         Ctrl := ToolBar1.ControlAtPos(Point, True);  
  10.         // ToolButton.Style が tbsSeparator のコントロールは Ctrl = nil が返る  
  11.     end;  
  12. end;  
そのため Toolbar 上のコントロールを探して一致するものを取得(例は横軸しか判定してません)
  1. procedure TForm1.PopupMenuItem1Click(Sender: TObject);  
  2. var  
  3.     Point: TPoint;  
  4.     Ctrl: TControl;  
  5.     I: Integer;  
  6. begin  
  7.     if (Sender is TMenuItem) then begin  
  8.         Point := ToolBar1.ScreenToClient(TPopupMenu(TMenuItem(Sender).GetParentMenu).PopupPoint);  
  9.   
  10.         for I := ToolBar1.ControlCount - 1 downto 0 do begin  
  11.             Ctrl := ToolBar1.Controls[I];  
  12.             if (Point.X > Ctrl.Left) and (Point.X < Ctrl.Left + Ctrl.Width) then begin  
  13.                 // 該当  
  14.                 Break;  
  15.             end;  
  16.         end;  
  17.   
  18.     end;  
  19. end;  
画面右端で PopupMenu を表示させた場合、右クリック位置とは違う場所にメニューが表示されるが、PopupPoint は最初に右クリックした位置が入っているようす

Controls に入っている順番は、Left等からの昇順ではなく ToolBar へ登録された順番となるため、ToolButton 等を動的に作成する時に Tag へ index 等を保存しておくとよいかも

コメント