Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以在表单应用程序中实现WPF样式的启动屏幕?_Wpf_Winforms_Splash Screen - Fatal编程技术网

是否可以在表单应用程序中实现WPF样式的启动屏幕?

是否可以在表单应用程序中实现WPF样式的启动屏幕?,wpf,winforms,splash-screen,Wpf,Winforms,Splash Screen,在我的VisualStudio10项目中使用资源时,我遇到了一个名为SplashScreen的构建操作,这使我在上找到了这篇文章 四处寻找,我在上找到了这篇MSDN文章,但这是一种不同的方法:WinForms版本在主窗体初始化时只显示启动屏幕,而不是在应用程序加载之前使用本机代码加载启动屏幕 有没有办法在WinForms应用程序中实现这种出色的启动屏幕类型?可以使用非WPF表单来实现这一点,而且工作起来非常愉快。另一方面,它也是VS2008中的一个特性。可以使用非WPF表单来实现这一点,而且工作

在我的VisualStudio10项目中使用资源时,我遇到了一个名为SplashScreen的构建操作,这使我在上找到了这篇文章

四处寻找,我在上找到了这篇MSDN文章,但这是一种不同的方法:WinForms版本在主窗体初始化时只显示启动屏幕,而不是在应用程序加载之前使用本机代码加载启动屏幕


有没有办法在WinForms应用程序中实现这种出色的启动屏幕类型?

可以使用非WPF表单来实现这一点,而且工作起来非常愉快。另一方面,它也是VS2008中的一个特性。

可以使用非WPF表单来实现这一点,而且工作起来非常愉快。顺便说一句,它也是VS2008中的一项功能。

是的。在WPF应用程序与.NET3.5SP1打包之前,我为它做了一个实现

基本上,在加载程序集和初始化应用程序时,创建本机Win32窗口并显示BMP图像。您可以使用其他图像格式,但BMP是首选格式,因为它需要加载的库数量最少

一个快速创建本机splash窗口的google发布了几篇文章。我从快速扫描中发现的最全面的是布拉德利·格兰杰的作品:。这篇文章是为WPF编写的,但其概念是相同的:创建一个本机窗口,启动应用程序,关闭窗口

明天我将在工作中查看实现的源代码,并用示例更新我的答案

在此之前,谷歌和谷歌研究了许多已经存在的例子,开始着手

更新

正如所承诺的,下面是一个完整的示例,它实现了一个闪屏

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Windows.Interop;

namespace SplashScreen
{

    public class SplashScreenManager
    {
        static SplashScreen _current = null;

        static SplashScreenManager() {}
        SplashScreenManager() { }

        public static SplashScreen Create(Module module, int resourceID)
        {
            if (_current != null)
            {
                _current.Close();
                _current.Dispose();
            }

            _current = new SplashScreen(module, resourceID);
            return _current;
        }

        public static void Close()
        {
            if (_current == null)
                return;

            _current.Close();
            _current.Dispose();
            _current = null;
        }

        public static SplashScreen Current
        {
            get { return _current; }
        }

    }

    public class SplashScreen : IDisposable
    {                
        static bool IsClassRegistered = false;
        static string WindowClassName = "SplashScreenWindowClass";

        IntPtr _bitmapHandle = IntPtr.Zero;
        int _bitmapHeight;
        int _bitmapWidth;
        bool _isClosed;

        UnsafeNativeMethods.WndProc _splashWindowProcedureCallback;

        IntPtr _windowHandle = IntPtr.Zero;

