2

のコンストラクター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が表示され、[OK] をクリックすると、OnActivated()が再び呼び出されるため、再び表示されます。

デバイス メーカーは、これは OS 固有の問題であると私に言いました。これが Windows Embedded 7 が「フォームを処理する」方法であることを確認できる人はいますか?

4

1 に答える 1

2

.NET CF 3.5 を搭載した Windows CE 5.0 デバイスでこれを試して、あなたと同じ動作を経験したかどうかを確認しました。まったく同じコードで、OnActivated が呼び出されませんでした。代わりに Application.Run() が使用された場合でも、Width を設定しても OnActivated が呼び出されませんでした。実際、Activate() を明示的に呼び出してみたため、Activate を実行できるようにフォームを表示する必要があったようです。

したがって、これは Windows Embedded 7 が以前のバージョンの Windows CE に対して行っていることのようです。また、Reflector を使用して CompactFramework .NET .dll を調べようとしましたが、幅が変更されたときにフォームをアクティブにするコードが .NET に見つかりませんでした。Width は 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();
}
于 2014-02-24T16:12:09.833 に答える