Sign in to follow this  
Followers 0
marko29

Possible to cast $lparam to autoit variable?

18 posts in this topic

#1 ·  Posted (edited)

I receive a pointer from dll file which i need to cast into reaable string var, in c i woul simply (TCHAR)lParam is any alternative possible in au3?, any suggestion? Here is all sorts of mess i was trying... I dont usually code like this, its just a test file

$hCallback = DllCallbackRegister("_MyUBCallback", "long", "long;long;long")
    ConsoleWrite($hCallback)
    ConsoleWrite("error is" & @error)
    Local $aRet = DllCall($hDSSUBCLS, "long", "SubClass", "hwnd", $sh, "ptr", DllCallbackGetPtr($hCallback), "long", 0, "long", 0, "long", 0, "long", 1)
    ConsoleWrite("error is" & @error)
    $aRet = DllCall($hDSSUBCLS, "long", "UseSendMessage", "long", 1)
    ConsoleWrite("error is" & @error)
    GUIRegisterMsg(0x000D, "_MyUBCallback")
    $a=GUICtrlRecvMsg($sh,0x000D)
    MsgBox(0, 0, $a)
EndFunc   ;==>_main


Func _MyUBCallback($uiMsg, $wParam, $lParam)
    Switch $uiMsg
        Case 0x000D
            $a=GUICtrlRecvMsg($sh,0x000D)
    MsgBox(0, 0, $a)

            $data = '0x' & Hex($lParam)
            $got = _MemoryRead($data, $DllInformation, "WCHAR")
            ;Local $Buffer = DllStructCreate("LPSTR",$data)
            ;ConsoleWrite($data&@LF)
            _WinAPI_ReadProcessMemory($iPID, $data, DllStructGetPtr($lParam), DllStructGetSize($Buffer), $read)
            ;$readed = DllStructGetData($Buffer, 1)
            ConsoleWrite("data is " &  $got  & @LF)

            ;MsgBox(0, 0, DllStructGetData($Buffer, 1))

    EndSwitch
EndFunc   ;==>_MyUBCallback
Edited by marko29

Share this post


Link to post
Share on other sites



lparams are either a pointer to something which you will know ahead of time based on the window message or it's just an integer.

You would cast it to an integer or a pointer to a DllStruct.

Share this post


Link to post
Share on other sites

lparams are either a pointer to something which you will know ahead of time based on the window message or it's just an integer.

You would cast it to an integer or a pointer to a DllStruct.

But how do you do it in au3?

Share this post


Link to post
Share on other sites

Don't you have thread about this in general support? You probably think this is dev stuff when you post new one here.

Make char or wchar buffer at lparam address and read it.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Don't you have thread about this in general support? You probably think this is dev stuff when you post new one here.

Make char or wchar buffer at lparam address and read it.

Yes i do have a topic but its pretty much sunk and i feel in inappropriate place, i hope no one minds if i put it here/.

Func _MyUBCallback($uiMsg, $wParam, $lParam)
    Switch $uiMsg
        Case 0x000D
            $data = '0x' & Hex($lParam)
            Local $Buffer = DllStructCreate("wchar", $data)
            Local $Buffer = DllStructCreate("wchar", $$lparam) ; this fails as well

            ConsoleWrite("error is? " & @error & @LF)

            ConsoleWrite(DllStructGetData($Buffer, 1)& @error & @LF)

            ;Local $Buffer = DllStructCreate("LPSTR",$data)
            ;ConsoleWrite($data&@LF)
            _WinAPI_ReadProcessMemory($iPID, $data, DllStructGetPtr($lParam), DllStructGetSize($Buffer), $read)
            ;$readed = DllStructGetData($Buffer, 1)
            ;ConsoleWrite("data is " &  $readed  & @LF)


    EndSwitch
EndFunc   ;==>_MyUBCallback

There are no errors returned, only weird symbol returned or "0?" in console. Wether i try $lparam as pointer or simply use $data as $lparam converted to hex

Edited by marko29

Share this post


Link to post
Share on other sites

It took me 5 minutes of light research to find the method you are using to subclass external controls by wbd and then find out that 0x000D is WH_KEYBOARD_LL... :)

How about posting code that is syntactically correct and/or vaguely looks like it might work? Once I found WBD's code I knew exactly what I was looking at, rather than a snippet of random code.

Mat

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

It took me 5 minutes of light research to find the method you are using to subclass external controls by wbd and then find out that 0x000D is WH_KEYBOARD_LL... :)

How about posting code that is syntactically correct and/or vaguely looks like it might work? Once I found WBD's code I knew exactly what I was looking at, rather than a snippet of random code.

Mat

Look again mate, 0x000D is actually wm_gettext http://msdn.microsoft.com/en-us/library/ms632627(v=vs.85).aspx

