12

ボタンクリック時にポップアップメニューを表示させたいのですが、Delphi XEではこの手順がエラーになります。

procedure ShowPopupMenuEx(var mb1:TMouseButton;var X:integer;var Y:integer;var pPopUP:TPopupMenu);
var
  popupPoint : TPoint;
begin
  if (mb1 = mbLeft) then begin
    popupPoint.X := x ;
    popupPoint.Y := y ;
    popupPoint := ClientToScreen(popupPoint);   //Error Here
    pPopUP.Popup(popupPoint.X, popupPoint.Y) ;   
  end;
end;

procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
begin
  ShowPopupMenuEx(button,Button1.Left,Button1.Top,PopupMenu1); //Error Here
end;

ボタンをクリックすると、このエラーが表示されます:

[DCC エラー] Form1.pas(205): E2010 互換性のない型: 'HWND' および 'TPoint'
[DCC エラー] Form1.pas(398): E2197 定数オブジェクトを var パラメーターとして渡すことはできません
[DCC エラー] Form1.pas( 398): E2197 定数オブジェクトは var パラメータとして渡すことができません

ボタンをクリックしたときに popupmenu を表示するためのより良い方法はありますか?

4

3 に答える 3

32

やるだけ

procedure TForm1.Button1Click(Sender: TObject);
var
  pnt: TPoint;
begin
  if GetCursorPos(pnt) then
    PopupMenu1.Popup(pnt.X, pnt.Y);
end;

もう少し議論

何らかの理由でを使用する必要OnMosuseUpがある場合は、次のことができます

procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  pnt: TPoint;
begin
  if (Button = mbLeft) and GetCursorPos(pnt) then
    PopupMenu1.Popup(pnt.X, pnt.Y);
end;

あなたのコードは機能しません

  1. ClientToScreen署名付きの Windows API の関数です

    function ClientToScreen(hWnd: HWND; var lpPoint: TPoint): BOOL;
    

    でも、TControl.ClientToScreenサイン入りもあります

    function TControl.ClientToScreen(const Point: TPoint): TPoint;
    

    したがって、クラスメソッドにいる場合、クラスは の子孫でありTControlClientToScreen後者を参照します。そうでない場合は、前者を参照します。もちろん、これはどのウィンドウから座標を変換するかを知る必要があります!

  2. また、宣言すると

    var mb1: TMouseButton
    

    パラメータとして、型の変数のみTMouseButtonが受け入れられます。しかし、関数のこの署名が必要な理由がわかりませんShowPopupMenuEx。実際、そのような機能はまったく必要ないと思います...

代替案

上記の私のコードは、カーソルの位置にメニューをポップアップします。ボタンの 1 つのコーナーに対してポイントを固定する必要がある場合は、代わりに次のことができます。

// Popup at the top-left pixel of the button
procedure TForm1.Button1Click(Sender: TObject);
begin
  with Button1.ClientToScreen(point(0, 0)) do
    PopupMenu1.Popup(X, Y);
end;

// Popup at the bottom-right pixel of the button
procedure TForm1.Button1Click(Sender: TObject);
begin
  with Button1.ClientToScreen(point(Button1.Width, Button1.Height)) do
    PopupMenu1.Popup(X, Y);
end;

// Popup at the bottom-left pixel of the button
procedure TForm1.Button1Click(Sender: TObject);
begin
  with Button1.ClientToScreen(point(0, Button1.Height)) do
    PopupMenu1.Popup(X, Y);
end;    
于 2010-10-21T11:45:28.477 に答える
6

Windows.ClientToScreenこのエラーは、コードが関数ではなく関数を TControl.ClientToScreen呼び出しているためです。

このようなことを試してください

procedure TForm6.Button2Click(Sender: TObject);
var
   pt : TPoint;
begin
    pt.x := TButton(Sender).Left + 1;
    pt.y := TButton(Sender).Top + TButton(Sender).Height + 1;
    pt := Self.ClientToScreen( pt );
    PopupMenu1.popup( pt.x, pt.y );
end;

または、クラスShowPopupMenuEx内でプロシージャを宣言すると、機能します。Tform1

于 2010-10-21T11:53:37.693 に答える