Gå til innhold

Ta screenshot av andre programmer


Anbefalte innlegg

Hvordan kan jeg ta ett screenshot av andre programmer(helst uten og viste det aktuelle vinduet på skjermen...)

 

til nå har jeg kun funnnet kode som henter ut bildet etter at det er blitt vist på skjermen:S

 

Takker for alle svar

Lenke til kommentar
Videoannonse
Annonse

Du tenker på å ta bildet av kun det som faktisk skjer på skjermen? Ikke noe vindu eller verktøylinje? Hva er det som er så farlig med det?

 

Trykker du Print Screen knappen på tastaturet tar du screen shot. Gå deretter i paing hvor du trykker Ctrl + V.

Lenke til kommentar

Mitt umiddelbare og relativt ugjennomtenkte tips ville være å bruke API for å aktivere det aktuelle vinduet og så bruke PRESSKEY metodikk for å tvinge igjennom f.eks. ALT+PrtSc, som jo betyr "Ta bildet av det aktive vinduet"

 

Hvordan du gjør dette i din kode er jeg dog usikker på, men kansje kommer du videre i din problemløsning alikevel nå...

Lenke til kommentar

Fant ut av hvordan det kan gjøres med klassisk GDI, det var lite om emnet på internett, så tok litt tid for meg å finne ut av det.

 

Her følger koden for å gjøre det:

[System.Runtime.InteropServices.DllImport("user32")]
private static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

[System.Runtime.InteropServices.DllImport("user32")]
private static extern bool GetWindowRect(IntPtr hWnd, ref Rectangle lpRect);

public enum CaptureParameters
{
CheckVisible = 0x00000001,
NonClient = 0x00000002,
Client = 0x00000004,
EraseBackground = 0x00000008,
Children = 0x00000010,
Owned = 0x00000020
}

public static Bitmap CaptureControl(IntPtr ctrl, CaptureParameters param)
{
Rectangle rect = new Rectangle();
GetWindowRect(ctrl, ref rect);
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
	IntPtr hdc = g.GetHdc();
	SendMessage(ctrl, 0x0317, hdc, new IntPtr((int)param));
	g.ReleaseHdc(hdc);
}
return bmp;
}
public static Bitmap CaptureControl(Control ctrl, CaptureParameters param)
{
return CaptureControl(ctrl.Handle, param);
}
public static Bitmap CaptureControl(IntPtr ctrl)
{
return CaptureControl(ctrl, CaptureParameters.Children | CaptureParameters.Client | CaptureParameters.NonClient);
}
public static Bitmap CaptureControl(Control ctrl)
{
return CaptureControl(ctrl.Handle, CaptureParameters.Children | CaptureParameters.Client | CaptureParameters.NonClient);
}

 

I all hovedsak har jeg skrevet to funksjoner, en som tar Control, hvor du kan legge inn .NET forms eller kontroller om du ønsker, og en som tar HWND som parameter.

Begge returnerer et bitmap som inneholder formen. Denne funker uansett om formen er minimert eller usynlig, og selv om det finnes topmost eller modale vinduer.

 

Jeg regner med at du klarer å finne HWND-en til vinduer i andre programmer (EnumWindows)

Endret av GeirGrusom
Lenke til kommentar

hmm, dette funka dårlig:S

 

 

har du noen andre idèer?

 

(her er koden min, clsWindow):

Public Class clsWindows
Private Structure win32RECT
	Public left As Integer
	Public top As Integer
	Public right As Integer
	Public bottom As Integer
End Structure

Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As Integer, ByRef lpRect As win32RECT) As Integer
Private Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByRef lParam As IntPtr) As Integer
Private Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" (ByVal hwnd As Integer, ByRef lpRect As win32RECT) As Integer

