Hi again. I search throught all the internet and all the methods to make an event Hover and Leave has wast quite nice to me. One of the main trhoubles was that only the message procesor of the window could get the events. so that means that if im making a form with a couple of buttons that make diferent things in the events i would have to create a lot of code. Also i dont find vb a good language to process message, cause that has to be fast as posible cause all message have to pass trhu the hook process, and every added reference is a lil more of time processing.
The search method in the list is not optimized, but im almost sure that is better than make it in vb.
well, i made a function that can redirect any message of any window to your own object function, this object require only implement an interface called IMessageCatcher, and thats all, cant be more simple.
vb code
Implements IMessageCatcher
Const WM_MOUSEHOVER = &H2A1&
Const WM_MOUSELEAVE = &H2A3&
Const WM_LBUTTONDOWN = &H201&
Const WM_LBUTTONUP = &H202&
Private WithEvents mouseeventsCommand2 As MessageCatcher
Private WithEvents mouseeventscommand3 As MessageCatcher
Private Declare Function EndWindowRedirection Lib "..\msgredir\msgredir.dll" (ByVal hWnd As Long) As Boolean
Private Declare Function RedirectMessage Lib "..\msgredir\msgredir.dll" (ByVal hWnd As Long, ByVal uMsg As Long, ByVal obj As IMessageCatcher) As Boolean
Private Sub cmdCommand1_Click()
MsgBox "This is the original event"
End Sub
Private Sub Form_Click()
MsgBox "Original event"
End Sub
Private Sub Form_Load()
Set mouseeventsCommand2 = New MessageCatcher
Set mouseeventscommand3 = New MessageCatcher
Call RedirectMessage(Me.hWnd, WM_MOUSEHOVER, Me)
Call RedirectMessage(Me.hWnd, WM_MOUSELEAVE, Me)
Call RedirectMessage(Me.hWnd, WM_LBUTTONDOWN, Me)
Call RedirectMessage(Me.cmdCommand1.hWnd, WM_MOUSEHOVER, Me)
Call RedirectMessage(Me.cmdCommand1.hWnd, WM_MOUSELEAVE, Me)
Call RedirectMessage(Me.cmdCommand1.hWnd, WM_LBUTTONUP, Me)
'now we r redirecting direfent messages of direfents windows on the same
'message processor, you may need to separate without doing a if.elseif.endif
'you could do this
Call mouseeventsCommand2.Redirect(Me.cmdCommand2.hWnd, WM_MOUSEHOVER)
Call mouseeventsCommand2.Redirect(Me.cmdCommand2.hWnd, WM_MOUSELEAVE)
Call mouseeventsCommand2.Redirect(Me.cmdCommand2.hWnd, WM_LBUTTONDOWN)
Call mouseeventsCommand2.Redirect(Me.cmdCommand2.hWnd, WM_LBUTTONUP)
Call mouseeventscommand3.Redirect(Me.cmdCommand3.hWnd, WM_MOUSEHOVER)
Call mouseeventscommand3.Redirect(Me.cmdCommand3.hWnd, WM_MOUSELEAVE)
End Sub
Private Function IMessageCatcher_OnMsg(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Me.txtText1 = "IMessageCatcher_OnMsg of the form" & vbCrLf
If hWnd = Me.hWnd Then
Me.txtText1 = Me.txtText1 & "Window: Form" & vbCrLf
ElseIf hWnd = Me.cmdCommand1.hWnd Then
Me.txtText1 = Me.txtText1 & "Window: Command1" & vbCrLf
End If
If uMsg = WM_LBUTTONUP Then
Me.txtText1 = Me.txtText1 & "Message: Click"
ElseIf uMsg = WM_MOUSEHOVER Then
Me.txtText1 = Me.txtText1 & "message: Mouse Hover"
ElseIf uMsg = WM_MOUSELEAVE Then
Me.txtText1 = Me.txtText1 & "message: Mouse Leave"
End If
End Function
Private Sub mouseeventsCommand2_OnMsg(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
If uMsg = WM_MOUSEHOVER Then
Me.cmdCommand2.Caption = "Hover"
ElseIf uMsg = WM_LBUTTONDOWN Then
Me.cmdCommand2.Caption = "Click.."
ElseIf uMsg = WM_LBUTTONUP Then
Me.cmdCommand2.Caption = "ClickOut"
Else
Me.cmdCommand2.Caption = "Leave"
End If
End Sub
Private Sub mouseeventscommand3_OnMsg(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
If uMsg = WM_MOUSEHOVER Then
Me.cmdCommand3.Caption = "Hover"
Else
Me.cmdCommand3.Caption = "Leave"
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
'in this case you dont need to call EndWindowRedirection
'cause is made it automatically when the windows get the wm_destroy
EndWindowRedirection Me.hWnd
EndWindowRedirection Me.cmdCommand1.hWnd
EndWindowRedirection Me.cmdCommand2.hWnd
EndWindowRedirection Me.cmdCommand3.hWnd
End Sub
'WARNING!! everytime u call redirectmessage the asm make a node in a list
'this is destroyed when the hook process of the window WM_DESTROY
'if u hook another windows that is not of yours remember to call EndWindowRedirection
'else if the IMessageCatcher is destroyed before the window a message is catched by asm,
'it will make an error trying to call the first public function of the interface of the
'deleted object
'Second WARNING: call twice RedirectMessage with same window and message dont work
'the first one only gets it (ill improve this when i have time)
'Third WARNING: if diferent objects whith IMessageCatcher are hooking diferent
'message of same window if some object have to be deleted then it have to call
'to EndWindowREdirect and in secondary efect makes the other object stop hooking
'messages, this is cause i didnt have time, and i didnt need it to make a function
'in the dll RemoveMessageRedirection, ill do it when i need it or have the time
'i think thats all, cant remember now, im too sleepy
asm code of the dll (only the important part)
.386
.model flat,stdcall
option casemap:none
include msgredir.inc
this is the way you define any object interface:
vbClass_VirtualTable struct
unk1 dd ?
unk2 dd ?
unk3 dd ?
unk4 dd ?
unk5 dd ?
unk6 dd ?
unk7 dd ?
vbClass_VirtualTable ends
IMessageCatcher_VirtualTable struct
unknown vbClass_VirtualTable <>;no idea what this info is
Func1 dd ? ;my function
IMessageCatcher_VirtualTable ends
vbObject struct
pVirtualTable dd ?
vbObject ends
.data
hInstance dd 0
hWindowsList dd ?
hDllVbVm dd 0
.code
DllEntry proc hInst:HINSTANCE, reason:DWORD, reserver1:DWORD
LOCAL hList:DWORD
.if reason == DLL_PROCESS_ATTACH
push hInst
pop hInstance
invoke CreateDataList
mov hWindowsList,eax
.elseif reason == DLL_PROCESS_DETACH
invoke EndAllWindowsRedirection
invoke DataList_Delete,hWindowsList
.endif
mov eax,TRUE
ret
DllEntry endp
MsgRedirectorProc proc hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
LOCAL retv:DWORD
LOCAL tme:TRACKMOUSEEVENT
push esi
invoke DataList_Get,hWnd,hWindowsList
;allways is going to return a list entry
mov esi,eax;esi = ptr WindowNode
invoke CallWindowProc,.WindowNode.pProc,hWnd,uMsg,wParam,lParam
push eax
.if uMsg== WM_DESTROY
invoke EndWindowRedirection,hWnd
ret
.elseif uMsg==02a3h;leave
mov .WindowNode.inside,0
mov tme.cbSize,SIZEOF(TRACKMOUSEEVENT)
mov tme.dwFlags,TME_HOVER
mov eax,hWnd
mov tme.hwndTrack,EAX
mov tme.dwHoverTime,HOVER_DEFAULT
INVOKE TrackMouseEvent,ADDR tme
;^
.ELSEIF uMsg==WM_MOUSEMOVE && .WindowNode.inside==0;hover
mov .WindowNode.inside,1
;seems like windows dont generate hover message, so i do it for him
invoke PostMessage,hWnd,WM_MOUSEHOVER,0,0
mov tme.cbSize,SIZEOF(TRACKMOUSEEVENT)
mov tme.dwFlags,TME_LEAVE
mov eax,hWnd
mov tme.hwndTrack,EAX
mov tme.dwHoverTime,HOVER_DEFAULT
INVOKE TrackMouseEvent,ADDR tme
.endif
invoke DataList_Get,uMsg,.WindowNode.hMsgs
.if eax; if we have to redirect the message of this window
;eax = ptr WindowMessageNode
mov esi,eax;esi = ptr WindowMessageNode
;call the function number 1 of the object interface
mov eax,.WindowMessageNode.pObj
mov edx,.vbObject.pVirtualTable
lea ecx,retv
push ecx ;push the address to the return value
push lParam ;push parameters as u define in vb
push wParam
push uMsg
push hWnd
push eax ;push object reference
call .IMessageCatcher_VirtualTable.Func1
.endif
pop eax
pop esi
ret
MsgRedirectorProc endp
RedirectMessage proc hWnd:HWND,uMsg:DWORD,pObj:DWORD;As boolean(true = ok)
LOCAL et:TRACKMOUSEEVENT
push esi
invoke DataList_Get,hWnd,hWindowsList
.if eax;the window already exist in the list
mov esi,eax;esi = window node
invoke WindowNode_addMessage,esi,uMsg,pObj
.ELSE;the window dont exist in the list
mov eax,hWindowsList
invoke WindowNode_create,hWnd;put in the list
mov esi,eax
invoke DataList_Add,hWnd,esi,hWindowsList
invoke WindowNode_addMessage,esi,uMsg,pObj
invoke SetWindowLong,hWnd,GWL_WNDPROC,ADDR MsgRedirectorProc
mov et.cbSize,SIZEOF(TRACKMOUSEEVENT)
mov et.dwFlags,TME_HOVER+TME_LEAVE+TME_CANCEL
mov eax,hWnd
mov et.hwndTrack,EAX
mov et.dwHoverTime,HOVER_DEFAULT
INVOKE TrackMouseEvent,ADDR et
.endif
pop esi
ret
RedirectMessage endp
EndWindowRedirection proc hWnd:DWORD;As long (success <> 0)
push esi
invoke DataList_Get,hWnd,hWindowsList
mov esi,eax;esi = windownode
invoke SetWindowLong,.WindowNode.hWnd,GWL_WNDPROC,.WindowNode.pProc;reestablezco el proceso original
invoke DataList_Delete,.WindowNode.hMsgs;borro lista de mensajes
invoke GlobalFree,esi
invoke DataList_Remove,hWnd,hWindowsList;borro el nodo de la lista
pop esi
ret
EndWindowRedirection endp
EnumCancelRedirection proc pWindowNode:DWORD
push esi
mov esi,pWindowNode
invoke EndWindowRedirection,.WindowNode.hWnd
pop esi
ret
EnumCancelRedirection endp
EndAllWindowsRedirection proc
lea ecx, EnumCancelRedirection
invoke DataList_Enum,hWindowsList,ecx
ret
EndAllWindowsRedirection endp
end DllEntry
i hope u find this usefull.
one last comment about virtual tables of vb objects
lets say that your class called MyClass is defined in vb like this:
vb code:
public myLong as long
private myPrivateLong as long 'private members dont afect the virtual table of the object, cause dont have default get and set methods
property get myOtherLong as long
myOtherLong = 5
end property
public function myFunction() as long
myFunction = myLong + 20
end function
to can use methods of the class from ASM having a reference to the object
u have to define the virtual table like this
MyClass_VirtualTable struct
unknown vbClass_VirtualTable <>
Get_myLong dd ?
Set_myLong dd ?
Get_myOtherLong dd ?
myFunction dd ?
MyClass_VirtualTable ends
remember that the calling convention of vb passes the pointer to the ret value first
and the pointer to the object at after the parameters, and i guess u know
how to pass byval and byref parameters.
sorry my english, but is understandable enought, isnt it?
thats all
The search method in the list is not optimized, but im almost sure that is better than make it in vb.
well, i made a function that can redirect any message of any window to your own object function, this object require only implement an interface called IMessageCatcher, and thats all, cant be more simple.
vb code
Implements IMessageCatcher
Const WM_MOUSEHOVER = &H2A1&
Const WM_MOUSELEAVE = &H2A3&
Const WM_LBUTTONDOWN = &H201&
Const WM_LBUTTONUP = &H202&
Private WithEvents mouseeventsCommand2 As MessageCatcher
Private WithEvents mouseeventscommand3 As MessageCatcher
Private Declare Function EndWindowRedirection Lib "..\msgredir\msgredir.dll" (ByVal hWnd As Long) As Boolean
Private Declare Function RedirectMessage Lib "..\msgredir\msgredir.dll" (ByVal hWnd As Long, ByVal uMsg As Long, ByVal obj As IMessageCatcher) As Boolean
Private Sub cmdCommand1_Click()
MsgBox "This is the original event"
End Sub
Private Sub Form_Click()
MsgBox "Original event"
End Sub
Private Sub Form_Load()
Set mouseeventsCommand2 = New MessageCatcher
Set mouseeventscommand3 = New MessageCatcher
Call RedirectMessage(Me.hWnd, WM_MOUSEHOVER, Me)
Call RedirectMessage(Me.hWnd, WM_MOUSELEAVE, Me)
Call RedirectMessage(Me.hWnd, WM_LBUTTONDOWN, Me)
Call RedirectMessage(Me.cmdCommand1.hWnd, WM_MOUSEHOVER, Me)
Call RedirectMessage(Me.cmdCommand1.hWnd, WM_MOUSELEAVE, Me)
Call RedirectMessage(Me.cmdCommand1.hWnd, WM_LBUTTONUP, Me)
'now we r redirecting direfent messages of direfents windows on the same
'message processor, you may need to separate without doing a if.elseif.endif
'you could do this
Call mouseeventsCommand2.Redirect(Me.cmdCommand2.hWnd, WM_MOUSEHOVER)
Call mouseeventsCommand2.Redirect(Me.cmdCommand2.hWnd, WM_MOUSELEAVE)
Call mouseeventsCommand2.Redirect(Me.cmdCommand2.hWnd, WM_LBUTTONDOWN)
Call mouseeventsCommand2.Redirect(Me.cmdCommand2.hWnd, WM_LBUTTONUP)
Call mouseeventscommand3.Redirect(Me.cmdCommand3.hWnd, WM_MOUSEHOVER)
Call mouseeventscommand3.Redirect(Me.cmdCommand3.hWnd, WM_MOUSELEAVE)
End Sub
Private Function IMessageCatcher_OnMsg(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Me.txtText1 = "IMessageCatcher_OnMsg of the form" & vbCrLf
If hWnd = Me.hWnd Then
Me.txtText1 = Me.txtText1 & "Window: Form" & vbCrLf
ElseIf hWnd = Me.cmdCommand1.hWnd Then
Me.txtText1 = Me.txtText1 & "Window: Command1" & vbCrLf
End If
If uMsg = WM_LBUTTONUP Then
Me.txtText1 = Me.txtText1 & "Message: Click"
ElseIf uMsg = WM_MOUSEHOVER Then
Me.txtText1 = Me.txtText1 & "message: Mouse Hover"
ElseIf uMsg = WM_MOUSELEAVE Then
Me.txtText1 = Me.txtText1 & "message: Mouse Leave"
End If
End Function
Private Sub mouseeventsCommand2_OnMsg(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
If uMsg = WM_MOUSEHOVER Then
Me.cmdCommand2.Caption = "Hover"
ElseIf uMsg = WM_LBUTTONDOWN Then
Me.cmdCommand2.Caption = "Click.."
ElseIf uMsg = WM_LBUTTONUP Then
Me.cmdCommand2.Caption = "ClickOut"
Else
Me.cmdCommand2.Caption = "Leave"
End If
End Sub
Private Sub mouseeventscommand3_OnMsg(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
If uMsg = WM_MOUSEHOVER Then
Me.cmdCommand3.Caption = "Hover"
Else
Me.cmdCommand3.Caption = "Leave"
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
'in this case you dont need to call EndWindowRedirection
'cause is made it automatically when the windows get the wm_destroy
EndWindowRedirection Me.hWnd
EndWindowRedirection Me.cmdCommand1.hWnd
EndWindowRedirection Me.cmdCommand2.hWnd
EndWindowRedirection Me.cmdCommand3.hWnd
End Sub
'WARNING!! everytime u call redirectmessage the asm make a node in a list
'this is destroyed when the hook process of the window WM_DESTROY
'if u hook another windows that is not of yours remember to call EndWindowRedirection
'else if the IMessageCatcher is destroyed before the window a message is catched by asm,
'it will make an error trying to call the first public function of the interface of the
'deleted object
'Second WARNING: call twice RedirectMessage with same window and message dont work
'the first one only gets it (ill improve this when i have time)
'Third WARNING: if diferent objects whith IMessageCatcher are hooking diferent
'message of same window if some object have to be deleted then it have to call
'to EndWindowREdirect and in secondary efect makes the other object stop hooking
'messages, this is cause i didnt have time, and i didnt need it to make a function
'in the dll RemoveMessageRedirection, ill do it when i need it or have the time
'i think thats all, cant remember now, im too sleepy
asm code of the dll (only the important part)
.386
.model flat,stdcall
option casemap:none
include msgredir.inc
this is the way you define any object interface:
vbClass_VirtualTable struct
unk1 dd ?
unk2 dd ?
unk3 dd ?
unk4 dd ?
unk5 dd ?
unk6 dd ?
unk7 dd ?
vbClass_VirtualTable ends
IMessageCatcher_VirtualTable struct
unknown vbClass_VirtualTable <>;no idea what this info is
Func1 dd ? ;my function
IMessageCatcher_VirtualTable ends
vbObject struct
pVirtualTable dd ?
vbObject ends
.data
hInstance dd 0
hWindowsList dd ?
hDllVbVm dd 0
.code
DllEntry proc hInst:HINSTANCE, reason:DWORD, reserver1:DWORD
LOCAL hList:DWORD
.if reason == DLL_PROCESS_ATTACH
push hInst
pop hInstance
invoke CreateDataList
mov hWindowsList,eax
.elseif reason == DLL_PROCESS_DETACH
invoke EndAllWindowsRedirection
invoke DataList_Delete,hWindowsList
.endif
mov eax,TRUE
ret
DllEntry endp
MsgRedirectorProc proc hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
LOCAL retv:DWORD
LOCAL tme:TRACKMOUSEEVENT
push esi
invoke DataList_Get,hWnd,hWindowsList
;allways is going to return a list entry
mov esi,eax;esi = ptr WindowNode
invoke CallWindowProc,.WindowNode.pProc,hWnd,uMsg,wParam,lParam
push eax
.if uMsg== WM_DESTROY
invoke EndWindowRedirection,hWnd
ret
.elseif uMsg==02a3h;leave
mov .WindowNode.inside,0
mov tme.cbSize,SIZEOF(TRACKMOUSEEVENT)
mov tme.dwFlags,TME_HOVER
mov eax,hWnd
mov tme.hwndTrack,EAX
mov tme.dwHoverTime,HOVER_DEFAULT
INVOKE TrackMouseEvent,ADDR tme
;^
.ELSEIF uMsg==WM_MOUSEMOVE && .WindowNode.inside==0;hover
mov .WindowNode.inside,1
;seems like windows dont generate hover message, so i do it for him
invoke PostMessage,hWnd,WM_MOUSEHOVER,0,0
mov tme.cbSize,SIZEOF(TRACKMOUSEEVENT)
mov tme.dwFlags,TME_LEAVE
mov eax,hWnd
mov tme.hwndTrack,EAX
mov tme.dwHoverTime,HOVER_DEFAULT
INVOKE TrackMouseEvent,ADDR tme
.endif
invoke DataList_Get,uMsg,.WindowNode.hMsgs
.if eax; if we have to redirect the message of this window
;eax = ptr WindowMessageNode
mov esi,eax;esi = ptr WindowMessageNode
;call the function number 1 of the object interface
mov eax,.WindowMessageNode.pObj
mov edx,.vbObject.pVirtualTable
lea ecx,retv
push ecx ;push the address to the return value
push lParam ;push parameters as u define in vb
push wParam
push uMsg
push hWnd
push eax ;push object reference
call .IMessageCatcher_VirtualTable.Func1
.endif
pop eax
pop esi
ret
MsgRedirectorProc endp
RedirectMessage proc hWnd:HWND,uMsg:DWORD,pObj:DWORD;As boolean(true = ok)
LOCAL et:TRACKMOUSEEVENT
push esi
invoke DataList_Get,hWnd,hWindowsList
.if eax;the window already exist in the list
mov esi,eax;esi = window node
invoke WindowNode_addMessage,esi,uMsg,pObj
.ELSE;the window dont exist in the list
mov eax,hWindowsList
invoke WindowNode_create,hWnd;put in the list
mov esi,eax
invoke DataList_Add,hWnd,esi,hWindowsList
invoke WindowNode_addMessage,esi,uMsg,pObj
invoke SetWindowLong,hWnd,GWL_WNDPROC,ADDR MsgRedirectorProc
mov et.cbSize,SIZEOF(TRACKMOUSEEVENT)
mov et.dwFlags,TME_HOVER+TME_LEAVE+TME_CANCEL
mov eax,hWnd
mov et.hwndTrack,EAX
mov et.dwHoverTime,HOVER_DEFAULT
INVOKE TrackMouseEvent,ADDR et
.endif
pop esi
ret
RedirectMessage endp
EndWindowRedirection proc hWnd:DWORD;As long (success <> 0)
push esi
invoke DataList_Get,hWnd,hWindowsList
mov esi,eax;esi = windownode
invoke SetWindowLong,.WindowNode.hWnd,GWL_WNDPROC,.WindowNode.pProc;reestablezco el proceso original
invoke DataList_Delete,.WindowNode.hMsgs;borro lista de mensajes
invoke GlobalFree,esi
invoke DataList_Remove,hWnd,hWindowsList;borro el nodo de la lista
pop esi
ret
EndWindowRedirection endp
EnumCancelRedirection proc pWindowNode:DWORD
push esi
mov esi,pWindowNode
invoke EndWindowRedirection,.WindowNode.hWnd
pop esi
ret
EnumCancelRedirection endp
EndAllWindowsRedirection proc
lea ecx, EnumCancelRedirection
invoke DataList_Enum,hWindowsList,ecx
ret
EndAllWindowsRedirection endp
end DllEntry
i hope u find this usefull.
one last comment about virtual tables of vb objects
lets say that your class called MyClass is defined in vb like this:
vb code:
public myLong as long
private myPrivateLong as long 'private members dont afect the virtual table of the object, cause dont have default get and set methods
property get myOtherLong as long
myOtherLong = 5
end property
public function myFunction() as long
myFunction = myLong + 20
end function
to can use methods of the class from ASM having a reference to the object
u have to define the virtual table like this
MyClass_VirtualTable struct
unknown vbClass_VirtualTable <>
Get_myLong dd ?
Set_myLong dd ?
Get_myOtherLong dd ?
myFunction dd ?
MyClass_VirtualTable ends
remember that the calling convention of vb passes the pointer to the ret value first
and the pointer to the object at after the parameters, and i guess u know
how to pass byval and byref parameters.
sorry my english, but is understandable enought, isnt it?
thats all
Anyone who reads this thread should know that none of this is new.
It might be a useful example for programmers interested in the lowlevel mechanisms that are used by object interfaces, but this is not an efficient way to write this kind of code, and it's not pretty to look at, either.
Members of this board have created many helper macros for defining and calling object interfaces and their methods.
In order of least complexity: Ernie's COINVOKE/COM macros, Ultrano's ATC oopasm framework, Biterider's OA32 oopasm framework.
So much stuff to look at!
These are just sets of helper macros that allow you to write what appears to be highlevel sourcecode, where in fact we're using macros that emit vanilla asm, so these frameworks only exist 'at buildtime', inside MASM.
In particular, OA32 supports many highlevel concepts such as N-deep single inheritance, polymorphism, runtime overloading of interface methods etc. which would make your life much more painful if you insisted on handcrafting all your code...it can create Vanilla, COM and C++ styles of interfaces.
Here's an incomplete example of some OA32-dependant code which shows what I mean:
I believe that ATC is now officially dead, however the other stuff is still being used regularly, and in particular OA32 is still being actively developed.
It might be a useful example for programmers interested in the lowlevel mechanisms that are used by object interfaces, but this is not an efficient way to write this kind of code, and it's not pretty to look at, either.
Members of this board have created many helper macros for defining and calling object interfaces and their methods.
In order of least complexity: Ernie's COINVOKE/COM macros, Ultrano's ATC oopasm framework, Biterider's OA32 oopasm framework.
So much stuff to look at!
These are just sets of helper macros that allow you to write what appears to be highlevel sourcecode, where in fact we're using macros that emit vanilla asm, so these frameworks only exist 'at buildtime', inside MASM.
In particular, OA32 supports many highlevel concepts such as N-deep single inheritance, polymorphism, runtime overloading of interface methods etc. which would make your life much more painful if you insisted on handcrafting all your code...it can create Vanilla, COM and C++ styles of interfaces.
Here's an incomplete example of some OA32-dependant code which shows what I mean:
mov ptemp, $OCall (pObj::MyObjectClass.EnumArgs,pPhrase,2)
Switch eax
Case NULL
DbgWarning "No Arguments were Enumerated"
Destroy ptemp
mov ptemp,0
I believe that ATC is now officially dead, however the other stuff is still being used regularly, and in particular OA32 is still being actively developed.
Anyone who reads this thread should know that none of this is new.
It might be a useful example for programmers interested in the lowlevel mechanisms that are used by object interfaces, but this is not an efficient way to write this kind of code, and it's not pretty to look at, either.
Sorry my ignorance, i didnt know that com clases whas the same that vb objects.
I just open my debug and start to c how vb makes the calls.
did u know where i can find the interface descriptors for the common objects in vb? like command buttons, forms, etc? thanks
i dont know what u mean by eficient, is it faster with the macros? maybe u mean a lil less of code and an added complexity. Anyway, i prefeer to write high level code with high level languages and use asm to write low level, even if is longer i found it easyer to read and mantain, when i start to use all those macros and stuff asm code start to be look kind of ugly to me.
OOPASM allows you to write programs that look and feel like a HLL, but actually generate asm (that you will never see).
It's efficient because it dramatically speeds up development times, especially when you are using, or deriving from, a set of standard objects.
The tired old arguments that have been used by HLL coders for years to put down ASM are no longer true.
We can write HLL code AND write asm at the SAME TIME.
We can write reusable code modules and port them easily between projects, etc.
The source is more readable, faster to write, easier to debug (TRUE!), and the development times are similar to any other HLL, with the added benefits that the binary code is more efficient, faster, and smaller than that produced by a Compiler.
You don't even need to study or understand the oopasm macros and the opcodes they generate in order to USE them, which is why I responded so quickly to your post.
I am not suggesting that understanding the lowlevel output of the macros is a bad idea, I am simply stating that the User does not NEED to do so in order to benefit from using it.
Anyone who reads this thread should know that none of this is new.
ive been reading the com librarys for asm. There is something new if i dont mistake, the com defines that every object interface have the iUnknown that have 6. This vb objects have 7 methods, i dont know if the 6 first belong to iunknown.
I dont know if write an app with asm even using HLL takes the same time, i would pay to c a vb programer next to a asm programer and c who ends first an entire project in just 1 languaje.
As i said before, i prefeer to use asm in things that the high level languaje that i use to write the application dont let me do it, or make it slow, or makes all confusing or make "strange" code, etc, etc
and all this discution just for 5 lines that could be replaced for a coinvoke call, i pass from low level to high leven in 5 lines. No matter how much macros i use, writting hll in asm depends more of the programer discipline than other thing, cause ull have allways at your hand to do low level code.
as i c this macros "emulate" oop, and that make trying to write Object Oriented code pretty much clumsy. Even with vb cant write acurate OO code, neither smalltalk, CLOS, Eiffel or c++ are completelly OO, so i doubt asm can be OO.
with those premises i could write fully OO with a electromagnetic pencil into a music cassette