C# 如何防止移动窗口?

C# 如何防止移动窗口?,c#,.net,winforms,user-interface,C#,.net,Winforms,User Interface,我将如何阻止窗体被移动。我将窗体边框样式设置为FixedSingle,并希望保持这种方式,因为它在vista中看起来很好:这不太好。当您尝试移动窗体时,会出现一些闪烁,但您可以使用LocationChanged属性将窗体保留在您想要的位置: private Point _desiredLocation; // assign the _desiredLocation variable with the form location at some // point in the code where

我将如何阻止窗体被移动。我将窗体边框样式设置为FixedSingle,并希望保持这种方式,因为它在vista中看起来很好:

这不太好。当您尝试移动窗体时,会出现一些闪烁,但您可以使用LocationChanged属性将窗体保留在您想要的位置:

private Point _desiredLocation;
// assign the _desiredLocation variable with the form location at some
// point in the code where you know that the form is in the "correct" position


private void Form_LocationChanged(object sender, EventArgs e)
{
    if (this.Location != _desiredLocation)
    {
        this.Location = _desiredLocation;
    }
}

出于好奇;为什么要这样做?

在Windows中,WS_标题样式是非客户端区域,允许使用鼠标移动窗口。因此,最简单的方法就是从窗口中删除此样式


然而,如果您需要一个标题,并且仍然实现了您想要的,那么下一种样式将是捕获WM_NCHITTEST消息并检查HTCAPTION。如果代码为HTCAPTION,则返回NTNOWHERE。这将阻止默认窗口过程执行默认的移动窗口操作。

我怀疑您是否需要使窗体不可移动。这听起来不太好。当然,您可以在窗口关闭时保存窗口的位置,然后将窗口重新打开到该位置。这让用户可以控制窗口的位置。

看看这个。您可能对选项3感兴趣。它需要您包装一些本机代码,但应该可以工作。链接底部还有一条注释,显示了一种更简单的方法。从评论中摘取的信息不能为其赢得荣誉,但我将为您节省一些搜索:

protected override void WndProc(ref Message message)
{
    const int WM_SYSCOMMAND = 0x0112;
    const int SC_MOVE = 0xF010;

    switch(message.Msg)
    {
        case WM_SYSCOMMAND:
           int command = message.WParam.ToInt32() & 0xfff0;
           if (command == SC_MOVE)
              return;
           break;
    }

    base.WndProc(ref message);
}
您可以尝试:

this.Locked = true;

您可以订阅事件并从中重新定位。

我发现这可以阻止表单在c中移动其位置

protected override void WndProc(ref Message m)
        {
            const int WM_SYSCOMMAND = 0x0112;
            const int SC_MOVE = 0xF010;

            switch (m.Msg)
            {
                case WM_SYSCOMMAND:
                    int command = m.WParam.ToInt32() & 0xfff0;
                    if (command == SC_MOVE)
                        return;
                    break;
            }
            base.WndProc(ref m);
        }
可以将窗体的FormBorderStyle属性设置为None

this.FormBorderStyle=System.Windows.Forms.FormBorderStyle.None

让你的身体不动不是一个好的练习。如果我是你,我会考虑的。 无论如何,您可以通过覆盖WinProc从系统菜单中禁用[Move]菜单项来实现这一点

[DllImport("user32.dll")]
private static extern Int32 EnableMenuItem ( System.IntPtr hMenu , Int32uIDEnableItem, Int32 uEnable);  
private const Int32 HTCAPTION = 0×00000002;  
private const Int32 MF_BYCOMMAND =0×00000000;  
private const Int32 MF_ENABLED =0×00000000;  
private const Int32 MF_GRAYED =0×00000001;  
private const Int32 MF_DISABLED =0×00000002; 
private const Int32 SC_MOVE = 0xF010; 
private const Int32 WM_NCLBUTTONDOWN = 0xA1;
private const Int32 WM_SYSCOMMAND = 0×112;
private const Int32 WM_INITMENUPOPUP = 0×117;

