Jump to content

Recommended Posts

Posted (edited)

I am not quite sure if this is the right place to post, but I am not looking for code or specific help; this is just for discussion.
Is a concept like this actually possible? If so, what would be the advantages?

server::

Local $hCallBack = .........

Local $hGUI = GUICreate("Server", 400, 120)
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func __subclassing($hWnd, $iMsg, $wParam, $lParam, $iID, $pData)
    ;...........
    Return DllCall('comctl32.dll', 'lresult', 'DefSubclassProc', .....................)[0]
EndFunc

Client::

Local $hCallBack = .........

Local $hGUI = GUICreate("Client", 450, 250)

Local $idListView = GUICtrlCreateListView("Items|Column 1|Column 2", 10, 10, 430, 230, -1, $LVS_EX_DOUBLEBUFFER)
Local $hListView = GUICtrlGetHandle($idListView)
Local $hHeader = GUICtrlSendMsg($idListView, $LVM_GETHEADER, 0, 0)

For $i = 1 To 5
    GUICtrlCreateListViewItem("row" & $i & "|dataA" & $i & "|dataB" & $i, $idListView)
Next
_WinAPI_SetWindowSubclass($hHeader, $hCallBack, 2000)

GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

_WinAPI_RemoveWindowSubclass($hHeader, $hCallBack, 2000)

 

Edited by jugador
Posted

I wouldn't over complicate things... 

Here's a snippet of something I  was playing with at some point.  In my main script, I just include the file and call the ApplySubclass func.

#include-once
#include <WinAPI.au3>

Global $__g_hCanvasProc = DllCallbackRegister("Canvas_WndProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr")
OnAutoItExitRegister("Canvas_FinalCleanup")

Func Canvas_WndProc($hWnd, $iMsg, $wParam, $lParam, $iIdSubclass, $dwRefData)
    #forceref $hWnd, $iMsg, $wParam, $lParam, $iIdSubclass, $dwRefData

    Switch $iMsg
        Case $WM_CLOSE
            Return Canvas_Close($hWnd, $iMsg, $wParam, $lParam, $iIdSubclass)
            
        ; etc...
        
        Case Else
            Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam)

    EndSwitch

EndFunc   ;==>Canvas_WndProc

Func Canvas_ApplySubclass($hWnd)
    _WinAPI_SetWindowSubclass($hWnd, DllCallbackGetPtr($__g_hCanvasProc), 0)
EndFunc   ;==>Canvas_ApplySubclass

Func Canvas_Close($hWnd, $iMsg, $wParam, $lParam, $iIdSubclass)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    _WinAPI_RemoveWindowSubclass($hWnd, DllCallbackGetPtr($__g_hCanvasProc), $iIdSubclass)
    Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>Canvas_Close

Func Canvas_FinalCleanup()
    DllCallbackFree($__g_hCanvasProc)
EndFunc

PS. For a control, I usually remove the subclass on  $WM_DESTROY.

Posted (edited)

Thanks, but its just for fun, nothing serious.
It just the bug within me of doing multi-threading and multi-processing in AutoIt.

My take, doing it this way is possible. 
But how practical it is and what the advantages are, I don't know.

Edited by jugador
Posted (edited)

nah, not very practical. 

Your ptrs are only valid for the process where you define it -  so you can't call your proc (or likely defsubclassproc) across process boundaries. To intercept window messages from another exe you'd probably be looking at a hook.  And if memory serves, that type of hook must be written within a dll.

Even if we were to get that all working, its going to be more efficient to deal with the messages in process ;)

Edit: more to the last point, the underlying dispachmessage in a msg loop is synchronous -  so your "client" process is going to sit and wait for the "server" to finish. You get all the overhead without a performance gain.

Edited by MattyD
Posted (edited)

main problem: 
HDC, HBITMAP, HPEN, and HBRUSH are process-specific tokens.
So, GDI handles like HDC are strictly local to the host process and cannot be used cross-process.
GetDC may work, but will flicker too much and lacks synchronization.

Edit:
so to make HDC work, you have to do it from client side.... but somewhat sluggish.

Local $tRect = DllStructCreate($tagRECT)
_WinAPI_SetBkMode($hDC, 1)
_WinAPI_SetTextColor($hDC, 0xFFFFFF)

Local $hBrush = _WinAPI_CreateSolidBrush($iColor)
_WinAPI_InflateRect($tRect, -1, 0)
_WinAPI_FillRect($hDC, $tRect, $hBrush)
_WinAPI_DeleteObject($hBrush)
_WinAPI_InflateRect($tRect, -5, -2)

_WinAPI_DrawText($hDC, $text, $tRect, BitOR($DT_LEFT, $DT_NOCLIP, $DT_VCENTER, $DT_SINGLELINE))

 

Edited by jugador
  • 1 month later...
