기타 [VB.NET] 윈도우 프로그램과 폼안의 객체만 따로 캡쳐하기
페이지 정보
본문
훔쳐온곳: h t t p s : / / m . b l o g . n a v e r . c o m / r o l e _ _ _ p l a y / 2 2 0 5 6 7 7 8 9 9 6 8
Imports System.Runtime.InteropServices Public Class Form1 'SendMessage 의 캡쳐 메세지 Private Const WM_PAINT = &HF ''' ''' GDI32 API 함수를 가지고있는 클래스입니다. ''' Private Class GDI32 Public Const SRCCOPY As Integer = &HCC0020 ' BitBlt dwRop parameter <DllImport("gdi32.dll")> _ Public Shared Function BitBlt(hObject As IntPtr, nXDest As Integer, nYDest As Integer, nWidth As Integer, nHeight As Integer, hObjectSource As IntPtr, _ nXSrc As Integer, nYSrc As Integer, dwRop As Integer) As Boolean End Function <DllImport("gdi32.dll")> _ Public Shared Function CreateCompatibleBitmap(hDC As IntPtr, nWidth As Integer, nHeight As Integer) As IntPtr End Function <DllImport("gdi32.dll")> _ Public Shared Function CreateCompatibleDC(hDC As IntPtr) As IntPtr End Function <DllImport("gdi32.dll")> _ Public Shared Function DeleteDC(hDC As IntPtr) As Boolean End Function <DllImport("gdi32.dll")> _ Public Shared Function DeleteObject(hObject As IntPtr) As Boolean End Function <DllImport("gdi32.dll")> _ Public Shared Function SelectObject(hDC As IntPtr, hObject As IntPtr) As IntPtr End Function End Class ''' ''' User32 API 함수를 가지고있는 클래스입니다. ''' Private Class User32 <StructLayout(LayoutKind.Sequential)> _ Public Structure RECT Public left As Integer Public top As Integer Public right As Integer Public bottom As Integer End Structure <DllImport("user32.dll", EntryPoint:="SendMessageA")> _ Public Shared Function SendMessage(hWnd As IntPtr, wMsg As Integer, wParam As IntPtr, lParam As IntPtr) As UInteger End Function <DllImport("user32.dll")> _ Public Shared Function GetDesktopWindow() As IntPtr End Function <DllImport("user32.dll")> _ Public Shared Function GetWindowDC(hWnd As IntPtr) As IntPtr End Function <DllImport("user32.dll")> _ Public Shared Function ReleaseDC(hWnd As IntPtr, hDC As IntPtr) As IntPtr End Function <DllImport("user32.dll")> _ Public Shared Function GetWindowRect(hWnd As IntPtr, ByRef rect As RECT) As IntPtr End Function End Class Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim bmp As Image = Nothing '프로세스가 체크되어있을경우 If cbProcess.Checked = True Then 'pname 변수에 프로세스를 담고 Dim pname As IntPtr = GetProcess(txtName.Text) '캡쳐하여 변수에 저장합니다. bmp = CaptureWindow(pname) '폼 객체가 체크되어있을경우 ElseIf cbFormObject.Checked = True Then 'cname 변수에 컨트롤을 담고 Dim cname As Control = StringToControl(txtName.Text) '캡쳐하여 변수에 저장합니다. bmp = getSnapShot(cname) End If '이미지를 띄웁니다. PictureBox1.Image = bmp End Sub ''' <summary> ''' 폼에 있는 객체를 캡쳐합니다. ''' </summary> ''' <param name="control"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function getSnapShot(control As System.Windows.Forms.Control) As Bitmap Try Dim image As Image = New Bitmap(control.Width, control.Height) ' 어느 컨트롤로 부터 그래픽 객체를 얻습니다. Dim g As Graphics = Graphics.FromImage(image) Dim hDCT As IntPtr = g.GetHdc() User32.SendMessage(control.Handle, WM_PAINT, hDCT, IntPtr.Zero) g.ReleaseHdc(hDCT) g.Dispose() Return New Bitmap(image) Catch ex As Exception End Try Return Nothing End Function ''' <summary> ''' 윈도우에 있는 프로그램을 캡쳐합니다. ''' </summary> ''' <param name="handle"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function CaptureWindow(handle As IntPtr) As Image ' 대상 윈도우의 hDC를 얻습니다. Dim hdcSrc As IntPtr = User32.GetWindowDC(handle) ' 사이즈를 얻습니다. Dim windowRect As New User32.RECT() User32.GetWindowRect(handle, windowRect) Dim width As Integer = windowRect.right - windowRect.left Dim height As Integer = windowRect.bottom - windowRect.top ' 복사할 수 있는 드라이브 장치를 만듭니다. Dim hdcDest As IntPtr = GDI32.CreateCompatibleDC(hdcSrc) ' 복사할 수 있는 비트맵 변수를 만듭니다. ' GetDeviceCaps 를 사용하여 너비/높이를 얻습니다. Dim hBitmap As IntPtr = GDI32.CreateCompatibleBitmap(hdcSrc, width, height) ' 비트맵 객체를 선택합니다. Dim hOld As IntPtr = GDI32.SelectObject(hdcDest, hBitmap) ' bitblt 처리 GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, _ 0, 0, GDI32.SRCCOPY) ' 선택한것을 복원합니다. GDI32.SelectObject(hdcDest, hOld) ' 마무리 GDI32.DeleteDC(hdcDest) User32.ReleaseDC(handle, hdcSrc) ' 이것으로 .NET 이미지 객체를 얻습니다. Dim img As Image = Image.FromHbitmap(hBitmap) ' 비트맵 객체를 지워줘서 공간을 확보해줍니다. GDI32.DeleteObject(hBitmap) Return img End Function ''' <summary> ''' 해당 프로세스를 찾아 반환합니다. ''' </summary> ''' <param name="name"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function GetProcess(name As String) As IntPtr Dim targetwindow As IntPtr ' targetwindow의 변수를 만들어준다. Dim a() As System.Diagnostics.Process = System.Diagnostics.Process.GetProcesses ' a는 프로세스를 가져오는 변수로 만들어준다. For Each p In a 'a에 p가 있을떄까지 포문을 돌립니다. If p.ProcessName = txtName.Text Then ' p의 프로세스 이름을 정해줍니다. targetwindow = p.MainWindowHandle 'targetwindow 변수는 프로세스의 메인윈도우핸들 값이 되고. Return targetwindow Exit For '찾았으니 포문을 탈출합니다. End If Next Return Nothing End Function ''' <summary> ''' 문자열형식을 Control형식으로 바꾸어 반환합니다. ''' </summary> ''' <param name="name"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function StringToControl(name As String) As Control Try '컨트롤을 찾아 저장시킬 변수를 만듭니다. Dim ControlName As Control = Nothing '컨트롤을 찾기위해 반복적으로 검색합니다. Dim SearchedControls = Me.Controls.Find(key:=name, searchAllChildren:=True) '한개의 컨트롤을 발견했을 경우 If SearchedControls.Count = 1 Then '변수에 담습니다. ControlName = SearchedControls(0) Return ControlName End If Catch ex As Exception End Try Return Nothing End Function Private Sub cbProcess_CheckedChanged(sender As Object, e As EventArgs) Handles cbProcess.CheckedChanged If cbProcess.Checked = True Then cbFormObject.Checked = False End If End Sub Private Sub cbFormObject_CheckedChanged(sender As Object, e As EventArgs) Handles cbFormObject.CheckedChanged If cbFormObject.Checked = True Then cbProcess.Checked = False End If End Sub End Class |
- 이전글[vb.net] 원문자 넣기 -> 한글 1자, 숫자 0~99, 영대 1자, 영소 2자 22.09.06
- 다음글[VB.NET] XML Parsing(파싱) - XML 추출하기 22.08.19
댓글목록
등록된 댓글이 없습니다.