Page 1 of 2

Brauche Hilfe bei GDIP

Posted: 19 Apr 2016, 03:08
by fump2000
Hallo zusammen,

hier passieren gerade komische Dinge.

In meinem Hauptscript sind einige Bestandteile dazu da eine bestimmte Anwendung im Chrome oder IE zu öffnen bzw. sofern offen eine Kundennummer ins Suchfeld einzutragen und die suche zu starten.

Um das Suchfeld ausfindig zu machen nutze ich Gdip_BitmapFromScreen("hwnd:" . HWND) die HWND ist 100%ig korrekt weil das Script selbst das Fenster öffnet und die HWND so direkt bekommt bzw. weiterverwendet.

Ich habe die Teile die gesucht werden sollen als BMP Dateien gespeichert und lese diese per Gdip_CreateBitmapFromFile(file) ein.

Meine Suchfunktion sieht nun so aus:

Code: Select all

SearchNeedle(hwnd, file)
	{
		Global RET, LIST, AAXDebug, AAXGDIalt
		If !gdipToken := Gdip_Startup()
			{
			   MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
			   Return
			}
		if (AAXDebug=1)
			{
				file2:=A_TickCount ".png"
				bmpHaystack := Gdip_BitmapFromScreen("hwnd:" . HWND)
				Gdip_SaveBitmapToFile(bmpHaystack, file2, 100)
			}
		else
			{
				bmpHaystack := Gdip_BitmapFromScreen("hwnd:" . HWND)
			}
		bmpNeedle := Gdip_CreateBitmapFromFile(file)
		RET := Gdip_ImageSearch(bmpHaystack,bmpNeedle,LIST,0,0,0,0,25,"",1)
		Gdip_DisposeImage(bmpHaystack)
		Gdip_DisposeImage(bmpNeedle)
		Gdip_Shutdown(gdipToken)
	}
Nun hat unser Admin auf Win10 umgestellt. Der IE ist neu, der Chrome ist nun Version 50. Meine kollegen beschweren sich nun, dass die Funktion zum Aufruf der Kundennummern weder im IE noch im Chrome klappt.

Es passierte schon mal, dass eine neue Browserversion neue Bilder für den Vergleich benötigte. Danach war das thema gegessen. Aber diesmal ist es anders. Wenn ich AAXDebug:=1 setze erstellt das Script das Bild welches es zum vergleichen nutzt ebenfalls als PNG. Öffne ich diese stellt es sich so dar, dass der Chrome komplett schwarz ist, und der IE komplett Weiß. Da ist kein Inhalt mehr.
Ich steh auf dem Schlauch. Warum ist das? Verhindern die Browser das erstellen des Bildes? Kann man das ändern?

Hilfe :)

MfG
fump


EDIT//

Nutze ich erst WinGetPos,x,y,w,h,ahk_id %hwnd% und dann bmpHaystack := Gdip_BitmapFromScreen(x "|" y "|" w "|" h) wird das Bild korrekt erstellt und auch die Suche klappt erfolgreich.
Ist aber nicht Sinn der Sache. Denn bmpHaystack := Gdip_BitmapFromScreen("hwnd:" . HWND) sollte ja nun genauso funktionieren.

Re: Brauche Hilfe bei GDIP

Posted: 19 Apr 2016, 03:56
by just me
Moin,

Gdip_BitmapFromScreen("hwnd:" . HWND) funktioniert aber nicht genauso. Wenn Du die Koordinaten übergibst, wird einfach dieser Teil des Desktops als Bild gespeichert. Wenn Du aber ein HWND für ein Fenster übergibst, wird versucht, die Daten genau dieses Fensters auszulesen. Anscheinend weigern sich aber diese Fenster, ihre Daten zu liefern, wenn sie so angesprochen werden.

Übrigens: Welches der GDIP-Skripte benutzt Du mit welchem Windows (x64 / x32)?

Re: Brauche Hilfe bei GDIP

Posted: 19 Apr 2016, 05:07
by fump2000
"genauso" war das falsche Wort. Aber bisher hat dies einwandfrei funktioniert. Jetzt plötzlich halt nicht mehr. Verwirrt mich eben.

Ich nutze AHK als 32 Bit Version. Windows selbst ist x64

Es ist in meinem Empfinden eine Präzisere Angabe wenn ich GDIP die HWND übergebe zum Bild erstellen anstatt Koordinaten. Auch in Punkto fehlerquote bzw. Verarbeitungszeit.
Die eigentliche Frage ist ja, warum klappt es jetzt nicht mehr?

