###前提・実現したいこと
Visual Studio 2017を用いてC#でWindowsフォームアプリケーションを作成しています。
以下のサイトの「Win32 APIを使用する方法」を参考にしながらアクティブウィンドウのスクリーンショットを撮り保存する機能を実装しました。
しかし保存された画像は私の想像していた画像とは少し違いました。
###発生している問題・エラーメッセージ
保存された画像は以下になります。
ウィンドウの左右と下の部分にアクティブウィンドウの後ろ側の壁紙(紫色の部分)が表示されてしまいます。
私はこれを解決する方法を調べたのですがお恥ずかしながら私では解決できませんでした。
###該当のソースコード
C#
1private void screenshot() 2{ 3 Bitmap bmp; 4 bmp = CaptureActiveWindow(); 5 string outputPath = "./" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".png"; 6 bmp.Save(outputPath, System.Drawing.Imaging.ImageFormat.Png); 7 bmp.Dispose(); 8} 9 10private const int SRCCOPY = 13369376; 11private const int CAPTUREBLT = 1073741824; 12 13[DllImport("user32.dll")] 14private static extern IntPtr GetDC(IntPtr hwnd); 15 16[DllImport("gdi32.dll")] 17private static extern int BitBlt(IntPtr hDestDC, 18 int x, 19 int y, 20 int nWidth, 21 int nHeight, 22 IntPtr hSrcDC, 23 int xSrc, 24 int ySrc, 25 int dwRop); 26 27[DllImport("user32.dll")] 28private static extern IntPtr ReleaseDC(IntPtr hwnd, IntPtr hdc); 29[StructLayout(LayoutKind.Sequential)] 30private struct RECT 31{ 32 public int left; 33 public int top; 34 public int right; 35 public int bottom; 36} 37 38[DllImport("user32.dll")] 39private static extern IntPtr GetWindowDC(IntPtr hwnd); 40 41[DllImport("user32.dll")] 42private static extern IntPtr GetForegroundWindow(); 43 44[DllImport("user32.dll")] 45private static extern int GetWindowRect(IntPtr hwnd, 46 ref RECT lpRect); 47 48/// <summary> 49/// アクティブなウィンドウの画像を取得する 50/// </summary> 51/// <returns>アクティブなウィンドウの画像</returns> 52public static Bitmap CaptureActiveWindow() 53{ 54 //アクティブなウィンドウのデバイスコンテキストを取得 55 IntPtr hWnd = GetForegroundWindow(); 56 IntPtr winDC = GetWindowDC(hWnd); 57 //ウィンドウの大きさを取得 58 RECT winRect = new RECT(); 59 GetWindowRect(hWnd, ref winRect); 60 //Bitmapの作成 61 Bitmap bmp = new Bitmap(winRect.right - winRect.left, 62 winRect.bottom - winRect.top); 63 //Graphicsの作成 64 Graphics g = Graphics.FromImage(bmp); 65 //Graphicsのデバイスコンテキストを取得 66 IntPtr hDC = g.GetHdc(); 67 //Bitmapに画像をコピーする 68 int bmpWidth = bmp.Width; 69 int bmpHeight = bmp.Height; 70 BitBlt(hDC, 0, 0, bmpWidth, bmpHeight, 71 winDC, 0, 0, SRCCOPY); 72 //解放 73 g.ReleaseHdc(hDC); 74 g.Dispose(); 75 ReleaseDC(hWnd, winDC); 76 77 return bmp; 78} 79
###試したこと
BitBlt(hDC, 0, 0, bmpWidth, bmpHeight,winDC, 0, 0, SRCCOPY);
で第2、第3引数の値を増加させると画像の左上が、bmpWidthとbmpHeightの値に対して減算すると画像の右下がトリミングされることが最初わかりました。
しかしアクティブウィンドウのサイズによって先に述べた紫色の部分の領域のサイズが変わることに気付き、固定値の加減算では上手く動作しないことがわかりました。
他の方法として最初に上げたリンク先の「.NET Framework 2.0以降で、Graphics.CopyFromScreenメソッドを使用する方法」はアクティブウィンドウのみでは無いため断念。
「Print Screenキーストロークを送信する方法」は画像を取得することが出来ず断念しました。
何卒よろしくお願いします。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/12/03 10:33
2017/12/03 13:46 編集
2017/12/05 14:11
2017/12/05 14:31