Winforms Windows Mobile/Compact Framework:检测表单移动

Winforms Windows Mobile/Compact Framework:检测表单移动,winforms,compact-framework,windows-mobile-6.5,Winforms,Compact Framework,Windows Mobile 6.5,我有一个紧凑的frameworkforms应用程序,其中包括显示非完整窗口大小的弹出窗口 目前情况下,当显示其中一个弹出窗口时,可以使用标题栏将其拖离可见屏幕区域。这给人的印象是表单没有响应,因为弹出窗口正在等待输入,但不可见 因此,我想检测表单的移动,以便我可以重置位置并使其在屏幕上居中。然而,我似乎无法做到这一点 到目前为止,我已经尝试过对表单进行子分类,然后查找WM_MOVE、WM_SIZE或WM_WINDOWPOSCHANGED消息-但是我从未在WndProc中看到这些消息(我也尝试记录

我有一个紧凑的frameworkforms应用程序,其中包括显示非完整窗口大小的弹出窗口

目前情况下,当显示其中一个弹出窗口时,可以使用标题栏将其拖离可见屏幕区域。这给人的印象是表单没有响应,因为弹出窗口正在等待输入,但不可见

因此,我想检测表单的移动,以便我可以重置位置并使其在屏幕上居中。然而,我似乎无法做到这一点

到目前为止,我已经尝试过对表单进行子分类,然后查找WM_MOVE、WM_SIZE或WM_WINDOWPOSCHANGED消息-但是我从未在WndProc中看到这些消息(我也尝试记录所有消息,但一旦显示表单,它在移动时或移动后不会收到任何消息,事实上,一旦显示,WndProc中的下一条消息就是单击表单上的按钮)

我还尝试在OnPaint/OnPaintBackground事件期间检测表单的当前位置。只要表单不包含主菜单控件,此方法就可以工作。如果主菜单控件存在,您可以将表单拖到菜单所在的屏幕底部,并且OnPaint/OnPaintBackground事件不再触发(不需要重新绘制,因为它不再可见)


我的想法已经用完了,有什么建议吗?

我刚刚更新了我的可移动WinForm解决方案:

更新的源代码位于

获取msg发送到表单的基本子类代码是(请参见winapi.cs):


使用这些代码,您应该能够“识别”表单是否已移动,并且可能已超出主屏幕边界。

我刚刚更新了我的可移动WinForm解决方案:

更新的源代码位于

获取msg发送到表单的基本子类代码是(请参见winapi.cs):


使用这些代码,您应该能够“识别”表单是否被移动,并且可能超出主屏幕边界。

这是一个愚蠢的解决方案,但是您是否考虑过在表单上设置计时器

public partial class Form1 : Form
{
    private Timer CheckLocation { get; set; }
    private Point FirstLocation { get; set; }

    public Form1()
    {
        InitializeComponent();

        FirstLocation = Location;
        CheckLocation.Tick += new EventHandler(CheckLocation_Tick);
    }

    void CheckLocation_Tick(object sender, EventArgs e)
    {
        if (FirstLocation != Location)
        {
            Location = FirstLocation;
        }
    }
}

这是一个愚蠢的解决方案,但你考虑过在表单上设置计时器吗

public partial class Form1 : Form
{
    private Timer CheckLocation { get; set; }
    private Point FirstLocation { get; set; }

    public Form1()
    {
        InitializeComponent();

        FirstLocation = Location;
        CheckLocation.Tick += new EventHandler(CheckLocation_Tick);
    }

    void CheckLocation_Tick(object sender, EventArgs e)
    {
        if (FirstLocation != Location)
        {
            Location = FirstLocation;
        }
    }
}

可能不重要,但正在创建表单,然后调用SetWindowLong以应用WS_边框、WS_弹出窗口和WS_标题。然后我还使用SHDB_HIDE调用SHDoneButton以隐藏默认的“Ok”按钮。您可以发布创建表单和更改布局的代码吗?compact framework的所有表单都是对话框。对话框窗口有自己的消息循环(DlgProc)。是否尝试在表单代码中实现MessageWindow类?可能不重要,但正在创建表单,然后调用SetWindowLong以应用WS_边框、WS_弹出窗口和WS_标题。然后我还使用SHDB_HIDE调用SHDoneButton以隐藏默认的“Ok”按钮。您可以发布创建表单和更改布局的代码吗?compact framework的所有表单都是对话框。对话框窗口有自己的消息循环(DlgProc)。您是否尝试在表单代码中实现MessageWindow类?太酷了,josef。我打算建议他在其中放置一个计时器,并在timer_Tick事件中重置表单位置。实际上,这几乎就是我第一次尝试接收消息所做的。我只是不接收WM_大小或WM_移动消息。我不会nder为什么我没有看到他们?顺便说一句;+1是一个非常详细的答案。这很酷,约瑟夫。我打算建议他在那里放一个计时器,并在timer_Tick事件上重置表单位置。这实际上是我在尝试和接收消息的第一步。我根本没有收到WM_大小或WM_移动消息。我想知道为什么你看到它们而我没有看到?顺便说一下;+1是非常详细的答案。