Re: Brauche Hilfe bei GDIP

Posted: 19 Apr 2016, 05:18
by just me
Das "Warum" kenne ich auch nicht. Ansonsten finde ich es eher unlogisch, wenn man einer Funktion mit Namen Gdip_BitmapFromScreen() ein HWND eines Fensters übergibt, das wohl auf dem aber nicht der Screen ist.

Hast Du mal Gdip_BitmapFromHWND() probiert?

Re: Brauche Hilfe bei GDIP

Posted: 19 Apr 2016, 06:18
by fump2000
Das Ergebnis ist auch dann dasselbe siehe hier:
http://www.bilder-upload.eu/show.php?fi ... 065926.png

Damals hatte ich dasselbe problem mit Gdip_BitmapFromHWND(HWND) da hattest du mir empfohlen es mit Gdip_BitmapFromScreen("hwnd:" . HWND) zu machen was dann auch klappte. Nun geht anscheinend beides nicht... Aber kann das Fenster tatsächlich verhindern, dass man den Inhalt so abgreift? Die Funktion will doch nur ein Bild machen...

Re: Brauche Hilfe bei GDIP

Posted: 19 Apr 2016, 06:43
by HinkerLoden
bekommst du ein bild ins clipboard mit der standard Druck taste. das wäre das schnelle workaround. aber nicht wirklich eine lösung bzg. GDIP. Btw. welche version ist die aktuelle. Hab ein wenig damit schon herum gebastelt. Hab die libs mal angehangen.

Re: Brauche Hilfe bei GDIP

Posted: 19 Apr 2016, 06:54
by fump2000
Ja mit der Druck taste bekomme ich ein Bild beider Monitorflächen in die Zwischenablage.

Re: Brauche Hilfe bei GDIP

Posted: 19 Apr 2016, 10:12
by nnnik
Hi
Ich kann dir nicht sagen, wieso deine HWND Version nicht mehr funktioniert.
Aber ich kann dir deine Angst über die Genauigkeit der übergebenen Parameter nehmen.
Ich habe mir angeschaut was die gdip Funktion bei mir genau macht, und wie sie die HWND verwendet.
Das einzige was die funktion macht ist die XY-Koordinaten des Fensters zu bestimmen und dann einen Screenshot davon zu machen:

Code: Select all

Gdip_BitmapFromScreen(Screen=0, Raster="")
{
	if (Screen = 0)
	{
		Sysget, x, 76
		Sysget, y, 77	
		Sysget, w, 78
		Sysget, h, 79
	} ;--Siehe hier
	else if (SubStr(Screen, 1, 5) = "hwnd:")
	{
		Screen := SubStr(Screen, 6)
		if !WinExist( "ahk_id " Screen)
			return -2
		WinGetPos,x,y, w, h, ahk_id %Screen% 
	} ;--Bis hier
	else if (Screen&1 != "")
	{
		Sysget, M, Monitor, %Screen%
		x := MLeft, y := MTop, w := MRight-MLeft, h := MBottom-MTop
	}
	else
	{
		StringSplit, S, Screen, |
		x := S1, y := S2, w := S3, h := S4
	}

	if (x = "") || (y = "") || (w = "") || (h = "")
		return -1

	chdc := CreateCompatibleDC(), hbm := CreateDIBSection(w, h, chdc), obm := SelectObject(chdc, hbm), hhdc := hhdc ? hhdc : GetDC()
	BitBlt(chdc, 0, 0, w, h, hhdc, x, y, Raster)
	ReleaseDC(hhdc)
	
	pBitmap := Gdip_CreateBitmapFromHBITMAP(hbm)
	SelectObject(chdc, obm), DeleteObject(hbm), DeleteDC(hhdc), DeleteDC(chdc)
	return pBitmap
}
Oder anders:

Code: Select all

GDIP_CopyHWNDAreaFromScreenToBitmap(HWND)
{
    if !WinExist( "ahk_id " . HWND)
        return -2
    WinGetPos,x,y, w, h, ahk_id %HWND%
    chdc := CreateCompatibleDC()
    hbm := CreateDIBSection(w, h, chdc)
    obm := SelectObject(chdc, hbm)
    hhdc := GetDC() ;Why should hhdc be true?
    BitBlt(chdc, 0, 0, w, h, hhdc, x, y, "")
    pBitmap := Gdip_CreateBitmapFromHBITMAP(hbm)
    ReleaseDC(hhdc)
    SelectObject(chdc, obm), DeleteObject(hbm), DeleteDC(hhdc), DeleteDC(chdc)
    return pBitmap
}

