Provides the ability to execute a function or object method when an API window receives a specified window message.
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. Value Description hwnd, uMsg, wParam or lParam parameter 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.
Flag Description BINDEVENTSEX_CALL_BEFORE Your function is called before CallWindowProc is called. BINDEVENTSEX_CALL_AFTER Your 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_VALUE CallWindowProc 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_RECURSION Is 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_CLASSPROC Instead 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:
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.
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.
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