[100分难题]WinForm:窗 体 拖 动 ,我 真 的 没 别 的 办 法 了 。

KaKaKaKa 2010-04-09 02:38:39
C# WinForm:

有什么办法能使拖动窗体时,保证窗体顶部永远不越过屏幕顶。

不想采取的方法:

用个计时器,时刻判断窗体的Top是否<0等属性来裁决。

因为这样等到你的记时器发现Top<0时,说明窗体顶部已经越过了屏幕顶,你再强制将窗体Top重设已经不是我需要了。

-------------------------------

只要不去采用类似判断Top是否<0的办法,其他一切办法皆可。

最好能通过一些设置,使窗体顶到了屏幕顶,根本不让再往上拖(但要允许用户往其他方向拖)

谢谢献策~
...全文
381 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangxianshou 2010-04-09
  • 打赏
  • 举报
回复
LocationChanged就完全可以解决这个问题
不需要计时器~
wangxianshou 2010-04-09
  • 打赏
  • 举报
回复
保证窗体不会跑出屏幕范围

private void Form1_LocationChanged(object sender, EventArgs e)
{
Rectangle rect = new Rectangle();
rect = Screen.GetWorkingArea(this);

if (this.Location.Y< 0)
this.Location = new Point(this.Location.X,0);
if (this.Location.X < 0)
this.Location = new Point(0, this.Location.Y);
if (this.Bottom >= rect.Height)
this.Location = new Point(this.Location.X, rect.Height - this.Height);
if (this.Right >= rect.Width)
this.Location = new Point(rect.Width - this.Width, this.Location.Y);

}
starts_2000 2010-04-09
  • 打赏
  • 举报
回复
public partial class Form1 : Form
{
private Point _mouseDownPos;

public Form1()
{
InitializeComponent();
}

protected override void WndProc(ref Message m)
{
RECT nativeRect;

switch (m.Msg)
{
case 0x20:
int lp = m.LParam.ToInt32();

if ((lp & 0xFFFF) == 2 &&
((lp >> 0x10) & 0xFFFF) == 0x201)
{
_mouseDownPos = Control.MousePosition;
}
break;
case 0x231:
Rectangle rect = Screen.GetWorkingArea(this);

nativeRect = new RECT(
_mouseDownPos.X - Location.X,
_mouseDownPos.Y - Location.Y,
rect.Right - (Bounds.Right - _mouseDownPos.X),
rect.Bottom - (Bounds.Bottom - _mouseDownPos.Y));

ClipCursor(ref nativeRect);
break;
case 0x0232:

nativeRect = new RECT(Screen.GetWorkingArea(this));
ClipCursor(ref nativeRect);
break;
}

base.WndProc(ref m);
}

[DllImport("user32.dll")]
public static extern bool ClipCursor(ref RECT lpRect);

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;

public RECT(int left, int top, int right, int bottom)
{
Left = left;
Top = top;
Right = right;
Bottom = bottom;
}

public RECT(Rectangle rect)
{
Left = rect.Left;
Top = rect.Top;
Right = rect.Right;
Bottom = rect.Bottom;
}

public Rectangle Rect
{
get
{
return new Rectangle(
Left,
Top,
Right - Left,
Bottom - Top);
}
}

public Size Size
{
get
{
return new Size(Right - Left, Bottom - Top);
}
}

public static RECT FromXYWH(int x, int y, int width, int height)
{
return new RECT(x,
y,
x + width,
y + height);
}

public static RECT FromRectangle(Rectangle rect)
{
return new RECT(rect.Left,
rect.Top,
rect.Right,
rect.Bottom);
}
}
loveyan924 2010-04-09
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 goga21cn 的回复:]
窗体中放入此方法即可:


C# code
protected override void OnMove(EventArgs e)
{
base.OnMove(e);
if (this.Location.X < 0)
{
this.Location = new ……
[/Quote]

支持。。。。。。。。。。。。。。
doubleu2005 2010-04-09
  • 打赏
  • 举报
回复
用hook应该可以吧
xingyuebuyu 2010-04-09
  • 打赏
  • 举报
回复
http://www.cnblogs.com/winnxm/archive/2008/01/30/1059186.html

记录移动之前鼠标的位置,然后通过计算限定鼠标移动的范围.
龙宜坡 2010-04-09
  • 打赏
  • 举报
回复
窗体中放入此方法即可:

protected override void OnMove(EventArgs e)
{
base.OnMove(e);
if (this.Location.X < 0)
{
this.Location = new System.Drawing.Point(0, this.Location.Y);
}
if (this.Location.Y < 0)
{
this.Location = new System.Drawing.Point(this.Location.X, 0);
}
}
jackywei1987 2010-04-09
  • 打赏
  • 举报
回复
9楼正解!!!应该是这样子设置就可以!!根本就不用用什么计数器的!!!!!!![Quote=引用 9 楼 ouzui 的回复:]
写在窗体的Move事件里,窗体一旦移动就会触发

C# code

private void DataGridViewFrm_Move(object sender, EventArgs e)
{
if (this.Top < 0) {
this.Top = 0;
}
}

……
[/Quote]
viki117 2010-04-09
  • 打赏
  • 举报
回复
获取当前桌面的大小(1024*768);
获取窗口大小(200*200);
一旦移动窗体,触发事件;
计算当前窗体处于桌面的地点,4个角的坐标;
超过桌面坐标,把Location重置。。
liuh6 2010-04-09
  • 打赏
  • 举报
回复
取屏显示的高宽,在移动中判断..超过归位..这是思路.
liuyu520hong 2010-04-09
  • 打赏
  • 举报
回复
别做得太好了,9楼的可以试试.
njyang110 2010-04-09
  • 打赏
  • 举报
回复
看看千千静听`有磁性的那种`可以仿照那个做
你说不用TOP
这就不明白了`为什么用简单的方法能做到不用非去想那些复杂的?
要是不用TOP 我给你说个牵强的方法
你不超过屏幕 你不通过TOP去判断
就去判断纵坐标 横坐标 不就是个数轴嘛

KnowKjava 2010-04-09
  • 打赏
  • 举报
回复
用move事件
shang123guan 2010-04-09
  • 打赏
  • 举报
回复
。。。。。。。。
肖无疾 2010-04-09
  • 打赏
  • 举报
回复
9楼是对的

无需轮询,事件驱动
kinglshadow 2010-04-09
  • 打赏
  • 举报
回复
friendly up
Code従業員 2010-04-09
  • 打赏
  • 举报
回复
达到效果便可,不要要求太多。。。

客户是不会去考虑你是如何实现的。
wzp144650 2010-04-09
  • 打赏
  • 举报
回复
mousedown事件记住鼠标起点 mousemove事件,时刻获取鼠标位置 即可算出鼠标位移,通过鼠标位移也就是控件的位移,通过此数更改拖动控件的location属性。OK
b3727180 2010-04-09
  • 打赏
  • 举报
回复
你的top 无限趋近与0 你这个动作的数学模型就是个 极限无限趋近于0 的 lim x->0 所以你必须和0 比较啊
problc 2010-04-09
  • 打赏
  • 举报
回复
OnWindowPosChanged?
加载更多回复(15)

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