        [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
        internal SplashScreen(Module module, int resourceID)
        {
            _bitmapHandle = UnsafeNativeMethods.LoadBitmap(Marshal.GetHINSTANCE(module), new IntPtr(resourceID));
            _splashWindowProcedureCallback = new UnsafeNativeMethods.WndProc(SplashWindowProcedure);
        }

        public void Close()
        {
            if (_isClosed)
                return;

            _isClosed = true;
            UnsafeNativeMethods.PostMessage(new HandleRef(this, _windowHandle), 0x10, IntPtr.Zero, IntPtr.Zero);
            if (_bitmapHandle != IntPtr.Zero)
            {
                UnsafeNativeMethods.DeleteObject(_bitmapHandle);
                _bitmapHandle = IntPtr.Zero;
            }
        }

        public void Close(IntPtr handle)
        {
            if (_windowHandle != IntPtr.Zero)
                UnsafeNativeMethods.SetForegroundWindow(handle);

            Close();
        }

        void CreateWindow()
        {
            if (!IsClassRegistered)
                RegisterClass();

            if (IsClassRegistered)
            {
                CreateWindowInternal();
                if (_windowHandle != IntPtr.Zero)
                    UnsafeNativeMethods.ShowWindow(_windowHandle, 5);

            }
        }

        public void Dispose()
        {
            Dispose(true);
        }

        protected virtual void Dispose(bool disposing)
        {
            Close(IntPtr.Zero);
            GC.SuppressFinalize(this);
        }

        void GetBitmapDimensions()
        {
            int cb = Marshal.SizeOf(typeof(UnsafeNativeMethods.BITMAP));
            IntPtr lpvObject = Marshal.AllocCoTaskMem(cb);
            UnsafeNativeMethods.GetObject(_bitmapHandle, cb, lpvObject);
            UnsafeNativeMethods.BITMAP bitmap = (UnsafeNativeMethods.BITMAP)Marshal.PtrToStructure(lpvObject, typeof(UnsafeNativeMethods.BITMAP));
            _bitmapWidth = bitmap.bmWidth;
            _bitmapHeight = bitmap.bmHeight;
            Marshal.FreeCoTaskMem(lpvObject);
        }

        void OnPaint(IntPtr hdc)
        {
            if (_bitmapHandle != IntPtr.Zero)
            {
                IntPtr ptr = UnsafeNativeMethods.CreateCompatibleDC(hdc);
                IntPtr hgdiobj = UnsafeNativeMethods.SelectObject(ptr, _bitmapHandle);
                UnsafeNativeMethods.BitBlt(hdc, 0, 0, _bitmapWidth, _bitmapHeight, ptr, 0, 0, 0xcc0020);
                UnsafeNativeMethods.SelectObject(ptr, hgdiobj);
                UnsafeNativeMethods.DeleteDC(ptr);
            }
        }

        void CreateWindowInternal()
        {
            int systemMetrics = UnsafeNativeMethods.GetSystemMetrics(0);
            int num4 = UnsafeNativeMethods.GetSystemMetrics(1);
            uint dwStyle = 0x80000000;
            uint dwExStyle = 0x188;
            IntPtr moduleHandle = UnsafeNativeMethods.GetModuleHandle(null);
            IntPtr desktopWindow = UnsafeNativeMethods.GetDesktopWindow();
            _windowHandle = UnsafeNativeMethods.CreateWindowEx(dwExStyle, WindowClassName, "", dwStyle, (systemMetrics - _bitmapWidth) / 2, (num4 - _bitmapHeight) / 2, _bitmapWidth, _bitmapHeight, desktopWindow, IntPtr.Zero, moduleHandle, IntPtr.Zero);
        }

        void RegisterClass()
        {
            IntPtr moduleHandle = UnsafeNativeMethods.GetModuleHandle(null);
            UnsafeNativeMethods.WNDCLASSEX lpwcx = new UnsafeNativeMethods.WNDCLASSEX();
            lpwcx.cbSize = (uint)Marshal.SizeOf(typeof(UnsafeNativeMethods.WNDCLASSEX));
            lpwcx.cbClsExtra = 0;
            lpwcx.cbWndExtra = 0;
            lpwcx.hbrBackground = IntPtr.Zero;
            lpwcx.hCursor = IntPtr.Zero;
            lpwcx.hIcon = IntPtr.Zero;
            lpwcx.hIconSm = IntPtr.Zero;
            lpwcx.hInstance = moduleHandle;
            lpwcx.lpfnWndProc = _splashWindowProcedureCallback;
            lpwcx.lpszClassName = WindowClassName;
            lpwcx.lpszMenuName = null;
            lpwcx.style = 0;
            if (UnsafeNativeMethods.RegisterClassExW(ref lpwcx) != 0)
            {
                IsClassRegistered = true;
            }
        }

        public void Show()
        {
            if (_windowHandle == IntPtr.Zero)
            {
                Thread thread = new Thread(new ThreadStart(ThreadMethod));
                thread.IsBackground = true;
                thread.Start();
            }
        }

        [SuppressUnmanagedCodeSecurity]
        IntPtr SplashWindowProcedure(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
        {
            if (msg == 15)
            {
                UnsafeNativeMethods.PAINTSTRUCT lpPaint = new UnsafeNativeMethods.PAINTSTRUCT();
                IntPtr hdc = UnsafeNativeMethods.BeginPaint(hWnd, out lpPaint);
                OnPaint(hdc);
                UnsafeNativeMethods.EndPaint(hWnd, ref lpPaint);
                return IntPtr.Zero;
            }

            return UnsafeNativeMethods.DefWindowProc(hWnd, msg, wParam, lParam);
        }

        [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
        void ThreadMethod()
        {
            if (_bitmapHandle != IntPtr.Zero)
            {
                GetBitmapDimensions();
                CreateWindow();
                MSG msg = new MSG();
                while (UnsafeNativeMethods.GetMessage(ref msg, _windowHandle, 0, 0) > 0)
                {
                    UnsafeNativeMethods.TranslateMessage(ref msg);
                    UnsafeNativeMethods.DispatchMessage(ref msg);
                }
                _windowHandle = IntPtr.Zero;
                GC.KeepAlive(this);
            }
        }

    }

    [SuppressUnmanagedCodeSecurity]
    internal sealed class UnsafeNativeMethods
    {
        // Fields
        internal const int GWL_EXSTYLE = -20;
        public const int LOGPIXELSX = 0x58;
        public const int LOGPIXELSY = 90;
        internal const uint MB_ICONASTERISK = 0x40;
        internal const uint MB_ICONERROR = 0x10;
        internal const uint MB_ICONEXCLAMATION = 0x30;
        internal const uint MB_ICONHAND = 0x10;
        internal const uint MB_ICONINFORMATION = 0x40;
        internal const uint MB_ICONQUESTION = 0x20;
        internal const uint MB_ICONWARNING = 0x30;
        internal const uint MB_OK = 0;
        internal const uint MB_OKCANCEL = 1;
        internal const uint MB_SETFOREGROUND = 0x10000;
        internal const uint MB_YESNO = 4;
        internal const uint MB_YESNOCANCEL = 3;
        internal const int SM_CXSCREEN = 0;
        internal const int SM_CYSCREEN = 1;
        public const int SPI_GETWORKAREA = 0x30;
        internal const uint SRCCOPY = 0xcc0020;
        public const int SW_HIDE = 0;
        internal const int SW_SHOW = 5;
        public const int SW_SHOWMAXIMIZED = 3;
        public const int SW_SHOWMINIMIZED = 2;
        public const int SW_SHOWNORMAL = 1;
        internal const int WM_CLOSE = 0x10;
        internal const uint WS_EX_TOOLWINDOW = 0x80;
        internal const uint WS_EX_TOPMOST = 8;
        internal const uint WS_EX_TRANSPARENT = 0x20;
        internal const uint WS_EX_WINDOWEDGE = 0x100;
        internal const uint WS_POPUP = 0x80000000;

        UnsafeNativeMethods() {}

        [DllImport("user32.dll")]
        public static extern IntPtr WindowFromPoint(POINT Point);
        [DllImport("user32.dll")]
        public static extern IntPtr ChildWindowFromPoint(IntPtr hWndParent, POINT Point);
        [DllImport("user32.dll")]
        public static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
        [DllImport("user32.dll")]
        internal static extern IntPtr BeginPaint(IntPtr hwnd, out PAINTSTRUCT lpPaint);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("gdi32.dll")]
        internal static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);
        [DllImport("gdi32.dll")]
        internal static extern IntPtr CreateCompatibleDC(IntPtr hdc);
        [DllImport("user32.dll", EntryPoint = "CreateWindowExW", CharSet = CharSet.Unicode)]
        internal static extern IntPtr CreateWindowEx(uint dwExStyle, string lpClassName, string lpWindowName, uint dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
        [DllImport("user32.dll")]
        internal static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("gdi32.dll")]
        internal static extern bool DeleteDC(IntPtr hdc);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("gdi32.dll")]
        internal static extern bool DeleteObject(IntPtr hObject);
        [DllImport("user32.dll")]
        internal static extern IntPtr DispatchMessage([In] ref MSG lpmsg);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool EndPaint(IntPtr hWnd, ref PAINTSTRUCT lpPaint);
        [DllImport("user32.dll")]
        public static extern IntPtr GetDC(IntPtr hWnd);
        [DllImport("user32.dll")]
        internal static extern IntPtr GetDC(HandleRef hWnd);
        [DllImport("user32.dll")]
        internal static extern IntPtr GetDesktopWindow();
        [DllImport("gdi32.dll")]
        public static extern int GetDeviceCaps(IntPtr hDC, int index);
        [DllImport("user32.dll", EntryPoint = "GetMessageW", CharSet = CharSet.Unicode, ExactSpelling = true)]
        internal static extern int GetMessage([In, Out] ref MSG msg, IntPtr hWnd, int uMsgFilterMin, int uMsgFilterMax);
        [DllImport("kernel32.dll", EntryPoint = "GetModuleHandleW", CharSet = CharSet.Unicode)]
        internal static extern IntPtr GetModuleHandle(string lpModuleName);
        [DllImport("gdi32.dll")]
        internal static extern int GetObject(IntPtr hgdiobj, int cbBuffer, IntPtr lpvObject);
        [DllImport("user32.dll")]
        internal static extern int GetSystemMetrics(int nIndex);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        internal static extern int GetWindowLong(IntPtr handle, int index);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        public static extern bool GetWindowPlacement(IntPtr hWnd, out WINDOWPLACEMENT lpwndpl);
        [DllImport("user32.dll", EntryPoint = "LoadBitmapW", CharSet = CharSet.Unicode)]
        internal static extern IntPtr LoadBitmap(IntPtr hInstance, IntPtr lpBitmapName);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool PostMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
        [return: MarshalAs(UnmanagedType.U2)]
        [DllImport("user32.dll")]
        internal static extern short RegisterClassExW([In] ref WNDCLASSEX lpwcx);
        [DllImport("user32.dll")]
        public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
        [DllImport("gdi32.dll")]
        internal static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool SetForegroundWindow(IntPtr hWnd);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        internal static extern int SetWindowLong(IntPtr handle, int index, int dwNewLong);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        public static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        public static extern bool SystemParametersInfo(int nAction, int nParam, ref RECT rc, int nUpdate);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool TranslateMessage([In] ref MSG lpMsg);

