CALLBACK
CALLBACK allows you to write a function or method in dBL code and setup a pointer to it that can be passed to an external program - such as Windows or the BDE or some other 3rd party software that supports callbacks.
Callbacks can be used to notify your program of specific events occurring with an external program OR to allow your program to modify what an external program is doing.
Syntax
CALLBACK <return type> <function name>([<param type>,...])
[FROM <filename>]
[OBJECT <oRef>]
<return type>
EXTERN type returned by function
<function name>
Name of dBL function or method to be made callable From external program
<param type>,...
Zero or more EXTERN types specifying the parameter types expected by the dBL function or method
<filename>
dBL source file containing function or method
<oRef>
Object reference of object containing dBL method
Examples:
this first example illustrate how we can use the Callback solutions
to subclassing the Window procedure of Form; in the following steps:
1) Open Form
2) Press the Notebook button "Attach"
3) Watch the messages on Command Window
class MyForm of FORM
with (this)
canClose = class::FORM_CANCLOSE
onOpen = class::FORM_ONOPEN
height = 12.2273
left = 57.5714
top = 8.3636
width = 59.8571
text = ""
endwith
this.ENTRYFIELD1 = new ENTRYFIELD(this)
with (this.ENTRYFIELD1)
height = 1.0
left = 4.0
top = 1.5
width = 22.0
value = "Entryfield1"
endwith
this.NOTEBOOK1 = new NOTEBOOK(this)
with (this.NOTEBOOK1)
canSelChange = class::NOTEBOOK1_CANSELCHANGE
tabStop = false
height = 2.5
left = 49.0
top = 0.5
width = 10.0
dataSource = 'ARRAY {"Detach","Attach"}'
buttons = true
multiple = true
focus = 2 // Never
endwith
function form_onOpen
#define GWL_WNDPROC (-4)
if type("GetWindowLong") # "FP"
extern CLONG GetWindowLong(CHANDLE, CINT) user32 from "GetWindowLongA"
endif
if type("SetWindowLong") # "FP"
extern CLONG SetWindowLong(CHANDLE, CINT, CLONG) user32 from "SetWindowLongA"
endif
if type("CallWindowProc") # "FP"
extern CLONG CallWindowProc(CPTR, CHANDLE, CUINT, CUINT, CUINT) user32 from "CallWindowProcA"
endif
this.newProc = null
this.oldProc = null
this.attached = false
return
function form_canClose
if this.attached
return false
endif
release callback callWndProc object this
return true
function NOTEBOOK1_canSelChange(newSel)
if newSel == 1
return form.detach()
elseif newSel == 2
return form.attach()
endif
return true
function attach
if this.attached OR this.hwnd == 0
return false
endif
if this.oldProc == null
this.oldProc = GetWindowLong(this.hwnd, GWL_WNDPROC)
endif
if this.newProc == null
callback CLONG callWndProc(CHANDLE, CUINT, CUINT, CUINT) object this
this.newProc = GetCallAddress(this.callWndProc)
endif
SetWindowLong(this.hwnd, GWL_WNDPROC, this.newProc)
? "hwnd:", this.hwnd, "oldProc:", this.oldProc, "newProc:", this.newProc
this.attached = true
return true
function detach
if not this.attached
return false
endif
SetWindowLong(this.hwnd, GWL_WNDPROC, this.oldProc)
this.attached = false
return true
function callWndProc(hWnd, uMsg, wParam, lParam)
? [MSG:], uMsg, [WP:], wParam, [LP:], lParam
return CallWindowProc(this.oldProc, hwnd, uMsg, wParam, lParam)
endclass
See Also