Posted (edited)

Has anyone tried anything other than running multiple MessageBoxes from different threads, such as running multiple EnumWindows from different threads?

Spoiler
Func _EnumWindowsProc1($hWnd, $lParam)
    ConsoleWrite('--> _EnumWindowsProc_10:  ' & $hWnd & ' | ' & $lParam & @crlf)
    Return 1
EndFunc

Func _EnumWindowsProc2($hWnd, $lParam)
    ConsoleWrite('++> _EnumWindowsProc_20:  ' & $hWnd & ' | ' & $lParam & @crlf)
    Return 1
EndFunc

Func _EnumWindowsProc3($hWnd, $lParam)
    ConsoleWrite('>>> _EnumWindowsProc_30:  ' & $hWnd & ' | ' & $lParam & @crlf)
    Return 1
EndFunc

 

output::

--> _EnumWindowsProc_10:  0x000802DC | 10
++> _EnumWindowsProc_20:  0x000802DC | 20
--> _EnumWindowsProc_10:  0x000C01F0 | 10
++> _EnumWindowsProc_20:  0x000C01F0 | 20
--> _EnumWindowsProc_10:  0x00010062 | 10
++> _EnumWindowsProc_20:  0x00010062 | 20
--> _EnumWindowsProc_10:  0x0001004E | 10
++> _EnumWindowsProc_20:  0x0001004E | 20
--> _EnumWindowsProc_10:  0x0001006A | 10
++> _EnumWindowsProc_20:  0x0001006A | 20
--> _EnumWindowsProc_10:  0x00010066 | 10
++> _EnumWindowsProc_20:  0x00010066 | 20
--> _EnumWindowsProc_10:  0x0001006C | 10
--> _EnumWindowsProc_10:  0x0001007A | 10
++> _EnumWindowsProc_20:  0x0001006C | 20
>>> _EnumWindowsProc_30:  0x000802DC | 30
--> _EnumWindowsProc_10:  0x00010064 | 10
++> _EnumWindowsProc_20:  0x0001007A | 20
>>> _EnumWindowsProc_30:  0x000C01F0 | 30
--> _EnumWindowsProc_10:  0x00010046 | 10
++> _EnumWindowsProc_20:  0x00010064 | 20
>>> _EnumWindowsProc_30:  0x00010062 | 30
.........
.........

 

 

Edited by jugador
  • jugador changed the title to Random thoughts
Posted (edited)

Converting AutoIt code to ASM is not easy because AutoIt is an interpreted scripting language. 
I couldn't find anything on the forums about converting AutoIt to ASM, so has anyone ever tried doing this?

Spoiler
Local $sCode = _
    "Local $i = 0" & @CRLF & _
    "While $i <= 3" & @CRLF & _
    "    DllCall(""user32.dll"", ""int"", ""MessageBoxW"", ""hwnd"", 0, ""ptr"", " & DllStructGetPtr($tText) & ", ""ptr"", " & DllStructGetPtr($tCaption) & ", ""int"", 0)" & @CRLF & _
    "    $i = $i + 1" & @CRLF & _
    "WEnd"

 

B8 00 00 00 00          mov eax, 0
89 05 A8 FB 9A 00       mov dword [ds:0x9afba8], eax
81 3D A8 FB 9A 00 03    cmp dword [ds:0x9afba8], 3
00 00 00
0F 8F 2B 00 00 00       jg 0x31
68 00 00 00 00          push 0
68 00 6D 9B 00          push 0x9b6d00
68 A8 E0 9A 00          push 0x9ae0a8
68 00 00 00 00          push 0
B8 5F EA AA 75          mov eax, 0x75aaea5f
FF D0                   call eax
B8 01 00 00 00          mov eax, 1
01 05 A8 FB 9A 00       add dword [ds:0x9afba8], eax
E9 C5 FF FF FF          jmp -0x3b
C3                      ret

 

 

Spoiler
Local $sCode = "DllCall(""ole32.dll"", ""long"", ""CLSIDFromProgID"", ""ptr"", " & $pProgID & ", ""ptr"", " & $pCLSID & ")" & @CRLF & _
               "DllCall(""ole32.dll"", ""int"", ""StringFromGUID2"", ""ptr"", " & $pCLSID & ", ""ptr"", " & $pStr & ", ""int"", 40)"

 

68 50 8A AD 00          push 0xad8a50
68 70 E9 AD 00          push 0xade970
B8 3C 50 30 77          mov eax, 0x7730503c
FF D0                   call eax
68 28 00 00 00          push 0x28
68 C0 4E 9C 00          push 0x9c4ec0
68 50 8A AD 00          push 0xad8a50
B8 EC 22 32 77          mov eax, 0x773222ec
FF D0                   call eax
C3                      ret

 

 

Edited by jugador

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
×
×
  • Create New...