Jump to content

Callback - no external library (dll) required


piccaso
 Share

Recommended Posts

Hey Jon this would be FANTASTIC!!!

Sorry for my reaction to question asked to picasso

but I can't help myself to express my mind ;-)

I agree with Zedna.

This is amazing piccaso.

I've just tried playing with it and here is a hurried example, in my usual untidy style, of how to overcome the problem when you need more than one AdLibEnable.

#include <GUIConstants.au3>
#include <dllcallback.au3>

Global $msg, $retval
;we will have 3 timers
$pt = DllStructCreate("int64;int64;int64");int64 found by trial and error
DllStructSetData($pt, 1, 1);set the timer ref numbers
DllStructSetData($pt, 2, 2);these could be any number
DllStructSetData($pt, 3, 3)

$pnID1 = DllStructGetPtr($pt, 1);ptrs to the timer ref nos
$pnID2 = DllStructGetPtr($pt, 2)
$pnID3 = DllStructGetPtr($pt, 3)
Global $gui = GUICreate("test")
GUISetState()

$hStub_T = _DllCallBack ("_TimerProc", "hwnd;int;ptr;int")

;set up the timers
$retval = DllCall("user32.dll", "int", "SetTimer", "hwnd", $gui, "int", $pnID1, "int", 5000, "ptr", $hStub_T)
Sleep(2000); delay so timers are spaced apart
$retval = DllCall("user32.dll", "int", "SetTimer", "hwnd", $gui, "ptr", $pnID2, "int", 10000, "ptr", $hStub_T)
$retval = DllCall("user32.dll", "int", "SetTimer", "hwnd", $gui, "ptr", $pnID3, "int", 2000, "ptr", $hStub_T)

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

$retval = DllCall("user32.dll", "int", "KillTimer", "hwnd", $gui, "ptr", $pnID1)
$retval = DllCall("user32.dll", "int", "KillTimer", "hwnd", $gui, "ptr", $pnID2)
$retval = DllCall("user32.dll", "int", "KillTimer", "hwnd", $gui, "ptr", $pnID3)
_DllCallBack_Free ($hStub_T)



Func _TimerProc($h, $a, $b, $c)
    Local $ts = DllStructCreate("int", $b)
    Local $TimerNumber = DllStructGetData($ts, 1)
    Switch $TimerNumber
        Case 1
            ConsoleWrite("T1 fired" & @CRLF)
        ;
        Case 2
            ConsoleWrite("T2 fired" & @CRLF)
        ;
        Case 3
            ConsoleWrite("T3 fired" & @CRLF)
        ;
    EndSwitch
    
    $ts = 0
EndFunc  ;==>_TimerProc

;error checking to be added but the above is just to show the idea
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

  • Replies 80
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

piccaso, would it be worth adding this natively into AutoIt? I'm not totally sure because it is a very advanced and niche function. So it depends on what I'd need to add and how much space it would need?

Also, I'm guessing it requires some assembly - we've stil not solved the 64bit DllCall problems because of the assembly.

( Awesome work btw :) )

That would be great!

Windows doesn't seem to like the detour over the message queue in every situation (that's why there is a subclassing option/workaround)

so i really would welcome a native implementation.

If it isn't a big problem to call user functions from 'inside' because the rest is quite simple.

I guess you dont want to waste your time studying the udf so i'll try to explain:

Allocate some (23bytes) executable memory and put this in there:

$ ==>   > 8D4424 04  LEA EAX,DWORD PTR SS:[ESP+4]           ; Load pointer to first parameter into eax
$+4  > 50            PUSH EAX                               ; Parameter 2 - Stack pointer
$+5  > 68 01010101  PUSH 1010101                            ; Parameter 1 - Internal identifier
$+A  > B8 02020202  MOV EAX,2020202                      ; mov eax, <Absolute address of handler function>
$+F  > FFD0      CALL EAX                               ; Call Callback Handler function
$+11     > 83C4 08      ADD ESP,8                            ; if handler is 'cdecl' - free stack
$+14     > C2 0000      RETN 0                               ; if callback is 'cdecl' - Retn 0
                                                                    ; if callback is 'stdcall' - Retn <nr of parameter*4>

I'm sure there are equivalent opcodes for 64bit, but sorry i dont know them (but i'll do some research)

Of course the Internal id, the address of the handler function and amount of bytes to remove from stack have to be set too.

the rest can be done in c/c++:

void* CallBackHandler (unsigned long ulInternalId, void* pParameters) {
// pParameters = pointer to first parameter
// pParameters+4 = pointer to second parameter
// ...
// Lookup & Call User Function and return value
}

If you want to keep it small it could look like this:

The user function takes as much parameters as defined in $sParameters and the Return value

is converted as specified.

I'll go and see if i can find some info on 64bit opcodes ;)

Edited by Jon
CoProc Multi Process Helper libraryTrashBin.nfshost.com store your AutoIt related files here!AutoIt User Map
Link to comment
Share on other sites

Ok i made an uneducated guess above.

I just learned that parameters are passed via registers on 64bit.

Which means the 64bit solution looks completely different.

Something like:

Allocate some extra space, copy all registers there and forward that pointer to the handler function...

Too bad i dont have a 64bit os to play around with it :)

But now i know what kind of problems you have with DllCall() :">

CoProc Multi Process Helper libraryTrashBin.nfshost.com store your AutoIt related files here!AutoIt User Map
Link to comment
Share on other sites

my regards too, this is the most powerfull udf i've seen so far here, but your other funcs are also very far above my knowledge border :)

thanks for developing and a healty and lucky life.

