public static extern bool AlphaBlend(SafeDCHandle hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, SafeDCHandle hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, BLENDFUNCTION blendFunction);
public static extern int GetThemePartSize(SafeThemeHandle hTheme, SafeDCHandle hdc, int part, int state, PRECT pRect, ThemeSize eSize, out Size size);
public static extern int GetThemeTextExtent(SafeThemeHandle hTheme, SafeDCHandle hdc, int iPartId, int iStateId, string text, int textLength, TextFormatFlags textFlags, ref RECT boundingRect, out RECT extentRect);
public static extern unsafe int DrawText( SafeDCHandle hDC, [Friendly(FriendlyFlags.Array | FriendlyFlags.Bidirectional)] char* lpString, int nCount, [Friendly(FriendlyFlags.Bidirectional)] RECT* lpRect, TextFormats uFormat);
public void DrawParentBackground(IWin32Window childWindow, IDeviceContext graphics, Rectangle?bounds = null) { using (var hdc = new SafeDCHandle(graphics)) DrawThemeParentBackground(new HandleRef(childWindow, childWindow.Handle), hdc, bounds); }
public static extern BackgroundMode SetBkMode(SafeDCHandle hdc, BackgroundMode mode);
public static extern bool TransparentBlt(SafeDCHandle hdcDest, int xOriginDest, int yOriginDest, int wDest, int hDest, SafeDCHandle hdcSrc, int xOriginSrc, int yOriginSrc, int wSrc, int hSrc, int crTransparent);
public static extern int DrawThemeText(SafeThemeHandle hTheme, SafeDCHandle hdc, int iPartId, int iStateId, string text, int textLength, TextFormatFlags textFlags, int textFlags2, ref RECT pRect);
public static extern int DrawThemeTextEx(SafeThemeHandle hTheme, SafeDCHandle hdc, int iPartId, int iStateId, string text, int iCharCount, TextFormatFlags dwFlags, ref RECT pRect, ref DrawThemeTextOptions pOptions);
public static extern int DrawThemeIcon(SafeThemeHandle hTheme, SafeDCHandle hdc, int iPartId, int iStateId, ref RECT pRect, IntPtr himl, int iImageIndex);
public static extern int DrawThemeParentBackgroundEx(IntPtr hwnd, SafeDCHandle hdc, DrawThemeParentBackgroundFlags dwFlags, PRECT pRect);
public static extern int DrawThemeBackgroundEx(SafeThemeHandle hTheme, SafeDCHandle hdc, int iPartId, int iStateId, ref RECT pRect, DrawThemeBackgroundOptions opts);
public static extern int DrawThemeBackground(SafeThemeHandle hTheme, SafeDCHandle hdc, int iPartId, int iStateId, ref RECT pRect, PRECT pClipRect);
/// <summary> /// カーソルの画像を取得する /// </summary> /// <param name="iconHandle"> /// カーソルアイコンへのハンドル /// </param> /// <param name="iconInfo"> /// カーソルアイコン情報 /// </param> /// <param name="backgroundImage"> /// カーソルの背景画像(NULLを指定した場合は白一色の背景として描画する) /// </param> /// <param name="drawPoint"> /// 背景画像に対してカーソルを描画する座標 /// (背景画像を使用しない場合は NULL を指定する)</param> /// <exception cref="PlatformInvokeException"> /// Win32Apiの下記の処理の呼び出しに失敗した場合に発生 /// ・「DLL:gdi32.dll、メソッド:CreateCompatibleDC」 /// ・「DLL:gdi32.dll、メソッド:SelectObject」 /// ・「DLL:gdi32.dll、メソッド:BitBlt」 /// ・「DLL:gdi32.dll、メソッド:DeleteObject」 /// ・「DLL:gdi32.dll、メソッド:DeleteDC」 /// </exception> /// <exception cref="Win32OperateException"> /// Win32Apiの下記の処理に失敗した場合に発生 /// ・「DLL:gdi32.dll、メソッド:CreateCompatibleDC」 /// ・「DLL:gdi32.dll、メソッド:SelectObject」 /// ・「DLL:gdi32.dll、メソッド:BitBlt」 /// ・「DLL:gdi32.dll、メソッド:DeleteObject」 /// ・「DLL:gdi32.dll、メソッド:DeleteDC」 /// </exception> /// <returns>カーソル画像(取得できない場合はNULLを返却する)</returns> private static Bitmap GetCursorImage( SafeCopyIconHandle iconHandle, IconInfo.ICONINFO iconInfo, Bitmap backgroundImage = null, Point?drawPoint = null) { // カラー・マスク情報が存在するか判定 bool hasColor = IsBitmap(iconInfo.ColorBitmapHandle); bool hasMask = IsBitmap(iconInfo.MaskBitmapHandle); // アイコンのカラー、マスクの両方が取得できない場合 // 画像情報は取得できないため NULL を返す if (!hasColor && !hasMask) { return(null); } // アイコンのハンドルからカーソルアイコンを取得する Icon cursorIcon; try { cursorIcon = Icon.FromHandle(iconHandle.Handle); } catch (ExternalException) { // アイコンのハンドルからカーソルアイコンを生成できない場合、NULL を返す return(null); } // カーソルがモノクロかカラーでそれぞれ取得を行う if (hasColor) { // カラーの場合 // アイコン画像をビットマップ形式に変換して、そのまま返す return(cursorIcon.ToBitmap()); } // モノクロの場合 // 画像に関するリソースの解放用の宣言 Bitmap cursorImage = null; Graphics cursorImageGraphics = null; Bitmap baseImage = null; Bitmap maskImage = null; bool isCreateBase = false; try { // 各画像データの生成 // カーソル画像と、グラフィックオブジェクト生成 cursorImage = new Bitmap(cursorIcon.Width, cursorIcon.Height); cursorImageGraphics = Graphics.FromImage(cursorImage); // 背景画像の生成 // 引数で背景画像が与えられていない場合、白一色の背景画像を生成する if (backgroundImage == null) { baseImage = new Bitmap(cursorIcon.Width, cursorIcon.Height); using (Graphics graphics = Graphics.FromImage(baseImage)) { graphics.FillRectangle(Brushes.White, graphics.VisibleClipBounds); } isCreateBase = true; } else { isCreateBase = false; } // マスク画像の生成 maskImage = Image.FromHbitmap(iconInfo.MaskBitmapHandle); // アンマネージリソースの解放用の宣言 SafeDCHandle cursorHdc = null; SafeDCHandle baseHdc = null; SafeDCHandle maskHdc = null; IntPtr beforeBase = IntPtr.Zero; IntPtr beforeMask = IntPtr.Zero; RuntimeHelpers.PrepareConstrainedRegions(); try { // カーソル画像のデバイスコンテキストを取得 cursorHdc = new SafeDCHandle(cursorImageGraphics); // 背景画像のデバイスコンテキストを取得 IntPtr baseHBitmap = isCreateBase ? baseImage.GetHbitmap() : backgroundImage.GetHbitmap(); baseHdc = CreateCompatibleDC(IntPtr.Zero); beforeBase = SelectBitmap(baseHdc, baseHBitmap); // マスク画像のデバイスコンテキストを取得 IntPtr maskHBitmap = maskImage.GetHbitmap(); maskHdc = CreateCompatibleDC(IntPtr.Zero); beforeMask = SelectBitmap(maskHdc, maskHBitmap); // 画像の合成処理 int width = cursorImage.Width; int height = cursorImage.Height; Point base1Pt = drawPoint ?? new Point(0, 0); Point mask1Pt = new Point(0, 0); Point mask2Pt = new Point(0, maskImage.Height / 2); BitBlt(cursorHdc, 0, 0, width, height, baseHdc, base1Pt.X, base1Pt.Y, ROPCode.SRCCOPY); BitBlt(cursorHdc, 0, 0, width, height, maskHdc, mask1Pt.X, mask1Pt.Y, ROPCode.SRCAND); BitBlt(cursorHdc, 0, 0, width, height, maskHdc, mask2Pt.X, mask2Pt.Y, ROPCode.SRCINVERT); } finally { // リソースの解放処理 // カーソル画像に関するリソースの解放 try { } finally { cursorHdc.Dispose(); } // 元となる背景画像に関するリソースの解放 try { if (baseHdc != null) { IntPtr baseHandle = SelectBitmap(baseHdc, beforeBase); if (baseHandle != IntPtr.Zero) { DeleteObject(baseHandle); } } } finally { baseHdc?.Dispose(); } // マスク画像に関するリソースの解放 try { if (maskHdc != null) { IntPtr maskHandle = SelectBitmap(maskHdc, beforeMask); if (maskHandle != IntPtr.Zero) { DeleteObject(maskHandle); } } } finally { maskHdc?.Dispose(); } } } catch { // 例外発生時はカーソル画像を破棄する cursorImage.Dispose(); // 発生した例外はそのままスローする throw; } finally { // 画像リソースを解放する cursorImageGraphics?.Dispose(); baseImage?.Dispose(); maskImage?.Dispose(); } // 背景画像を白一色で生成した場合、背景を透過する if (isCreateBase) { cursorImage.MakeTransparent(Color.White); } // 合成したカーソル画像を返す return(cursorImage); }
public static extern bool BitBlt(SafeDCHandle hdc, int nXDest, int nYDest, int nWidth, int nHeight, SafeDCHandle hdcSrc, int nXSrc, int nYSrc, RasterOperationMode dwRop);
public static extern int GetThemeBackgroundContentRect(SafeThemeHandle hTheme, SafeDCHandle hdc, int iPartId, int iStateId, ref RECT pBoundingRect, out RECT pContentRect);
public static extern IntPtr SelectObject(SafeDCHandle hDC, IntPtr hObject);
public static extern int GetThemeBitmap(SafeThemeHandle hTheme, SafeDCHandle hdc, int iPartId, int iStateId, int iPropId, int dwFlags, out IntPtr phBitmap);
public static extern DCLayout SetLayout(SafeDCHandle hdc, DCLayout dwLayout);
public static extern int GetThemeMargins(SafeThemeHandle hTheme, SafeDCHandle hdc, int iPartId, int iStateId, int iPropId, IntPtr prc, out RECT pMargins);
public static extern int GetThemeFont(SafeThemeHandle hTheme, SafeDCHandle hdc, int iPartId, int iStateId, int iPropId, out LOGFONT pFont);
public static extern int GetThemeMetric(SafeThemeHandle hTheme, SafeDCHandle hdc, int iPartId, int iStateId, int iPropId, out int piVal);
public static extern unsafe int DrawTextEx( SafeDCHandle hdc, [Friendly(FriendlyFlags.Array | FriendlyFlags.Bidirectional)] char* lpchText, int cchText, [Friendly(FriendlyFlags.Bidirectional)] RECT* lprc, uint dwDTFormat, [Friendly(FriendlyFlags.In | FriendlyFlags.Optional)] DRAWTEXTPARAMS* lpDTParams);
/// <summary> /// Gets the background image of the current visual style element within the specified background color. If <paramref name="states"/> /// is set, the resulting image will contain each of the state images side by side. /// </summary> /// <param name="rnd">The <see cref="VisualStyleRenderer"/> instance.</param> /// <param name="clr">The background color. This color cannot have an alpha channel.</param> /// <param name="states">The optional list of states to render side by side.</param> /// <returns>The background image.</returns> public static Bitmap GetBackgroundBitmap(this VisualStyleRenderer rnd, Color clr, int[] states = null) { const int wh = 200; if (rnd == null) { throw new ArgumentNullException(nameof(rnd)); } rnd.SetParameters(rnd.Class, rnd.Part, 0); if (states == null) { states = new[] { rnd.State } } ; var i = states.Length; // Get image size Size imgSz; using (var sg = Graphics.FromHwnd(IntPtr.Zero)) imgSz = rnd.GetPartSize(sg, new Rectangle(0, 0, wh, wh), ThemeSizeType.Draw); if (imgSz.Width == 0 || imgSz.Height == 0) { imgSz = new Size(rnd.GetInteger(IntegerProperty.Width), rnd.GetInteger(IntegerProperty.Height)); } var bounds = new Rectangle(0, 0, imgSz.Width * i, imgSz.Height); // Draw each background linearly down the bitmap using (var memoryHdc = SafeDCHandle.ScreenCompatibleDCHandle) { // Create a device-independent bitmap and select it into our DC var info = new BITMAPINFO(bounds.Width, -bounds.Height); using (new SafeDCObjectHandle(memoryHdc, CreateDIBSection(SafeDCHandle.Null, ref info, DIBColorMode.DIB_RGB_COLORS, out var ppv, IntPtr.Zero, 0))) { using (var memoryGraphics = Graphics.FromHdc(memoryHdc.DangerousGetHandle())) { // Setup graphics memoryGraphics.CompositingMode = CompositingMode.SourceOver; memoryGraphics.CompositingQuality = CompositingQuality.HighQuality; memoryGraphics.SmoothingMode = SmoothingMode.HighQuality; memoryGraphics.Clear(clr); // Draw each background linearly down the bitmap var rect = new Rectangle(0, 0, imgSz.Width, imgSz.Height); foreach (var state in states) { rnd.SetParameters(rnd.Class, rnd.Part, state); rnd.DrawBackground(memoryGraphics, rect); rect.X += imgSz.Width; } } // Copy DIB to Bitmap var bmp = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb); using (var primaryHdc = new SafeDCHandle(Graphics.FromImage(bmp))) BitBlt(primaryHdc, bounds.Left, bounds.Top, bounds.Width, bounds.Height, memoryHdc, 0, 0, RasterOperationMode.SRCCOPY); return(bmp); } } }