JohnOne Posted February 24, 2012 Share Posted February 24, 2012 What exactly is the nature of this function? The help file does not say much about it execept you use it with the other Dll* functions. In my head it sounds like it makes a regular DllCall but returns immediately and a function is called when the DllCall actually returns. Is this right? and if not, can someone explain it for a layman? AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 24, 2012 Moderators Share Posted February 24, 2012 JohnOne,This is my hobbyist coder attempt to explain it - no doubt a guru will be along in a while and blind you with all sorts of wondeful pixie-dust. I have only used DLLCallBackRegister when I an subclassing controls - that means to replace the procedure that they execute when actioned. It works like this:- 1. You write a new procedure for the control so that it does something different when actioned, An example is my NoFocusLines UDF where I tell the controls not to honour the $WM_SETFOCUS message so as not to get the dotted lines - look at the _NoFocusLines_Proc function within the UDF.- 2. You now register the procedure by using DllCallbackRegister like this:$hNoFocusLines_Proc = DllCallbackRegister("_NoFocusLines_Proc", "int", "hwnd;uint;wparam;lparam")This reserves a chunk of memory that contains the code you want Windows to run later and returns a handle to the procedure you have now registered. You also need a pointer so Windows know where to find it:$pNew_WindowProc= DllCallbackGetPtr($hNoFocusLines_Proc)- 3. Now we can tell Windows to replace the current procedure for a control with the one we have registered:$aRet = _WinAPI_SetWindowLong($hWnd, -4, $pNew_WindowProc)- 4. And when that control is now actioned it will use our procedure and not the default one. In the case of my UDF I wanted to pass on all other messages to the default Windows procedure for the control - the handle to which is returned by the WinAPI call we made earlier. So I can do this by using a call to _WinAPI_CallWindowProc(The_Returned_Handle, $hWnd, $iMsg, $wParam, $lParam) as the final line of my replacement procedure.- 5. And then when you have done and want to exit, you have to do the reverse - reset the control to the normal procedure by using _WinAPI_SetWindowLong again and finally clear the memory you reserved with the original DllCallbackRegister call by using DllCallbackFree.Head hurting yet? M23P.S. Do not use the Beta if you want to play with this function (or the UDF I mentioned above) as it is not working correctly - it is fine with 3.3.8.1. Beege 1 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
JohnOne Posted February 24, 2012 Author Share Posted February 24, 2012 Cheers M23, I get it a lot more than I have previously when trying to get my head around it. Thank you very glad. I was hoping for what I thought it was to be correct though I'm after a way to call a function in a dll but not wait for its return as it has a rather lengthy procedure and I don't need a return value. I don't suppose you know of such a spell do you? AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 24, 2012 Moderators Share Posted February 24, 2012 JohnOne,I do not believe you can call a DLL asynchronously - but you will need a guru to confirm that. Try posting in the "Developer Chat" section - but I am not moving this thread there as my ears would burn all evening from the laughter when they saw my post above! M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
JohnOne Posted February 24, 2012 Author Share Posted February 24, 2012 You are most likely correct, I doubt there is a way to do this. I'll go away and do a little more research on how I can achieve my goal from the dll side of the relationship before I go next door for an autoit solution. I'm thinking maybe create a new thread for the procedure and return from dll function. Wish me luck AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted February 24, 2012 Moderators Share Posted February 24, 2012 JohnOne, I think that would be the way to do it. Which inter-script communication solution will you use? M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
JohnOne Posted February 24, 2012 Author Share Posted February 24, 2012 JohnOne,I think that would be the way to do it. Which inter-script communication solution will you use? M23Well currently I'm reading the stdout from the dll module, of course this means (69255) that I already have torun another exe from an autoit script to be able to do this via a PID.But that is where my problem lies, no matter where I call the dll from, it will still take too much time to returnand the stdout is not being fully read (for some reason) plus the calling exe seems to use too much cpu.I imagine that is because it's sitting there waiting for a return from the dll.In the end, I will probably use my favourite interprocess communication created by GreenCan (cant think of the link)which is via memory AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Shaggi Posted February 24, 2012 Share Posted February 24, 2012 I'm after a way to call a function in a dll but not wait for its return as it has a rather lengthy procedureWhy dont you just create a thread on it then? (see msdn: CreateThread).As for dllcallbackregister, it provides an "standardized" or binary interface for other programs to communicate with yours, so that autoit funcs may be called from other languages. this is usefull with DLLs and callbacks, and COM Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG Link to comment Share on other sites More sharing options...
Skitty Posted February 25, 2012 Share Posted February 25, 2012 Talking about DllCallbackRegister.. I've always wondered if it's possible to register a callback for cases when a process is created/terminated, I've searched far and beyond to no avail, is this possible? Link to comment Share on other sites More sharing options...
Shaggi Posted February 25, 2012 Share Posted February 25, 2012 Talking about DllCallbackRegister..I've always wondered if it's possible to register a callback for cases when a process is created/terminated, I've searched far and beyond to no avail, is this possible?Yeah, either through hooking or some lower level driver stuff (pssetcreateprocessnotifyroutine). You can also use wmi to do it, here's an example (in c#): http://weblogs.asp.net/whaggard/archive/2006/02/11/438006.aspxhere's some of the relevant wmi documentation: http://msdn.microsoft.com/en-us/library/aa392727#_hmm_processes Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG Link to comment Share on other sites More sharing options...
Skitty Posted February 25, 2012 Share Posted February 25, 2012 Yeah, either through hooking or some lower level driver stuff (pssetcreateprocessnotifyroutine). You can also use wmi to do it, here's an example (in c#): http://weblogs.asp.net/whaggard/archive/2006/02/11/438006.aspx here's some of the relevant wmi documentation: http://msdn.microsoft.com/en-us/library/aa392727#_hmm_processes Oh, well, that's a bummer, I was hoping there would be something better than this. Local $Obj = ObjGet("winmgmts:{impersonationLevel=impersonate}!" & @ComputerName & "rootcimv2") Local $hObj = ObjCreate("WbemScripting.SWbemSink") If IsObj($Obj) And IsObj($hObj) Then ObjEvent($hObj, "SINK_"); Set up a callback to populate the list view when a process dies or is spawned $Obj.ExecNotificationQueryAsync($hObj, "SELECT * FROM __InstanceOperationEvent WITHIN 0.1 WHERE TargetInstance ISA 'Win32_Process'") EndIf Link to comment Share on other sites More sharing options...
Shaggi Posted February 26, 2012 Share Posted February 26, 2012 Oh, well, that's a bummer, I was hoping there would be something better than this. Local $Obj = ObjGet("winmgmts:{impersonationLevel=impersonate}!" & @ComputerName & "rootcimv2") Local $hObj = ObjCreate("WbemScripting.SWbemSink") If IsObj($Obj) And IsObj($hObj) Then ObjEvent($hObj, "SINK_"); Set up a callback to populate the list view when a process dies or is spawned $Obj.ExecNotificationQueryAsync($hObj, "SELECT * FROM __InstanceOperationEvent WITHIN 0.1 WHERE TargetInstance ISA 'Win32_Process'") EndIfWhy so? Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG Link to comment Share on other sites More sharing options...
Skitty Posted February 26, 2012 Share Posted February 26, 2012 Why so?Because in comparison to a call back, the call back will only operate while it was called, the object event works in intervals "WITHIN 0.1 WHERE" I found out that the object event will use a lot of CPU resources if I don't set it to something a little higher than "0.1", which "0.8" seems to be ok for me, I had a hard time finding out that that was what was causing 10-20% cpu usage by my application. Link to comment Share on other sites More sharing options...
trancexx Posted February 26, 2012 Share Posted February 26, 2012 Because in comparison to a call back, the call back will only operate while it was called, the object event works in intervals "WITHIN 0.1 WHERE" I found out that the object event will use a lot of CPU resources if I don't set it to something a little higher than "0.1", which "0.8" seems to be ok for me, I had a hard time finding out that that was what was causing 10-20% cpu usage by my application.What was causing it then? I mean what was causing it?...In your words. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Skitty Posted February 26, 2012 Share Posted February 26, 2012 What was causing it then? I mean what was causing it?...In your words.After being on these forums for quite a while now, getting to know you little by little through your posts that usually contain the most cryptic indecipherable code and knowing that you are personally involved in the development of AutoIt and seeing that I have caught your attention enough so that you quoted me means I must have said something that made you a little unsettled... Long story short, I'm wrong aren't I?To answer your question directly, in my words, I can not really know what was causing it, but I know you are more eligible to conceive a more accurate explanation. Link to comment Share on other sites More sharing options...
Skitty Posted March 29, 2012 Share Posted March 29, 2012 What was causing it then? I mean what was causing it? ...In your words. I hate to resurrect a diseased thread but I just felt the need to correct myself after discovering the true reason for the high CPU usage due to using the WMI callback on event function, the reason was that I was getting results for __InstanceOperationEvent when I should have only been requesting $Obj.ExecNotificationQueryAsync($hObj, "SELECT * FROM __InstanceCreationEvent WITHIN 0.5 WHERE TargetInstance ISA 'Win32_Process'") $Obj.ExecNotificationQueryAsync($hObj, "SELECT * FROM __InstanceDeletionEvent WITHIN 0.5 WHERE TargetInstance ISA 'Win32_Process'") in order to avoid being bombarded with unwanted information involving modification events which you will receive a F*** load of them if you do. Link to comment Share on other sites More sharing options...
Bluesmaster Posted December 16, 2013 Share Posted December 16, 2013 (edited) @CaptainClucks ( and any other expert ) Have you found a lower level method for monitoring process creation / destruction? The wmi method causes 5% cpu usage for me on polling just every 3 seconds, which is definitly to much for a background task. Would be nice to hear any proposals. HotKeySet("{ESC}","ESC") Func ESC() Exit(0) EndFunc Local $Obj = ObjGet( "winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\cimv2") Local $hObj = ObjCreate( "WbemScripting.SWbemSink" ) If IsObj($Obj) And IsObj($hObj) Then ObjEvent( $hObj , "SINK_" ) $Obj.ExecNotificationQueryAsync( $hObj , "SELECT * FROM __InstanceCreationEvent WITHIN 3.0 WHERE TargetInstance ISA 'Win32_Process'") $Obj.ExecNotificationQueryAsync( $hObj , "SELECT * FROM __InstanceDeletionEvent WITHIN 3.0 WHERE TargetInstance ISA 'Win32_Process'") EndIf Sleep(100000) Func SINK_OnObjectReady($OB) if $OB.Path_.Class = "__InstanceCreationEvent" Then ; $ob.TargetInstance.ProcessID, $ob.targetinstance.parentprocessid consolewrite( "start " & $ob.targetinstance.name & @LF ) else consolewrite( "end " & $ob.targetinstance.name & @LF ) EndIf EndFunc Best regards Blues Edited December 16, 2013 by Bluesmaster My UDF: [topic='156155']_shellExecuteHidden[/topic] 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