![]() |
Bei Maus klich Timer stoppen
Hallo,
ich möchte sobald die linkemaustaste gedrückt wird meinen Timer stoppen. Alerdings soll es egal sein wo die Maus geklickt wird da ich eine Art Color Picker progammieren will. Ich denke das OnMouseDown deshalb nicht in Frage kommt und weiß nun keine weitere möglichkeit. |
Re: Bei Maus klich Timer stoppen
Hi,
Du koenntest SetCapture() verwenden. Es wird ein OnMouseUp ausgeloest wenn die Maus losgelassen wird. Eignet sich gut fuer einen Color Picker. |
Re: Bei Maus klich Timer stoppen
Du könntest versuchen, im OnTimer die Windows-Message abzufangen, die bei einem Klick gesendet wird. Such mal im Forum danach, da wirst du sicher fündig ;)
|
Re: Bei Maus klich Timer stoppen
Ich hab mal im Forum gesucht, aber nicht wirklick was gefunden
was sich eignet. |
Re: Bei Maus klich Timer stoppen
Colorpicker ?
Ich hab' mal einen gemacht, mit nem Image und onMouseMove (im OnClick dann die Farbe gespeichert) ... |
Re: Bei Maus klich Timer stoppen
Wenn du ein TApplicationEvents-Objekt einbaust, müsste das eigentlich gehen. Damit bekämst du dann alle MouseDown-Events die auf der Form insgesamt niedergehen. ...Nötig hierfür wäre dann nur noch mehr ein entsprechender ApplicationEvents1.OnMessage-Eventhandler und darin dann auf wm_lbuttondown prüfen.
|
Re: Bei Maus klich Timer stoppen
Und wie funktioniert das?
|
Re: Bei Maus klich Timer stoppen
(?). Das Teil einfach auf die Form ziehen und dann im OI einen Doppelklick rechts neben die OnMessage-Property. In diesen (so dann erzeugten) Eventhandler werden dann quasi sämtliche Messages zuerst hin/umgeleitet, ...jene welche nämlich ansonsten gleich an die WndProc der Form bzw. die WndProcs der einzelnen Controls darauf gehen würden. Dort könntest du dann also auf WM_LButtonDown prüfen und entsprechend reagieren...
Delphi-Quellcode:
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean); begin if Msg.message = wm_lbuttondown then begin ... end; end; |
Re: Bei Maus klich Timer stoppen
Zitat:
|
Re: Bei Maus klich Timer stoppen
Zitat:
MfG Binärbaum |
Re: Bei Maus klich Timer stoppen
Wenn du das für den gesamten Screen haben willst (also auch über den Rand deiner Application hinaus), wird es wohl nur mittels eines globalen MousHooks klappen. Denn: Wenn du nämlich über einer anderen Application clickst, dann wird die ja natürlich auch aktiv und dh. dass alle Mausereignisse dann nur noch mehr dorthin geleitet würden. Außerdem bedeutet das auch, dass du u.U. bei diesen anderen Applications auch wieder event. ungewollte Ereignisse auslösen würdest.
Ergo: Mittels des globalen MousHooks alle MouseDown-Events registrieren, diese Events dann für alle anderen Apps "abfangen bzw. verschwinden lassen" und gleichzeitig bezüglich eines jeden solchen MousDowns dann noch die Farbinformation (z.B. per GetPixel) ermitteln und sie an dein ColorPick-Programm zurückschicken. |
Re: Bei Maus klich Timer stoppen
So, jetzt habe ich mir mal nen kleinen hook gebaut, kriege auch alles
ohne Fehler gestartet, nur passiert nix. mousehook.dll
Delphi-Quellcode:
MainFrm.pas
library mousehook;
uses SysUtils, Classes, Windows, Messages, Dialogs; var HookHandle: Cardinal = 0; WindowHandle: Cardinal = 0; {$R *.res} function MouseHookProc(nCode:integer;wParam:WParam;lParam:LParam): LResult; stdcall; begin Result := CallNextHookEx(HookHandle,nCode,wParam,lParam); case nCode < 0 of true: exit; false: begin if GetAsynckeyState(vk_lbutton) <> 0 then showmessage('Die linke taste wurde gedrückt'); end; end; end; function InstallHook(Hwnd: Cardinal): Boolean; stdcall; begin result := false; if HookHandle = 0 then begin HookHandle := SetWindowsHookEx(WH_Mouse,@MouseHookProc, hInstance, 0); WindowHandle := hwnd; Result := true; end; end; function UninstallHook: Boolean; stdcall; begin Result := UnHookWindowsHookEx(HookHandle); HookHandle := 0; end; exports InstallHook, UninstallHook; end.
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin lib := loadlibrary('keyhook.dll'); if lib <> Invalid_Handle_Value then begin InstallHook := GetProcAddress(lib,'InstallHook'); UninstallHook := GetProcAddress(lib,'UninstallHook'); end else Close; end; |
Re: Bei Maus klich Timer stoppen
Also es ist schon ein paar Monate her, wo ich mich etwas gründlicher mit Hooks beschäftigt habe, aber ich glaube nicht, dass man bei einem globalen Hook bzw. in dessen HookProcs (die dann ja auch in alle möglichen fremde Adressräume hineingelinkt werden) VCL-Routinen (=showMessage) benutzen kann. Mal ein einfaches Beep an dieser Stelle wäre wahrscheinlich besser.
Außerdem scheint mir deine DLL für einen globalen Hook doch irgendwie etwas zu einfach zu sein. So weit ich weiß, ist da z.B. auch noch ein extra Mapping des Variablen-Speichers nötig ...also für diejenigen Variablen, auf die du in der jeweiligen HookProc dann ja auch zugreifen können möchtest, wie z.B. auf die Handle deines ursprünglichen Programms. Hier vielleicht mal kurz ein diesbezüglicher Code mit dem ich bisher eigentlich immer ganz gut gefahren bin:
Delphi-Quellcode:
[edit, bezüglich "SetHook"]: "OtherApp" (-> Handle der zu hookenden App) noch nachträglich eingebaut. ("ProgHandle" ist da die Handle des den Hook erzeugt habenden Delphi-Programms).
uses
Windows, Messages, SysUtils; const WM_SpecialEvent = WM_User + 1678; type THookRec = record hMSNHook: HHOOK; hMSNWnd: HWND; end; var hMap: DWord; buf: ^THookRec; function PROC(nCode: Integer; wp: wParam; lp: lParam): LongInt; stdcall; var pt : TSmallPoint; begin if (nCode >= HC_ACTION) then if wp = WM_LButtondown then begin pt := PointToSmallPoint(PMouseHookStruct(lp)^.pt); PostMessage(buf^.hMSNWnd, WM_SpecialEvent, wp, integer(pt)); // z.B. informieren des ursprünglichen Progs darüber, bei welchem X,Y das LButtonDown stattgefunden hat... {...} end; Result := CallNextHookEx(buf^.hMSNHook, nCode, wp, lp); end; // sets up hook function SetHook(ProgHandle, OtherApp : integer): Boolean; stdcall; export; begin try Result := false; if (not assigned(buf)) then begin hMap := CreateFileMapping(DWord(-1), nil, PAGE_READWRITE, 0, SizeOf(THookRec), 'HookRecMemBlock'); buf := MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); buf^.hMSNHook := SetWindowsHookEx(WH_Mouse, @Proc, hInstance, GetWindowThreadProcessId(OtherApp,nil)); // OtherApp=0 heißt dann: globaler Hook buf^.hMSNWnd:=HWND(ProgHandle); Result := true; end; except Result := false; MessageBox(0, 'error in SetHook', 'error', MB_OK); end; end; // removes hook function RemoveHook: Boolean; stdcall; export; begin Result := false; if (assigned(buf)) then begin UnhookWindowsHookEx(buf^.hMSNHook); buf^.hMSMHook := 0; UnmapViewOfFile(buf); buf := nil; CloseHandle(hMap); hMap := 0; Result := true; end; end; // DLL entry point procedure DllEntry(dwReason: DWord); begin Case dwReason of DLL_PROCESS_ATTACH: begin if (not assigned(buf)) then begin hMap := OpenFileMapping(FILE_MAP_ALL_ACCESS, false, 'HookRecMemBlock'); buf := MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); CloseHandle(hMap); hMap := 0; end; end; DLL_PROCESS_DETACH: begin if (not assigned(buf)) then begin UnmapViewOfFile(buf); buf := nil; end; end; end; { of case } end; exports SetHook, RemoveHook; begin // ähnlich dem initialization-Bereich bei Units DllProc := @DLLEntry; DllEntry(DLL_PROCESS_ATTACH); // bewirkt: initiales Memery-Mappen end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz