弹出式菜单与窗体的关联
弹出式菜单(PopupMenu)是我们经常使用的,很多初学者制作好菜单后都在想如何与相关的窗体关联。在这里我就告诉大家两种方法。
第一种方法非常简单,新建一个窗体,在窗体上放置一个PopupMenu,设置好它的选项;然后在窗体的PopupMenu属性中选择你刚才放置在窗体上的PopupMenu,Delphi自动将窗体和菜单关联;运行程序,在窗体上点击鼠标右键,菜单是不是弹出了?
第二种方法就是纯手工的方法。准备工作和第一种方法一样,只是不把菜单和窗体关联。然后我们想想,当我们做一件什么事情时,菜单才会弹出呢?应该是鼠标右键弹起的时候,所以我们在窗口的OnMouseUp事件中添加控制代码。
在BCB中使用方法是相同的,但是我想不少新手在把上面的Delphi代码转换成C++时会出错,为什么?那你自己写一下就知道了,我给出了两段正确的BCB代码作为参考:
第一段代码:
第二段代码:
看出他们的不同了吗?个中原因留给读者自己分析,不过放心,机制并不复杂,认真想想C++的语法是怎么说的?
细心的读者也许已经发现,过程TForm1.FormMouseUp接受的参数中有这么两个:X, Y: Integer,他们是做什么用的呢?其实他们也是光标的坐标,把x,y放到PopupMenu1.Popup()中,运行,在窗体上按下鼠标右键,我们发现菜单弹出的位置并不在光标所在的位置;我们把PopupMenu1.Popup()函数中的参数更改为x+Form1.Left,y+Form1.Top,再次运行,菜单的位置是不是被校正了,可惜还有点小小的误差,这是由于窗口的标题栏的那段坐标没有被算入造成的,你可以手工加上这个误差。
在这里我们谈两个概念:相对坐标和绝对坐标。绝对坐标是相对整个屏幕来说的,屏幕的左上角为(0,0)右下角为屏幕分辨率的最大值,我们通过GetCursorPos()函数获得的是绝对坐标,所以无论窗体的位置如何,菜单中能在正确的位置显示。相对坐标则是针对当前活动窗口来说的,它以窗口的左上角为(0,0)起始坐标(不包括窗口标题栏),窗体的右下角为终止坐标,坐标值为(Form.Width,Form.Height);x,y正是这样的相对坐标,于是上面的问题就彻底分析清楚了。如果你还不是很明白,我将给你一个示例。
新建一个窗体,放置两个Label,将Label拉长一点,把AutoSize设置为false,在窗体的OnMouseMove事件中添加如下代码:
运行程序,在窗体上移动鼠标,你看到了什么?把鼠标放到窗体的左上角(标题栏的左下角),什么都明白了吧!
第一种方法非常简单,新建一个窗体,在窗体上放置一个PopupMenu,设置好它的选项;然后在窗体的PopupMenu属性中选择你刚才放置在窗体上的PopupMenu,Delphi自动将窗体和菜单关联;运行程序,在窗体上点击鼠标右键,菜单是不是弹出了?
第二种方法就是纯手工的方法。准备工作和第一种方法一样,只是不把菜单和窗体关联。然后我们想想,当我们做一件什么事情时,菜单才会弹出呢?应该是鼠标右键弹起的时候,所以我们在窗口的OnMouseUp事件中添加控制代码。
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
MousePos: TPoint;//声明一个TPoint类型的变量,存放光标在屏幕上的坐标
begin
if(Button=mbRight) then//判断按下的是鼠标左键还是右键
begin
GetCursorPos(MousePos);//获得光标的坐标
PopupMenu1.Popup(MousePos.X,MousePos.Y);//弹出菜单,括号中的参数指定菜单弹出的位置
end;
end;
Shift: TShiftState; X, Y: Integer);
var
MousePos: TPoint;//声明一个TPoint类型的变量,存放光标在屏幕上的坐标
begin
if(Button=mbRight) then//判断按下的是鼠标左键还是右键
begin
GetCursorPos(MousePos);//获得光标的坐标
PopupMenu1.Popup(MousePos.X,MousePos.Y);//弹出菜单,括号中的参数指定菜单弹出的位置
end;
end;
在BCB中使用方法是相同的,但是我想不少新手在把上面的Delphi代码转换成C++时会出错,为什么?那你自己写一下就知道了,我给出了两段正确的BCB代码作为参考:
第一段代码:
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
TPoint *MousePos=new TPoint();
if(Button==mbRight)
{
GetCursorPos(MousePos);
PopupMenu1->Popup(MousePos->x,MousePos->y);
}
}
TShiftState Shift, int X, int Y)
{
TPoint *MousePos=new TPoint();
if(Button==mbRight)
{
GetCursorPos(MousePos);
PopupMenu1->Popup(MousePos->x,MousePos->y);
}
}
第二段代码:
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
TPoint MousePos;
if(Button==mbRight)
{
GetCursorPos(&MousePos);
PopupMenu1->Popup(MousePos->x,MousePos->y);
}
}
TShiftState Shift, int X, int Y)
{
TPoint MousePos;
if(Button==mbRight)
{
GetCursorPos(&MousePos);
PopupMenu1->Popup(MousePos->x,MousePos->y);
}
}
看出他们的不同了吗?个中原因留给读者自己分析,不过放心,机制并不复杂,认真想想C++的语法是怎么说的?
细心的读者也许已经发现,过程TForm1.FormMouseUp接受的参数中有这么两个:X, Y: Integer,他们是做什么用的呢?其实他们也是光标的坐标,把x,y放到PopupMenu1.Popup()中,运行,在窗体上按下鼠标右键,我们发现菜单弹出的位置并不在光标所在的位置;我们把PopupMenu1.Popup()函数中的参数更改为x+Form1.Left,y+Form1.Top,再次运行,菜单的位置是不是被校正了,可惜还有点小小的误差,这是由于窗口的标题栏的那段坐标没有被算入造成的,你可以手工加上这个误差。
在这里我们谈两个概念:相对坐标和绝对坐标。绝对坐标是相对整个屏幕来说的,屏幕的左上角为(0,0)右下角为屏幕分辨率的最大值,我们通过GetCursorPos()函数获得的是绝对坐标,所以无论窗体的位置如何,菜单中能在正确的位置显示。相对坐标则是针对当前活动窗口来说的,它以窗口的左上角为(0,0)起始坐标(不包括窗口标题栏),窗体的右下角为终止坐标,坐标值为(Form.Width,Form.Height);x,y正是这样的相对坐标,于是上面的问题就彻底分析清楚了。如果你还不是很明白,我将给你一个示例。
新建一个窗体,放置两个Label,将Label拉长一点,把AutoSize设置为false,在窗体的OnMouseMove事件中添加如下代码:
rocedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
MousePos: TPoint;
begin
Label1.Caption:='相对坐标'+IntToStr(x)+','+IntToStr(y);
GetCursorPos(MousePos);
Label2.Caption:='绝对坐标'+IntToStr(MousePos.X)+','+IntToStr(MousePos.Y);
end;
Y: Integer);
var
MousePos: TPoint;
begin
Label1.Caption:='相对坐标'+IntToStr(x)+','+IntToStr(y);
GetCursorPos(MousePos);
Label2.Caption:='绝对坐标'+IntToStr(MousePos.X)+','+IntToStr(MousePos.Y);
end;
运行程序,在窗体上移动鼠标,你看到了什么?把鼠标放到窗体的左上角(标题栏的左下角),什么都明白了吧!

浙公网安备 33010602011771号