$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")
For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)
Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])));''Chr("a")&"HI"
Next ;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;
MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)
Link to comment
Share on other sites

@piccaso

I have ran the examples and it's very impressive.

Neverthelesss even if I don't understand a bit of this I can smell some opportunities.

Does this now mean that some of the previous limitations, relating to callback functions of the SQLite DLL, are now gone ?

Great job !! :)

regards,

ptrex

Edited by ptrex
Link to comment
Share on other sites

Here are some results on my WIN98 SE:

With version 6.4 there was problems: EnumWindows returned too little windows and script don't stopped automatically, Subclass crashed after start

but new version 6.5 seems to be OK.

Subclass is perfect!!

But some examples don't return expected results:

CopyFileEx.au3 - nothing happens

EnumChildProc.au3 - no result

Richedit.au3 - nothing happens

EDIT: I will make some tests also on WIN XP to compare results later

I made some more tests:

On WINXP SP2 all examples works OK

On WIN98 SE two examples needs tweak to work OK.

EnumChildProc.au3

;~ $hWnd_Desktop = DllCall("user32.dll", "hwnd", "GetDesktopWindow")
$hWnd_Desktop = WinGetHandle("Ttitle of your desired app")

Richedit.au3

...
Global $RTFClassName

If @OSTYPE = "WIN32_WINDOWS" Then; 95/98/Me
    DllOpen("RICHED20.DLL")
    $RTFClassName = "RichEdit20A"
Else; NT/2000/XP/2003/Vista 
    DllOpen("MSFTEDIT.DLL")
    $RTFClassName = "RichEdit50W"
EndIf

; $RTFClassName used later in CreateWindowEx
...

I'm not sure if versions of RichEdit will be the same also on WIN2000/NT, so this part must be maybe tweaked also for these OS versions.

So result is: All is working fine also on WIN98, (two examples after tweaking).

Thank you very much for this very good functionality brought to AutoIt :)

Edited by Zedna
Link to comment
Share on other sites

Ptrex, you're right, all limitations are gone now.

But sqlite's api is giving me a headache, and i dont have a concept on how to provide this functionality without making it

awfully complicated.

I also found a way to load dll's from memory in autoit, but using this in the sqlite wrapper would require changing all dllcalls...

This should take some time until i have it all pieced together :)

Thank you for your tests Zedna.

I'll add your fixes to the example.

And martin, you're right, the example is messy :P

But timers are useful so i'll add some simple example on next update...

Wow, this really got more popular than i taught :)

CoProc Multi Process Helper libraryTrashBin.nfshost.com store your AutoIt related files here!AutoIt User Map
Link to comment
Share on other sites

  • 2 weeks later...

piccaso

Hi,

I using the subclassing to disable the context menu, but in the example there is one problem - it's not disabling the context menu when you press the Win key (or Shift F10), so the solution is to change a litle first line in the _WindowProc() function:

Func _WindowProc($hWnd, $uiMsg, $wParam, $lParam)
    ; Disable the context menu and show your own menu
    If $uiMsg = 0x007B Then Return 0 ; 0x007B = WM_CONTEXTMENU
    
    ; Returning a Pointer to the original WindowProc means: We did not process this message.
    ; Do not call CallWindowProc() api yourself, the stub will do that for you!
    Return $OriginalWindowProc
EndFunc

:)

Thanks again for the great tool! (CallBacks).

Added: Please look at example here, maybe you could add it to the example of subclassing (as second example of it's usage).

Edited by MsCreatoR

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

  • 2 weeks later...

any hard-core guide for the pure retard maybe ?!

- i don't know a thing about DLLs and i realy have to use a call-back function for my TCP-download-manager to work propperly however i can't seem to realize how can i convert my normal script (which uses no dlls) to a DLL based script such as your examples...

- if there are any guides for the moron i'd love it !!!

- also about you're other UDF -> 'CoProc' (which seems by far more easier to use and i can't seem to realize the difference), i'm having some difficulties with using it with multiple args for the function call...

seems like it works perfect with 1 arg though... :) {P.S- also wrote ya in that UDF's thread!!!}

[u]My Au3 Scripts:[/u]____________(E)Lephant, A Share download manager (RS/MU etc)Http1.1 Console, The Ez Way!Internet Reconnection Automation Suite & A Macro Recording Tool.SK's Alarm Clock, Playing '.MP3 & .Wav' Files._________________Is GOD a mistake of the Humanity Or the Humanity is a mistake of GOD ?!

Link to comment
Share on other sites

  • 1 month later...
  • Administrators

The only 2 things that changed were long_ptr and int_ptr were removed and the default alignment of structs was changed to 8 rather than 1. I can't see any _ptr references in there so it probably needs some "align 1" prefixes in the structs.

Link to comment
Share on other sites

Awesome, i wasnt here for some time and now i come here and see that Callback is built in and even execute is unlimited now :P

I have to play with it right away, thanks Jon ;)

Can someone (who has the rights) please unsticky & lock this thread please?

To avoid confusion...

I'll translate the existing examples to new callback functions and post them as example.

thanks

CoProc Multi Process Helper libraryTrashBin.nfshost.com store your AutoIt related files here!AutoIt User Map
Link to comment
Share on other sites

  • Moderators

Awesome, i wasnt here for some time and now i come here and see that Callback is built in and even execute is unlimited now :P

I have to play with it right away, thanks Jon ;)

Can someone (who has the rights) please unsticky & lock this thread please?

To avoid confusion...

I'll translate the existing examples to new callback functions and post them as example.

thanks

Done... Go play!

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...