Sorry but this is pretty much all i have, i didnt post basic stuff as i thought its not important to show how i am getting process id but here it goes...

What i see as important thing is that i receive the text streaming message and the lparam that contains the buffer with text as the wm_Gettext message impplies, now the problem is reading from it into au3, i apologize for not describing this before, i know it annoys to read hard to understand problems.

#include <GuiToolBar.au3>
#include <GuiToolTip.au3>
#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>
#include <NomadMemory.au3>

$main = GUICreate("testah", 542, 895, 248, 133)
$Button1 = GUICtrlCreateButton("Start", 39, 317, 75, 26)
GUISetState(@SW_SHOW)

Global $hDSSUBCLS, $dll
$hDSSUBCLS = DllOpen("dssubcls.dll")

$read = 4445
$sh = 0
$iPID = 0
$lista = WinList("[CLASS:tooltips_class32]")

Local $iRead1 = 555

While 1
    $aMsg = GUIGetMsg(1) ; Use advanced parameter to get array
    Switch $aMsg[1] ; check which GUI sent the message
        Case $main
            Switch $aMsg[0] ; Now check for the messages for $hGUI1
                Case $GUI_EVENT_CLOSE
                    $aRet = DllCall($hDSSUBCLS, "long", "SubClass", "hwnd", 0, "ptr", DllCallbackGetPtr($hCallback), "long", 0, "long", 0, "long", 0, "long", 1) ;              Case $Button1
                           _main()
            EndSwitch
    EndSwitch

WEnd

Func _main()

    For $wnd = 1 To $lista[0][0] - 1  // THIS IS JUST TO GET THE HANDLE OF APP THAT STREAMS TEXT, 

        $text = WinGetClassList($lista[$wnd][1])

        If (StringInStr($text, "VBFloatingPalette")) = 1 Then

            ConsoleWrite("got it " & $lista[$wnd][1] & @CRLF)
            $sh = $lista[$wnd][1]

        EndIf

    Next

    _WinAPI_GetWindowThreadProcessId($sh, $iPID) // just getting process ID for memory reading later...

    Global $DllInformation = _MemoryOpen($iPID) // housekeeping of nomad memory before using it...

    If @error Then
        MsgBox(4096, "ERROR", "Failed to open memory.")
        Exit
    EndIf

    $hCallback = DllCallbackRegister("_MyUBCallback", "long", "long;long;long") >> REGISTERING CALLBACK
    Local $aRet = DllCall($hDSSUBCLS, "long", "SubClass", "hwnd", $sh, "ptr", DllCallbackGetPtr($hCallback), "long", 0, "long", 0, "long", 0, "long", 1)
    ConsoleWrite("error is" & @error)
    $aRet = DllCall($hDSSUBCLS, "long", "UseSendMessage", "long", 1)
    ConsoleWrite("error is" & @error)
    GUIRegisterMsg(0x000D, "_MyUBCallback")  << REGISTERING CALLBACK

EndFunc   ;==>_main


Func _MyUBCallback($uiMsg, $wParam, $lParam)
    Switch $uiMsg
        Case 0x000D // my app streams text and it triggers here...

            $data = '0x' & Hex($lParam)
            Local $Buffer = DllStructCreate("char", $lParam)
            ConsoleWrite("error is? " & @error & @LF)

            ConsoleWrite(DllStructGetData($Buffer, 1)& @error & @LF)

            ;Local $Buffer = DllStructCreate("LPSTR",$data)
            ;ConsoleWrite($data&@LF)
            _WinAPI_ReadProcessMemory($iPID, $data, DllStructGetPtr($lParam), DllStructGetSize($Buffer), $read)
            ;$readed = DllStructGetData($Buffer, 1)
            ;ConsoleWrite("data is " &  $readed  & @LF)


    EndSwitch
EndFunc   ;==>_MyUBCallback
Edited by marko29

Share this post


Link to post
Share on other sites

I got sick of this so much i am now heading to make dll that will do everything by itself and just send message to my script when its done, perhaps its easier then break my head with converting lparam to text, still if anyone knows solution for this i d be more then happy to see what made me do 2 days of researching

Share this post


Link to post
Share on other sites

What I don't get is what is supposed to be in the buffer before the message is handled? Try and play around with this:

This is what I'd call sample code when asking a question. It will run on most people pc's and is nice and simple:

#include <WindowsConstants.au3>
#include <GuiListbox.au3>

Global $hList
Global $hDSSUBCLS = DllOpen("dssubcls.dll")
Global $fRunning = True
Global $hNotepad

_Main()

Exit

