OSDN Git Service

AppliStation-GUI,半透明スプラッシュスクリーンの導入
authorttp <ttp@users.sourceforge.jp>
Sat, 6 Dec 2008 14:34:33 +0000 (14:34 +0000)
committerttp <ttp@users.sourceforge.jp>
Sat, 6 Dec 2008 14:34:33 +0000 (14:34 +0000)
git-svn-id: http://localhost/svn/AppliStation/trunk@999 34ed2c89-c49f-4a4b-abdb-c318350108cf

AppliStation/AppliStation.Util/SprashScreenLayered.cs [new file with mode: 0644]
AppliStation/AppliStation.csproj
AppliStation/Program.cs
AppliStation/SplashScreen.png

diff --git a/AppliStation/AppliStation.Util/SprashScreenLayered.cs b/AppliStation/AppliStation.Util/SprashScreenLayered.cs
new file mode 100644 (file)
index 0000000..9e61338
--- /dev/null
@@ -0,0 +1,225 @@
+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
index caaf6f3..8f0a982 100644 (file)
@@ -68,6 +68,7 @@
     <Compile Include="AppliStation.Util\ListViewItemSortComparer.cs" />\r
     <Compile Include="AppliStation.Util\NativeMethods.cs" />\r
     <Compile Include="AppliStation.Util\GUIUtils.cs" />\r
+    <Compile Include="AppliStation.Util\SprashScreenLayered.cs" />\r
     <Compile Include="AppliStation.Util\ToolStripPetitLauncherMenuItem.cs" />\r
     <Compile Include="AppliStation.Util\ToolStripWeb2LikeTextBox.cs" />\r
     <Compile Include="AssemblyInfo.cs" />\r
index b6acf53..f448d31 100644 (file)
@@ -189,15 +189,15 @@ namespace AppliStation
                \r
                private static Form createAndOpenSplashScreen()\r
                {\r
-                       Form splashScreen = new Form();\r
-                       splashScreen.FormBorderStyle = FormBorderStyle.None;\r
-                       splashScreen.BackgroundImage = System.Drawing.Bitmap.FromFile(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "SplashScreen.png"));\r
-                       splashScreen.Size = splashScreen.BackgroundImage.Size;\r
-                       splashScreen.ShowIcon = false;\r
-                       splashScreen.ShowInTaskbar = false;\r
-                       splashScreen.StartPosition = FormStartPosition.CenterScreen;\r
+                       System.Drawing.Bitmap bitmap;\r
+                       \r
+                       bitmap = new System.Drawing.Bitmap(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "SplashScreen.png"));\r
+                       Form splashScreen = AppliStation.Util.SprashScreenLayered.CreateSprashScreenLayered(bitmap, System.Drawing.Color.Black);\r
+                       \r
+                       splashScreen.Text = "AppliStation";\r
+                       splashScreen.Icon = System.Drawing.Icon.ExtractAssociatedIcon(Application.ExecutablePath);\r
                        splashScreen.Show();\r
-               \r
+                       \r
                        return splashScreen;\r
                }\r
                \r
index daa5c53..6d6af84 100644 (file)
Binary files a/AppliStation/SplashScreen.png and b/AppliStation/SplashScreen.png differ