鼠标滚轮实现窗体图形缩放MouseWheel
功能描述:在鼠标进入一个用于绘制图形的窗体(如:Show_3D)时,滚动鼠标滚轮,使窗体中的内容能够进行放大缩小.此处以绘制XNA图形为例.
滚动鼠标的滚轮,触发的是窗体或控件上的 MouseWheel 事件。但是在VS2008以及其他版本中,窗体和控件的事件列表中并不包含 MouseWheel 事件,因此对于这个事件的事件处理函数须手动创建和实现。
首先在窗体的构造函数中,添加如下代码:
1 this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.Panel_MouseWheel);
这样只是使Panel能接收鼠标的滚动事件,但还不能实现窗体中内容的放大缩小,因此还需要添加以下代码:
private void Show_3D_MouseWheel(object sender, MouseEventArgs e) { float Mo = 0; if (e.Delta > 0) { Mo = 8; } else { Mo = -8; } if (Global.myCamera.cameraPosition.Y < 90.0f) { Global.myCamera.cameraPosition += 0.01f * Mo * (Global.myCamera.cameraTarget - Global.myCamera.cameraPosition); } else { Global.myCamera.cameraPosition.Y = 89.0f; } }
添加了以上代码后,运行上述的程序,发现无论是在窗体内还是在窗体外鼠标滚轮都会对窗体中内容进行缩放。解决方法是可以通过窗体的MouseEnter事件和MouseLeave事件来对一个bool变量进行赋值更改,标识当前鼠标是否在窗体的范围内,以达到目的。也就是说增加变量inxna,使其在窗体外滚动鼠标滚轮时,不能起到放大缩小的功能.
除此之外还要说的一点是,触发鼠标的滚动事件后,处理事件的函数参数 MouseEventArgs e 中有个Delta属性,默认情况下向上滚动e.Delta == 120,向下滚动e.Delta == -120。
完整的程序代码如下:
1 public partial class Show_3D : Form 2 { 3 public Show_3D() 4 { 5 InitializeComponent(); 6 7 //lxw0109 20130314 8 //Show_3D窗体中鼠标滚轮实现缩放的处理 9 this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.Show_3D_MouseWheel); 10 } 11 //lxw0109 20130314 12 //通过滚轮实现放大缩小的更改 13 private void Show_3D_MouseWheel(object sender, MouseEventArgs e) 14 { 15 if (Global.inxna) 16 { 17 float Mo = 0; 18 if (e.Delta > 0) 19 { 20 Mo = 8; 21 } 22 else 23 { 24 Mo = -8; 25 } 26 if (Global.myCamera.cameraPosition.Y < 90.0f) 27 { 28 Global.myCamera.cameraPosition += 0.01f * Mo * (Global.myCamera.cameraTarget - Global.myCamera.cameraPosition); 29 } 30 else 31 { 32 Global.myCamera.cameraPosition.Y = 89.0f; 33 } 34 } 35 } 36 37 private void Show_3D_MouseEnter(object sender, EventArgs e) 38 { 39 //lxw0109 20130314 滚轮缩放 40 Global.inxna = true; 41 this.Focus(); 42 ... 43 } 44 45 private void Show_3D_MouseLeave(object sender, EventArgs e) 46 { 47 //lxw0109 20130314 滚轮缩放 48 Global.inxna = false; 49 ... 50 } 51 ... 52 }
20130327 补充:
上次做的这个是Form窗体,所以其实在上面的代码中及时不写this.Focus();这行代码也是可行的!但最近我处理了一个Panel控件捕获鼠标滚轮消息处理缩放的问题:
由于panel控件(此处假设控件名称为XNAPanel,并且增加了相关的消息处理函数如:XNAPanel_MouseEnter(),XNAPanel_MouseWheel()等,具体方法和上面的一样)默认不能获得焦点,所以不能够捕获鼠标,这时就必须要增加获取焦点的代码.
因此,需要在XNAPanel_MouseEnter() 或者 XNAPanel_MouseClick()中增加如下的代码:
1 this.XNAPanel.Focus();