Scenario:
VFP8
Win2k
Reports containing ActiveX Bound Control
Barcode ActiveX control: IDAutomation PDF417 (IDAuto.PDF417)
| %SYSTEM32%\IDAutomationPDF417e.dll
| (http://www.idautomation.com)
----
The report basically prints bills/notices/etc (various mail outs). The
OLE Bound Control displays an Image generated on the fly by a
procedure.
There can be as many as 5000 records (or more), therefore 5000+ General
fields. We have tried this several ways - the first of which was to
create a general field in the cursor used in the report. That made the
cursor enormous, so we decided to go with a function call that creates
a single field, single record cursor - here is the function used to
create the barcode cursor:
- Code: Select all
FUNCTION PopulateBarCode
LPARAMETER tcBarCodeVal
LOCAL lcOldCursor
* Save the old cursor to local var for later
STORE ALIAS() TO lcOldCursor
* Check for previously opened cursor, if open close
IF USED("cur_barcode") = .T. THEN
close_cursor("cur_barcode")
ENDIF
* Create cursor add the class
CREATE CURSOR cur_barcode (barcode G)
APPEND BLANK
APPEND GENERAL barcode CLASS ("IDAuto.PDF417")
* This is the best way we could come up with for this.
frmTemp = CreateObject("Form")
frmTemp.AddObject("BarCode", "OLEBoundControl")
frmTemp.BarCode.ControlSource = "cur_barcode.barcode"
* Refresh to assure we are on the right record, then assign the data.
frmTemp.BarCode.Refresh()
frmTemp.BarCode.Object.DataToEncode = tcBarCodeVal
* Get rid of the objects
frmTemp.RemoveObject("BarCode")
frmTemp.Release()
* Return to original cursor
SELECT &lcOldCursor
ENDFUNC
In the report there is an ActiveX OLE Bound Control with the field set
to cur_barcode.barcode, before that there is a call to
PopulateBarCode(ALLTRIM(barcodedata)).
Everything works fine to generate the reports, the problem arises when
we try to print (Printer or Adobe PDF driver) where it prints up until
about 3100-3300 pages (front and back, 1600+- actual records, then it
bombs throwing the infamous C0000005 fatal error code. Normally the
error looks similar to the following:
<pre>
Fatal error: Exception code=C0000005 @ DATETIMESTAMP. Error log file:
C\Program Files\Common Files\Microsoft Shared\VFP\vfp8rerr.log
Called from - populatebarcode line 0 {mail_shared.fxp}
[rest of call stack]
</pre>
A co-worker reported the same error which specified the same thing,
except in the call stack entries:
<pre>
Fatal error: Exception code=C0000005 @ DATETIMESTAMP. Error log file:
C\Program Files\Common Files\Microsoft Shared\VFP\vfp8rerr.log
Called from - populatebarcode line 602 {mail_shared.fxp}
[rest of call stack]
</pre>
Line 602 coincides with the APPEND GENERAL statement. So my thoughts on
this is that somehow, even though we are closing the cursor if it
exists, and destroying any objects we create, something is lingering in
memory somehow.
I have also added to the beginning of the PopulateBarCode() function:
- Code: Select all
CLEAR RESOURCES
Which *should* clear out any cached images from memory and reload them
as they are used. All in all, this logically should create the barcode
image for each page of the report and not store any previous pages
barcodes in memory. The General field type, from my understanding, not
only stores the Object and Image data, but also quite a bit of
overhead.
An idea I had was to use the IDAuto.PDF417 objects
.SaveBarCode(cFilePath) method to write out a barcode to a temp file
with the constant name of curbarcode.wmf (it only saves to Windows
Metafile format), then assigning the OLEBoundControl on the report to
that filename. The result is no error, but also no barcode.
I guess the question of the moment is: Has anyone come across similar
situations; if so, are there any ways around this.
There must be a better way around this. Any help would be greatly
appreciated.