        [StructLayout(LayoutKind.Sequential)]
        internal struct BITMAP
        {
            public int bmType;
            public int bmWidth;
            public int bmHeight;
            public int bmWidthBytes;
            public ushort bmPlanes;
            public ushort bmBitsPixel;
            public IntPtr bmBits;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct PAINTSTRUCT
        {
            public IntPtr hdc;
            public bool fErase;
            public UnsafeNativeMethods.RECT rcPaint;
            public bool fRestore;
            public bool fIncUpdate;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
            public byte[] rgbReserved;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int X;
            public int Y;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct WINDOWPLACEMENT
        {
            public int Length;
            public int Flags;
            public int ShowCmd;
            public UnsafeNativeMethods.POINT MinPosition;
            public UnsafeNativeMethods.POINT MaxPosition;
            public UnsafeNativeMethods.RECT NormalPosition;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        internal struct WNDCLASSEX
        {
            public uint cbSize;
            public uint style;
            public UnsafeNativeMethods.WndProc lpfnWndProc;
            public int cbClsExtra;
            public int cbWndExtra;
            public IntPtr hInstance;
            public IntPtr hIcon;
            public IntPtr hCursor;
            public IntPtr hbrBackground;
            public string lpszMenuName;
            public string lpszClassName;
            public IntPtr hIconSm;
        }

        internal delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
    }

}

对。在WPF应用程序与.NET3.5SP1打包之前,我为它做了一个实现

基本上,在加载程序集和初始化应用程序时,创建本机Win32窗口并显示BMP图像。您可以使用其他图像格式,但BMP是首选格式,因为它需要加载的库数量最少

一个快速创建本机splash窗口的google发布了几篇文章。我从快速扫描中发现的最全面的是布拉德利·格兰杰的作品:。这篇文章是为WPF编写的,但其概念是相同的:创建一个本机窗口,启动应用程序,关闭窗口

明天我将在工作中查看实现的源代码,并用示例更新我的答案

在此之前,谷歌和谷歌研究了许多已经存在的例子,开始着手

更新

正如所承诺的,下面是一个完整的示例,它实现了一个闪屏

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Windows.Interop;

namespace SplashScreen
{

