Provides the ability to execute a function or object method when an API window receives a specified window message.

BindEventsEx(nHwnd, nMsg, oObject, cFunction [, cParmDefinition [, nFlags]])

Parameters

nHwnd

The handle to the window which messages should be intercepted.

nMsg

The window message which should trigger the callback function e.g. WM_MOUSEMOVE, WM_ACTIVATE

oObject

The object on which the function passed in cFunction should be called or NULL if cFunction is a public FUNCTION / PROCEDURE.

cFunction

Name of the function or method which should be called when the message is received by the window.

cParmDefinition (optional)

A comma seperated list of parameters to pass to the function.

If you omit cParmDefinition or pass NULL the default is like in BINDEVENTSEX, that is 4 parameters are passed to your callback function:

FUNCTION YourFunc(Hwnd, uMsg, wParam, lParam)

and wParam & lParam are marshaled as signed integers.

You can also specify you own function definition e.g.

&& you only want wParam & lParam as parameters
BINDEVENTSEX(yourHwnd,WM_SOMEMESSAGE,NULL,'SomeFunc','wParam,lParam')
&& if you don't need parameters at all pass an empty string
BINDEVENTSEX(yourHwnd,WM_SOMEMESSAGE,NULL,'SomeFunc','')

Possible values for the list are.
ValueDescription
hwnd, uMsg, wParam or lParamparameter as signed integer
UNSIGNED(wParam or lParam)wParam or lParam as unsigned integer
HIWORD(wParam or lParam)high word (upper 16 bit) as a signed short
LOWORD(wParam or lParam)low word (lower 16 bit) as a signed short
UNSIGNED(HIWORD(wParam or lParam))high word (upper 16 bit) as a unsigned short
UNSIGNED(LOWORD(wParam or lParam))low word (lower 16 bit) as a unsigned short
BOOL(wParam or lParam)parameter converted to boolean, 0 = .F. everything else = .T.
nFlags (optional, additive)

If you omit the nFlags parameter or pass 0 the default is BINDEVENTSEX_CALL_BEFORE.

FlagDescription
BINDEVENTSEX_CALL_BEFOREYour function is called before CallWindowProc is called.
BINDEVENTSEX_CALL_AFTERYour function is called after CallWindowProc is called.
You have to return a numeric value from your callback function which is used as the return value of the underlying window procedure.
BINDEVENTSEX_RETURN_VALUECallWindowProc is not called automatically, you can either call it yourself in the callback function or omit it.
You have to return a numeric value from you callback function which is used as the return value of the underlying window procedure.
BINDEVENTSEX_NO_RECURSIONIs the same as in BINDEVENTS
_VFP.AutoYield is set to .F. before your function is called and reset to it's original value afterwards to prevent recursion.
BINDEVENTSEX_CLASSPROCInstead of the actual window the window class of the passed nHwnd is subclassed.
All subsequent windows created from the windowclass are automatically subclassed.
!! You have to call UnbindEventsEx with the third parameter set to .T. if you unbind a message from a windowclass !!

Note

The flags BINDEVENTSEX_CALL_BEFORE, BINDEVENTSEX_CALL_AFTER & BINDEVENTSEX_RETURN_VALUE are
mutually exclusive, that means you can only specify one of the values, otherwise error "invalid parameters" is risen.

Return Value

A pointer (numeric) to the original window procedure, returned from GetWindowLong(nHwnd, GWL_WNDPROC).

Remarks

BindEventsEx almost behaves exactly as BINDEVENT does, the differences are:

1. It returns the pointer to the original window procedure instead of no meaningful value, so you don't have to call GetWindowLong(nHwnd, GWL_WNDPROC).
2. You don't have to bind the message to an object method, it can also be a public function / procedure
3. You don't have to call CallWindowProc by default, CallWindowProc is automatically called with the original parameters before/after your function is called back this behaviour is controllable through the nFlags parameter
4. You can specify exactly what parameters should be send to your callback function / method and how they should be marshaled.
5. You cannot pass 0 as the nHwnd parameter like in BINDEVENT to bind to all windows

To emulate callbacks on an object the library has to make a copy of the object into a public variable.
The name of the variable is auto generated by the following scheme:

Copy code
lcVarName = "__VFP2C_WCBO" + IIF(BITAND(nFlags, BINDEVENTSEX_CLASSPROC) > 0, "1", "0") + "_" + ALLTRIM(STR(nHwnd)) + "_" + ALLTRIM(STR(nMsg))

This workaround is necessary cause the FoxPro LCK doesn't provide an API function to call methods of an object.
The public variable is automatically released when you unbind the message.
Although a copy of the object is made the internal object reference count is not incremented, the public copy doesn't affect your object's lifetime (scope).
The only thing you have to consider is that your own variables doesn't conflict with the above naming scheme which is very unlikely.

Example

Bind the mousemove event of a window with proper parameters.

Copy code
BINDEVENTSEX(yourHwnd, WM_MOUSEMOVE, NULL, 'MouseMoveCallback', 'wParam, LOWORD(lParam), HIWORD(lParam)')
FUNCTION MouseMoveCallback(nKeyState, nXCoord, nYCoord)
&& handle mousemove ..
ENDFUNC


Bind the activation/deactivation of your application window.

Copy code
BINDEVENTSEX(_SCREEN.hWnd, WM_ACTIVATE, 'AppFocusStateChanged', 'BOOL(wParam)')
FUNCTION AppFocusStateChanged(bState)
? "Application " + IIF(m.bState, 'got focus', 'lost focus')
ENDFUNC

See Also

Reference

AsyncWaitForObject
CancelWaitForObject
CreateCallbackFunc
CreatePublicShadowObjReference
DestroyCallbackFunc
ReleasePublicShadowObjReference
UnbindEventsEx

Used WinApi functions

SetWindowLong
GetWindowLong
SetClassLong
GetClassLong
CallWindowProc
HeapAlloc
VirtualProtect