OSDN Git Service

AppliStation-GUI,インストール除外リストの設定を設定ダイアログに追加
[applistation/AppliStation.git] / AppliStation / AppliStation.Util / SprashScreenLayered.cs
1 using System;\r
2 using System.Drawing;\r
3 using System.Windows.Forms;\r
4 \r
5 using System.Runtime.InteropServices;\r
6 \r
7 namespace AppliStation.Util\r
8 {\r
9         public class DisplayDeviceContext : IDeviceContext, IDisposable\r
10         {\r
11                 private HandleRef hWnd;\r
12                 private IntPtr hDc;\r
13                 private bool isGottenDc;\r
14                 \r
15                 /// <summary>\r
16                 /// ディスプレイコンテクストの生成\r
17                 /// </summary>\r
18                 /// <param name="hWnd">ウィンドウハンドル</param>\r
19                 public DisplayDeviceContext(IntPtr hWnd)\r
20                         : this(new HandleRef(null, hWnd))\r
21                 {\r
22                 }\r
23 \r
24                 /// <summary>\r
25                 /// ディスプレイコンテクストの生成\r
26                 /// </summary>\r
27                 /// <param name="hWnd">ウィンドウハンドル</param>\r
28                 public DisplayDeviceContext(HandleRef hWnd)\r
29                 {\r
30                         this.hWnd = hWnd;\r
31                         this.hDc = GetDC(hWnd);\r
32                         this.isGottenDc = true;\r
33                 }\r
34                 \r
35                 protected DisplayDeviceContext(IntPtr hDc, bool isGottenDc)\r
36                 {\r
37                         this.hDc = hDc;\r
38                         this.isGottenDc = isGottenDc;\r
39                 }\r
40                 \r
41                 public static DisplayDeviceContext FromHdc(IntPtr hDc)\r
42                 {\r
43                         return new DisplayDeviceContext(hDc, false);\r
44                 }\r
45                 \r
46                 public DisplayDeviceContext CreateCompatibleDisplayDeviceContext()\r
47                 {\r
48                         return FromHdc(CreateCompatibleDC(hDc));\r
49                 }\r
50                 \r
51                 public IntPtr GetHdc()\r
52                 {\r
53                         return hDc;\r
54                 }\r
55                 \r
56                 public void ReleaseHdc()\r
57                 {\r
58                         if (this.isGottenDc) { // GetDC 関数を使って取得した場合\r
59                                 int result = ReleaseDC(hWnd, hDc);\r
60                                 if (result != 1) {\r
61                                         throw new System.ComponentModel.Win32Exception();\r
62                                 }\r
63                         } else {\r
64                                 DeleteObject(hDc);\r
65                         }\r
66                 }\r
67                 \r
68                 public void Dispose()\r
69                 {\r
70                         ReleaseHdc();\r
71                         GC.SuppressFinalize(this);\r
72                 }\r
73                 \r
74                 /// <summary>\r
75                 /// 指定されたデバイスコンテキストのオブジェクトを選択\r
76                 /// </summary>\r
77                 /// <example><code>\r
78                 ///     context.SelectObject(bitmap.GetHbitmap(Color.FromArgb(0)));\r
79                 /// </code></example>\r
80                 /// <param name="hGdiObj">選択するオブジェクトのハンドル</param>\r
81                 /// <returns>置き換えが発生する前のオブジェクトのハンドル</returns>\r
82                 public IntPtr SelectObject(IntPtr hGdiObj)\r
83                 {\r
84                         return SelectObject(hDc, hGdiObj);\r
85                 }\r
86                 \r
87                 #region DllImport\r
88                 \r
89                 [DllImport("user32.dll")]\r
90                 private static extern IntPtr GetDC(HandleRef hWnd);\r
91                 \r
92                 [DllImport("user32.dll")]\r
93                 private static extern int ReleaseDC(HandleRef hWnd, IntPtr hDC);\r
94                 \r
95                 [DllImport("gdi32.dll", SetLastError=true)]\r
96                 private static extern IntPtr CreateCompatibleDC(IntPtr hdc);\r
97                 \r
98                 [DllImport("gdi32.dll", ExactSpelling=true, PreserveSig=true, SetLastError=true)]\r
99                 private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);\r
100                 \r
101                 [DllImport("gdi32.dll")]\r
102                 [return: MarshalAs(UnmanagedType.Bool)]\r
103                 private static extern bool DeleteObject(IntPtr hObject);\r
104                 \r
105                 #endregion\r
106         }\r
107         \r
108         public class SprashScreenLayered : Form\r
109         {\r
110                 public static Form CreateSprashScreenLayered(Image img, Color bgColor)\r
111                 {\r
112                         Form form;\r
113                         SprashScreenLayered ss = null;\r
114                         \r
115                         if (OSFeature.Feature.IsPresent(OSFeature.LayeredWindows)) {\r
116                                 form = ss = new SprashScreenLayered();\r
117                                 form.BackgroundImage = img;\r
118                         } else {\r
119                                 form = new Form();\r
120                                 form.BackgroundImage = img;\r
121                                 form.BackColor = bgColor;\r
122                         }\r
123                         //form.ShowInTaskbar = false;\r
124                         form.ControlBox = false;\r
125                         form.FormBorderStyle = FormBorderStyle.None;\r
126                         form.StartPosition = FormStartPosition.CenterScreen;\r
127                         form.Size = img.Size;\r
128                         \r
129                         if (ss != null) {\r
130                                 ss.CenterToScreen2();\r
131                         }\r
132                         \r
133                         return form;\r
134                 }\r
135                 \r
136                 public SprashScreenLayered()\r
137                 {\r
138                 }\r
139                 \r
140                 protected internal void CenterToScreen2()\r
141                 {\r
142                         base.CenterToScreen();\r
143                 }\r
144                 \r
145                 protected override CreateParams CreateParams {\r
146                         get {\r
147                                 CreateParams param = base.CreateParams;\r
148                                 // param.ExStyle |= WS_EX_LAYERED;\r
149                                 param.ExStyle |= 0x00080000;\r
150                                 return param;\r
151                         }\r
152                 }\r
153                 \r
154                 public override Image BackgroundImage {\r
155                         set {\r
156                                 base.BackgroundImage = value;\r
157                                 updateLayeredWindow();\r
158                         }\r
159                 }\r
160                                 \r
161                 #region UpdateLayeredWindow関連\r
162                 \r
163                 [DllImport("user32.dll", ExactSpelling=true, SetLastError=true)]\r
164                 [return: MarshalAs(UnmanagedType.Bool)]\r
165                 private static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst,\r
166                                                                [In] ref Point pptDst, [In] ref Size psize,\r
167                                                                IntPtr hdcSrc, [In] ref Point pptSrc,\r
168                                                                uint crKey,\r
169                                                                [In] ref BLENDFUNCTION pblend,\r
170                                                                uint dwFlags);\r
171                 \r
172                 private static Bitmap convertBitmap(Image img)\r
173                 {\r
174                         Bitmap bitmap;\r
175                         \r
176                         bitmap = img as Bitmap;\r
177                         if (bitmap == null) {\r
178                                 bitmap = new Bitmap(img.Width, img.Height, img.PixelFormat);\r
179                                 Graphics.FromImage(bitmap).DrawImage(img, 0, 0);\r
180                         }\r
181                         return bitmap;\r
182                 }\r
183                 \r
184                 protected void updateLayeredWindow()\r
185                 {\r
186                         Point ptDest = this.Location;\r
187                         Point ptSrc  = Point.Empty;\r
188                         Size  size   = BackgroundImage.Size;\r
189                         \r
190                         BLENDFUNCTION blend = new BLENDFUNCTION();\r
191                         blend.BlendOp = 0; // AC_SRC_OVER\r
192                         blend.BlendFlags = 0;\r
193                         blend.SourceConstantAlpha = 255;\r
194                         blend.AlphaFormat = 1; // AC_SRC_ALPHA\r
195                         \r
196                         using(DisplayDeviceContext screen = new DisplayDeviceContext(IntPtr.Zero))\r
197                         using(DisplayDeviceContext mem = screen.CreateCompatibleDisplayDeviceContext())\r
198                         using(DisplayDeviceContext hBitmap = DisplayDeviceContext.FromHdc(\r
199                                 convertBitmap(BackgroundImage).GetHbitmap(Color.FromArgb(0))\r
200                         )) {\r
201                                 IntPtr hOldBitmap = IntPtr.Zero;\r
202                                 \r
203                                 try {\r
204                                         hOldBitmap = mem.SelectObject(hBitmap.GetHdc());\r
205                                         \r
206                                         UpdateLayeredWindow(this.Handle, screen.GetHdc(),\r
207                                             ref ptSrc, ref size,\r
208                                             mem.GetHdc(), ref ptDest,\r
209                                             0,\r
210                                             ref blend,\r
211                                             2 /* ULW_ALPHA */);\r
212                                 } finally {\r
213                                         if (hBitmap.GetHdc() != IntPtr.Zero) {\r
214                                                 mem.SelectObject(hOldBitmap);\r
215                                         }\r
216                                 }\r
217                         }\r
218                 }\r
219                 \r
220                 [StructLayout(LayoutKind.Sequential, Pack=1)]\r
221                 protected internal struct BLENDFUNCTION\r
222                 {\r
223                         public byte BlendOp;\r
224                         public byte BlendFlags;\r
225                         public byte SourceConstantAlpha;\r
226                         public byte AlphaFormat;\r
227                 }\r
228                 \r
229                 #endregion\r
230                 \r
231         }\r
232 }\r