    public class SplashScreenManager
    {
        static SplashScreen _current = null;

        static SplashScreenManager() {}
        SplashScreenManager() { }

        public static SplashScreen Create(Module module, int resourceID)
        {
            if (_current != null)
            {
                _current.Close();
                _current.Dispose();
            }

            _current = new SplashScreen(module, resourceID);
            return _current;
        }

        public static void Close()
        {
            if (_current == null)
                return;

            _current.Close();
            _current.Dispose();
            _current = null;
        }

        public static SplashScreen Current
        {
            get { return _current; }
        }

    }

    public class SplashScreen : IDisposable
    {                
        static bool IsClassRegistered = false;
        static string WindowClassName = "SplashScreenWindowClass";

        IntPtr _bitmapHandle = IntPtr.Zero;
        int _bitmapHeight;
        int _bitmapWidth;
        bool _isClosed;

        UnsafeNativeMethods.WndProc _splashWindowProcedureCallback;

        IntPtr _windowHandle = IntPtr.Zero;

        [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
        internal SplashScreen(Module module, int resourceID)
        {
            _bitmapHandle = UnsafeNativeMethods.LoadBitmap(Marshal.GetHINSTANCE(module), new IntPtr(resourceID));
            _splashWindowProcedureCallback = new UnsafeNativeMethods.WndProc(SplashWindowProcedure);
        }

        public void Close()
        {
            if (_isClosed)
                return;

            _isClosed = true;
            UnsafeNativeMethods.PostMessage(new HandleRef(this, _windowHandle), 0x10, IntPtr.Zero, IntPtr.Zero);
            if (_bitmapHandle != IntPtr.Zero)
            {
                UnsafeNativeMethods.DeleteObject(_bitmapHandle);
                _bitmapHandle = IntPtr.Zero;
            }
        }

        public void Close(IntPtr handle)
        {
            if (_windowHandle != IntPtr.Zero)
                UnsafeNativeMethods.SetForegroundWindow(handle);

            Close();
        }

        void CreateWindow()
        {
            if (!IsClassRegistered)
                RegisterClass();

            if (IsClassRegistered)
            {
                CreateWindowInternal();
                if (_windowHandle != IntPtr.Zero)
                    UnsafeNativeMethods.ShowWindow(_windowHandle, 5);

            }
        }

        public void Dispose()
        {
            Dispose(true);
        }

        protected virtual void Dispose(bool disposing)
        {
            Close(IntPtr.Zero);
            GC.SuppressFinalize(this);
        }

        void GetBitmapDimensions()
        {
            int cb = Marshal.SizeOf(typeof(UnsafeNativeMethods.BITMAP));
            IntPtr lpvObject = Marshal.AllocCoTaskMem(cb);
            UnsafeNativeMethods.GetObject(_bitmapHandle, cb, lpvObject);
            UnsafeNativeMethods.BITMAP bitmap = (UnsafeNativeMethods.BITMAP)Marshal.PtrToStructure(lpvObject, typeof(UnsafeNativeMethods.BITMAP));
            _bitmapWidth = bitmap.bmWidth;
            _bitmapHeight = bitmap.bmHeight;
            Marshal.FreeCoTaskMem(lpvObject);
        }

        void OnPaint(IntPtr hdc)
        {
            if (_bitmapHandle != IntPtr.Zero)
            {
                IntPtr ptr = UnsafeNativeMethods.CreateCompatibleDC(hdc);
                IntPtr hgdiobj = UnsafeNativeMethods.SelectObject(ptr, _bitmapHandle);
                UnsafeNativeMethods.BitBlt(hdc, 0, 0, _bitmapWidth, _bitmapHeight, ptr, 0, 0, 0xcc0020);
                UnsafeNativeMethods.SelectObject(ptr, hgdiobj);
                UnsafeNativeMethods.DeleteDC(ptr);
            }
        }

        void CreateWindowInternal()
        {
            int systemMetrics = UnsafeNativeMethods.GetSystemMetrics(0);
            int num4 = UnsafeNativeMethods.GetSystemMetrics(1);
            uint dwStyle = 0x80000000;
            uint dwExStyle = 0x188;
            IntPtr moduleHandle = UnsafeNativeMethods.GetModuleHandle(null);
            IntPtr desktopWindow = UnsafeNativeMethods.GetDesktopWindow();
            _windowHandle = UnsafeNativeMethods.CreateWindowEx(dwExStyle, WindowClassName, "", dwStyle, (systemMetrics - _bitmapWidth) / 2, (num4 - _bitmapHeight) / 2, _bitmapWidth, _bitmapHeight, desktopWindow, IntPtr.Zero, moduleHandle, IntPtr.Zero);
        }

        void RegisterClass()
        {
            IntPtr moduleHandle = UnsafeNativeMethods.GetModuleHandle(null);
            UnsafeNativeMethods.WNDCLASSEX lpwcx = new UnsafeNativeMethods.WNDCLASSEX();
            lpwcx.cbSize = (uint)Marshal.SizeOf(typeof(UnsafeNativeMethods.WNDCLASSEX));
            lpwcx.cbClsExtra = 0;
            lpwcx.cbWndExtra = 0;
            lpwcx.hbrBackground = IntPtr.Zero;
            lpwcx.hCursor = IntPtr.Zero;
            lpwcx.hIcon = IntPtr.Zero;
            lpwcx.hIconSm = IntPtr.Zero;
            lpwcx.hInstance = moduleHandle;
            lpwcx.lpfnWndProc = _splashWindowProcedureCallback;
            lpwcx.lpszClassName = WindowClassName;
            lpwcx.lpszMenuName = null;
            lpwcx.style = 0;
            if (UnsafeNativeMethods.RegisterClassExW(ref lpwcx) != 0)
            {
                IsClassRegistered = true;
            }
        }

        public void Show()
        {
            if (_windowHandle == IntPtr.Zero)
            {
                Thread thread = new Thread(new ThreadStart(ThreadMethod));
                thread.IsBackground = true;
                thread.Start();
            }
        }

        [SuppressUnmanagedCodeSecurity]
        IntPtr SplashWindowProcedure(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
        {
            if (msg == 15)
            {
                UnsafeNativeMethods.PAINTSTRUCT lpPaint = new UnsafeNativeMethods.PAINTSTRUCT();
                IntPtr hdc = UnsafeNativeMethods.BeginPaint(hWnd, out lpPaint);
                OnPaint(hdc);
                UnsafeNativeMethods.EndPaint(hWnd, ref lpPaint);
                return IntPtr.Zero;
            }

            return UnsafeNativeMethods.DefWindowProc(hWnd, msg, wParam, lParam);
        }

        [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
        void ThreadMethod()
        {
            if (_bitmapHandle != IntPtr.Zero)
            {
                GetBitmapDimensions();
                CreateWindow();
                MSG msg = new MSG();
                while (UnsafeNativeMethods.GetMessage(ref msg, _windowHandle, 0, 0) > 0)
                {
                    UnsafeNativeMethods.TranslateMessage(ref msg);
                    UnsafeNativeMethods.DispatchMessage(ref msg);
                }
                _windowHandle = IntPtr.Zero;
                GC.KeepAlive(this);
            }
        }

    }

    [SuppressUnmanagedCodeSecurity]
    internal sealed class UnsafeNativeMethods
    {
        // Fields
        internal const int GWL_EXSTYLE = -20;
        public const int LOGPIXELSX = 0x58;
        public const int LOGPIXELSY = 90;
        internal const uint MB_ICONASTERISK = 0x40;
        internal const uint MB_ICONERROR = 0x10;
        internal const uint MB_ICONEXCLAMATION = 0x30;
        internal const uint MB_ICONHAND = 0x10;
        internal const uint MB_ICONINFORMATION = 0x40;
        internal const uint MB_ICONQUESTION = 0x20;
        internal const uint MB_ICONWARNING = 0x30;
        internal const uint MB_OK = 0;
        internal const uint MB_OKCANCEL = 1;
        internal const uint MB_SETFOREGROUND = 0x10000;
        internal const uint MB_YESNO = 4;
        internal const uint MB_YESNOCANCEL = 3;
        internal const int SM_CXSCREEN = 0;
        internal const int SM_CYSCREEN = 1;
        public const int SPI_GETWORKAREA = 0x30;
        internal const uint SRCCOPY = 0xcc0020;
        public const int SW_HIDE = 0;
        internal const int SW_SHOW = 5;
        public const int SW_SHOWMAXIMIZED = 3;
        public const int SW_SHOWMINIMIZED = 2;
        public const int SW_SHOWNORMAL = 1;
        internal const int WM_CLOSE = 0x10;
        internal const uint WS_EX_TOOLWINDOW = 0x80;
        internal const uint WS_EX_TOPMOST = 8;
        internal const uint WS_EX_TRANSPARENT = 0x20;
        internal const uint WS_EX_WINDOWEDGE = 0x100;
        internal const uint WS_POPUP = 0x80000000;

        UnsafeNativeMethods() {}

        [DllImport("user32.dll")]
        public static extern IntPtr WindowFromPoint(POINT Point);
        [DllImport("user32.dll")]
        public static extern IntPtr ChildWindowFromPoint(IntPtr hWndParent, POINT Point);
        [DllImport("user32.dll")]
        public static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
        [DllImport("user32.dll")]
        internal static extern IntPtr BeginPaint(IntPtr hwnd, out PAINTSTRUCT lpPaint);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("gdi32.dll")]
        internal static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);
        [DllImport("gdi32.dll")]
        internal static extern IntPtr CreateCompatibleDC(IntPtr hdc);
        [DllImport("user32.dll", EntryPoint = "CreateWindowExW", CharSet = CharSet.Unicode)]
        internal static extern IntPtr CreateWindowEx(uint dwExStyle, string lpClassName, string lpWindowName, uint dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
        [DllImport("user32.dll")]
        internal static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("gdi32.dll")]
        internal static extern bool DeleteDC(IntPtr hdc);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("gdi32.dll")]
        internal static extern bool DeleteObject(IntPtr hObject);
        [DllImport("user32.dll")]
        internal static extern IntPtr DispatchMessage([In] ref MSG lpmsg);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool EndPaint(IntPtr hWnd, ref PAINTSTRUCT lpPaint);
        [DllImport("user32.dll")]
        public static extern IntPtr GetDC(IntPtr hWnd);
        [DllImport("user32.dll")]
        internal static extern IntPtr GetDC(HandleRef hWnd);
        [DllImport("user32.dll")]
        internal static extern IntPtr GetDesktopWindow();
        [DllImport("gdi32.dll")]
        public static extern int GetDeviceCaps(IntPtr hDC, int index);
        [DllImport("user32.dll", EntryPoint = "GetMessageW", CharSet = CharSet.Unicode, ExactSpelling = true)]
        internal static extern int GetMessage([In, Out] ref MSG msg, IntPtr hWnd, int uMsgFilterMin, int uMsgFilterMax);
        [DllImport("kernel32.dll", EntryPoint = "GetModuleHandleW", CharSet = CharSet.Unicode)]
        internal static extern IntPtr GetModuleHandle(string lpModuleName);
        [DllImport("gdi32.dll")]
        internal static extern int GetObject(IntPtr hgdiobj, int cbBuffer, IntPtr lpvObject);
        [DllImport("user32.dll")]
        internal static extern int GetSystemMetrics(int nIndex);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        internal static extern int GetWindowLong(IntPtr handle, int index);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        public static extern bool GetWindowPlacement(IntPtr hWnd, out WINDOWPLACEMENT lpwndpl);
        [DllImport("user32.dll", EntryPoint = "LoadBitmapW", CharSet = CharSet.Unicode)]
        internal static extern IntPtr LoadBitmap(IntPtr hInstance, IntPtr lpBitmapName);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool PostMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
        [return: MarshalAs(UnmanagedType.U2)]
        [DllImport("user32.dll")]
        internal static extern short RegisterClassExW([In] ref WNDCLASSEX lpwcx);
        [DllImport("user32.dll")]
        public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
        [DllImport("gdi32.dll")]
        internal static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool SetForegroundWindow(IntPtr hWnd);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        internal static extern int SetWindowLong(IntPtr handle, int index, int dwNewLong);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        public static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        public static extern bool SystemParametersInfo(int nAction, int nParam, ref RECT rc, int nUpdate);
        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll")]
        internal static extern bool TranslateMessage([In] ref MSG lpMsg);

