無論如何要控制你可以移動窗體的位置嗎?C#窗體控件移動
所以,如果我移動一個窗體,它只能在垂直軸上移動,當我嘗試水平移動它時,什麼都不會發生。
我不想像位置改變或移動事件並將其彈回內聯的bug的實現。我不知道有什麼方法使用像WndProc覆蓋的東西,但搜索一段時間後,我找不到任何東西。請幫忙
無論如何要控制你可以移動窗體的位置嗎?C#窗體控件移動
所以,如果我移動一個窗體,它只能在垂直軸上移動,當我嘗試水平移動它時,什麼都不會發生。
我不想像位置改變或移動事件並將其彈回內聯的bug的實現。我不知道有什麼方法使用像WndProc覆蓋的東西,但搜索一段時間後,我找不到任何東西。請幫忙
你很可能想覆蓋WndProc並處理WM_MOVING消息。 According to MSDN:
WM_MOVING消息發送到用戶正在移動的 窗口。通過 處理此消息, 應用程序可以監視拖動矩形的位置 ,如果需要, 更改其位置。
這將是一個辦法做到這一點,但是,你顯然需要tweek它爲您的需求:
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace VerticalMovingForm
{
public partial class Form1 : Form
{
private const int WM_MOVING = 0x0216;
private readonly int positionX;
private readonly int positionR;
public Form1()
{
Left = 400;
Width = 500;
positionX = Left;
positionR = Left + Width;
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_MOVING)
{
var r = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
r.Left = positionX;
r.Right = positionR;
Marshal.StructureToPtr(r, m.LParam, false);
}
base.WndProc(ref m);
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
}
}
例如:
using System.Runtime.InteropServices;
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x216) // WM_MOVING = 0x216
{
Rectangle rect =
(Rectangle) Marshal.PtrToStructure(m.LParam, typeof (Rectangle));
if (rect.Left < 100)
{
// compensates for right side drift
rect.Width = rect.Width + (100 - rect.Left);
// force left side to 100
rect.X = 100;
Marshal.StructureToPtr(rect, m.LParam, true);
}
}
base.WndProc(ref m);
}
上述代碼設置一個最小左側位置爲100.
沒有必要重新創建RECT結構,就像driis那樣,.NET原生Rectangle工作正常。但是,您必須通過X屬性設置位置,因爲Left是Get only屬性。
VB.NET版本:
Protected Overloads Overrides Sub WndProc(ByRef m As Message)
If m.Msg = &H216 Then
' WM_MOVING = 0x216
Dim rect As Rectangle = DirectCast(Marshal.PtrToStructure(m.LParam, GetType(Rectangle)), Rectangle)
If rect.Left < 100 Then
' compensates for right side drift
rect.Width = rect.Width + (100 - rect.Left)
' force left side to 100
rect.X = 100
Marshal.StructureToPtr(rect, m.LParam, True)
End If
End If
MyBase.WndProc(m)
End Sub
+1使用盡可能多的本地CLR代碼越好。 – 2009-06-01 00:16:34