一个自动服务程序说明属性和方法程序如何在其他具有自动特性的应用程序中进行设置和调用。
要创建一个自动服务程序,您需要做到:
可以在本地或远程调用一个自动服务程序,通过方法程序的调用或者设置属性来实现商务功能。
这是一个 Pool Manager 示例,它在一个自定义的 OLE Server 中实现。一个客户端可以向 Pool Manager 发送作业(Pool Manager 可以位于一个远程计算机上),并让 Pool Manager 处理作业的执行过程。由于 Pool Manager 的资源处理作业的执行,所以您可以继续执行自己的工作。本示例的作业都是虚设的模拟作业。
若要打开 Pool Manager 示例的项目
MODIFY PROJECT (HOME(2) + 'servers\poolmgr\pool')
若要运行 Pool Manager 示例
当运行 Pool 表单时,首先要执行的代码是 Init 事件,此事件创建一个 poolmgr 对象:
* Pool Init
SET PROC TO jobmgr.prg
THIS.oPoolMgr = CreateObject('Pool.Poolmgr')
当创建 oPoolMgr 对象时,会定义一个数组来跟踪作业,同时创建一个计时器对象。这个计时器对象基于 PoolTimer 类的基础上,用来检查新作业和已完成的作业。
当用户在 pool 表单上选择“Print”、“Fax”或者“Excel Chart”按钮时,会调用 AddJob 方法程序。AddJob 执行如下的操作:
PARAMETER cJobType
LOCAL oNewJobRef
IF ALEN(THIS.aJobs)>1 OR TYPE('THIS.aJobs[1]') = 'O'
DIMENSION THIS.aJobs[ALEN(THIS.aJobs)+1]
ENDIF
oNewJobRef = CreateObject(m.cJobType,THIS)
THIS.oPoolMgr.NewJob(m.oNewJobRef)
PoolMgr 对象的 NewJob 方法程序重新定义两个 PoolMgr 作业数组,并将对作业对象的参数存储在新行的第一个元素里,将 0 存储在第二个元素里,表明这是一个新的作业。
PARAMETER oNewJob
IF TYPE('oNewJob') # 'O' OR ISNULL(m.oNewJob)
RETURN .F.
ENDIF
IF ALEN(THIS.aJobObjs,1) > 1 ;
OR ISNULL(THIS.aJobObjs[1])
DIMENSION THIS.aJobObjs[ALEN(THIS.aJobObjs,1)+1,2]
ENDIF
THIS.aJobObjs[ALEN(THIS.aJobObjs,1),1] = oNewJob
THIS.aJobObjs[ALEN(THIS.aJobObjs,1),2] = 0
每隔三秒钟,会执行 PoolTimer 的 timer 事件代码。此代码在这个作业数组中进行循环。如果第二个参数是 0,表明这是一个新的作业,然后创建一个新的PrintJob, FaxJob 或 GraphJob 对象(poolmgr.prg 文件中 Job 的一个子类)来管理作业。例如,下面的代码行在 PrintJob 的基础上创建一个对象,并将对它的引用存储在 timer 的 aJobs 数组中:
THIS.aJobs[ALEN(THIS.aJobs)] = CREATEOBJECT('Pool.PrintJob')
然后,将此数组中针对该行的第二个元素设置为 1,表明已经开始了该作业,再调用这个新对象的 SetupJob 方法程序。对此作业对象的参数会传递给 SetupJob 方法程序:
THIS.aJobs[ALEN(THIS.aJobs)].SetupJob(THIS.Parent.aJobObjs[m.i,1])
在 Poolmgr.prg 文件中定义 Job 类:
DEFINE CLASS Job AS FORM
当在 Job 类或其他任意的 Job 子类基础上创建对象时,该对象的 StartJob 方法程序被调用:
PROCEDURE SetupJob
PARAMETER oJob
THIS.oJob = m.oJob
THIS.Caption = THIS.oJob.Jobtype
THIS.Visible = .T.
ENDPROC
例如,PrintJob 类是 Job 类的一个子类。如果该对象是在 PrintJob 基础上创建,StartJob 方法程序会执行父类 StartJob 方法程序的默认过程,将设置表单的标题,并显示一个标签。然后,调用 INKEY( ) 函数将时间暂停设置为 10 秒。在本示例的功能实现时,没有使用 INKEY( ) 函数,而在此处通过编写代码来处理打印作业。
DEFINE CLASS PrintJob AS Job OLEPublic
PROCEDURE StartJob
DoDefault()
=INKEY(10)
THIS.EndJob()
ENDPROC
ENDDEFINE
该对象的 EndJob 方法程序调用了原来作业对象的 JobDone 方法程序,并释放了 PrintJob、FaxJob 或者 GraphJob 对象。
PROCEDURE EndJob
THIS.lbl1.caption = 'Ending job...'
THIS.oJob.JobDone()
THIS.oJob = .null.
THIS.Visible = .F.
THISFORM.Release
ENDPROC
在原始作业对象的 JobDone 方法程序中的代码,通过调用表单的 JobDone 方法程序,提示表单作业已经完成。
PROCEDURE jobdone
IF TYPE('THIS.oFormRef')='O'
THIS.oFormRef.JobDone(THIS.JobType)
ENDIF
ENDPROC
最后,表单的 JobDone 方法程序在表单上的列表框中显示作业的状态:
PARAMETER cJob
THIS.lstJobs.AddItem(m.cJob+' job is complete.')
Job 对象(基于在 JOBMGR.prg 文件中定义的 PrintJob、FaxJob 或者 GraphJob 类):