🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

3203閲覧

C# MDI子フォームの領域取得方法について

Taffy

総合スコア33

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2019/09/11 06:11

編集2019/09/11 06:56

C#(Visual Studio 2015 Express for Desktop)を使用して
MDIフォームのアプリケーションを作成しています。

下記のようなイメージで、「スクリーンショット」ボタン押下時に
MDIの子フォームのスクリーンショットを取り、印刷したいです。

イメージ説明

現在、以下のようなコードを書いています。

C#

1 private void button1_Click(object sender, EventArgs e) 2 { 3 // スクリーン・キャプチャする範囲を子ウィンドウにする 4 Rectangle rc; 5 rc = frm.Bounds; 6 7 // 子ウィンドウの座標をクライアント座標→スクリーン座標に変換 8 Rectangle rcSrc = frm.RectangleToScreen(rc); 9 10 // Bitmapオブジェクトにスクリーン・キャプチャ 11 Bitmap bmp = new Bitmap(frm.Size.Width, frm.Size.Height, PixelFormat.Format32bppArgb); 12 using (Graphics g = Graphics.FromImage(bmp)) 13 { 14 g.CopyFromScreen(rcSrc.X, rcSrc.Y, 0, 0, 15 frm.Size, CopyPixelOperation.SourceCopy); 16 } 17 18 // ビットマップ画像として保存して表示 19 string filePath = @"D:\screen.bmp"; 20 bmp.Save(filePath, ImageFormat.Bmp); 21 Process.Start(filePath); 22 }

このコードでは、子フォームの座標と領域の取得が正確にできず、
以下のようなイメージになってしまいます。
イメージ説明

正確に、子フォームのみを抜き出したいのですが、
現在のコードでは何がまずいのか、
そして、座標と領域の指定方法についてなどの解決策を教えていただけないでしょうか?

[補足]抜き出したい領域を赤枠表示しました。
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takabosoft

2019/09/11 06:24

具体的にどこをキャプチャしたいのか、赤枠とか付けてもらえますか?
guest

回答2

0

ベストアンサー

C#

1private void button1_Click(object sender, EventArgs e) 2{ 3 using(Bitmap bmp = new Bitmap(frm.Width, frm.Height)) 4 { 5 frm.DrawToBitmap(bmp, new Rectangle(0, 0, frm.Width, frm.Height)); 6 7 // ビットマップ画像として保存して表示 8 string filePath = @"D:\screen.bmp"; 9 bmp.Save(filePath, ImageFormat.Bmp); 10 Process.Start(filePath); 11 } 12}

じゃダメですか?

投稿2019/09/11 06:41

編集2019/09/11 06:53
YAmaGNZ

総合スコア10469

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Taffy

2019/09/11 06:59

コントロールにDrawToBitmapメソッドがあったのですね。 これで期待通りのスクリーンショットが取れるようになりました。ありがとうございます。
guest

0

もしかしてこうですかね?

csharp

1 private void toolStripButton1_Click(object sender, EventArgs e) 2 { 3 // スクリーン・キャプチャする範囲を子ウィンドウにする 4 Rectangle rc = frm.Bounds; 5 6 // 子ウィンドウの座標をクライアント座標→スクリーン座標に変換 7 Rectangle rcSrc = frm.Parent.RectangleToScreen(rc); 8 9 // Bitmapオブジェクトにスクリーン・キャプチャ 10 using (var bmp = new Bitmap(rcSrc.Width, rcSrc.Height, PixelFormat.Format32bppArgb)) 11 using (var g = Graphics.FromImage(bmp)) 12 { 13 g.CopyFromScreen(rcSrc.X, rcSrc.Y, 0, 0, frm.Size, CopyPixelOperation.SourceCopy); 14 15 // ビットマップ画像として保存して表示 16 string filePath = @"C:\screen.bmp"; 17 bmp.Save(filePath, ImageFormat.Bmp); 18 Process.Start(filePath); 19 } 20 }

結果:
イメージ説明


追記

上記コードではDPI仮想化環境ではうまく動作しないようです。
フォームやコントロールの外観をキャプチャする
に他のやり方もいろいろ載っていました。

以下のコードでしたらDPI仮想化環境下でもOKでした。

csharp

1 [System.Runtime.InteropServices.DllImport("User32.dll")] 2 private extern static bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags); 3 4 /// <summary> 5 /// コントロールのイメージを取得する 6 /// </summary> 7 /// <param name="ctrl">キャプチャするコントロール</param> 8 /// <returns>取得できたイメージ</returns> 9 public Bitmap CaptureControl(Control ctrl) 10 { 11 Bitmap img = new Bitmap(ctrl.Width, ctrl.Height); 12 Graphics memg = Graphics.FromImage(img); 13 IntPtr dc = memg.GetHdc(); 14 PrintWindow(ctrl.Handle, dc, 0); 15 memg.ReleaseHdc(dc); 16 memg.Dispose(); 17 return img; 18 } 19 20 private void toolStripButton1_Click(object sender, EventArgs e) 21 { 22 //コントロールの外観を描画するBitmapの作成 23 using (var bmp = CaptureControl(frm)) 24 { 25 // ビットマップ画像として保存して表示 26 string filePath = @"C:\screen.bmp"; 27 bmp.Save(filePath, ImageFormat.Bmp); 28 Process.Start(filePath); 29 } 30 }

すでにクローズしちゃってましたが、一応動きましたという報告だけ。

投稿2019/09/11 06:20

編集2019/09/12 07:12
takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Taffy

2019/09/11 07:12

すみません。追記が遅れました。 試してみましたが、左上の座標がずれてしまいます。(質問時と同様でした)
takabosoft

2019/09/11 07:24

中身すべてコピペしましたか? 自分の所では貼った画像の通り動いていますよ。
Taffy

2019/09/12 06:46

toolStripButton1_Clickイベントの中身をすべてコピペしてみたのですが、 何度か試してみてもずれてしまいます。 → すみません。OS(Windows 10)のディスプレイ設定にて 「テキスト、アプリ、その他の項目のサイズを変更する」という項目を 100%にしたところ、ずれなくなりました。(125%を使っていた時は、ずれていました)
takabosoft

2019/09/12 07:15

125%でうまく動作しない件、こちらのミスでした。申し訳ないです。一応別の回答を追記しました。 YAmaGNZさんの方法で問題ないようでしたら、そちらをお使いください。 ただ、DrawToBitmapでは場合によってはうまくレンダリングされない場合があるようですので、保険としてこちらの案も備えておくと良いと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問