// Initialize callback function using BAP nCallBack := BaCallBack("DesignerCallback", BA_CB_GENERIC3) // Hand callback function handle to LL LlSetNotificationCallbackExt(hJob,LL_NTFY_DESIGNERPRINTJOB,nCallBack)
DesignerCallback is a function that has a signature like:
FUNCTION DesignerCallback(nNotification,nStructurePtr,xUserParam)
BEGIN STRUCTURE My_LlCallback MEMBER UINT _nSize MEMBER POINTER _nUserParam MEMBER POINTER32 _pszProjectName MEMBER POINTER32 _pszOriginalProjectFileName MEMBER UINT _nPages MEMBER UINT _nFunction MEMBER HWND _hWnd MEMBER HANDLE _hEvent MEMBER POINTER32 _pszExportFormat MEMBER BOOL _bWithoutDialog END STRUCTURE
// Create a local copy of the structure // get the structure nStructurePtr points to - .F. means: not a copy oCbLocal := My_LlCallback():New():_link_(nStructurePtr,.F.) oCbLocal:_lock_() … // do something with oCbLocal oCbLocal:_unlock_() // unlock the structure oCbLocal:_unlink_(.F.) // unlink the structure
An important thing to keep in mind is that you need to copy all members of the structure to local/global variables as the structure will no longer be valid once the callback routine returns. So you cannot rely on the validity of any of the structure members anywhere else in the code. Thus, the sample copies all members and passes these copies to the central printing routine:
// Init values for the print thread cProjectName := PeekStr(oCbLocal:_pszProjectName,,-1) // filename from structure pointer cOrgProjectName := PeekStr(oCbLocal:_pszOriginalProjectFileName,,-1) // filename from structure pointer nProjecthWnd := oCbLocal:_hWnd // window handle nRecNo := oCbLocal:_nUserParam // record number in INVOICE.DBF nPages := oCbLocal:_nPages // number of pages to be printed hEvent := oCbLocal:_hEvent // event handle for synchronization // Start print thread oPrintThread := Thread():new() oPrintThread:start( {||PrintPreviewData(cProjectName,cOrgProjectName,nProjecthWnd,nRecNo,nPages,hEvent)})
The PrintPreviewData routine is more or less identical to the “normal” printing, only the progress box is removed by using LlPrintStart() instead of LlPrintWithBoxStart() and the print code attaches to the designer’s preview window by calling LlAssociatePreviewControl(). We’ll add the full sample to our knowledge base area shortly.
The sample could easily be extended to support the drilldown callback as well, which would enable the report parameter pane in the preview or expandable regions for Xbase++ applications.