neues Fenster automatisch erkennen

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

TVTomy
Posts: 2
Joined: 26 Mar 2018, 05:16

neues Fenster automatisch erkennen

26 Mar 2018, 06:35

Hallo!

Gibt es eine möglichkeit, dass automatisch im hintergrund erkannt wird, wann immer ein neues fenster vorhanden ist, damit dann eine bestimmte aktion durchgeführt wird?

Danke für die hilfe!
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: neues Fenster automatisch erkennen

26 Mar 2018, 10:07

Welche art von anwendungsfenster soll denn erfasst werden?
just me
Posts: 9425
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: neues Fenster automatisch erkennen

26 Mar 2018, 10:07

Moin,

eine Möglichkeit ist ein Timer, der regelmäßig die IDs der aktuellen Fenster abruft (siehe WinGet, ..., List - Beispiel #2) und mit dem Ergebnis des vorigen Aufrufs abgleicht. Wenn der aktuelle Aufruf eine ID liefert, die im vorigen Ergebnis nicht enthalten ist, ist das Fenster neu.
TVTomy
Posts: 2
Joined: 26 Mar 2018, 05:16

Re: neues Fenster automatisch erkennen

27 Mar 2018, 03:56

BoBo wrote:Welche art von anwendungsfenster soll denn erfasst werden?
Zum beispiel Excel, Word, Internet Explorer, Firefox, etc.
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: neues Fenster automatisch erkennen

27 Mar 2018, 05:42

TVTomy wrote:
BoBo wrote:Welche art von anwendungsfenster soll denn erfasst werden?
Zum beispiel Excel, Word, Internet Explorer, Firefox, etc.
Also in der regel Windows konforme standard applications (nix JAVA ;) ) was es vereinfacht.
just me's vorschlag sollte da schon passen :)
Folllast
Posts: 91
Joined: 24 Jan 2018, 04:57

Re: neues Fenster automatisch erkennen

27 Mar 2018, 16:16

TVTomy wrote:Hallo!

Gibt es eine möglichkeit, dass automatisch im hintergrund erkannt wird, wann immer ein neues fenster vorhanden ist, damit dann eine bestimmte aktion durchgeführt wird?

Danke für die hilfe!
Oder mehrere WinWait?
User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

Re: neues Fenster automatisch erkennen

30 Apr 2018, 10:12

Das Problem mit Timer ist das das Programm die gesamte Zeit CPU-Zeit beansprucht. Um so kürzer das Intervall umso mehr. Selbst mit der schnellsten Untersuchung einer Liste kam ich bei meinen Versuchen nicht unter 10% Last, wenn die Erkennung neuer Fenster nicht über ein Intervall von 500ms gehen sollte. Wenn Du dann noch für mehrere Fenster automatische Funktionen bereitstellt dann erreicht Du fix 30% Auslastung.
Die Lösung ist OnMessage(). Darüber gibt es etliche Posts hier im Forum.
Aber alles was einen Vorteil hat, hat auch einen Nachteil. Die Auswertung der abgefangenen Nachrichten muss schnell erfolgen. Es ist aber auch wichtig das Schließen der Fenster abzufangen. Was machst Du mit dem Tool tip der noch angezeigt wird , wenn der User das Fenster schon lange geschlossen hat?
just me
Posts: 9425
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: neues Fenster automatisch erkennen

30 Apr 2018, 15:56

Frosti wrote:Selbst mit der schnellsten Untersuchung einer Liste kam ich bei meinen Versuchen nicht unter 10% Last, wenn die Erkennung neuer Fenster nicht über ein Intervall von 500ms gehen sollte. Wenn Du dann noch für mehrere Fenster automatische Funktionen bereitstellt dann erreicht Du fix 30% Auslastung.
Mal abgesehen davon, dass TVTomy anscheinend nicht mehr auf eine Antwort wartet, ist das interessant. Mein Versuch mit einemTimerintervall von 10 ms zeigt im Taskmanager eine CPU-Auslastung von 0 %.
User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

