Entwickler-Ecke
Windows API - "Blinken" in der Taskleiste registrieren
zakoon - Mi 28.01.09 01:20
Titel: "Blinken" in der Taskleiste registrieren
Hallo zusammen,
ich würde gerne herausfinden, ob irgendein Fenster eines bestimmten Prozesses in der Taskleiste "blinkt". Es gibt einige Programm, die das machen um Aufmerksamkeit zu erregen, z.B. Messenger. In der Windows Taskleiste wird der Eintrag des Fensters dann 3 mal kurz "ge-highlighted" :)
Wie ich die Handles der Unterfenster meines Prozesses bekomme weiß ich schon. Aber nicht wie ich dieses "Blink"-Event registrieren kann.
Über sachdienliche Hinweise freut sich:
Zacharias.
zakoon - Mi 28.01.09 10:34
Okay, danke, das deckt sich leider mit den wenigen anderen Hinweisen, die ich gefunden habe :(
Kennt jemand zufällig ein gutes Tutorial zu Hooks? Habe so etwas bisher noch nicht gebraucht.
Habe jetzt ein Beispiel auf Delphi-Treff gefunden und so angepasst, dass es die Messages an die Fenster abfangen sollte
Jetzt frage ich mich, wie ich herausfinde ob die Flashwindow() die Message ausgelößt hat, und an wie ich das Handle des Fensters bekomme, das "flashed". Oder kann ich irgendwie den Hook nur für einen Prozess setzen?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49:
| library WindowHook;
uses Windows, Messages;
var HookHandle: Cardinal = 0; WindowHandle: Cardinal = 0;
function WindowHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; begin Result := CallNextHookEx(HookHandle, nCode, wParam, lParam); case nCode < 0 of TRUE: exit; FALSE: begin end; end; end;
function InstallHook(Hwnd: Cardinal): Boolean; stdcall; begin Result := False; if HookHandle = 0 then begin HookHandle := SetWindowsHookEx(WH_CALLWNDPROC, @WindowHookProc, HInstance, 0); WindowHandle := Hwnd; Result := TRUE; end; end;
function UninstallHook: Boolean; stdcall; begin Result := UnhookWindowsHookEx(HookHandle); HookHandle := 0; end;
exports InstallHook, UninstallHook; end. |
Laden tue ich die DLL so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| type TInstallHook = function(Hwnd: THandle): Boolean; stdcall; TUninstallHook = function: Boolean; stdcall;
var InstallHook: TInstallHook; UninstallHook: TUninstallHook; lib: Cardinal;
procedure TForm1.Button1Click(Sender: TObject); begin lib := LoadLibrary('windowhook.dll'); if lib <> INVALID_HANDLE_VALUE then begin InstallHook := GetProcAddress(lib, 'InstallHook'); UnInstallHook := GetProcAddress(lib, 'UninstallHook'); end; end; |
JayEff - Mi 28.01.09 14:07
Laut
Assarbad's Hook Tutorial [
http://assarbad.net/stuff/tutorials/hooks/hook_tutorial.pdf] ist der von dir genutzte Hooktyp WH_CALLWNDPROC ein lokaler Hooktyp, d.h. du musst beim einhaken ohnehin die ThreadID des Prozesses in den du dich einhaken willst angeben. Ich kenne mich aber mit Hooks nicht aus und habe keine Ahnung, woher "HInstance" kommt :nixweiss:
Ich bin sicher, das Tutorial wird dir aber trotzdem helfen :)
zakoon - Mi 28.01.09 14:39
JayEff hat folgendes geschrieben : |
Laut Assarbad's Hook Tutorial [http://assarbad.net/stuff/tutorials/hooks/hook_tutorial.pdf] ist der von dir genutzte Hooktyp WH_CALLWNDPROC ein lokaler Hooktyp, d.h. du musst beim einhaken ohnehin die ThreadID des Prozesses in den du dich einhaken willst angeben. Ich kenne mich aber mit Hooks nicht aus und habe keine Ahnung, woher "HInstance" kommt :nixweiss:
Ich bin sicher, das Tutorial wird dir aber trotzdem helfen :) |
Danke für den Hinweis auf das Tutorial. Den gehookten Prozess kann ich jetzt also durch angeben der ID als vierten Parameter in SetWindowsHookEx() festlegen. Einen Schritt weiter :-)
Jetzt fehlt mir also noch, wie ich aus den zurückgegebenen Parametern meiner Function WindowHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM) ermitteln kann, ob FlashWindow() aufgerufen wurde. Hat jemand dazu eine Idee?
zakoon - Mi 28.01.09 15:09
Ja, die von dir genannten Seiten auf msdn hab ich leider auch schon durchwühlt. Da steht dann immer Parameter XY "Specifies additional information ... " Aber ich habe nicht herausfinden können, was diese "Informationen" im Falle der FlashWindow() sein werden. :(
JayEff - Mi 28.01.09 15:51
Probiers doch mal aus. Schreib dir ein Programm, welches sein Fenster alle 5 sekunden flasht, dann eines, welches einen WH_CALLWNDPROC auf dieses Fenster setzt. In deiner Callback lässt du dir alle interessanten informationen ausgeben, vorallem den message Parameter. Dieser dürfte eine Zahl sein, welche Message das dann ist, musst du selbst rausfinden.
Sobald du weißt, welche Message das ist, kannst du ja in MSDN konkret nach der Bedeutung der w und lParams suchen.
zakoon - Mi 28.01.09 16:45
JayEff hat folgendes geschrieben : |
Probiers doch mal aus. Schreib dir ein Programm, welches sein Fenster alle 5 sekunden flasht, dann eines, welches einen WH_CALLWNDPROC auf dieses Fenster setzt. In deiner Callback lässt du dir alle interessanten informationen ausgeben, vorallem den message Parameter. Dieser dürfte eine Zahl sein, welche Message das dann ist, musst du selbst rausfinden.
Sobald du weißt, welche Message das ist, kannst du ja in MSDN konkret nach der Bedeutung der w und lParams suchen. |
Gute Idee :D Ich probiers mal aus berichte...
JayEff - Mi 28.01.09 16:56
zakoon hat folgendes geschrieben : |
| Gute Idee :D Ich probiers mal aus berichte... |
Das wäre wünschenswert! Wie du vielleicht bemerkt hast, hab ich auch selbst Interesse dran :)
zakoon - Mi 28.01.09 18:04
JayEff hat folgendes geschrieben : |
zakoon hat folgendes geschrieben : | | Gute Idee :D Ich probiers mal aus berichte... | Das wäre wünschenswert! Wie du vielleicht bemerkt hast, hab ich auch selbst Interesse dran :) |
Ok, here mal ein Dump. Mein Testprogramm flasht alle 5 sekunden einmal.
Kannst du daraus etwas erkennen?
EDIT: PS: 134 ist WM_NCACTIVATE und 127 WM_GETICON. Kann man aus einer der Messages auf das Flashen schliessen?
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| Zeit: CWPRETSTRUCT.Message - nCode - wParam - lParam 17:59:14: 134 - 0 - 0 - 1244532 17:59:14: 127 - 0 - 1 - 1244792 17:59:15: 134 - 0 - 0 - 1244808 17:59:15: 127 - 0 - 1 - 1244792 17:59:15: 134 - 0 - 0 - 1244808 17:59:15: 127 - 0 - 1 - 1244792 17:59:19: 134 - 0 - 0 - 1244532 17:59:19: 127 - 0 - 1 - 1244792 17:59:20: 134 - 0 - 0 - 1244808 17:59:20: 127 - 0 - 1 - 1244792 17:59:20: 134 - 0 - 0 - 1244808 17:59:20: 127 - 0 - 1 - 1244792 17:59:24: 134 - 0 - 0 - 1244532 17:59:24: 127 - 0 - 1 - 1244792 17:59:25: 134 - 0 - 0 - 1244808 17:59:25: 127 - 0 - 1 - 1244792 17:59:25: 134 - 0 - 0 - 1244808 17:59:25: 127 - 0 - 1 - 1244792 |
PS: Den Dump habe ich mit folgenden Änderungen erstellt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| function WindowHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; var cwps: TCWPStruct; begin Result := CallNextHookEx(HookHandle, nCode, wParam, lParam); case nCode < 0 of TRUE: exit; FALSE: begin CopyMemory(@cwps, Pointer(lParam), SizeOf(CWPSTRUCT));
outStr:= TimeToStr(now)+': '+IntToStr(cwps.message)+' - '+ IntToStr(nCode)+' - '+IntToStr(wParam)+' - '+IntToStr(lParam); assignfile(datei, 'dump.txt'); if FileExists('dump.txt') then Append (datei) else rewrite(datei); writeln(datei, outStr); closefile(datei); end; end; end; |
JayEff - Mi 28.01.09 22:58
OK das war nicht hilfreich :( Reichlich enttäuschend. Ich vermute, da muss man noch mehr tun...
OK neuer Ansatz: Nutze die uallCollection, im speziellen die uallHook. Meine Callback-Funktion wird aufgerufen aber ich hab einen Fehler drin: danach kommt eine AV:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| var NextFunc: FlashFunc;
function myCallBack(hWnd : HWND; bInvert : LongBool) : LongBool; begin showmessage('flashed' + IntToStr(hWnd)); result := NextFunc(hWnd, bInvert); end;
procedure TForm1.FormCreate(Sender: TObject); begin HookCode(@FlashWindow, @myCallBack, @NextFunc); end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin UnHookCode(@NextFunc); end;
procedure TForm1.Button1Click(Sender: TObject); begin FlashWindow(self.Handle, false); end; |
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!