Re: Brauche Hilfe bei GDIP

Posted: 19 Apr 2016, 10:45
by just me
Also, Google (und vielleicht auch Microsoft) scheinen unter Win 10 mit den Fenstern merkwürdige Sachen zu veranstalten. Wenn ich das folgende Skript hier laufen lasse und mir per Ctrl+LButton die Fenster-ID (HWND) von Chrome hole, ergibt das eine Titelleiste im Win 7 Stil und viel Schwarz:

Code: Select all

#NoEnv
SetBatchLines, -1
pToken := Gdip_Startup()
Return
^LButton::
MouseGetPos, , , HWIN
PBITMAP := Gdip_BitmapFromHWND(HWIN)
HBITMAP := Gdip_CreateHBITMAPFromBitmap(PBITMAP)
Gui, Add, Pic, w800 h-1, HBITMAP:%HBITMAP%
Gui, Show, , Test
Return
GuiClose:
Gdip_Shutdown(pToken)
ExitApp
#Include GDIP.ahk
Das Fensters, dessen ID AHK ermittelt, scheint nicht das zu enthalten, was auf dem Bildschirm erscheint.

Firefox verhält sich übrigens noch wie früher.

P.S.: Wegen GDIP.ahk läft das nur mit 32 Bit AHK.

Re: Brauche Hilfe bei GDIP

Posted: 19 Apr 2016, 12:31
by nnnik
P.S.: Wegen GDIP.ahk läft das nur mit 32 Bit AHK.
Wieso dann nicht die GDIP_all Version verwenden?
Also, Google (und vielleicht auch Microsoft) scheinen unter Win 10 mit den Fenstern merkwürdige Sachen zu veranstalten. Wenn ich das folgende Skript hier laufen lasse und mir per Ctrl+LButton die Fenster-ID (HWND) von Chrome hole, ergibt das eine Titelleiste im Win 7 Stil und viel Schwarz:
Das war aber nicht nur unter Win 10 so.
Ein Fenster muss nicht unbedingt auf die PrintWindow Funktion/Nachricht reagieren.
Eventuell kann es auch ein Hinweis darauf sein, dass ein anderes Fenster das eigentliche Zeichnen übernimmt und man einfach nur dieses Fenster finden müsste.

Re: Brauche Hilfe bei GDIP

Posted: 19 Apr 2016, 15:58
by just me
nnnik wrote:Ein Fenster muss nicht unbedingt auf die PrintWindow Funktion/Nachricht reagieren.
Ja, witzigerweise wird aber eine Bitmap erzeugt. Und ich frage mich, woher die Win 7 Titelleiste kommt.
nnnik wrote:Eventuell kann es auch ein Hinweis darauf sein, dass ein anderes Fenster das eigentliche Zeichnen übernimmt und man einfach nur dieses Fenster finden müsste.
Genau das wollte ich damit sagen. ;)

Re: Brauche Hilfe bei GDIP

Posted: 20 Apr 2016, 01:15
by fump2000
Mmh heißt für mich, es gibt keinen anderen Weg mehr per HWND ein Bild zu bekommen?

Re: Brauche Hilfe bei GDIP

Posted: 20 Apr 2016, 04:46
by just me
OK, so bekomme ich mit beiden Varianten (wenn auch leicht unterschiedliche) Bilder von Chrome, wenn die Hardwarebeschleunigung abgeschaltet und das Chrome-Fenster im Vordergrund ist!:

Code: Select all

#NoEnv
SetBatchLines, -1
pToken := Gdip_Startup()
HWIN := WinExist("ahk_exe Chrome.exe")
WinActivate
; PBITMAP := Gdip_BitmapFromHWND(HWIN) ; Alternative 1
PBITMAP := Gdip_BitmapFromScreen("HWND:" . HWIN) ; Alternative 2
HBITMAP := Gdip_CreateHBITMAPFromBitmap(PBITMAP)
Gdip_DisposeImage(PBITMAP)
Gui, Add, Pic, w800 h-1, HBITMAP:%HBITMAP%
Gui, Show, , Test
Return
GuiClose:
Gui, Destroy
Gdip_Shutdown(pToken)
ExitApp
#Include GDIP.ahk

Re: Brauche Hilfe bei GDIP

Posted: 20 Apr 2016, 07:28
by fump2000
Die Hardwarebschleunigung ist anscheinend der Knackpunkt.
Beim Chrome klappt es mit deinem Testscript. Beim IE nicht.
Hardwarebesschleunigung habe ich bei beiden abgeschaltet.
Warum die dabei wohl Probleme macht?

