We're trying to create something like a printer driver wrapper for POS applications, that would allow us to capture the printed receipt, and then forward it again to the original printer.
So far, we implemented one as a service object on top of "POS for .Net", it worked excellent and everything, but it turned out that some legacy POS applications only support OPOS. In order to support them, we either have to make our "POS for .Net" service object available as an OPOS service object, or we have to write our own OPOS service object using the CCOs.
My questions are:
Q) In these legacy POS apps, is it even possible to use our POS for .Net solution? (if yes, how?)
A) No, these apps don’t use the POS for .Net libraries and don’t search for service objects using the POS for .Net registry keys, these apps only use the OPOS(OLE POS) registry entries to search for registered service objects, and usually call the CCO which in turn call the service object.
Q) How to build an OPOS service object? and can it be using .Net framework (C# for example)?
A) Yes it can be done using .Net, but you need to expose it as a COM library, a good way is to implement the interfaces in the CCO, there is a DLL for each device, reference the one for the device you need, implement its interface, and mark your type as COM visible, add a GUID and a ProgId, register it using the regasm “path” /register /codebase /tlb command, add the needed registry keys –can be found in the UPOS specification\development guide document- and you will be done, or that’s at least what I thought, with this you will get an error stating that there are missing methods from your service object which are needed to run it correctly, well I found this the hard way, but there is 7 methods which are not referenced in the interfaces – although are referenced in the UPOS specification\development guide document- these methods are:
After implementing these methods everything works fine, which is strange since none are referenced in the CCO interfaces, however as I said each of these is referenced in the UPOS specification and have a full description.
It seem the reason OpenService and CloseService methods exist, is that when the CCO libraries were implemented as a com the Open and Close method names were not suitable and had to be changed to OpenService and CloseService, the same apply for Claim and Release with new names ClaimDevice and Release Device – however these are exposed correctly in the interfaces, as for the rest of the methods I couldn’t find a reason.
Get\Set Property Methods
These 4 methods are used to access all the properties in your object, why? I am not sure, but it seems these should be used from the Dispatch interface to access your object, why is that interface not available by default? Are C++ service objects implemented in the same way? I don’t have an answer.
To implement these in a correct way, one should look at the Include directory under the OPOS installation – CCO installation - and check the *.hi files, mainly Opos.hi and OposPtr.hi(depends on the device, in our case printer), you will see that these include constants for CCO, like the success or failure enums, and for those 4 methods the properties index and the device index offset.
With the use of the numbers from the OPOS constants you only need to switch on the PropIndex parameter value, and get\set the correct property value.
if (PropertyIndexHelper.IsStringPidx(PropIndex))
{
switch (PropIndex)
{
case PropertyIndexHelper.PIDX_CheckHealthText:
return _physicalPrinter.CheckHealthText;
case PropertyIndexHelper.PIDX_DeviceDescription:
return _physicalPrinter.DeviceDescription;
case PropertyIndexHelper.PIDX_DeviceName:
return _physicalPrinter.DeviceName;
.
.
.
.
.