        [StructLayout(LayoutKind.Sequential)]
        internal struct BITMAP
        {
            public int bmType;
            public int bmWidth;
            public int bmHeight;
            public int bmWidthBytes;
            public ushort bmPlanes;
            public ushort bmBitsPixel;
            public IntPtr bmBits;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct PAINTSTRUCT
        {
            public IntPtr hdc;
            public bool fErase;
            public UnsafeNativeMethods.RECT rcPaint;
            public bool fRestore;
            public bool fIncUpdate;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
            public byte[] rgbReserved;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int X;
            public int Y;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct WINDOWPLACEMENT
        {
            public int Length;
            public int Flags;
            public int ShowCmd;
            public UnsafeNativeMethods.POINT MinPosition;
            public UnsafeNativeMethods.POINT MaxPosition;
            public UnsafeNativeMethods.RECT NormalPosition;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        internal struct WNDCLASSEX
        {
            public uint cbSize;
            public uint style;
            public UnsafeNativeMethods.WndProc lpfnWndProc;
            public int cbClsExtra;
            public int cbWndExtra;
            public IntPtr hInstance;
            public IntPtr hIcon;
            public IntPtr hCursor;
            public IntPtr hbrBackground;
            public string lpszMenuName;
            public string lpszClassName;
            public IntPtr hIconSm;
        }

        internal delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
    }

}

这看起来不错。另请参阅奥尔森的《重塑》:@Tom:我实际上是先读奥尔森的帖子,然后通过链接找到布拉德利的文章。今天晚些时候有时间我会更新我的答案。这看起来不错。另请参阅奥尔森的《重塑》:@Tom:我实际上是先读奥尔森的帖子,然后通过链接找到布拉德利的文章。今天晚些时候有时间的时候我会更新我的答案。