Public hWnd As IntPtr
Public Text As String
Public Class_s As String
Public Function filter(ByRef strFilter As String) As Boolean
	strFilter = LCase(strFilter)

	If InStr(hWnd.ToString, strFilter) <> 0 Then Return True
	If InStr(LCase(Text), strFilter) <> 0 Then Return True
	If InStr(LCase(Class_s), strFilter) <> 0 Then Return True

	Return False
End Function


Public ScreenShot As Bitmap

Public Function RefreshScreenshot() As Bitmap
	ScreenShot = CaptureWindow()

	Return ScreenShot
End Function

Public Function CaptureWindow() As Bitmap
	Dim bTemp As Bitmap
	Dim r As win32RECT
	Dim g As Graphics
	Dim ret As Integer

	'ret = GetClientRect(hWnd, r)
	ret = GetWindowRect(hWnd, r)
	If ret <> 0 Then
		bTemp = New Bitmap(r.right - r.left, r.bottom - r.top)
		g = Graphics.FromImage(bTemp)
		Dim hDc As IntPtr = g.GetHdc
		Dim msg As Integer = &H317
		SendMessage(hWnd, msg, hDc, New IntPtr(0))
		g.ReleaseHdc()
		'g.Dispose()
	Else
		bTemp = Nothing
	End If

	Return bTemp
End Function
End Class

 

(både getclientrect og getwindowrect returnerer gode resultater)

Lenke til kommentar

hmm, etter og ha oppdatert koden og testet litt til, så funker ingenting:S (har prøvd mange forskjellige vinduer også:S)

 

 

her er den oppdaterte koden, skrik ut viss noen finner feil:O

 

Public Class clsWindows
Private Enum CaptureParameters
	CheckVisible = &H1
	NonClient = &H2
	Client = &H4
	EraseBackground = &H8
	Children = &H10
	Owned = &H20
End Enum

Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As Integer, ByRef lpRect As Rectangle) As Integer
Private Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByRef lParam As IntPtr) As Integer
Private Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" (ByVal hwnd As Integer, ByRef lpRect As Rectangle) As Integer

Private Const WM_PAINT As Long = &HF
Private Const WM_PRINT As Long = &H317

Public hWnd As IntPtr
Public Text As String
Public Class_s As String
Public Function filter(ByRef strFilter As String) As Boolean
	strFilter = LCase(strFilter)

	If InStr(hWnd.ToString, strFilter) <> 0 Then Return True
	If InStr(LCase(Text), strFilter) <> 0 Then Return True
	If InStr(LCase(Class_s), strFilter) <> 0 Then Return True

	Return False
End Function


Public ScreenShot As Bitmap

Public Function RefreshScreenshot() As Bitmap
	ScreenShot = CaptureWindow()

	Return ScreenShot
End Function

Public Function CaptureWindow() As Bitmap
	Dim bTemp As Bitmap
	Dim r As New Rectangle
	Dim g As Graphics
	Dim ret As Integer

	ret = GetClientRect(hWnd, r)
	If ret <> 0 Then
		bTemp = New Bitmap(r.Width, r.Height)
		g = Graphics.FromImage(bTemp)
		Dim hDc As IntPtr = g.GetHdc
		Dim msg As Integer = WM_PRINT
		SendMessage(hWnd, WM_PAINT, hDc, 0)
		SendMessage(hWnd, WM_PRINT, hDc, New IntPtr(CaptureParameters.Children Or CaptureParameters.Client))
		g.ReleaseHdc()
		'g.Dispose()
	Else
		bTemp = Nothing
	End If

	Return bTemp
End Function
End Class

 

Lenke til kommentar
  • 2 uker senere...
Jeg får access denied på nesten alle vinduer som ikke tilhører egen thread. Dette er visst et problem i Vista og oppover.

 

Regner med at dette er en feature, først og fremst for å hindre at malware/spyware kan hente ut slik informasjon uten at du er klar over det.

Antar at et program som kjører med høyere privilegier kanskje kommer rundt en slik begrensning siden det tross alt kan være nyttig å ha slike muligheter.

Lenke til kommentar
  • 4 måneder senere...

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...