Func _Main()
    Local $hGUI = GUICreate("Subclass", 400, 400)
    Local $cList = GUICtrlCreateList("", 8, 8, 384, 384, BitOR($WS_BORDER, $WS_VSCROLL))
    GUISetState()
    $hList = GUICtrlGetHandle($cList)

    Run("Notepad.exe")
    WinWait("[CLASS:Notepad]")
    $hNotepad = ControlGetHandle("[CLASS:Notepad]", "", "Edit1")
    Local $hCallback = DllCallbackRegister("_MyCallback", "long", "long;long;long")
    Local $aRet = DllCall($hDSSUBCLS, "long", "SubClass", "hwnd", $hNotepad, "ptr", DllCallbackGetPtr($hCallback), "long", 0, "long", 0, "long", 0, "long", 1)
    $aRet = DllCall($hDSSUBCLS, "long", "UseSendMessage", "long", 1)

    While $fRunning And GUIGetMsg() <> -3
        Sleep(10)
    WEnd

    GUIDelete()
    ProcessClose("Notepad.exe")
    ProcessWaitClose("Notepad.exe")
    DllCallbackFree($hCallback)
    DllClose($hDSSUBCLS)
EndFunc   ;==>_Main

Func _MyCallback($uiMsg, $wParam, $lParam)
    Switch $uiMsg
        Case $WM_GETTEXT
            $t = DllStructCreate("wchar[" & $wParam & "]", $lParam)
            _GUICtrlListBox_AddString($hList, DllStructGetData($t, 1))
        Case $WM_CLOSE
            $fRunning = False
    EndSwitch
    Return 0
EndFunc   ;==>_MyCallback

For people other than the op: You'll need the package here and extract it to the script dir.

Mat

Share this post


Link to post
Share on other sites

I got sick of this so much i am now heading to make dll that will do everything by itself and just send message to my script when its done, perhaps its easier then break my head with converting lparam to text, still if anyone knows solution for this i d be more then happy to see what made me do 2 days of researching

Your incompetence is kinda annoying.

Func _MyUBCallback($iMsg, $wParam, $lParam)
    Switch $iMsg
        Case 0xD
            ConsoleWrite(DllStructGetData(DllStructCreate("wchar[" & $wParam & "]", $lParam), 1) & @CRLF)
        Case Else
            ConsoleWrite("$wParam = " & $wParam & ", $lParam =  " & $lParam & @CRLF)
    EndSwitch
EndFunc

And lose

GUIRegisterMsg(0x000D, "_MyUBCallback")  << REGISTERING CALLBACK
...line

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Is this what you're asking for?

$tString = DLLStructCreate("wchar[" & ($StringLength+1) & "]", $lParam)
$String = DLLStructGetData($tString, 1)

[EDIT] I missed trancexx's answer above, and the delete button doesn't work: clicking OK does nothing. Anyone else with the same problem?

Edited by danielkza

Share this post


Link to post
Share on other sites

And I missed Mat's.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Your incompetence is kinda annoying.

If its annoying then you dont need to help me, i d rather figure it by myself then get flamed for asking something i admit i dont know how to solve. Some people are not "all knowing" like yourself.

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

And this is the output > ??SOH???hSOH

from

Func _MyUBCallback($iMsg, $wParam, $lParam)
    Switch $iMsg
        Case 0xD
            $tString = DLLStructCreate("wchar[" & $wParam & "]", $lParam)
            $String = DLLStructGetData($tString, 1)
            ConsoleWrite($String)

            ;ConsoleWrite(DllStructGetData(DllStructCreate("wchar[" & $wParam & "]", $lParam), 1) & @CRLF)
        Case Else

    EndSwitch
EndFunc
Edited by marko29

Share this post


Link to post
Share on other sites

If I wanted to flame I would say that your incompetence is kinda annoying.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Is it actually unicode data? If it is not you should use 'char' instead of 'wchar'. And if $wParam is the string's length, you should add 1 to it on the struct declaration or you'll overflow the buffer eventually.

Share this post


Link to post
Share on other sites

Is it actually unicode data? If it is not you should use 'char' instead of 'wchar'. And if $wParam is the string's length, you should add 1 to it on the struct declaration or you'll overflow the buffer eventually.

tried with both

$tString = DLLStructCreate("wchar[" & $wParam+1 & "]", $lParam) and

$tString = DLLStructCreate("char[" & $wParam+1 & "]", $lParam)

wchar is indeed max characters to be copied and when i use char i get bit different symbols and thats about it, thanks anyway for the help, time to do the job in the dll and forget about reading this text in autoit

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

Is it actually unicode data? If it is not you should use 'char' instead of 'wchar'. And if $wParam is the string's length, you should add 1 to it on the struct declaration or you'll overflow the buffer eventually.

tried with both

$tString = DLLStructCreate("wchar[" & $wParam+1 & "]", $lParam) and

$tString = DLLStructCreate("char[" & $wParam+1 & "]", $lParam)

wparam is indeed max characters to be copied and when i use char i get bit different symbols and thats about it, thanks anyway for the help, time to do the job in the dll and forget about reading this text in autoit

Edited by marko29

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0