资源描述
C#如何在运行时通过鼠标拖动改变控件的大小
作者:oayx | 出处:博客园 | 2011/10/26 22:12:23 | 阅读13次
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Windows.Forms;
using System.Drawing;
namespace WindowsApplication2
{
class ResizeAction
{
bool IsMoving = false;
int ctrlLastWidth = 0;
int ctrlLastHeight = 0;
int ctrlWidth;
int ctrlHeight;
int ctrlLeft;
int ctrlTop;
int cursorL;
int cursorT;
int ctrlLastLeft;
int ctrlLastTop;
int Htap;
int Wtap;
bool ctrlIsResizing = false;
System.Drawing.Rectangle ctrlRectangle = new System.Drawing.Rectangle();
private Control ctrl;
private Form frm;
public ResizeAction(Control c, Form frm)
{
ctrl = c;
this.frm = frm;
this.Htap = this.frm.Height - this.frm.ClientRectangle.Height;
this.Wtap = this.frm.Width - this.frm.ClientRectangle.Width;
ctrl.MouseDown += new MouseEventHandler(MouseDown);
ctrl.MouseMove += new MouseEventHandler(MouseMove);
ctrl.MouseUp += new MouseEventHandler(MouseUp);
}
public void MouseMove(object sender, MouseEventArgs e)
{
if (frm == null)
return;
if (e.Button == MouseButtons.Left)
{
if (this.IsMoving)
{
if (ctrlLastLeft == 0)
ctrlLastLeft = ctrlLeft;
if (ctrlLastTop == 0)
ctrlLastTop = ctrlTop;
int locationX = (Cursor.Position.X - this.cursorL + this.frm.DesktopLocation.X + this.Wtap + this.ctrl.Location.X);
int locationY = (Cursor.Position.Y - this.cursorT + this.frm.DesktopLocation.Y + this.Htap + this.ctrl.Location.Y);
if (locationX < this.frm.DesktopLocation.X + this.Wtap)
locationX = this.frm.DesktopLocation.X + this.Wtap;
if (locationY < this.frm.DesktopLocation.Y + this.Htap)
locationY = this.frm.DesktopLocation.Y + this.Htap;
this.ctrlLeft = locationX;
this.ctrlTop = locationY;
ctrlRectangle.Location = new System.Drawing.Point(this.ctrlLastLeft, this.ctrlLastTop);
ctrlRectangle.Size = new System.Drawing.Size(ctrlWidth, ctrlHeight);
ControlPaint.DrawReversibleFrame(ctrlRectangle, Color.Empty, System.Windows.Forms.FrameStyle.Dashed);
ctrlLastLeft = ctrlLeft;
ctrlLastTop = ctrlTop;
ctrlRectangle.Location = new System.Drawing.Point(ctrlLeft, ctrlTop);
ctrlRectangle.Size = new System.Drawing.Size(ctrlWidth, ctrlHeight);
ControlPaint.DrawReversibleFrame(ctrlRectangle, Color.Empty, System.Windows.Forms.FrameStyle.Dashed);
return;
}
int sizeageX = (Cursor.Position.X - this.frm.DesktopLocation.X - this.Wtap - this.ctrl.Location.X);
int sizeageY = (Cursor.Position.Y - this.frm.DesktopLocation.Y - this.Htap - this.ctrl.Location.Y);
if (sizeageX < 2)
sizeageX = 1;
if (sizeageY < 2)
sizeageY = 1;
ctrlWidth = sizeageX;
ctrlHeight = sizeageY;
if (ctrlLastWidth == 0)
ctrlLastWidth = ctrlWidth;
if (ctrlLastHeight == 0)
ctrlLastHeight = ctrlHeight;
if (ctrlIsResizing)
{
ctrlRectangle.Location = new System.Drawing.Point(this.frm.DesktopLocation.X + this.ctrl.Left + this.Wtap, this.frm.DesktopLocation.Y + this.Htap + this.ctrl.Top);
ctrlRectangle.Size = new System.Drawing.Size(ctrlLastWidth, ctrlLastHeight);
}
ctrlIsResizing = true;
ControlPaint.DrawReversibleFrame(ctrlRectangle, Color.Empty, System.Windows.Forms.FrameStyle.Dashed);
ctrlLastWidth = ctrlWidth;
ctrlLastHeight = ctrlHeight;
ctrlRectangle.Location = new System.Drawing.Point(this.frm.DesktopLocation.X + this.Wtap + this.ctrl.Left, this.frm.DesktopLocation.Y + this.Htap + this.ctrl.Top);
ctrlRectangle.Size = new System.Drawing.Size(ctrlWidth, ctrlHeight);
ControlPaint.DrawReversibleFrame(ctrlRectangle, Color.Empty, System.Windows.Forms.FrameStyle.Dashed);
}
}
public void MouseDown(object sender, MouseEventArgs e)
{
if (frm == null)
return;
if (e.X < this.ctrl.Width - 10 || e.Y < this.ctrl.Height - 10)
{
this.IsMoving = true;
this.ctrlLeft = this.frm.DesktopLocation.X + this.Wtap + this.ctrl.Left;
this.ctrlTop = this.frm.DesktopLocation.Y + this.Htap + this.ctrl.Top;
this.cursorL = Cursor.Position.X;
this.cursorT = Cursor.Position.Y;
this.ctrlWidth = this.ctrl.Width;
this.ctrlHeight = this.ctrl.Height;
}
ctrlRectangle.Location = new System.Drawing.Point(this.ctrlLeft, this.ctrlTop);
ctrlRectangle.Size = new System.Drawing.Size(ctrlWidth, ctrlHeight);
ControlPaint.DrawReversibleFrame(ctrlRectangle, Color.Empty, System.Windows.Forms.FrameStyle.Dashed);
}
public void MouseUp(object sender, MouseEventArgs e)
{
if (frm == null)
return;
ctrlIsResizing = false;
if (this.IsMoving)
{
ctrlRectangle.Location = new System.Drawing.Point(this.ctrlLeft, this.ctrlTop);
ctrlRectangle.Size = new System.Drawing.Size(ctrlWidth, ctrlHeight);
ControlPaint.DrawReversibleFrame(ctrlRectangle, Color.Empty, System.Windows.Forms.FrameStyle.Dashed);
this.ctrl.Left = this.ctrlLeft - this.frm.DesktopLocation.X - this.Wtap;
this.ctrl.Top = this.ctrlTop - this.frm.DesktopLocation.Y - this.Htap;
this.IsMoving = false;
this.ctrl.Refresh();
return;
}
ctrlRectangle.Location = new System.Drawing.Point(this.frm.DesktopLocation.X + this.Wtap + this.ctrl.Left, this.frm.DesktopLocation.Y + this.Htap + this.ctrl.Top);
ctrlRectangle.Size = new System.Drawing.Size(ctrlWidth, ctrlHeight);
ControlPaint.DrawReversibleFrame(ctrlRectangle, Color.Empty, System.Windows.Forms.FrameStyle.Dashed);
this.ctrl.Width = ctrlWidth;
this.ctrl.Height = ctrlHeight;
this.ctrl.Refresh();
}
}
}
调用:
private void Form1_Load(object sender, EventArgs e)
{
//WindowsApplication2.ResizeAction rs = new WindowsApplication2.ResizeAction(this.label1,this);
WindowsApplication2.ResizeAction rs = new WindowsApplication2.ResizeAction(this.button1, this);
}
参考:
本文来自CSDN博客,转载请标明出处:
分享到: QQ空间 新浪微博 腾讯微博 人人网 百度空间 百度搜藏 QQ收藏 百度贴吧
上一篇: 口译词汇
下一篇: 雅可比迭代法和高斯赛德尔迭代法
关于 (转)C#如何在运行时通过鼠标拖动改变控件的大小 的相关阅读
· 在运行时能用鼠标拖动报表上的LABEL
· c# winform 鼠标改变窗体的大小,使窗体内的图片跟着改变
· [转]c# winform 用鼠标滚轮控制图片大小,获取鼠标中键滚轮事件,MouseWheel事件
· Delphi实现运行时控件的拖动、改变大小等,并且做到与控件类型的解耦
· 鼠标拖动层效果(产品拖动到购物车效果)
· js鼠标拖动对象可让任何div实现拖动效果
· 鼠标拖动表单特效(带拖动动画)
· 鼠标拖动改变左右单元格宽度
· 控件拖动、调整大小类(任何具备拖动能力的控件均可)
· 鼠标拖动图片控件
· 图片长度过长时,用鼠标拖动观看
· 运行时在一定范围内拖动控件的示例
· VC中鼠标拖动改变窗体大小
· delphi 在运行的EXE拖动控件及改变控件的大小
· 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。
C#实现自定义外观并可拖动和改变大小的窗口
时间:2008-10-27 Tag: 点击:320
收藏 挑错 推荐 打印
自定义窗口在c#中只需重写OnPaint方法就行了,不过有几处关键之处要设置
下面给出重会的方法,具体你只要修改下就行了
protected override void OnPaint(PaintEventArgs e)
...{
ResourceManager rm = new ResourceManager("SafeBox.Resources.Skin", Assembly.GetExecutingAssembly());
Image TopLeft = (Image)(rm.GetObject("TopLeft"));
Graphics g = e.Graphics;
//画标题栏左边
智动软件
Brush brush = new TextureBrush(TopLeft, new Rectangle(0, 0, TopLeft.Width, TopLeft.Height));
g.FillRectangle(brush, 0, 0, TopLeft.Width, TopLeft.Height);
//画标题栏中间
Brush MidBrush = new SolidBrush(Color.FromArgb(0, 163, 227));
g.FillRectangle(MidBrush, 1, TopLeft.Height - 1, DrawForm.ClientSize.Width, 1);
//画左边框 本文来自智动软件
Brush BoardBrush = new SolidBrush(Color.FromArgb(78, 205, 255));
g.FillRectangle(BoardBrush, 0, 0, 2, DrawForm.ClientSize.Height);
//画右边框
g.FillRectangle(BoardBrush, DrawForm.ClientSize.Width - 2, 0, 2, DrawForm.ClientSize.Height);
//画上边框
g.FillRectangle(BoardBrush, 0, 0, DrawForm.ClientSize.Width, 2); 智动软件
//画下边框
g.FillRectangle(BoardBrush, 0, DrawForm.ClientSize.Height - 2, DrawForm.ClientSize.Width, 2);
base.OnPaint(e);
}
这样写好后窗口样式变了,不过你首先得把窗口的 FormBoardStyle 设为None,但光这样无法拖动窗口,
智动软件
下面是拖动和改变窗口的方法:重写WndProc
switch (Msg.Msg)
{
case 0x0084: //WM_NCHITTEST改变窗口大小
{
// 分解当前鼠标的坐标
int nPosX = (Msg.LParam.ToInt32() & 65535);
内容来自
int nPosY = (Msg.LParam.ToInt32() >> 16);
if (nPosX >= this.Left + this.Width - 6 && nPosY >= this.Top + this.Height - 6)
{
// 鼠标位置在窗体的右下角附近
Msg.Result = new IntPtr(HTBOTTOMRIGHT);
return;
}
else if (nPosX >= this.Left + this.Width - 2) 内容来自
{
// 鼠标位置在窗体右侧
Msg.Result = new IntPtr(HTRIGHT);
return;
}
else if (nPosY >= this.Top + this.Height - 2)
copyright 智动软件
{
// 鼠标位置在窗体下方
Msg.Result = new IntPtr(HTBOTTOM);
return;
}
else if (nPosX <= this.Left + 2)
{
// 鼠标位置在窗体左侧
本文来自智动软件
Msg.Result = new IntPtr(HTLEFT);
return;
}
else if (nPosY <= this.Top + 2)
{
// 鼠标位置在窗体上侧
Msg.Result = new IntPtr(HTTOP); copyright 智动软件
return;
}
// 以上只判断鼠标位置是否在右侧,右下角,下方,所以仅仅当鼠标指针在这三个位置时才会改动成改动大小的形状,拖动后可改动大小。
break;
}
case 0x0201://移动窗口
{
m.Msg = 0x00A1;//更改消息为非客户区按下鼠标 copyright 智动软件
m.LParam = IntPtr.Zero;//默认值
m.WParam = new IntPtr(2);//鼠标放在标题栏内
}
default:
break;
}
使用以上方法时别忘了加入自定义常数哦:
const int HTERROR = -2;
本文来自智动软件
const int HTTRANSPARENT = -1;
const int HTNOWHERE = 0;
const int HTCLIENT = 1;
const int HTCAPTION = 2;
const int HTSYSMENU = 3;
const int HTGROWBOX = 4;
const int HTSIZE = HTGROWBOX;
const int HTMENU = 5; copyright 智动软件
const int HTHSCROLL = 6;
const int HTVSCROLL = 7;
const int HTMINBUTTON = 8;
const int HTMAXBUTTON = 9;
本文来自智动软件
const int HTLEFT = 10;
const int HTRIGHT = 11;
const int HTTOP = 12;
const int HTTOPLEFT = 13;
本文来自智动软件
const int HTTOPRIGHT = 14;
const int HTBOTTOM = 15;
const int HTBOTTOMLEFT = 16;
const int HTBOTTOMRIGHT = 17;
copyright 智动软件
const int HTBORDER = 18;
const int HTREDUCE = HTMINBUTTON;
const int HTZOOM = HTMAXBUTTON;
const int HTSIZEFIRST = HTLEFT;
本文来自智动软件
const int HTSIZELAST = HTBOTTOMRIGHT;
好了,OK了吧,能拖动,能改变大小,而且外观也自定义了,你移动看看,出问题了吧,窗口的残留画面去不了,不用急,在窗口的构造函数中加入:
this.SetStyle(ControlStyles.ResizeRedraw, true);行了吧,又出问题了,窗口会闪,再设置下窗口的属性:DoubleBuffered=true,ok了吧,,这个对控件双缓存处理,这样一个完美的自定义外观并可拖动和改变大小的窗口就搞定了,,当然这不是标准的解决方法,标准的应该重绘标题栏等吧,等有时间有贴啦
效果如下:
用C#创建定制窗口界面一例
[收藏此页] [打印]
作者:朱先忠 2006-08-10
内容导航:
第1页
第1页: 第1页
【it168技术文章】
简介
早在Visual Studio 6.0时代,在很多网站上都可以看到有关用VC/VB创建定制窗口的源码示例;但是,在.NET时代,这方面的小文章实在不多。本文基于一种早期用VC6制作定制窗口的思路,并结合C#的新特征来尝试创建一个定制的窗口界面,例子虽然丑陋,但却具有一般指导意义。你会看到在.NET环境下,用C#创建一个定制窗口更为容易。
实现过程
首先,你需要准备一些定制图像。在本文例子中,我使用的是jpeg格式的图像。
现在,打开Visual Studio 2005并创建一个新的C# Windows应用程序。为此,只需转到“File->New->Project->Visual C# Projects->Windows Application”,为你的工程确定一个名字,然后点击OK(当然,你也可以改变你的工程的存放位置)。一切顺利的话,呈现在你面前的将是一个毫无内容的空窗口。我们先对该表单进行一些设计修改,然后进行编码。首先,按F4键调出“属性”窗口。
在“属性”窗口中,我们必须改变一些缺省设置。首先,我们必须把窗口的FormBorderStyle属性设置为None。另外,我还把另一个TopMost属性设置为True,但这不是必需的(把这个属性设置为真后,应用程序窗口就可以一直位于其它窗口的顶部而不管其是否具有焦点)。
然后,添加标题栏。为此,选择菜单项“View->ToolBox”。我们需要添加一个PictureBox控件,因此你可以直接把它拖动到窗口表面。然后,调用其大小和位置,使其看上去大致如下图所示:
在调整PictureBox之前,我们必须添加图片。为此,我们可以从解决方案资源管理器中右击工程名,并选择“Add->New Folder”。命名文件夹为Images或任何另外你喜欢的命名。现在,右击我们刚才创建的文件夹,选择“Add->Add Existing Item…”,浏览到你想使用的图像并选择它们,按下OK后,它们即被包括到当前工程中。接下来,我们要选择PictureBox并且调整其属性。我们必须把这个控件的Image属性设置为我们想使用的在前面已经加入的图像。然后,要把另一个Dock属性改变为Top。现在,我们需要添加另一个PictureBox控件,用于表示关闭按钮。把这个新的PictureBox放到窗口右上角,并设置其Image属性为你想使用的图像(在本例子中,其文件名为closenormal.jpg)。
现在,让我们开始编码部分。首先,我们需要加入一些代码以便关闭窗口。为此,双击第二个PictureBox,然后Visual Studio将创建下列方法:
private void pictureBox2_Click_1(object sender,System.EventArgs e)
{
}
因为我们需要告诉该表单,当点击该picturebox时,它必须关闭;所以,我们需要加入如下的代码:
this.Close();
现在,这个示例程序可以进行第一次运行试验了。为此,你可以选择“Debug->Start Without Debugging”(或按下组合键Ctrl+F5)。
最后,让我们加入功能以便用户可以移动这个窗口。为此,我们必须处理鼠标动作事件MouseDown,MouseMove和MouseUp。在Designer视图下,选择第一个PictureBox(较大的那个),打开其属性窗口(或按F4),并点击加亮的按钮。在Mouse部分,双击MouseDown属性。Visual Studio已经为你创建了一个现成的函数以便处理在PictureBox上的MouseDown行为(不是表单上的):
private void pictureBox1_MouseDown(object sender,System.Windows.Forms.MouseEventArgs e)
{
}
首先,我们需要声明一个变量来标记是否按下鼠标(名字为mouse_is_down)。我们必须在类定义后声明这个变量。然后,加入如下代码:
private bool mouse_is_down=false;
现在,转到pictureBox1_MouseDown方法并且添加下列代码:
mouse_is_down=true;
现在,你知道何时按下鼠标了。但是,如果用户按下鼠标然后即松开它的话,变量mouse_is_down还是为true。为了修正这个问题,我专门添加一个处理MouseUp事件的函数。在Mouse部分,双击MouseUp属性,然后添加下列代码:
mouse_is_down=false;
到目前为止,一切顺利。现在,让我们处理MouseMove行为。双击MouseMove,现在我们位于pictureBox1_MouseMove方法中了。如果鼠标按下,并且用户想移动窗口,我们要使之能够移动,这只要添加如下代码即可:
if ( mouse_is_down )
{
Point current_pos = Control.MousePosition;
this.Location=current_pos;
}
上面Point类型的变量代表鼠标的当前位置。
现在,让我们运行程序来看一下所发生的事情。
如你所见,窗口移动时,鼠标位置停留在窗口的左上角。为什么会这样呢?通过改变鼠标的位置,我们也改变了窗口的位置,并且把鼠标坐标设置为(0,0)(相对于窗口)。这种情况可以通过添加另外一些代码加以避免。为此,我们只须记下点击时的鼠标的位置。首先,我们需要在类的开始声明另一个Point类型的变量mouse_pos。
private Point mouse_pos;
在pictureBox1_MouseDown方法中,添加下列代码以记忆当执行点击时的鼠标的位置:
mouse_pos.X=e.X;
mouse_pos.Y=e.Y;
现在,让我们转到pictureBox1_MouseMove方法,并且添加:
if ( mouse_is_down )
{
Point current_pos = Control.MousePosition;
current_pos.X = current_pos.X - mouse_pos.X; //新加current_pos.Y = current_pos.Y - mouse_pos.Y; //新加
this.Location = current_pos;
}
好,现在可以再次运行示例程序了。
最后,让我们再作一下改进:
在pictureBox1_MouseDown方法中,加入下列代码行:
pictureBox1.Image=new Bitmap("..\\..\\Images\\up bar selected.jpg");
上面语句实现,在你点击时,改变pictureBox1的Image属性。
在PictureBox_MouseUp方法中,让我们改变回原来的图像:
pictureBox1.Image =new Bitmap("..\\..\\Images\\up bar.jpg");
注意:当你运行程序时,你的当前目录为“{path to application}\bin\Debug”。再让我们把表单的BackgroundImage属性设置为face.jpg图像(也是位于Images文件夹下)。而且,设置TransparencyKey为Gray(128,128,128)(注意,你可能需要把颜色深度设置为16位才能看到这种效果)。
这是最后的应用程序快照:
小
展开阅读全文