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:
- COFreezeEvents: Same as the property FreezeEvents.
- GetPropertyNumber: Used to get the value of a numeric\Boolean property by the property’s index, more on that later.
- SetPropertyNumber: Used to set the value of a numeric\Boolean property by the property’s index, more on that later.
- GetPropertyString: Used to get the value of a string property by the property’s index, more on that later.
- SetPropertyString: Used to set the value of a string property by the property’s index, more on that later.
- OpenService: Same as the method open.
- CloseService: Same as the method close.
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;
.
.
.
.
.