c# - 构造函数期间 OnActivated

标签 c# winforms compact-framework windows-embedded

当在 Form 的构造函数期间我触摸特定属性(即 Width 属性)时,它会立即调用 OnActivated ()。我仅在运行 Windows Embedded 7 及其附带的 .NET 3.5 的设备上注意到此行为。

这是我用来重现问题的代码:

static class Program
{
    [MTAThread]
    static void Main()
    {
        new MyForm();
    }
}

public class MyForm : Form
{
    public MyForm()
    {
        Width = 100;
    }

    protected override void OnActivated(EventArgs e)
    {
        MessageBox.Show("Activated!");
    }
}

(请注意,我没有 Show() 表单,也没有使用 Application.Run())

在我的桌面或 WinCE 5 设备上运行上述代码不会显示 MessageBox。在我的 Windows Embedded 7 设备上,出现 MessageBox,单击“确定”后它又重新出现,因为 OnActivated() 被再次调用。

设备制造商告诉我这是一个操作系统特定问题,任何人都可以确认这是 Windows Embedded 7 应该“处理其表单”的方式吗?

最佳答案

我在装有 .NET CF 3.5 的 Windows CE 5.0 设备上尝试了此操作,看看我是否遇到了与您相同的行为。使用完全相同的代码,我没有调用 OnActivated 。即使使用 Application.Run(),设置宽度也不会导致 OnActivated 被调用。事实上,似乎必须显示表单才能允许激活激活,因为我尝试显式调用激活()。

因此,这似乎是 Windows Embedded 7 与以前版本的 Windows CE 所做的事情。我还尝试使用 Reflector 查看 CompactFramework .NET .dll,但我在 .NET 中没有找到任何在宽度更改时激活表单的代码。宽度不是 Form 的属性(它是 Control 的属性),并且 Form 似乎没有以任何方式处理调整大小事件,从而允许它调用其 Activate 方法。

我确实为您提供了一个可能的解决方法的建议。即使我显式调用Activate(),以下代码也完全阻止了Activate的发生;

尝试一下:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        DisableActivate();
        Activate(); // No call is made to OnActivated
        EnableActivate();
    }

    protected override void OnActivated(EventArgs e)
    {
        Debug.WriteLine("Activated");
    }

    private void DisableActivate()
    {
        WindowStyles style = GetWindowLong(Handle, GWL_EX_STYLE);
        style |= WindowStyles.WS_EX_NOACTIVATE;
        SetWindowLong(Handle, GWL_EX_STYLE, style);
    }

    private void EnableActivate()
    {
        WindowStyles style = GetWindowLong(Handle, GWL_EX_STYLE);
        style &= ~WindowStyles.WS_EX_NOACTIVATE;
        SetWindowLong(Handle, GWL_EX_STYLE, style);
    }

    public const int GWL_EX_STYLE = -20;

    [DllImport("coredll.dll", SetLastError = true)]
    public static extern WindowStyles GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("Coredll.dll", SetLastError = true)]
    public static extern int SetWindowLong(IntPtr hWnd, int nIndex, WindowStyles dwNewLong);

    [Flags]
    public enum WindowStyles : uint
    {
        WS_CHILD = 0x40000000,
        WS_VISIBLE = 0x10000000,
        WS_DISABLED = 0x08000000,
        WS_GROUP = 0x00020000,
        WS_TABSTOP = 0x00010000,
        WS_OVERLAPPED = WS_BORDER | WS_CAPTION,
        WS_CLIPSIBLINGS = 0x04000000,
        WS_CLIPCHILDREN = 0x02000000,
        WS_CAPTION = 0x00C00000,    /* WS_BORDER | WS_DLGFRAME  */
        WS_BORDER = 0x00800000,
        WS_DLGFRAME = 0x00400000,
        WS_VSCROLL = 0x00200000,
        WS_HSCROLL = 0x00100000,
        WS_SYSMENU = 0x00080000,
        WS_THICKFRAME = 0x00040000,
        WS_MAXIMIZEBOX = 0x00020000,
        WS_MINIMIZEBOX = 0x00010000,
        WS_SIZEBOX = WS_THICKFRAME,
        WS_POPUP = 0x80000000,
        WS_EX_NOACTIVATE = 0x08000000,
        WS_EX_DLGMODALFRAME = 0x00000001,
        WS_EX_TOPMOST = 0x00000008,
        WS_EX_TOOLWINDOW = 0x00000080,
        WS_EX_WINDOWEDGE = 0x00000100,
        WS_EX_CLIENTEDGE = 0x00000200,
        WS_EX_CONTEXTHELP = 0x00000400,
        WS_EX_RIGHT = 0x00001000,
        WS_EX_RTLREADING = 0x00002000,
        WS_EX_LEFTSCROLLBAR = 0x00004000,
        WS_EX_STATICEDGE = 0x00020000,
        WS_EX_NOINHERITLAYOUT = 0x00100000, // Disable inheritence of mirroring by children
        WS_EX_LAYOUTRTL = 0x00400000, // Right to left mirroring
        WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE),
        WS_EX_CAPTIONOKBTN = 0x80000000,
        WS_EX_NODRAG = 0x40000000,
        WS_EX_ABOVESTARTUP = 0x20000000,
        WS_EX_INK = 0x10000000,
        WS_EX_NOANIMATION = 0x04000000
    }
}

所以基本上,用你的代码做:

public MyForm()
{
    DisableActivate();
    Width = 100;
    EnableActivate();
}

关于c# - 构造函数期间 OnActivated,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21932099/

相关文章:

multithreading - 我可以阻止垃圾收集器停止我的某些线程吗?

timer - 在 Compact Framework 中使用 System.Threading.Timer

c# - 用于序列化 C++ 和反序列化为 C# 类的 Protocol Buffer

C# 和 NPOI 无法读取数字和字符串值

c# - 如何使用键盘快捷键组合运行 WinForms 应用程序?

c# - Windows 应用程序在使用后台工作进程时被挂起

c# - ASP.NET 5 在 Startup 类中的ConfigureServices 中访问上下文或请求信息

c# - 使用 C# 与 Reporting Services 交互

c# - 如何检测C#表单中是否按下了多个键

WinCE 平台上 webkit 的 C# Qyoto 绑定(bind)