SplashScreen.cs
Upload User: wertech
Upload Date: 2016-01-22
Package Size: 27773k
Code Size: 16k
Category:

CSharp

Development Platform:

C#

  1. //---------------------------------------------------------------------------
  2. //
  3. //  Copyright (c) Microsoft Corporation.  All rights reserved.
  4. //
  5. //---------------------------------------------------------------------------
  6. using System;
  7. using System.Windows;
  8. using System.Diagnostics.CodeAnalysis;
  9. using System.Runtime.InteropServices;
  10. using System.Runtime.InteropServices.ComTypes;
  11. [module: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "Microsoft.Elementalist.SplashScreen+WNDCLASSEX..ctor()")]
  12. [module: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "Microsoft.Elementalist.SplashScreen.Open():System.Void")]
  13. [module: SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources", Scope = "member", Target = "Microsoft.Elementalist.SplashScreen+WNDCLASSEX.hCursor")]
  14. [module: SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources", Scope = "member", Target = "Microsoft.Elementalist.SplashScreen._splashScreenHwnd")]
  15. namespace MsdnReader
  16. {
  17.     internal class SplashScreen
  18.     {
  19.         //-------------------------------------------------------------------
  20.         //
  21.         //  Public Methods
  22.         //
  23.         //-------------------------------------------------------------------
  24.         public void Open()
  25.         {
  26.             IntPtr hInstance = Marshal.GetHINSTANCE(typeof(SplashScreen).Module);
  27.             BITMAP bitmapInfo = new BITMAP();
  28.             IntPtr splashScreenBitmap = GetHBitmapFromResource(hInstance, SplashScreenResourceType, SplashScreenResourceId);
  29.             GetBitmapInformation(splashScreenBitmap, Marshal.SizeOf(typeof(BITMAP)), ref bitmapInfo);
  30.             int top, left;
  31.             CreateWindow(hInstance, bitmapInfo.bmWidth, bitmapInfo.bmHeight, out left, out top);
  32.             SelectBitmap(splashScreenBitmap, bitmapInfo.bmWidth, bitmapInfo.bmHeight, left, top);
  33.         }
  34.         public void Close()
  35.         {
  36.             DestroyWindow(_splashScreenHwnd);
  37.             _splashScreenHwnd = IntPtr.Zero;
  38.             GlobalUnlock(_hBuffer);
  39.             GlobalFree(_hBuffer);
  40.             GdiplusShutdown(_gdiPlusToken);
  41.         }
  42.         public void SetParent(IntPtr hNewParent)
  43.         {
  44.             SetParent(_splashScreenHwnd, hNewParent);
  45.         }
  46.         //-------------------------------------------------------------------
  47.         //
  48.         //  Private Methods
  49.         //
  50.         //-------------------------------------------------------------------
  51.         private void SelectBitmap(IntPtr hBitmap, int width, int height, int left, int top)
  52.         {
  53.             IntPtr screenDc = GetDC(IntPtr.Zero);
  54.             IntPtr memDc = CreateCompatibleDC(screenDc);
  55.             IntPtr hOldBitmap = IntPtr.Zero;
  56.             try
  57.             {
  58.                 hOldBitmap = SelectObject(memDc, hBitmap);
  59.                 Size newSize = new Size(width, height);
  60.                 Point sourceLocation = new Point(0, 0);
  61.                 Point newLocation = new Point(left, top);
  62.                 BLENDFUNCTION blend = new BLENDFUNCTION();
  63.                 blend.BlendOp = AC_SRC_OVER; 
  64.                 blend.BlendFlags = 0; 
  65.                 blend.SourceconstantAlpha = 255; 
  66.                 blend.AlphaFormat = AC_SRC_ALPHA;
  67.                 Bool result = UpdateLayeredWindow(this._splashScreenHwnd, screenDc, ref newLocation, ref newSize,
  68.                     memDc, ref sourceLocation, 0, ref blend, ULW_ALPHA);
  69.             }
  70.             finally
  71.             {
  72.                 ReleaseDC(IntPtr.Zero, screenDc);
  73.                 if (hBitmap != IntPtr.Zero)
  74.                 {
  75.                     SelectObject(memDc, hOldBitmap);
  76.                     DeleteObject(hBitmap);
  77.                 }
  78.                 DeleteDC(memDc);
  79.             }
  80.         }
  81.         private void CreateWindow(IntPtr hInstance, int width, int height, out int left, out int top)
  82.         {
  83.             left = top = 0;
  84.             // Prepare the window class
  85.             WNDCLASSEX splashScreenWindowClass = new WNDCLASSEX();
  86.             splashScreenWindowClass.cbSize = Marshal.SizeOf(typeof(WNDCLASSEX));
  87.             splashScreenWindowClass.style = CS_HREDRAW | CS_VREDRAW;
  88.             splashScreenWindowClass.lpfnWndProc = _splashWndProc;
  89.             splashScreenWindowClass.cbClsExtra = 0;
  90.             splashScreenWindowClass.cbWndExtra = 0;
  91.             splashScreenWindowClass.hInstance = hInstance;
  92.             splashScreenWindowClass.hCursor = LoadCursor(IntPtr.Zero, IDC_ARROW);
  93.             splashScreenWindowClass.lpszClassName = SplashScreenClassName;
  94.             splashScreenWindowClass.lpszMenuName = String.Empty;
  95.             // Register the window class
  96.             if (RegisterClassEx(ref splashScreenWindowClass) != 0)
  97.             {
  98.                 // Calculate the window position
  99.                 int screenWidth = GetSystemMetrics(SM_CXSCREEN);
  100.                 int screenHeight = GetSystemMetrics(SM_CYSCREEN);
  101.                 int x = (screenWidth - width) / 2;
  102.                 int y = (screenHeight - height) / 2;
  103.                 // Create and display the window
  104.                 _splashScreenHwnd = CreateWindowEx(
  105.                     WS_EX_PALETTEWINDOW | WS_EX_LAYERED, // | WS_EX_TOPMOST,
  106.                     SplashScreenClassName,
  107.                     String.Empty,
  108.                     WS_POPUP | WS_VISIBLE,
  109.                     x, y, width, height,
  110.                     IntPtr.Zero, IntPtr.Zero, hInstance, IntPtr.Zero);
  111.                 left = x;
  112.                 top = y;
  113.             }
  114.         }
  115.         private IntPtr GetHBitmapFromResource(IntPtr hInstance, string resourceType, int resourceId)
  116.         {
  117.             // Initialize GDIPLUS
  118.             _gdiPlusStartupInput.GdiplusVersion = 1;
  119.             _gdiPlusStartupInput.DebugEventCallback = IntPtr.Zero;
  120.             _gdiPlusStartupInput.SuppressBackgroundThread = false;
  121.             _gdiPlusStartupInput.SuppressExternalCodecs = false;
  122.             StartupOutput output;
  123.             GdiplusStartup(out _gdiPlusToken, ref _gdiPlusStartupInput, out output);
  124.             IntPtr hBitmap = IntPtr.Zero;
  125.             IntPtr hResource = FindResource(hInstance, resourceId, resourceType);
  126.             uint size = SizeofResource(hInstance, hResource);
  127.             IntPtr pResourceData = LoadResource(hInstance, hResource);
  128.             pResourceData = LockResource(pResourceData);
  129.             _hBuffer = GlobalAlloc(GMEM_MOVEABLE, size);
  130.             if (_hBuffer != IntPtr.Zero)
  131.             {
  132.                 IntPtr pBuffer = GlobalLock(_hBuffer);
  133.                 CopyMemory(pBuffer, pResourceData, size);
  134.                 IStream pIStream;
  135.                 if (CreateStreamOnHGlobal(_hBuffer, false, out pIStream) == 0)
  136.                 {
  137.                     IntPtr pBmp;
  138.                     int result = GdipCreateBitmapFromStream(pIStream, out pBmp);
  139.                     result = GdipCreateHBITMAPFromBitmap(pBmp, out hBitmap, 0);
  140.                 }
  141.             }
  142.             return hBitmap;
  143.         }
  144.         //-------------------------------------------------------------------
  145.         //
  146.         //  P/Invoke
  147.         //
  148.         //-------------------------------------------------------------------
  149.         #region Interop private constants
  150.         private const int SM_CXSCREEN = 0;
  151.         private const int SM_CYSCREEN = 1;
  152.         private const int CS_HREDRAW = 0x0001;
  153.         private const int CS_VREDRAW = 0x0002;
  154.         private const uint WS_EX_PALETTEWINDOW = 0x00000100 | 0x00000080;
  155.         private const uint WS_POPUP = 0x80000000;
  156.         private const uint WS_VISIBLE = 0x10000000;
  157.         private const int WS_EX_LAYERED = 0x00080000;
  158.         private const int WS_EX_TOPMOST = 0x00000008;
  159.         private const uint GMEM_MOVEABLE = 0x0002;
  160.         private const Int32 HTCAPTION = 0x02;
  161.         private const Int32 WM_NCHITTEST = 0x84;
  162.         private const Int32 ULW_ALPHA = 0x02;
  163.         private const byte AC_SRC_OVER = 0x00;
  164.         private const byte AC_SRC_ALPHA = 0x01;
  165.         #endregion
  166.         #region DllImports
  167.         [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
  168.         private static extern IntPtr CreateCompatibleDC(IntPtr hDC);
  169.         [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
  170.         private static extern Bool DeleteDC(IntPtr hdc);
  171.         [DllImport("Gdi32.dll")]
  172.         private static extern bool DeleteObject(IntPtr hObject);
  173.         [DllImport("Gdi32.dll", CharSet = CharSet.Unicode, EntryPoint = "GetObjectW")]
  174.         private static extern int GetBitmapInformation(IntPtr hgdiobj, int cbBuffer, ref BITMAP lpvObject);
  175.         [DllImport("gdi32.dll", ExactSpelling = true)]
  176.         private static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
  177.         [DllImport("gdiplus.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
  178.         private static extern int GdipCreateBitmapFromStream(IStream stream, out IntPtr pBitmap);
  179.         [DllImport("gdiplus.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
  180.         private static extern int GdipCreateHBITMAPFromBitmap(IntPtr pBitmap, out IntPtr hBitmap, int argb);
  181.         [DllImport("gdiplus.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
  182.         private static extern int GdiplusShutdown(IntPtr token);
  183.         [DllImport("gdiplus.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
  184.         private static extern int GdiplusStartup(out IntPtr token, ref StartupInput input, out  StartupOutput output);
  185.         [DllImport("kernel32.dll")]
  186.         private static extern IntPtr CopyMemory(IntPtr destination, IntPtr source, uint length);
  187.         [DllImport("kernel32.dll")]
  188.         private static extern IntPtr FindResource(IntPtr hModule, int lpName, int lpType);
  189.         [DllImport("kernel32.dll")]
  190.         private static extern IntPtr FindResource(IntPtr hModule, int lpName, string lpType);
  191.         [DllImport("kernel32.dll")]
  192.         private static extern IntPtr GlobalAlloc(uint uFlags, uint dwBytes);
  193.         [DllImport("kernel32.dll")]
  194.         private static extern IntPtr GlobalFree(IntPtr hMem);
  195.         [DllImport("kernel32.dll")]
  196.         private static extern IntPtr GlobalLock(IntPtr hMem);
  197.         [DllImport("kernel32.dll")]
  198.         private static extern IntPtr GlobalUnlock(IntPtr hMem);
  199.         [DllImport("kernel32.dll", SetLastError = true)]
  200.         private static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
  201.         [DllImport("kernel32.dll")]
  202.         private static extern IntPtr LockResource(IntPtr hResData);
  203.         [DllImport("kernel32.dll", SetLastError = true)]
  204.         private static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);
  205.         [DllImport("ole32.dll")]
  206.         private static extern int CreateStreamOnHGlobal(IntPtr hGlobal, bool fDeleteOnRelease, out IStream ppstm);
  207.         [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
  208.         private static extern Bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);
  209.         [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
  210.         private static extern IntPtr GetDC(IntPtr hWnd);
  211.         [DllImport("user32.dll", ExactSpelling = true)]
  212.         private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
  213.         [DllImport("User32.dll", CharSet = CharSet.Unicode, EntryPoint = "CreateWindowExW")]
  214.         private static extern IntPtr CreateWindowEx(
  215.             uint dwExStyle,
  216.             string lpClassName,
  217.             string lpWindowName,
  218.             uint dwStyle,
  219.             int x,
  220.             int y,
  221.             int nWidth,
  222.             int nHeight,
  223.             IntPtr hWndParent,
  224.             IntPtr hMenu,
  225.             IntPtr hInstance,
  226.             IntPtr lpParam
  227.             );
  228.         [DllImport("User32.dll")]
  229.         private static extern bool DestroyWindow(IntPtr hWnd);
  230.         [DllImport("User32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegisterClassExW")]
  231.         [return: MarshalAs(UnmanagedType.U2)]
  232.         private static extern short RegisterClassEx([In] ref WNDCLASSEX lpwcx);
  233.         [DllImport("User32.dll", CharSet = CharSet.Unicode, EntryPoint = "DefWindowProcW")]
  234.         private static extern int DefWindowProc(IntPtr hWnd, int Msg, int wParam, int lParam);
  235.         private delegate int WindowProc(IntPtr hWnd, int Msg, int wParam, int lParam);
  236.         [DllImport("User32.dll", CharSet = CharSet.Unicode, EntryPoint = "LoadCursorW")]
  237.         private static extern IntPtr LoadCursor(
  238.             IntPtr hInstance,
  239.             IntPtr lpCursorName
  240.         );
  241.         [DllImport("User32.dll")]
  242.         private static extern int GetSystemMetrics(int nIndex);
  243.         [DllImport("user32.dll")]
  244.         private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
  245.         #endregion
  246.         #region Interop structures
  247.         [StructLayout(LayoutKind.Sequential)]
  248.         private struct StartupOutput
  249.         {
  250.             public IntPtr hook;
  251.             public IntPtr unhook;
  252.         }
  253.         [StructLayout(LayoutKind.Sequential)]
  254.         private struct StartupInput
  255.         {
  256.             public int GdiplusVersion;
  257.             public IntPtr DebugEventCallback;
  258.             public bool SuppressBackgroundThread;
  259.             public bool SuppressExternalCodecs;
  260.         }
  261.         [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  262.         private struct WNDCLASSEX
  263.         {
  264.             public int cbSize;
  265.             public int style;
  266.             [MarshalAs(UnmanagedType.FunctionPtr)]
  267.             public WindowProc lpfnWndProc;
  268.             public int cbClsExtra;
  269.             public int cbWndExtra;
  270.             public IntPtr hInstance;
  271.             public IntPtr hIcon;
  272.             public IntPtr hCursor;
  273.             public IntPtr hbrBackground;
  274.             public string lpszMenuName;
  275.             public string lpszClassName;
  276.             public IntPtr hSmIcon;
  277.         }
  278.         [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  279.         private struct BITMAP
  280.         {
  281.             public int bmType;
  282.             public int bmWidth;
  283.             public int bmHeight;
  284.             public int bmWidthBytes;
  285.             public short bmPlanes;
  286.             public short bmBitsPixel;
  287.             public IntPtr bmBits;
  288.         }
  289.         private enum Bool
  290.         {
  291.             False = 0,
  292.             True = 1
  293.         }
  294.         [StructLayout(LayoutKind.Sequential)]
  295.         private struct Point
  296.         {
  297.             public Int32 x;
  298.             public Int32 y;
  299.             public Point(Int32 x, Int32 y)
  300.             {
  301.                 this.x = x; 
  302.                 this.y = y; 
  303.             }
  304.         }
  305.         [StructLayout(LayoutKind.Sequential)]
  306.         private struct Size
  307.         {
  308.             public Int32 cx;
  309.             public Int32 cy;
  310.             public Size(Int32 cx, Int32 cy)
  311.             {
  312.                 this.cx = cx;
  313.                 this.cy = cy;
  314.             }
  315.         }
  316.         [StructLayout(LayoutKind.Sequential, Pack = 1)]
  317.         private struct ARGB
  318.         {
  319.             public byte Blue;
  320.             public byte Green;
  321.             public byte Red;
  322.             public byte Alpha;
  323.         }
  324.         [StructLayout(LayoutKind.Sequential, Pack = 1)]
  325.         private struct BLENDFUNCTION
  326.         {
  327.             public byte BlendOp;
  328.             public byte BlendFlags;
  329.             public byte SourceconstantAlpha;
  330.             public byte AlphaFormat;
  331.         }
  332.         #endregion
  333.         //-------------------------------------------------------------------
  334.         //
  335.         //  Private Fields
  336.         //
  337.         //-------------------------------------------------------------------
  338.         private readonly static IntPtr IDC_ARROW = new IntPtr(32512);
  339.         private readonly static WindowProc _splashWndProc = new WindowProc(DefWindowProc); // Keep the reference alive
  340.         private const string SplashScreenClassName = "WpfSplashScreen";
  341.         private const int SplashScreenResourceId = 101;
  342.         private const string SplashScreenResourceType = "PNG";
  343.         
  344.         private IntPtr _splashScreenHwnd;
  345.         private IntPtr _gdiPlusToken;
  346.         private StartupInput _gdiPlusStartupInput;
  347.         private IntPtr _hBuffer;
  348.     }
  349. }