0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

フォーム上で自身のスクリーンショットを取得する

Last updated at Posted at 2025-12-13

環境

  • Windows 10 / 11
  • .NET Framework
  • WinForms

機能

  • フォーム上で自身のスクリーンショット画像を取得する

実装した結果

  • 当初は開発者がレビューやマニュアル素材に使用することを想定していた
  • 実際はユーザーの使用が多かった
    • 業務で問題や問い合わせが発生した際のメモ代わり

ソースコード

    ''' <summary>
    ''' キャプチャボタン押下時の処理
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub BtnCapture_Click(sender As Object, e As EventArgs) Handles BtnCapture.Click
        ' フォームのキャプチャ
        Dim bmpForm As Bitmap = CaptureForm()

        ' ファイル保存する
        bmpForm.Save("test.bmp")
    End Sub

    ''' <summary>
    ''' キャプチャする
    ''' </summary>
    ''' <returns>キャプチャした画像</returns>
    ''' <remarks></remarks>
    Private Function CaptureForm() As Bitmap
        ' 四角形
        Dim Bounds, Rect As RECT

        ' アクティブウィンドウのハンドルを取得する
        Dim ptrHWnd As IntPtr = GetForegroundWindow()

        ' ウィンドウ全体のデバイスコンテキストを取得する
        Dim ptrWinDC As IntPtr = GetWindowDC(ptrHWnd)

        ' デスクトップウィンドウマネージャー属性の現在値を取得する
        DwmGetWindowAttribute(ptrHWnd, DWMWA_EXTENDED_FRAME_BOUNDS, Bounds, Marshal.SizeOf(GetType(RECT)))

        ' 指定したウィンドウの左上端と右下端の座標を取得する
        GetWindowRect(ptrHWnd, Rect)

        ' キャプチャ画像
        Dim bmpForm As Bitmap = New Bitmap(Bounds.Right - Bounds.Left, Bounds.Bottom - Bounds.Top)

        ' Graphicsクラス
        Dim Graphics As Graphics = Graphics.FromImage(bmpForm)

        ' Graphicsオブジェクトのデバイスコンテキストを取得する
        Dim hDC As IntPtr = Graphics.GetHdc()

        ' 画像コピーのオフセット(コピー元の左上の座標)
        Dim OffsetX As Integer = Bounds.Left - Rect.Left
        Dim OffsetY As Integer = Bounds.Top - Rect.Top

        ' 画像をビットブロック転送する
        BitBlt(hDC, 0, 0, bmpForm.Width, bmpForm.Height, ptrWinDC, OffsetX, OffsetY, SRCCOPY)

        ' Graphicsオブジェクトのデバイスコンテキストを解放する
        Graphics.ReleaseHdc(hDC)

        ' Graphicsオブジェクトを破棄する
        Graphics.Dispose()

        ' ウィンドウ全体のデバイスコンテキストを破棄する
        ReleaseDC(ptrHWnd, ptrWinDC)

        Return bmpForm
    End Function

    ''' <summary>
    ''' ラスター演算コード
    ''' </summary>
    ''' <remarks>
    ''' コピー元の四角形をコピー先の四角形に直接コピーする
    ''' </remarks>
    Public Const SRCCOPY As Integer = 13369376

    ''' <summary>
    ''' DwmGetWindowAttribute関数のパラメータ
    ''' </summary>
    ''' <remarks>
    ''' 画面空間内の拡張フレーム境界の四角形を取得する
    ''' </remarks>
    Public Const DWMWA_EXTENDED_FRAME_BOUNDS As Integer = 9

    ''' <summary>
    ''' 四角形
    ''' </summary>
    ''' <remarks>
    ''' DLLとの受け渡しのために定義
    ''' </remarks>
    <StructLayout(LayoutKind.Sequential)>
    Public Structure RECT
        Public Left As Integer
        Public Top As Integer
        Public Right As Integer
        Public Bottom As Integer
    End Structure

    ''' <summary>
    ''' アクティブウィンドウのハンドルを取得する
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <DllImport("user32.dll")>
    Public Shared Function GetForegroundWindow() As IntPtr
        ' DLLから呼び出すので定義だけ
    End Function

    ''' <summary>
    ''' デバイスコンテキストを取得する
    ''' </summary>
    ''' <param name="hWnd"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <DllImport("user32.dll")>
    Public Shared Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
        'DLLから呼び出すので定義だけ
    End Function

    ''' <summary>
    ''' デスクトップウィンドウマネージャー属性の現在値を取得する
    ''' </summary>
    ''' <param name="hWnd"></param>
    ''' <param name="dwAttribute"></param>
    ''' <param name="rect"></param>
    ''' <param name="cbAttribute"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <DllImport("dwmapi.dll")>
    Public Shared Function DwmGetWindowAttribute(ByVal hWnd As IntPtr, ByVal dwAttribute As Integer, ByRef rect As RECT, ByVal cbAttribute As Integer) As Integer
        ' DLLから呼び出すので定義だけ
    End Function

    ''' <summary>
    ''' 指定したウィンドウの左上端と右下端の座標を取得する
    ''' </summary>
    ''' <param name="hWnd"></param>
    ''' <param name="rect"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <DllImport("user32.dll")>
    Public Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef rect As RECT) As IntPtr
        ' DLLから呼び出すので定義だけ
    End Function

    ''' <summary>
    ''' 画像をビットブロック転送する
    ''' </summary>
    ''' <param name="hDestDC"></param>
    ''' <param name="x"></param>
    ''' <param name="y"></param>
    ''' <param name="nWidth"></param>
    ''' <param name="nHeight"></param>
    ''' <param name="hSrcDC"></param>
    ''' <param name="xSrc"></param>
    ''' <param name="ySrc"></param>
    ''' <param name="dwRop"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <DllImport("gdi32.dll")>
    Public Shared Function BitBlt(ByVal hDestDC As IntPtr, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hSrcDC As IntPtr, ByVal xSrc As Integer, ByVal ySrc As Integer, ByVal dwRop As Integer) As Integer
        ' DLLから呼び出すので定義だけ
    End Function

    ''' <summary>
    ''' デバイスコンテキストを破棄する
    ''' </summary>
    ''' <param name="hWnd"></param>
    ''' <param name="hdc"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <DllImport("user32.dll")>
    Public Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hdc As IntPtr) As IntPtr
        ' DLLから呼び出すので定義だけ
    End Function
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?