Re: neues Fenster automatisch erkennen

01 May 2018, 13:59

Okay ich zeig dann mal den Code her, es wäre "genial" wenn ich es mir einfach nur schwer gemacht habe.
Und einen Tip könnte ich auch gebrauchen. Möglicherweise lerne ich noch was dazu. ( :dance: )

Code: Select all


compname:= A_ComputerName

;Clientabhängige Rechnerroutinen - wird nur alle 200ms ausgeführt 
;nur die Kontrolle auf diese Fenster macht im Schnitt 15,7%
;mehr Timer oder irgendein Hook sind nicht an - einzig der Stundentimer
SetTimer, nopopup_%compname%, 200

;Errinnerungsfenster für die Schwestern, Kontrolle von Wochentag und Uhrzeit finden stündlich statt
If Instr("SP1 AnmeldungPC FUNKTION", compname) {
	SetTimer, seldom_%compname%, 3600000						
		}

;wenn ein Rechner unbenutzt ist (Idle Zustand), werden bestimmte Routinen angehalten
	SetTimer, UserAway, 30000

			.
			.
			.

nopopup_AnmeldungPC: ;{

		;drückt ein Fenster weg
		ChipKartenNachfrage()		
		
		;schließt Teamviewer Hinweisfenster						
		TeamViewerGSClose()								

		;korrigiert die Fensterposition bei Veränderung der Position 
		If (WinActive("Telegram") or WinActive("Claws Mail")) {		
			MailAndTelegramWindow()						
		}

		;HELP Taskbar für Praxomat
		IfWinActive, ALBIS ahk_class OptoAppClass
			AlbisHotKeyHilfe(AddendumHelp, PraxomatHelp)

		;diese Routine zeigt ein Ausfüllhinweis für die Angestellten an 
		;der muss natürlich geschlossen werden wenn das Fenster nicht mehr da ist
		If (WinExist("Cave! von") And CTTExist=0) {				
				AlbisCaveVonToolTip(compname)
		} else If (!WinExist("Cave! von") And CTTExist=1) {			
				CTTExist=0
				ToolTip,,,, 10
		}


return

;diese wird nur einmal pro Stunde aufgerufen
seldom_AnmeldungPC:

	If ( (A_WDay = Donnerstag) AND (A_HOUR > 10) AND (AuffuellFlag = 0) ) {
				Auffuellflag = 1
				IniWrite, 1, %AddendumDir%\Praxomat.ini, Anmeldung-PC, Auffuellflag
				SprechzimmerAuffuellen("1")
		}

		If ( (Auffuellflag = 1) AND (!A_WDay = Donnerstag) ) {
				Auffuellflag = 0
				IniWrite, 0, %AddendumDir%\Praxomat.ini, Anmeldung-PC, Auffuellflag
		}

return

;Funktionen -----

ChipKartenNachfrage() {	;automatisches Schließen des Fensters - der Patient hat in diesem Quartal seine Chipkarte noch nicht vorgelegt

	SetTitleMatchMode, 2
	CoordMode, ToolTip, Window
	If WinExist("ALBIS", "Patient hat in diesem Quartal") {
		ControlGet, BHwnd, Hwnd, , Button1, ALBIS
		ToolTip, Chipkartennachfrage Fenster wurde gefunden`nEs wird geschlossen. Button "Ja" Hwnd ist: %BHwnd%, 100,2, 19
		WinActivate, ALBIS ahk_class #32770, Patient hat in diesem Quartal
		ControlFocus, Button1, ALBIS ahk_class #32770, Patient hat in diesem Quartal
		ControlClick, Button1, ALBIS ahk_class #32770, Patient hat in diesem Quartal, LEFT, NA
		sleep, 1000
		ToolTip,,,,19
	}
	CoordMode, ToolTip, Screen
	SetTitleMatchMode, Slow
}

TeamViewerGSClose() {	;schließt das Teamviewer Fenster automatisch

	;schließen des gesponserte Sitzung Fenster von Teamviewer
	If WinExist("Gesponserte Sitzung ahk_exe TeamViewer.exe") or WinExist("Verbindungs Timeout! ahk_exe TeamViewer.exe")
				ControlClick, Button4, ahk_exe TeamViewer.exe ahk_class #32770

return
}

MailAndTelegramWindow() { ;fixieren der Positionen von ClawsMail und Telegramfenster am AnmeldungsPC

	;ClawsMailFenster
	ClawsID:= WinExist("Claws Mail ahk_class gdkWindowToplevel")
	If (ClawsID) {

			WinGet, minmax, minmax, ahk_id %ClawsID%
			if (minmax<>0) {
				WinRestore, ahk_id %ClawsID%
			}

			Claws_RecPointer:= GetWindowPos(ClawsID, ClawsX, ClawsY, ClawsW, ClawsH)
			WinGet, Claws_Style, Style, ahk_id %ClawsID%
			WinGet, Claws_ExStyle, ExStyle, ahk_id %ClawsID%


			if (ClawsX<>1686 OR ClawsY<>12 OR ClawsW<>605 OR ClawsH<>1031) {
						WinMove, ahk_id %ClawsID%,, 1686, 12, 605, 1031
				}
			if ((ClawsStyle<> 0x160F0000) OR (ClawsExStyle<> 0x00000110)) {
						WinSet, Style, 0x160F0000, ahk_id %ClawsID%  ; Entfernt die Titelleiste des aktiven Fensters (WS_CAPTION).
						WinSet, ExStyle, 0x0000011, ahk_id %ClawsID%
			}
	}
	

	;Telegram Fenster
	TGramID:= WinExist("Telegram ahk_class Qt5QWindowIcon")
	If (TGramID) {

			WinGet, minmax, minmax, ahk_id %TGramID%
			if (minmax<>0) {
				WinRestore, ahk_id %TGramID%
			}

			TGram_RecPointer:= GetWindowPos(TGramID, TGramX, TGramY, TGramW, TGramH)
			;WinGet, TGram_Style, Style, ahk_id %TGramID%
			;WinGet, TGram_ExStyle, ExStyle, ahk_id %TGramID%

			if (TGramX<>2302 OR TGramY<>13 OR TGramW<>654 OR TGramH<>1024) {
						WinMove, ahk_id %TGramID%,, 2302, 13, 654, 1024
				}

	}

}



just me
Posts: 9425
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: neues Fenster automatisch erkennen

02 May 2018, 03:30

Moin,

meine Angabe zur CPU-Auslastung bezog sich auf die Abarbeitung einer mit WinGet, Liste, List erstellten Fensterliste bei der Suche nach neuen Fenstern. Dein Timer macht schon andere Dinge.

Was in Deinem Code zu sehen ist, spricht auf den ersten Blick nicht unbedingt für eine so hohe CPU-Auslastung. Das ist aber narürlich auch abhängig von der Leitsungsfähigkeit der Hardware, auf der das Skript läuft, und von weiteren Einstellung im Skript, wie

Code: Select all

#NoEnv
SetBatchLines, ...
SetWinDelay, ...
SetControlDelay, ...
SetTitleMatchMode, ...
DetectHiddenWindows, ...
Dein Code macht es AHK aber auch nicht gerade leicht. Anweisungen wie

Code: Select all

	If WinExist("ALBIS", "Patient hat in diesem Quartal") {
zwingen AHK immer wieder dazu, sich durch die Fensterliste und dann auch noch durch die Controls des Fensters zu hangeln. Die Win... und Control... Anweisungen bewirken viel weniger Aufwand, wenn man immer wenn möglich mit der ahk_id (HWND) arbeitet und/oder das "Zuletzt gefundene Fenster" 'benutzt', das von Anweisungen wie WinExist() oder IfWinActive gesetzt wird.

Als Beispiel für mögliche Verbesserungen mal ChipKartenNachfrage() und TeamViewerGSClose() (ungetestet):

Code: Select all

ChipKartenNachfrage() {	;automatisches Schließen des Fensters - der Patient hat in diesem Quartal seine Chipkarte noch nicht vorgelegt
	SetTitleMatchMode, 2 ; Muss das hier geändert werden?
	CoordMode, ToolTip, Window ; Warum? Es wird kein Tooltip angezeigt!
	If WinExist("ALBIS ahk_class #32770", "Patient hat in diesem Quartal") { ; falls ahk_class #32770 benötigt wird
		ControlGet, BHwnd, Hwnd, , Button1 ; last-found window
		ToolTip, Chipkartennachfrage Fenster wurde gefunden`nEs wird geschlossen. Button "Ja" Hwnd ist: %BHwnd%, 100,2, 19
		WinActivate ; last-found window
		ControlFocus, , ahk_id %BHwnd% ; BHwnd benutzen
		ControlClick, , ahk_id %BHwnd%, , LEFT, NA ; BHwnd benutzen
		sleep, 1000
		ToolTip,,,,19
	}
	CoordMode, ToolTip, Screen ; Warum? Siehe oben!
	SetTitleMatchMode, Slow ; Ist das notwendig?
}

TeamViewerGSClose() {	;schließt das Teamviewer Fenster automatisch
   ;schließen des gesponserte Sitzung Fenster von Teamviewer
   If WinExist("Gesponserte Sitzung ahk_class #32770 ahk_exe TeamViewer.exe") or WinExist("Verbindungs Timeout! ahk_class #32770 ahk_exe TeamViewer.exe")
      ControlClick, Button4 ; last-found window
return
}
Es könnte auch noch ewas bringen, MailAndTelegramWindow() und die zugehörige Abfrage

Code: Select all

		;korrigiert die Fensterposition bei Veränderung der Position
		If (WinActive("Telegram") or WinActive("Claws Mail")) {
			MailAndTelegramWindow()
		}
aufzuteilen. Aufgerufen wird die Funktion nur, wenn eines der Fenster aktiv ist. Innerhalb der Funktion spielt das dann aber keine Rolle. Hier könnte es sich auch lohnen, das zuletzt gefundene Handle (HWND) von "Claws Mail" in einer statischen Variablen zwischenzuspeichern. Es sollte eigentlich reichen, die Style und ExStyle Änderungen nur einmal zu machen.

Die Änderungenwirken sich aber nur aus, wenn die Fenster tatsächlich gefunden werden. Sollte die CPU-Last hauptsächlich durch die Fenstersuche im Timer entstehen, wird das nicht viel bringen. Es könnte aber etwas bringen, die wiederholten IfWInActive Anweisungen im Timer durch ein

Code: Select all

If (ActiveID := WinExist("A")
zu ersetzen und anschließend selbst zu prüfen, ob das Fenster die Kriterien erfüllt. Und wenn eines der Fenster aktiv ist, können es die anderen nicht sein.

Die Funktionen AlbisHotKeyHilfe() und AlbisCaveVonToolTip() fehlen leider. Darin mag sich auch noch Zündstoff verbergen.

Edit:
Noch ein kleiner 'Verbesserungsvorschlag' um ein WinExist() einzusparen:

Code: Select all

   ;diese Routine zeigt ein Ausfüllhinweis für die Angestellten an
   ;der muss natürlich geschlossen werden wenn das Fenster nicht mehr da ist
   If WinExist("Cave! von") {
      If (CTTExist = 0)
         AlbisCaveVonToolTip(compname)
   } Else {
      If (CTTExist = 1) {
         CTTExist := 0
         ToolTip,,,, 10
      }
   }
User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

Re: neues Fenster automatisch erkennen

23 May 2018, 17:36

Ist jetzt einiges an Zeit vergangen und ich habe Deine Vorschläge umgesetzt. Es hat etwas gebracht. Ich liege circa bei 8-9% CPU Auslastung. Das ist aber immer noch zuviel. Ich habe mir jetzt allerdings auch nicht weiter den Kopf zerbrochen.
just me
Posts: 9425
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: neues Fenster automatisch erkennen

24 May 2018, 01:18

Wenn Du Deinen aktuellen Code einstellst, würde ich mir den noch einmal intensiver anschauen. Eine CPU-Last von 0 % wird in diesem Fall aber eher nicht zu erreichen sein.
User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

Re: neues Fenster automatisch erkennen

24 May 2018, 14:38

Der aktuelle Code entspricht Deinen Änderungen. Hat doch aber auch was gebracht. Sieh mal was ich hier gerade aus einem anderen Thread von EvilC als Antwort gepostet gefunden haben.
https://autohotkey.com/boards/viewtopic ... sleep+time
while (A_TickCount < reopen)
{ ;do nothing
}

DO NOT do this. It will use LOTS of CPU time.
On my work PC, this code alone uses ~5% CPU

However, with MicroTimer, I can have a 1 MILLISECOND timer running and the CPU usage is like 0.1%
Diesen Teil mit A_Tickcount habe ich nicht gepostet. Ich bin zufrieden von 13-15% auf 8-9%. Ich habs jedoch in meiner vollen Blase, daß da noch irgendein anderer Grund da ist. Ich werde das Problem finden.
Ich möchte es jetzt auch allein finden. Neulich haperte es an meiner Konzentration und da habe ich halt gefragt weil es merkbar den Computer ausbremste und ich keine Lösung fand und das Problem weg musste.
Jetzt ist ein Ausbremsen nicht mehr zu merken und es hat deshalb Zeit.

Doch was denkst Du über obiges? Wie meint er das?
Meint er den Loop, den Variablenvergleich oder A_TickCount das CPU Zeit kostet oder die Kombination?
just me
Posts: 9425
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: neues Fenster automatisch erkennen

25 May 2018, 03:01

Moin,

AHK führt den Skriptcode aus und braucht dafür Rechenleistung (CPU). Und weil es eine interpretierte Sprache ist, wird während der Ausführung ein Teil der Leistung nur für den Interpreter benötigt.

Code: Select all

WaitUntil := A_TickCount + 60000
While (A_TickCount < WaitUntil) {
}
läuft auf meinem Rechner (4 Prozessorkerne - 2 echte + 2 logische) mit ~13 % CPU-Last. Das ist ungefähr ein halber Kern.
Wenn ich noch

Code: Select all

SetBatchLines, -1
einfüge, komme ich auf ~25 % CPU-Last. Das ist schon ein ganzer Kern. Es liegt daran, dass AHK die Skriptausführung dann nicht mehr regelmäßig intern unterbricht.

Für (A_TickCount < WaitUntil) muss AHK bei jedem Schleifendurchlauf
  • erst einmal den Ausdruck im Skriptcode parsen/auflösen,
  • dann den aktuellen Wert des Systemtimers TickCount per Aufruf der API-Funktion GetTickcount() abrufen,
  • dann den Wert der Variablen WaitUntil ermitteln
  • und schließlich beide Werte vergleichen.
Und wenn die Schleife nicht durch AHK selbst oder z.B. einen Timer unterbrochen wird, nimmt sich AHK dafür alle Rechenleistung, die zur Verfügung steht, maximal also einen kompletten CPU-Kern.

Die Schleife ist aber nicht nur ein 'CPU-Fresser', sie ist auch ein 'sinnloser' CPU-Fresser. Der Wert des Systemtimers TickCount wird auf normalen Rechnern nur alle 15 oder 16 (genauer ~15,625) Millisekunden verändert (es soll auch Systeme mit einem ~10 Millisekunden Intervall geben). In dieser Zeit wird die Schleife zig-mal durchlaufen und vergleicht 'sinnlos' immer wieder identische Werte. Und das bedeutet auch, dass AHK eine 'auf die Millisekunde genaue' Prüfung systembedingt nicht leisten kann. Es ist deshalb sinnvoll, in die Schleife ein Sleep Kommando einzufügen, das diesen sinnlosen Aktionismus abstellt. Das darf auch ein Sleep, 1 sein, weil auch die internen Prüfungen für den Ablauf der Sleep-Zeit auf den TickCount abgestellt sind. Ein Sleep, 1 wartet also darauf, dass der TickCount einen neuen Wert bekommt.

Deshalb:

Code: Select all

#NoEnv
SetBatchLines, -1
WaitUntil := A_TickCount + 1000
While (A_TickCount < WaitUntil) {
   Sleep, 1
}
Das reduziert die angezeigte CPU-Last hier auf 00 und reagiert mit einer Genauigkeit von 15,625 Millisekunden.

Als weiteres Beispiel:

Code: Select all

#NoEnv
SetBatchLines, -1
Iterations1 := 0
Iterations2 := 0
Sleep, 1 ; A_TickCount synchronisieren
WaitUntil := A_TickCount + 1000
While (A_TickCount < WaitUntil) {
   Iterations1++
}
Sleep, 1 ; A_TickCount synchronisieren
WaitUntil := A_TickCount + 1000
While (A_TickCount < WaitUntil) {
   Iterations2++
   Sleep, 1
}
MsgBox, 0, Schleifendurchläufe, Ohne Sleep: %Iterations1%`nMit Sleep: %Iterations2%
User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

Re: neues Fenster automatisch erkennen

25 May 2018, 14:02

Grandios erklärt! Das sollte am besten in der Autohotkey Hilfe untergebracht werden. Jetzt verstehe ich warum es bei einem meiner anderen Skripte regelmässig zu CPU Auslastungspeaks kommt.
Gast

Re: neues Fenster automatisch erkennen

28 May 2018, 06:40

Ich möchte in diesem Zusammenhang noch einmal auf einen nicht ganz neuen Thread verweisen, der in der Google-Suche unter "[How to] Hook on to Shell to receive its messages?" zu finden ist. (https://goo.gl/cvHU1B)

Diese Methode führt nämlich zu überhaupt keiner relevanten Systemauslastung.

Bei mir läuft seit Jahren ständig ein Script mit ca. 1.400 Codezeilen im Hintergrund, was unter anderem sämtliche Fenster überwacht. Die Systemauslastung liegt dabei in Ruhe nie über 0,16%.

Der Ablauf sieht in etwa so aus, dass Windows ständig u.a. auch alle vorhandenen Fenster über gerade ablaufende Systemereignisse informiert.

Also erzeugt man ein Fake-Fenster und überwacht das Eintreffen dieser Messages.

Erhält das Fake-Fenster nun eine Benachrichtigung darüber, dass irgendwas mit einem anderen Fenster passiert, ruft der Befehl OnMessage die Funktion "ShellMessage" auf und man kann entsprechend auf das jeweilige Ereignis reagieren.

Meine Variante davon sieht so aus:
Am Anfang des Scriptes

Code: Select all

	Gui, New, +HwndFakeWinHwnd
	DllCall( "RegisterShellHookWindow", UInt, FakeWinHwnd)
	OnMessage( DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" ), "ShellMessage" )
Irgendwo unten dann die Funktion "ShellMessage", um die Message auszuwerten

Code: Select all

ShellMessage(wParam,lParam) {
			If ( wParam = 1 ) { ; HSHELL_WINDOWCREATED
		;	Ausgangszustand feststellen und versteckte Fenster für AHK sichtbar machen
			HiddenWinState := A_DetectHiddenWindows
			HiddenTextState := A_DetectHiddenText
			DetectHiddenText, On
			DetectHiddenWindows, On

		;	Infos über das neue Fenster abfragen
			WinHWND := lParam	; Windows-Handle
			WinGetPos , WinX, WinY, WinWidth, WinHeight, ahk_id %WinHWND%	; Koordinaten, Höhe und Breite
			WinGetTitle, WinTitle, ahk_id %WinHWND%	; Fenstertitel
			WinGetText, WinText, ahk_id %WinHWND%	; Textinhalt
			WinGetClass, WinClass, ahk_id %WinHWND%	; Klasse (ahk_class)
			WinGet, WinControlList, ControlList, ahk_id %WinHWND%	; Liste der Controls
			WinGet, WinStyle, Style, ahk_id %WinHWND%	; Style
			WinGet, WinExStyle, ExStyle, ahk_id %WinHWND%	; Extended Style
			WinGet, WinPID, PID, ahk_id %WinHWND%	; Prozess-ID
			For Process In ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process where Handle=" . WinPID) {	; Infos über den Prozess holen
				Commandline := Process.CommandLine	; Kommandozeilenaufruf
				ExePath := Process.ExecutablePath	; Pfad zur EXE
			}

		;... weiterer beliebiger Code zur Auswertung der erhaltenen Informationen über das neue Fenster...

		} ;# Ende der Funktion ShellMessage()
Allerdings werden nur "Elternfenster" erkannt. Erzeugen diese wiederum "Unterfenster" kann man von der Funktion aus z.B. einen Timer starten und über ein separates Label auf diese Fenster reagieren.

Kann z.B. so aussehen (wäre dann ein Teil des "weiteren beliebigen Codes" innerhalb der Funktion)

Code: Select all

			;Automatisch einloggen wenn SFirm gestartet wird
			If( ExePath = "c:\program files (x86)\sfirmv3\programm\sfmainprg.exe") {
				SetTimer, WatchSFirmAnmeldung, 200 ; Label 'WatchSFirmAnmeldung' überprüft periodisch, ob das LogIn-Fenster vorhanden ist und trägt die LogIn-Daten ein
			}
An beliebiger Stelle außerhalb der Funktion steht dann das Label

Code: Select all

;	SFirm Passworteingabe
	WatchSFirmAnmeldung:
		IfWinActive, SFirm Anmeldung
		{
			Send, ********************{ENTER}
			SetTimer, WatchSFirmAnmeldung, Off
		}
	Return
just me
Posts: 9425
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: neues Fenster automatisch erkennen

29 May 2018, 07:57

Ja, das ist eine gute Lösung. Sie verlangt vom Skriptschreiber aber mehr Kenntnisse, wenn er nicht einfach nur 'blind' Code kopieren will, den er dann möglicherweise nicht selbst warten kann. Wenn es geht, bevorzuge ich deshalb die eingebauten und dokumentierten AHK Anweisungen.
Gast

Re: neues Fenster automatisch erkennen

29 May 2018, 09:37

just me wrote:Ja, das ist eine gute Lösung. Sie verlangt vom Skriptschreiber aber mehr Kenntnisse, wenn er nicht einfach nur 'blind' Code kopieren will, den er dann möglicherweise nicht selbst warten kann. Wenn es geht, bevorzuge ich deshalb die eingebauten und dokumentierten AHK Anweisungen.
Wenn es um das grundlegende Verständnis für die in Windows ablaufenden Prozesse und für AHK geht, bist du hier vermutlich so etwas wie "das letzte Einhorn". Mit Glück gibt es hier noch 2 oder 3 weitere Leute mit Spezialwissen auf einzelnen Fachgebieten.
Irgendwie verstehe ich dann auch, dass man keine Lust hat, die Erklärung der Erklärung noch einmal erklären zu müssen und wie selbstverständlich davon ausgeht, dass tüfteln und nachdenken von den meisten Fragestellern nicht gewollt ist.

Anyway ... der Code enthält 6 Zeilen, die sich einem nicht wirklich von selbst erschließen. Der Rest ist frühe Kindersprache von AHK und in der Doc nachzulesen.

Wenn man bei AHK 3.0 dereinst nur noch durch Antippen von Kacheln fertige Codebausteine aneinanderfügen muss, werde ich glücklicherweise schon tot sein :offtopic:
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: neues Fenster automatisch erkennen

29 May 2018, 10:06

Entgegen aller deiner Unterstellungen hier dürften sich die meisten mit dem ShellHook auskennen und sich schon mal an einem ShellHook versucht haben.
Bei dem Versuch einen zu erzeugen wird einem dann doch relativ schnell klar wieso diese Technik nichts für Neulinge ist:
Sie ist sehr instabil. Für schon kleinere Verzögerungen schmeißt Windows dich aus der ShellHook raus - ohne Vorwarnung und ohne Hinweis.
Es gibt sehr viel was man beachten und wissen muss was einem auf Anhieb nicht direkt klar ist.
Für einen Neuling ist diese Technik nichts.
Recommends AHK Studio
User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

Re: neues Fenster automatisch erkennen

29 May 2018, 15:57

Ja als Neuling habe ich Shellhooks erstellt. Kein Ding. Das kapiert man schnell. Schwierig wurde es eben wenn wenn ChildWindows hinzu kommen. Mit der hier im Forum gefundenen Funktion IsBlocked() oder FindChildWindow oder noch einfacher (der Name fällt mir nicht ein gerade) einem einfachen DllCall einer WindowsRoutine mit der sich das zuletzt erstellte childwindow eines Prozesses ermitteln lässt , vereinfacht sich vieles. Letztere Funktion eignet sich hervorragend nach und nach alle blockierend ChildWindows zu schliessen um auf schnellem Wege auch ohne Enumerierung (so heisst das glaube ich) der Childs schnell weiter arbeiten zu können. Schwierig finde ich allerdings die Abarbeitung eingehender Messenges, wenn ich Subfunktionen aufrufe die langamer sind als die eintreffende Nachrichten. Mein Versuch zum zwischenpuffern der Messages (nennt man das Stack) hat mir zuviel Zeit gekostet und darum muss es über den die AHK internen Befehle erstmal reichen. Die Shellhooks laufen bei mir zu Hause bei meinem Scanprogramm. Ein Programm das manchmal Fenster nicht in der gleichen Reihenfolge öffnet. Auf Arbeit sind es gezählt 7 Programme die bearbeitet werden müssen. Wobei das Praxisprogramm manchmal childs öffnet manchmal eigene externe Prozesse mit eigenen Fenstern öffnet. Das Medikamentendatenbank nutzt 20 sichtbare Fenster und bei 200 (da habe ich aufgehört zu zählen) unsichtbare Fenster. So habt ihr beide durchaus recht. Ich schreibe meine Skripte so das interessierte Kollegen auch etwas damit anfangen können.
Try Ewig.langer().Objekt.Syntax.mit.(*Hashtag.enum.und."Sonstwas").bricht.mir.die.Augen.InsertAt(vorne):= Keine Ahnung.
Mehr versteh ich dann kaum und soll ja anpassbar bleiben und insbesondere für nicht Programmierer lesbar. Ansonsten bin ich ein Fan von Assembler! Der heutige Assemblercode ist allerdings nicht mehr so schön wie früher auf dem C64.

Anmerkung die wunderbare Funktion deren Namen ich nicht wußte ist diese hier:

Code: Select all

WinID:=WinExist("A")
popHwnd:= DLLCall("GetLastActivePopup", "uint", WinID)
Last edited by Frosti on 30 May 2018, 15:02, edited 1 time in total.

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: No registered users and 33 guests