Popular Post binhnx Posted September 20, 2014 Popular Post Share Posted September 20, 2014 (edited) Version 3: Ops, you may ask, where's the version 2? The answer is, you will never see it. I skipped it to jump to version 3 directly. Why? Actually, I didn't learn M$ about that versioning The reason is, I planed to write version 2, using the new window/control handle indexing technique to eliminate all the ugly and slow loop. But when nearly finish, I feel so tired, tired of using a lots of all workaround. And finally, I decided to rewrite entire the UDF, using the direct solution, the way all other languages used, and should use. I late some day, because of some machine code (it's actually not so necessary, but if the control is doing an expensive task, like heavy drawing then passing all the Window Message to AutoIt is not a so good idea because its slow speed may result in some annoying-small-but-easy-to-figure-out problems, (like tearing as example). So I use machine code directly to pass over it. Now you have not a Stupid but a Smart UDF And it's still simple. API change: Remove a parameter from _SSCtrlHover_Register. You nolonger can attach other controls to the registered control. Use another method to do it and when you delete the control be sure to delete all the attached controls yourself. This breaks your old script. Add double click event (last 2 parameters of _SSCtrlHover_Register) Remove the _SSCtrlHover_Delete. You must manually delete yourself. It's easy with GUICtrlDelete and I decide not to duplicate this function to my UDF (be sure to delete your attached control too) This version eliminate all the odd limit of old version, include: No:longer use timer/adlib to test the control is on mouse event. Now it directly use native WinAPI method to provide a truly event-driven way. Every click is detected, every mouse hover/left, is handled perfectly. Fast and very fast. All the loop is eliminated. Machine code. Execute speed is much much improved. (read as: nano seconds instead of milliseconds ) I documented it quite well so if you want you can easily browse it and change it the way you want. Now you can use in both GUIGetMsg() loop mode or event mode. No longer setting constants like before because it works perfectly in both mode. Cheer Remark: I don't include <WinAPI.au3> and <WinAPIShellEx.au3> in my UDF, because those UDF is very large and it will consume much more memory when you run (not matter you run the 'compiled' exe, the au3 file, or the .a3x file). In the CtrlHover UDF, i included a small subset of those UDF with the same name, so if you have already included <WinAPI.au3> or <WinAPIShell.au3>, be sure to edit the UDF and comment out the corresponding region. Edit 2: Reorganize script. Fix some issues when drag too fast. Add ability to handle "click" (work RIGHT as normal button, will not fire if you only release the mouse button upon the control as some UDF use MouseUp event) Add a helper method to check if MouseUp event is click event or not. Add compability function to call as normal UDF (with first letter is underscore). Edit 1: Add some function descriptions as JS's advice. Thank you I also changed script name (shorter) and modify the register function so it may be called with less parameter. From now on, the function name and calling syntax will be fixed. OK, I know there is the famous "GUICtrlOnHover" UDF already in this forum, and many people have used it and enjoyed it! But the UDF didn't work as I expected . So I wrote an UDF myself, as much simple as possible, and it works out of the box It has some advantages compare to the old GUICtrlOnHover.au3 It creates the normal button behavior. When you press primary mouse button in the control and begin to drag, it do not set other controls to "hover" state. Faster. I try to add 2k controls. When mouse change from one control to another, it only take about 25ms to handle. In idle state (mouse cursor is not over any control), the cost is ignorable with < 0.1ms. Compare with GUICtrlOnHover UDF takes about 3ms when mouse cursor is over the control, but in idle state, it takes about 35ms. (I do not know why) (That is, because I tested script with overlapped controls. GUICtrlOnHover rely on WinAPI function WindowFromPoint(), which return the first created control (the control with is overlapped any others), but my script rely on GUIGetCursorInfo() which return the last created control - which is the most nested control in Windows). So my script need to check entire 2k control, but GUICtrlOnHover return the first element. I will wait for information about GUIGetCursorInfo() to decide that my UDF should use WinAPI function instead of the native function. In the normal usecase and controls is not overlapped, my UDF is far faster. Edit: Add a setting constant, make you ability to choose use WindowFromPoint() or GUIGetCursorInfo(). Default to the WinAPI function) Faster time to create/ register control. Native AutoIt. No Callback. The only DllCall I use is to get parent window of a control. Wonder why AutoIt do not have a similar function. Found a new bug #2899. If someone can ad more functinal to WinGetHandle("[LAST]"), it should be great Edit: Use some other WinAPI call to provide workaround for issue with GUIGetCursorInfo. Smaller size, about 280 lines compare with about 400 lines of GUICtrlOnHover. More simple, more easy to use. No more than 120 characters in one line. No annoying jumping when scroll the UDF Support event mode to detect mouse down event. But it doesn't work with overlay control. So you cannot have a control (with event) over another control. (use $_BGUIGETCURSORINFOFIX const setting to get rid of this). It seems that it's a AutoIt bug, the GUIGetCursorInfo return a useless control id when controls overlapped. Its not the same with the control received with WindowFromPoint(), or the control which fire event (anyone can confirm it's a bug? Or it's a special feature? ) ( I open a new Trac Ticket here: #2900) Current limit: Mouse down Almost all mouse event is currently detected by timeout (this is why the script called Simple and Stupid, but every UDF I found in this forum also use this method). You can set a smaller timeout to catch the mouse, but sometimes its annoying. Edit: Default changed to 30ms timeout, it should be fast enough to detect any click! You can also change to use event mode to detect click better! Otherwise, it works like a charm. Try it and happy with it Example: Callback function #include "SSCtrlHover.au3" GUICreate(@AutoItVersion) $idLbl1 = GUICtrlCreateLabel("Label 1", 5, 5) SSCtrlHover_Register($idLbl1, "FnNormal", 0, "FnHover", 0, "FnActive", 0, "FnClick", 0) $idLbl2 =GUICtrlCreateLabel("Label 2", 5, 35) SSCtrlHover_Register($idLbl2, "FnNormal", 0, "FnHover", 0, "FnActive", 0, "FnClick", 5) GUISetState() While GUIGetMsg() <> -3 Sleep(10) WEnd Func FnNormal($idCtrl, $hWnd, $vData) ConsoleWrite(@CRLF & "Normal/Leave " & $idCtrl) EndFunc Func FnHover($idCtrl, $hWnd, $vData) ConsoleWrite(@CRLF & "Hover " & $idCtrl) EndFunc Func FnActive($idCtrl, $hWnd, $vData) ConsoleWrite(@CRLF & "Active " & $idCtrl) EndFunc Func FnClick($idCtrl, $hWnd, $vData) ConsoleWrite(@CRLF & "CLICK! " & $idCtrl & " - " & $hWnd & " - " & $vData) EndFunc You can use it with GUICtrlSetImage to provide a "hover button" effect Version 1: SSCtrlHover.au3 Version 3: SSCtrlHover.zip Edited October 20, 2014 by binhnx BBs19, argumentum, boomingranny and 2 others 5 99 little bugs in the code 99 little bugs! Take one down, patch it around 117 little bugs in the code! Link to comment Share on other sites More sharing options...
JScript Posted September 20, 2014 Share Posted September 20, 2014 (edited) Nice! You have some examples to provide us? SSControlHover_Register($idCtrl, $aIdAttachedCtrl, _ $fnNormalCb, $vNormalData, $fnHoverCb, $vHoverData, $fnActiveCb, $vActiveData) Something like popular the sentences below ; #FUNCTION# ==================================================================================================================== ; Name ..........: SSControlHover_Register ; Description ...: ; Syntax ........: SSControlHover_Register($idCtrl, $aIdAttachedCtrl, $fnNormalCb, $vNormalData, $fnHoverCb, $vHoverData, ; $fnActiveCb, $vActiveData) ; Parameters ....: $idCtrl - An integer value. ; $aIdAttachedCtrl - An array of unknowns. ; $fnNormalCb - A boolean value. ; $vNormalData - A variant value. ; $fnHoverCb - A boolean value. ; $vHoverData - A variant value. ; $fnActiveCb - A boolean value. ; $vActiveData - A variant value. ; Return values .: None ; Author ........: Your Name ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== JS Edited September 20, 2014 by JScript http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!) Somewhere Out ThereJames Ingram Download Dropbox - Simplify your life!Your virtual HD wherever you go, anywhere! Link to comment Share on other sites More sharing options...
jaberwacky Posted September 21, 2014 Share Posted September 21, 2014 Where's the code? Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
binhnx Posted September 21, 2014 Author Share Posted September 21, 2014 Where's the code? In the attached file 99 little bugs in the code 99 little bugs! Take one down, patch it around 117 little bugs in the code! Link to comment Share on other sites More sharing options...
jaberwacky Posted September 21, 2014 Share Posted September 21, 2014 Kewl, that wasn't here when I was here though. You may have been editing at the same time I got here. Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
pat4005 Posted October 7, 2014 Share Posted October 7, 2014 (edited) Thank you very much! I used old UDF by Creator for making GUI "buttons" with Pic controls instead and I've noticed that the state fuctions returns too many results at a time. 'Cause of this I had not critical, but unpleasant blinks on my buttons when push and hold mouse button. Your UDF has solved all the problems. Can you clarify for me more detailed, what Data parameters (like $vClickData) do in your UDF? P. S. There is a mistake in the _SSCtrlHover_Register function parameters' description. Last two names of parameters duplicating two others above. Edited October 7, 2014 by pat4005 Link to comment Share on other sites More sharing options...
binhnx Posted October 8, 2014 Author Share Posted October 8, 2014 @pat4005: I'm glad you are happy with my UDF Sorry about the description, I wrote it at very late so I almost copy & paste & forget every thing The $vClickData is a variable which then be pass to your $fnClickCb function callback, as like every other $v...Data in my UDF. I planed to change the UDF a little more (using a fantastic method to store window and control infos so we don't need to loop to find the hover/active... control anymore, and a addtional UDF using the new handy Map feature in new AutoIt version). So I delay changing the description until I finish all the works (I'm too lazy ) (Currently I have no time for it , but I will begin as soon as possible, so just wait ) 99 little bugs in the code 99 little bugs! Take one down, patch it around 117 little bugs in the code! Link to comment Share on other sites More sharing options...
pat4005 Posted October 14, 2014 Share Posted October 14, 2014 (edited) binhnx, hi. Not so long ago I've had a problem with your UDF. When I point "-1" value as a first parameter in _SSCtrlHover_Register function then nothing works. I need to use a variable with control id instead. Also when I use _SSCtrlHover_Register function in multiple places in my program (in multiple windows) some of buttons work and some don't. Can you explain such behavior? Unpatiently wait for a new version of your UDF anyway! Edited October 14, 2014 by pat4005 Link to comment Share on other sites More sharing options...
binhnx Posted October 15, 2014 Author Share Posted October 15, 2014 (edited) At line 67: $_aControlHoverData[$iIndex][0] = $idCtrl I forgot to check $idCtrl = -1 at that point. You can modify it by adding this line after line 57 (before WinAPI GetAncestor() call) If ($idCtrl=-1) Then $idCtrl = DllCall("user32.dll", "INT", "GetDlgCtrlID", "HWND", $hWnd)[0] Sorry about that odd bug. I'll fix it in new version. About the second bug, I haven't pointed out what wrong yet. Currently, my script only working with controls inside top-level GUI. If you use with nested GUI (child GUI(s) created by specified $WS_CHILD in GUICreate), you may get unexpected behavior. I'm not sure if that is your problem or not. When I wrote the first line of the UDF, I decided that it should be much AutoIt as possible. So I try to reduce any WinAPI call (by DllCall), callback or timer function. But as time go by, I realize that it's impossible to write a good UDF without using many WinAPI functions This will solve a lot of problems with current version. Good news: Will start writing today. You may have the new version tomorrow Edited October 15, 2014 by binhnx 99 little bugs in the code 99 little bugs! Take one down, patch it around 117 little bugs in the code! Link to comment Share on other sites More sharing options...
pat4005 Posted October 22, 2014 Share Posted October 22, 2014 (edited) binhnx, your work is impressively REMARKABLE! Of course, I've already downloaded and tested new v3 UDF and it works perfectly great. To be more specific I've noticed speed improvement even by eye, my former problem was just miraculously solved and however blinking defect is still absent. Thank you very much! But here is some "but". I found a little problem and I want to ask you some other questions: 1) Problem is that when I try to exit script containing your UDF functions using HotKeySet function for that, it crushes with an AutoIt big-don't-know-how-to-call-it error twice. Other times all works well. 2) Why don't you put your Assert function inside UDF? 3) Whether еру hover button effect must work when GUI is not active (just curious)? 4) Can you please post an example which will contain ready to use and clickable "button on hover" working scheme with images on controls (if I expressed my thoughts correctly)? UPD: When compiled script crushes after any way to exit it . Edited October 22, 2014 by pat4005 Link to comment Share on other sites More sharing options...
binhnx Posted October 22, 2014 Author Share Posted October 22, 2014 (edited) @pat4005: 1. About the crash problem: I'll fix it later. But it's a good practice to manually delete all the GUI (using GUIDelete) before using the Exit function. 2. Assert function is used for all my UDF so I think it's better to separate it to a different file. If you find it annoying and you only use this UDF, copy that function to main UDF file. 3. The event is delivered by Windows directly, so the hover function is called exactly when a control is on hover, and the normal function is called exactly when the mouse leave the control. Don't worry, it works no matter your GUI is activated or not. It only not work when your GUI is minimized or hidden (why do you need it to work when you can not put your mouse over the control ) It works when you need it and doesn't work when you don't need to save your CPU ) 4. Later, later, later. I'll add a addition SSButtonHover UDF. Now I'm messing with another project Edit: Assert is intended to use in dev. It's only mission is check for something that may cause if you write something careless. So, if you're sure all things you wrote a right: check error, ensure the variable type you specified is match with the expected type... so you definitely safe to remove all the assert statement from my UDF. PS: Thank you for your feedback, it helps me a lot to improve my UDF quality. Edited October 22, 2014 by binhnx 99 little bugs in the code 99 little bugs! Take one down, patch it around 117 little bugs in the code! Link to comment Share on other sites More sharing options...
pat4005 Posted November 5, 2014 Share Posted November 5, 2014 binhnx, I got it. There is more about your UDF. After using hovering image onto pic control I've saw image lags similar to those that was with using Creator's UDF. Is it a known bag? Link to comment Share on other sites More sharing options...
Yashied Posted November 5, 2014 Share Posted November 5, 2014 I use their own small and very simple Skin UDF. My UDFs: iKey | FTP Uploader | Battery Checker | Boot Manager | Font Viewer | UDF Keyword Manager | Run Dialog Replacement | USBProtect | 3D Axis | Calculator | Sleep | iSwitcher | TM | NetHelper | File Types Manager | Control Viewer | SynFolders | DLL Helper Animated Tray Icons UDF Library | Hotkeys UDF Library | Hotkeys Input Control UDF Library | Caret Shape UDF Library | Context Help UDF Library | Most Recently Used List UDF Library | Icons UDF Library | FTP UDF Library | Script Communications UDF Library | Color Chooser UDF Library | Color Picker Control UDF Library | IPHelper (Vista/7) UDF Library | WinAPI Extended UDF Library | WinAPIVhd UDF Library | Icon Chooser UDF Library | Copy UDF Library | Restart UDF Library | Event Log UDF Library | NotifyBox UDF Library | Pop-up Windows UDF Library | TVExplorer UDF Library | GuiHotKey UDF Library | GuiSysLink UDF Library | Package UDF Library | Skin UDF Library | AITray UDF Library | RDC UDF Library Appropriate path | Button text color | Gaussian random numbers | Header's styles (Vista/7) | ICON resource enumeration | Menu & INI | Tabbed string size | Tab's skin | Pop-up circular menu | Progress Bar without animation (Vista/7) | Registry export | Registry path jumping | Unique hardware ID | Windows alignment More... Link to comment Share on other sites More sharing options...
ura Posted April 15, 2017 Share Posted April 15, 2017 Great job Link to comment Share on other sites More sharing options...
ura Posted April 16, 2017 Share Posted April 16, 2017 How to make click and double click trigger different mouse event ? Link to comment Share on other sites More sharing options...
ura Posted April 16, 2017 Share Posted April 16, 2017 Hi About the crash problem Is there a better way? Link to comment Share on other sites More sharing options...
Developers Jos Posted April 16, 2017 Developers Share Posted April 16, 2017 2 hours ago, ura said: About the crash problem Which crash problem? You do realize you're posting in a 3 years old thread? Jos SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
ura Posted April 16, 2017 Share Posted April 16, 2017 8 hours ago, Jos said: 哪个崩溃的问题?你确实意识到你在一个3年的线程发布? 乔斯 Hi, Jos. 1) Compile and run in the exit when there will be two prompt error (The reason seems to be that the registered subclasses have not been removed) 2) I need this udf, and in improving this UDF, help me Link to comment Share on other sites More sharing options...
LarsJ Posted April 18, 2017 Share Posted April 18, 2017 It's true that the crash during script end when the script is run as 64-bit code is caused by the subclasses have not been removed. You can remove the subclasses in the example in the first post in this way: #AutoIt3Wrapper_UseX64=y #include "SSCtrlHover_v3.au3" GUICreate(@AutoItVersion) $idLbl1 = GUICtrlCreateLabel("Label 1", 5, 5) SSCtrlHover_Register($idLbl1, "FnNormal", 0, "FnHover", 0, "FnActive", 0, "FnClick", 0) $idLbl2 =GUICtrlCreateLabel("Label 2", 5, 35) SSCtrlHover_Register($idLbl2, "FnNormal", 0, "FnHover", 0, "FnActive", 0, "FnClick", 5) GUISetState() While GUIGetMsg() <> -3 Sleep(10) WEnd _WinAPI_RemoveWindowSubclass(GUICtrlGetHandle($idLbl1), $__SSCTRLHOVER_PSUBCLASSEXE, GUICtrlGetHandle($idLbl1)) _WinAPI_RemoveWindowSubclass(GUICtrlGetHandle($idLbl2), $__SSCTRLHOVER_PSUBCLASSEXE, GUICtrlGetHandle($idLbl2)) Func FnNormal($idCtrl, $hWnd, $vData) ConsoleWrite(@CRLF & "Normal/Leave " & $idCtrl) EndFunc Func FnHover($idCtrl, $hWnd, $vData) ConsoleWrite(@CRLF & "Hover " & $idCtrl) EndFunc Func FnActive($idCtrl, $hWnd, $vData) ConsoleWrite(@CRLF & "Active " & $idCtrl) EndFunc Func FnClick($idCtrl, $hWnd, $vData) ConsoleWrite(@CRLF & "CLICK! " & $idCtrl & " - " & $hWnd & " - " & $vData) EndFunc argumentum 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
ura Posted June 16, 2017 Share Posted June 16, 2017 On 2017-4-19 at 0:03 AM, LarsJ said: 确实,当脚本运行时,脚本中的崩溃是64位代码由子类引起的还没有被删除。 您可以通过以下方式删除第一篇文章中示例中的子类: #AutoIt3Wrapper_UseX64 = Y #include “SSCtrlHover_v3.au3” GUICreate(@AutoItVersion) $ idLbl1 = GUICtrlCreateLabel(“标记1” , 5 , 5 ) SSCtrlHover _寄存器($ idLbl1 , “FnNormal” , 0 , “FnHover” , 0 , “FnActive” , 0 , “FnClick” , 0 ) $ idLbl2 = GUICtrlCreateLabel(“Label 2” , 5 , 35 ) SSCtrlHover _ Register($ idLbl2 , “FnNormal” , 0 , “FnHover” , 0 , “FnActive” , 0 , “FnClick” , 5 ) GUISetState() 而 GUIGetMsg() <> - 3 睡眠(10 ) WEnd _WinAPI_RemoveWindowSubclass(GUICtrlGetHandle($ idLbl1 ), $ __ SSCTRLHOVER_PSUBCLASSEXE , GUICtrlGetHandle($ idLbl1 )) _WinAPI_RemoveWindowSubclass(GUICtrlGetHandle($ idLbl2 ), $ __ SSCTRLHOVER_PSUBCLASSEXE , GUICtrlGetHandle($ idLbl2 )) Func FnNormal($ idCtrl , $ hWnd , $ vData ) ConsoleWrite(@CRLF & “Normal / Leave” & $ idCtrl ) EndFunc Func FnHover($ idCtrl , $ hWnd , $ vData ) ConsoleWrite(@CRLF & “Hover” & $ idCtrl ) EndFunc Func FnActive($ idCtrl , $ hWnd , $ vData ) ConsoleWrite(@CRLF & “Active” & $ idCtrl ) EndFunc Func FnClick($ idCtrl , $ hWnd , $ vData ) ConsoleWrite(@CRLF & “CLICK!” & $ idCtrl & “ - ” & $ hWnd & “ - ” & $ vData ) EndFunc How to integrate into the UDF? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now