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