85782


C#のControl.DrawToBitmap(Bitmap, Rectangle)
メソッドで画面キャプチャを出力すると、タイトルバーのスタイル（テーマ？）がWindows XP?のようなイメージで出力されます。  
Windows10だと四角でスタイリッシュに表示されると思うのですが、そうはなりません。  
仕様といえばそれまでなのかもしれませんが、その文献も見つけられません。  
ご存じの方おしえてください。[![画像の説明をここに入力](https://i.stack.imgur.com/M0YRm.png)](https://i.stack.imgur.com/M0YRm.png)


CC BY-SA 4.0
2022-01-18T14:14:43.060
85780
2022-01-19T06:27:16.700
9228
question
c# winforms
DrawToBitmapで画面キャプチャを取得した際の画面イメージが実際の画面イメージと異なる


トップレベルウインドウの非クライアント領域は、DWM(デスクトップ ウィンドウ マネージャー)が描画しています。  
DrawToBitmp でビットマップに描画されるのは、Form 自身が描画しているものです。

「デスクトップ ウィンドウ マネージャー」  
<https://docs.microsoft.com/ja-jp/windows/win32/dwm/dwm-overview>  
「DWM の概要」  
<https://docs.microsoft.com/ja-jp/windows/win32/dwm/desktop-window-manager-
overviews>

あたりを読んでみてください。

下のコードで外観そのままキャプチャできますが、タスクマネージャーなど  
TOPMOST な ウインドウが手前にあると写りこんでしまうんですよね。

[![](https://i.stack.imgur.com/J5y3q.png)](https://i.stack.imgur.com/J5y3q.png)

[code]

    using System;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    public partial class Form1 : Form
    {
        public Form1() {
            InitializeComponent();
        }
    
        private void button1_Click(object sender, EventArgs e) {
            Rectangle r = GetDwmWindowRect();
            using (Bitmap bmp = new Bitmap(r.Width, r.Height))
            using (Graphics g = Graphics.FromImage(bmp)) {
                g.CopyFromScreen(r.Location, Point.Empty, r.Size);
                Clipboard.SetImage(bmp);
            }
        }
    
        private Rectangle GetDwmWindowRect() {
            RECT rect = new RECT();
            IntPtr nResult = DwmGetWindowAttribute(
                        Handle,
                        DWMWINDOWATTRIBUTE.DWMWA_EXTENDED_FRAME_BOUNDS,
                        out rect,
                        Marshal.SizeOf(rect));
            if (nResult.ToInt32() == S_OK) {
                return rect.Rectangle;
            }
            return Bounds;
        }
    
        private enum DWMWINDOWATTRIBUTE : int
        {
            DWMWA_NCRENDERING_ENABLED = 1,
            DWMWA_NCRENDERING_POLICY,
            DWMWA_TRANSITIONS_FORCEDISABLED,
            DWMWA_ALLOW_NCPAINT,
            DWMWA_CAPTION_BUTTON_BOUNDS,
            DWMWA_NONCLIENT_RTL_LAYOUT,
            DWMWA_FORCE_ICONIC_REPRESENTATION,
            DWMWA_FLIP3D_POLICY,
            DWMWA_EXTENDED_FRAME_BOUNDS,
            DWMWA_HAS_ICONIC_BITMAP,
            DWMWA_DISALLOW_PEEK,
            DWMWA_EXCLUDED_FROM_PEEK,
            DWMWA_CLOAK,
            DWMWA_CLOAKED,
            DWMWA_FREEZE_REPRESENTATION,
            DWMWA_PASSIVE_UPDATE_MODE,
            DWMWA_USE_HOSTBACKDROPBRUSH,
            DWMWA_USE_IMMERSIVE_DARK_MODE,
            DWMWA_WINDOW_CORNER_PREFERENCE,
            DWMWA_BORDER_COLOR,
            DWMWA_CAPTION_COLOR,
            DWMWA_TEXT_COLOR,
            DWMWA_VISIBLE_FRAME_BORDER_THICKNESS,
            DWMWA_LAST
        }
    
        [StructLayout(LayoutKind.Sequential)]
        private struct RECT
        {
            public int Left, Top, Right, Bottom;
            public Rectangle Rectangle {
                get {
                    return Rectangle.FromLTRB(Left, Top, Right, Bottom);
                }
            }
        }
    
        [DllImport("dwmapi.dll")]
        private static extern IntPtr DwmGetWindowAttribute(
                    IntPtr hwnd,
                    DWMWINDOWATTRIBUTE attr,
                    out RECT pvAttribute,
                    int attrSize);
    
        private const int S_OK = 0;
    
    }
    
[/code]


CC BY-SA 4.0
2022-01-18T16:58:31.280
85782
2022-01-19T06:27:16.700
2022-01-19T06:27:16.700
50741
50741
85780
answer