protected override void WndProc(ref System.Windows.Forms.Message m )
{
if (m.Msg == WM_INITMENUPOPUP)
{
    //handles popup of system menu
    if ((m.LParam.ToInt32() / 65536) != 0) // 'divide by 65536 to get hiword
    {
        Int32 AbleFlags = MF_ENABLED;
        if (!Moveable)
        {
            AbleFlags = MF_DISABLED | MF_GRAYED; // disable the move
        }
        EnableMenuItem(m.WParam, SC_MOVE, MF_BYCOMMAND | AbleFlags);
    }
}
if (!Moveable)
{
    if (m.Msg == WM_NCLBUTTONDOWN) //cancels the drag this is IMP
    {
        if (m.WParam.ToInt32() == HTCAPTION) return;
    }
    if (m.Msg == WM_SYSCOMMAND) // Cancels any clicks on move menu
    {
        if ((m.WParam.ToInt32() & 0xFFF0) == SC_MOVE) return;
    }
}
base.WndProc(ref m);
}  
此外,还可以处理表单的OnMove事件。但我认为这会引起一些闪烁:

private void Form1_Move(object sender, EventArgs e)
{
    this.Location = defaultLocation;
}

尝试覆盖WndProc:

protected override void WndProc(ref Message m)
{
   const int WM_NCLBUTTONDOWN = 161;
   const int WM_SYSCOMMAND = 274;
   const int HTCAPTION = 2;
   const int SC_MOVE = 61456;

   if ((m.Msg == WM_SYSCOMMAND) && (m.WParam.ToInt32() == SC_MOVE))
   {
       return;
   }

   if ((m.Msg == WM_NCLBUTTONDOWN) && (m.WParam.ToInt32() == HTCAPTION))
   {
       return;
   }

   base.WndProc(ref m);
}

只需将formlocation_changed事件上的位置重置为原来的位置,即在移动前将Form.location设置为变量,当用户尝试移动它时,它将返回到您设置的变量位置。

将表单属性StartPostion更改为手动。 然后,处理LocationChanged事件:

private void frmMain_LocationChanged(object sender, EventArgs e)
{
Location = new Point(0, 0);
}
转到表单事件->位置已更改 编写以下代码

Location = new Point(this.Width,this.Height);
私有子MyFormLock Me.Location=新点0,0 端接头

Private Sub SearchSDR_LocationChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LocationChanged
    Call MyFormLock()
End Sub


只需将FormBorderStyle属性更改为None。

移动是什么意思?你的意思是不能将其拖动到桌面上的其他位置吗?如果用户在右下角有其他小部件,比如vista边栏,该怎么办?你真的想决定你的窗户应该放在哪里吗?这绝对不是用户友好的,我个人也不会接受这样的限制。如果表单被移动,是否可以将其重新定位到初始位置?是的,我认为这并不容易:我想要这样做的原因是因为我想让表单像菜单一样出现在屏幕的右下角。所以你可以选择文件等。我会怎么做-不看我不认为有一个属性,你可以在.NET中设置这样做,所以这是你最好的选择。谢谢你的答复。我大约一个月前才开始进行桌面编程,所以我不知道如何实现你所说的任何内容。。很抱歉我感到无知:嗯。。。整个计划的重点是它不被移动lol。谢谢,这是完美的工作。也有一个网站周围的阅读。我需要进一步研究WinAPI。如何使它再次可移动?您必须在switch语句中设置某种标志,以确定是否要运行代码,该语句只检查windows消息是否要移动窗口。。。在这种情况下,它会返回并且什么也不做。是的,我试过了,但是当我尝试将表单移动到一个新位置时,表单开始频繁闪烁。@Failed\u Noob-编辑您的问题,发布代码,也许有人可以建议解决方法。在什么情况下我应该写这个?您必须覆盖WndProc,因为您希望的表单不应该被移动。输入override和space,您将得到一个列表,在其中可以找到所提到的方法above@V4Vendetta也许是因为你的答案和两年前公布的答案完全一样。。。我也不明白不是我的downvote@Knickedi在这种情况下,类似的问题可能会与答案合并在一起,所以你会看到时间线上的巨大差异。有比这个更好的答案!如果你想添加一个完全不同的答案,至少解释一下!我怎样才能让它再次移动?好吧,这正是我想要的。全屏用户界面。对我来说不合适!我认为您应该首先保存顶部和左侧位置的值,然后:Location=newpointleftposition,TopPosition;