Re: Brauche Hilfe bei GDIP

Posted: 20 Apr 2016, 07:49
by jNizM
Macht OnTopReplica das, was du brauchst?
Source Code ist auch enthalten und basiert auf DWM Thumbnails.

Re: Brauche Hilfe bei GDIP

Posted: 20 Apr 2016, 08:08
by fump2000
Ja, auch mit aktiver Hardwarebeschleunigung kann dieses Tool das Bild abgreifen.
Aber lässt sich das in AHK Verwenden? Wie denn?

Re: Brauche Hilfe bei GDIP

Posted: 20 Apr 2016, 08:20
by jNizM

Re: Brauche Hilfe bei GDIP

Posted: 20 Apr 2016, 09:03
by fump2000
Ja... Da bin ich dann mal raus :D

Re: Brauche Hilfe bei GDIP

Posted: 21 Apr 2016, 02:44
by just me
fump2000 wrote:Die Hardwarebschleunigung ist anscheinend der Knackpunkt. ... Warum die dabei wohl Probleme macht?
Wenn man sich Chrome bei aktivierter Hardwarebeschleunigung mit 'Active Window Info' anschaut, taucht recht weit oben in der Hierarchie ein Control der Klasse Intermediate D3D Window auf. Daraus kann man wohl schließen, dass Chrome dann "DirectDraw" Routinen nutzt, um die Fenster zu zeichnen. Die wiederum zeichnen direkt auf dem Bildschirm bzw. in den Speicher der Grafikkarte, und eben nicht in den 'device context (DC)' des Controls.

Beim IE stellt sich die Frage, welcher bei Euch überhaupt läuft. 'Edge' ist eine 'Windows App' und macht entsprechende Probleme, das 'korrekte' Anwendungsfenster zu ermitteln.

Re: Brauche Hilfe bei GDIP

Posted: 21 Apr 2016, 03:38
by jNizM
Nur ne schnell-Übersetzung aus dem Forum ins aktuelle ahk 1.1 (von skrommel)

Code: Select all

#NoEnv
#SingleInstance Force
SetBatchLines, -1
DetectHiddenWindows, On

; ===============================================================================================================================

WinGet, source, Id, A
MsgBox % source
Gui, Show, w800 h800
Gui, +LastFound
WinGet, target, Id, A
DetectHiddenWindows, On

DWM(target, source, 0.8)

; ===============================================================================================================================

DWM(target, source, zoom := 1, flags := 0x13, opacity := 150)
{
    VarSetCapacity(thumbnail, A_PtrSize, 0)
    if (DllCall("dwmapi.dll\DwmRegisterThumbnail", "ptr", target, "ptr", source, "ptr", &thumbnail) != 0)
        return (ErrorLevel := 1) & 0
    thumbnail := NumGet(thumbnail, 0, "ptr")

    WinGetPos, wx, wy, ww, wh, % "ahk_id " target
    VarSetCapacity(DWM_THUMBNAIL_PROPERTIES, 45, 0)
    NumPut(flags,   DWM_THUMBNAIL_PROPERTIES,  0, "uint")
    NumPut(0,       DWM_THUMBNAIL_PROPERTIES,  4, "int")
    NumPut(0,       DWM_THUMBNAIL_PROPERTIES,  8, "int")
    NumPut(ww,      DWM_THUMBNAIL_PROPERTIES, 12, "int")
    NumPut(wh,      DWM_THUMBNAIL_PROPERTIES, 16, "int")
    NumPut(0,       DWM_THUMBNAIL_PROPERTIES, 20, "int")
    NumPut(0,       DWM_THUMBNAIL_PROPERTIES, 24, "int")
    NumPut(ww/zoom, DWM_THUMBNAIL_PROPERTIES, 28, "int")
    NumPut(wh/zoom, DWM_THUMBNAIL_PROPERTIES, 32, "int")
    NumPut(opacity, DWM_THUMBNAIL_PROPERTIES, 36, "uchar")
    NumPut(1,       DWM_THUMBNAIL_PROPERTIES, 37, "int")
    NumPut(1,       DWM_THUMBNAIL_PROPERTIES, 41, "int")
    if (DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", "ptr", thumbnail, "ptr", &DWM_THUMBNAIL_PROPERTIES) != 0)
        return (ErrorLevel := 2) & 0
    return 1
}
Lässt sich bestimmt mit spielen
Noch mehr hier: AeroThumbnail by maul.esel