OSDN Git Service

aa3da3fa21b04fe8b065a210e9accae8c213af36
[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                                 ReleaseDC(hWnd, hDc);\r
60                         } else {\r
61                                 DeleteObject(hDc);\r
62                         }\r
63                 }\r
64                 \r
65                 public void Dispose()\r
66                 {\r
67                         ReleaseHdc();\r
68                 }\r
69                 \r
70                 /// <summary>\r
71                 /// 指定されたデバイスコンテキストのオブジェクトを選択\r
72                 /// </summary>\r
73                 /// <example><code>\r
74                 ///     context.SelectObject(bitmap.GetHbitmap(Color.FromArgb(0)));\r
75                 /// </code></example>\r
76                 /// <param name="hGdiObj">選択するオブジェクトのハンドル</param>\r
77                 /// <returns>置き換えが発生する前のオブジェクトのハンドル</returns>\r
78                 public IntPtr SelectObject(IntPtr hGdiObj)\r
79                 {\r
80                         return SelectObject(hDc, hGdiObj);\r
81                 }\r
82                 \r
83                 #region DllImport\r
84                 \r
85                 [DllImport("user32.dll")]\r
86                 private static extern IntPtr GetDC(HandleRef hWnd);\r
87                 \r
88                 [DllImport("user32.dll")]\r
89                 private static extern int ReleaseDC(HandleRef hWnd, IntPtr hDC);\r
90                 \r
91                 [DllImport("gdi32.dll", SetLastError=true)]\r
92                 private static extern IntPtr CreateCompatibleDC(IntPtr hdc);\r
93                 \r
94                 [DllImport("gdi32.dll", ExactSpelling=true, PreserveSig=true, SetLastError=true)]\r
95                 private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);\r
96                 \r
97                 [DllImport("gdi32.dll")]\r
98                 private static extern bool DeleteObject(IntPtr hObject);\r
99                 \r
100                 #endregion\r
101         }\r
102         \r
103         public class SprashScreenLayered : Form\r
104         {\r
105                 public static Form CreateSprashScreenLayered(Bitmap bitmap, Color bgColor)\r
106                 {\r
107                         Form form;\r
108                         \r
109                         if (OSFeature.Feature.IsPresent(OSFeature.LayeredWindows)) {\r
110                                 form = new SprashScreenLayered();\r
111                                 form.BackgroundImage = bitmap;\r
112                         } else {\r
113                                 form = new Form();\r
114                                 form.BackgroundImage = bitmap;\r
115                                 form.BackColor = bgColor;\r
116                         }\r
117                         //form.ShowInTaskbar = false;\r
118                         form.ControlBox = false;\r
119                         form.FormBorderStyle = FormBorderStyle.None;\r
120                         form.StartPosition = FormStartPosition.CenterScreen;\r
121                         form.Size = bitmap.Size;\r
122                         \r
123                         if (form is SprashScreenLayered) {\r
124                                 ((SprashScreenLayered) form).CenterToScreen2();\r
125                         }\r
126                         \r
127                         return form;\r
128                 }\r
129                 \r
130                 public SprashScreenLayered()\r
131                 {\r
132                 }\r
133                 \r
134                 protected internal void CenterToScreen2()\r
135                 {\r
136                         base.CenterToScreen();\r
137                 }\r
138                 \r
139                 protected override CreateParams CreateParams {\r
140                         get {\r
141                                 CreateParams param = base.CreateParams;\r
142                                 // param.ExStyle |= WS_EX_LAYERED;\r
143                                 param.ExStyle |= 0x00080000;\r
144                                 return param;\r
145                         }\r
146                 }\r
147                 \r
148                 public override Image BackgroundImage {\r
149                         set {\r
150                                 base.BackgroundImage = value;\r
151                                 updateLayeredWindow();\r
152                         }\r
153                 }\r
154                                 \r
155                 #region UpdateLayeredWindow関連\r
156                 \r
157                 [DllImport("user32.dll", ExactSpelling=true, SetLastError=true)]\r
158                 private static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst,\r
159                                                                [In] ref Point pptDst, [In] ref Size psize,\r
160                                                                IntPtr hdcSrc, [In] ref Point pptSrc,\r
161                                                                uint crKey,\r
162                                                                [In] ref BLENDFUNCTION pblend,\r
163                                                                uint dwFlags);\r
164                 \r
165                 private Bitmap convertBitmap(Image img)\r
166                 {\r
167                         if (img is Bitmap) {\r
168                                 return (Bitmap) img;\r
169                         } else {\r
170                                 Bitmap bitmap = new Bitmap(img.Width, img.Height, img.PixelFormat);\r
171                                 Graphics.FromImage(bitmap).DrawImage(img, 0, 0);\r
172                                 return bitmap;\r
173                         }\r
174                 }\r
175                 \r
176                 protected void updateLayeredWindow()\r
177                 {\r
178                         Point ptDest = this.Location;\r
179                         Point ptSrc  = Point.Empty;\r
180                         Size  size   = BackgroundImage.Size;\r
181                         \r
182                         BLENDFUNCTION blend = new BLENDFUNCTION();\r
183                         blend.BlendOp = 0; // AC_SRC_OVER\r
184                         blend.BlendFlags = 0;\r
185                         blend.SourceConstantAlpha = 255;\r
186                         blend.AlphaFormat = 1; // AC_SRC_ALPHA\r
187                         \r
188                         using(DisplayDeviceContext screen = new DisplayDeviceContext(IntPtr.Zero))\r
189                         using(DisplayDeviceContext mem = screen.CreateCompatibleDisplayDeviceContext())\r
190                         using(DisplayDeviceContext hBitmap = DisplayDeviceContext.FromHdc(\r
191                                 convertBitmap(BackgroundImage).GetHbitmap(Color.FromArgb(0))\r
192                         )) {\r
193                                 IntPtr hOldBitmap = IntPtr.Zero;\r
194                                 \r
195                                 try {\r
196                                         hOldBitmap = mem.SelectObject(hBitmap.GetHdc());\r
197                                         \r
198                                         UpdateLayeredWindow(this.Handle, screen.GetHdc(),\r
199                                             ref ptSrc, ref size,\r
200                                             mem.GetHdc(), ref ptDest,\r
201                                             0,\r
202                                             ref blend,\r
203                                             2 /* ULW_ALPHA */);\r
204                                 } finally {\r
205                                         if (hBitmap.GetHdc() != IntPtr.Zero) {\r
206                                                 mem.SelectObject(hOldBitmap);\r
207                                         }\r
208                                 }\r
209                         }\r
210                 }\r
211                 \r
212                 [StructLayout(LayoutKind.Sequential, Pack=1)]\r
213                 protected struct BLENDFUNCTION\r
214                 {\r
215                         public byte BlendOp;\r
216                         public byte BlendFlags;\r
217                         public byte SourceConstantAlpha;\r
218                         public byte AlphaFormat;\r
219                 }\r
220                 \r
221                 #endregion\r
222                 \r
223         }\r
224 }\r