--- /dev/null
+using System;\r
+using System.Drawing;\r
+using System.Windows.Forms;\r
+\r
+using System.Runtime.InteropServices;\r
+\r
+namespace AppliStation.Util\r
+{\r
+ public class DisplayDeviceContext : IDeviceContext, IDisposable\r
+ {\r
+ private HandleRef hWnd;\r
+ private IntPtr hDc;\r
+ private bool isGottenDc;\r
+ \r
+ /// <summary>\r
+ /// ディスプレイコンテクストの生成\r
+ /// </summary>\r
+ /// <param name="hWnd">ウィンドウハンドル</param>\r
+ public DisplayDeviceContext(IntPtr hWnd)\r
+ : this(new HandleRef(null, hWnd))\r
+ {\r
+ }\r
+\r
+ /// <summary>\r
+ /// ディスプレイコンテクストの生成\r
+ /// </summary>\r
+ /// <param name="hWnd">ウィンドウハンドル</param>\r
+ public DisplayDeviceContext(HandleRef hWnd)\r
+ {\r
+ this.hWnd = hWnd;\r
+ this.hDc = GetDC(hWnd);\r
+ this.isGottenDc = true;\r
+ }\r
+ \r
+ protected DisplayDeviceContext(IntPtr hDc, bool isGottenDc)\r
+ {\r
+ this.hDc = hDc;\r
+ this.isGottenDc = isGottenDc;\r
+ }\r
+ \r
+ public static DisplayDeviceContext FromHdc(IntPtr hDc)\r
+ {\r
+ return new DisplayDeviceContext(hDc, false);\r
+ }\r
+ \r
+ public DisplayDeviceContext CreateCompatibleDisplayDeviceContext()\r
+ {\r
+ return FromHdc(CreateCompatibleDC(hDc));\r
+ }\r
+ \r
+ public IntPtr GetHdc()\r
+ {\r
+ return hDc;\r
+ }\r
+ \r
+ public void ReleaseHdc()\r
+ {\r
+ if (this.isGottenDc) { // GetDC 関数を使って取得した場合\r
+ ReleaseDC(hWnd, hDc);\r
+ } else {\r
+ DeleteObject(hDc);\r
+ }\r
+ }\r
+ \r
+ public void Dispose()\r
+ {\r
+ ReleaseHdc();\r
+ }\r
+ \r
+ /// <summary>\r
+ /// 指定されたデバイスコンテキストのオブジェクトを選択\r
+ /// </summary>\r
+ /// <example><code>\r
+ /// context.SelectObject(bitmap.GetHbitmap(Color.FromArgb(0)));\r
+ /// </code></example>\r
+ /// <param name="hGdiObj">選択するオブジェクトのハンドル</param>\r
+ /// <returns>置き換えが発生する前のオブジェクトのハンドル</returns>\r
+ public IntPtr SelectObject(IntPtr hGdiObj)\r
+ {\r
+ return SelectObject(hDc, hGdiObj);\r
+ }\r
+ \r
+ #region DllImport\r
+ \r
+ [DllImport("user32.dll")]\r
+ private static extern IntPtr GetDC(HandleRef hWnd);\r
+ \r
+ [DllImport("user32.dll")]\r
+ private static extern int ReleaseDC(HandleRef hWnd, IntPtr hDC);\r
+ \r
+ [DllImport("gdi32.dll", SetLastError=true)]\r
+ private static extern IntPtr CreateCompatibleDC(IntPtr hdc);\r
+ \r
+ [DllImport("gdi32.dll", ExactSpelling=true, PreserveSig=true, SetLastError=true)]\r
+ private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);\r
+ \r
+ [DllImport("gdi32.dll")]\r
+ private static extern bool DeleteObject(IntPtr hObject);\r
+ \r
+ #endregion\r
+ }\r
+ \r
+ public class SprashScreenLayered : Form\r
+ {\r
+ public static Form CreateSprashScreenLayered(Bitmap bitmap, Color bgColor)\r
+ {\r
+ Form form;\r
+ \r
+ if (OSFeature.Feature.IsPresent(OSFeature.LayeredWindows)) {\r
+ form = new SprashScreenLayered();\r
+ form.Size = bitmap.Size;\r
+ form.BackgroundImage = bitmap;\r
+ } else {\r
+ form = new Form();\r
+ form.Size = bitmap.Size;\r
+ form.BackgroundImage = bitmap;\r
+ form.BackColor = bgColor;\r
+ }\r
+ //form.ShowInTaskbar = false;\r
+ form.ControlBox = false;\r
+ form.FormBorderStyle = FormBorderStyle.None;\r
+ form.StartPosition = FormStartPosition.CenterScreen;\r
+ \r
+ if (form is SprashScreenLayered) {\r
+ ((SprashScreenLayered) form).CenterToScreen2();\r
+ }\r
+ \r
+ return form;\r
+ }\r
+ \r
+ public SprashScreenLayered()\r
+ {\r
+ }\r
+ \r
+ protected internal void CenterToScreen2()\r
+ {\r
+ base.CenterToScreen();\r
+ }\r
+ \r
+ protected override CreateParams CreateParams {\r
+ get {\r
+ CreateParams param = base.CreateParams;\r
+ // param.ExStyle |= WS_EX_LAYERED;\r
+ param.ExStyle |= 0x00080000;\r
+ return param;\r
+ }\r
+ }\r
+ \r
+ public override Image BackgroundImage {\r
+ set {\r
+ base.BackgroundImage = value;\r
+ updateLayeredWindow();\r
+ }\r
+ }\r
+ \r
+ #region UpdateLayeredWindow関連\r
+ \r
+ [DllImport("user32.dll", ExactSpelling=true, SetLastError=true)]\r
+ private static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst,\r
+ [In] ref Point pptDst, [In] ref Size psize,\r
+ IntPtr hdcSrc, [In] ref Point pptSrc,\r
+ uint crKey,\r
+ [In] ref BLENDFUNCTION pblend,\r
+ uint dwFlags);\r
+ \r
+ private Bitmap convertBitmap(Image img)\r
+ {\r
+ if (img is Bitmap) {\r
+ return (Bitmap) img;\r
+ } else {\r
+ Bitmap bitmap = new Bitmap(img.Width, img.Height, img.PixelFormat);\r
+ Graphics.FromImage(bitmap).DrawImage(img, 0, 0);\r
+ return bitmap;\r
+ }\r
+ }\r
+ \r
+ protected void updateLayeredWindow()\r
+ {\r
+ Point ptDest = this.Location;\r
+ Point ptSrc = Point.Empty;\r
+ Size size = BackgroundImage.Size;\r
+ \r
+ BLENDFUNCTION blend = new BLENDFUNCTION();\r
+ blend.BlendOp = 0; // AC_SRC_OVER\r
+ blend.BlendFlags = 0;\r
+ blend.SourceConstantAlpha = 255;\r
+ blend.AlphaFormat = 1; // AC_SRC_ALPHA\r
+ \r
+ using(DisplayDeviceContext screen = new DisplayDeviceContext(IntPtr.Zero))\r
+ using(DisplayDeviceContext mem = screen.CreateCompatibleDisplayDeviceContext())\r
+ using(DisplayDeviceContext hBitmap = DisplayDeviceContext.FromHdc(\r
+ convertBitmap(BackgroundImage).GetHbitmap(Color.FromArgb(0))\r
+ )) {\r
+ IntPtr hOldBitmap = IntPtr.Zero;\r
+ \r
+ try {\r
+ hOldBitmap = mem.SelectObject(hBitmap.GetHdc());\r
+ \r
+ UpdateLayeredWindow(this.Handle, screen.GetHdc(),\r
+ ref ptSrc, ref size,\r
+ mem.GetHdc(), ref ptDest,\r
+ 0,\r
+ ref blend,\r
+ 2 /* ULW_ALPHA */);\r
+ } finally {\r
+ if (hBitmap.GetHdc() != IntPtr.Zero) {\r
+ mem.SelectObject(hOldBitmap);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
+ [StructLayout(LayoutKind.Sequential, Pack=1)]\r
+ protected struct BLENDFUNCTION\r
+ {\r
+ public byte BlendOp;\r
+ public byte BlendFlags;\r
+ public byte SourceConstantAlpha;\r
+ public byte AlphaFormat;\r
+ }\r
+ \r
+ #endregion\r
+ \r
+ }\r
+}\r