Does anyone have an idea how to convert the C# code below? In C# the (int)OPOS_Constants.OPOS_SUCCESS returns a 0 but if I try that in the ABL it returns a 1009. The OPOS_Constants class declares all the OPOS Constants as enumerations. I have used EnumHelper in the past to compare to enum but how would I use to compare to an integer?
Sample C# Code
int nRC;
// Open the printer.
nRC = Printer.Open("Printer");
// If succeeded, then claim.
if (nRC == (int)OPOS_Constants.OPOS_SUCCESS)
Sample ABL Code
DEF VAR iReturnCode AS INTEGER NO-UNDO.
iReturnCode = oPrinter:
/* If succeeded, then claim. */
IF iReturnCode = INTEGER (OPOS_Constants:OPOS_SUCCESS) THEN
Open("Printer").1009 sounds a lot like the ABL is interpreting it an a pseudo widget handle.
IF iReturnCode = INTEGER (OPOS_Constants:OPOS_SUCCESS) THEN
Try INTEGER (UNBOX (OPOS_Constants:OPOS_SUCCESS))
or
UNBOX (OPOS_Constants:OPOS_SUCCESS)
I did try that but progress does not like it. I get a syntax error:
The argument to UNBOX must be a class of type System.Object or be a .NET array object. (14690)
Roger Blanchard
I've worked with the Microsoft POS SDK before, but I never needs that class.
How does that property/enum look like in the Class browser? Or do you have a Microsoft reference at hand? Some enum members may actually have a value.
From the Class Browser it has the following info.
PUBLIC VARIABLE OPOS_SUCCESS AS POS.Devices.OPOS_Constants
Member of POS.Devices.OPOS_Constants
Summary:
For the OPOS_Constants class.
CLASS OPOS_Constants FINAL :
Member of POS.Devices
Inherits System.Enum
Implements System.IComparable, System.IFormattable, System.IConvertible
Summary:
ABL Syntax:
USING
USING POS.Devices.OPOS_Constants.
DEFINE VARIABLE class1 AS CLASS OPOS_Constants.
class1 = NEW OPOS_Constants().
DEFINE
DEFINE VARIABLE class1 AS CLASS POS.Devices.OPOS_Constants.
class1 = NEW POS.Devices.OPOS_Constants().
Roger Blanchard
If you look at the IConvertible interface which OPOS_Constants implements it has conversion methods like ToInt( ). Try
iReturnCode = oPrinter:Open("Printer").
/* If succeeded, then claim. */
IF iReturnCode = OPOS_Constants:OPOS_SUCCESS:ToInt( ) THEN ...
I did not try it but I think it should do what you are looking for.
FYI: When you called INTEGER (OPOS_Constants:OPOS_SUCCESS)you are asking for an integer representation of the objRef. Under the covers the objRef calls ToString( ) to by default returns a pointer value for the object.
-Shelley
Well I tried OPOS_Constants:OPOS_SUCCESS:ToInt() and received the syntax error:
Could not locate element ‘ToInt’ in class ‘POS.Devices.OPOS_Constants’. (12927)
Roger Blanchard
My mistake. The method is Actually ToInt32( ). You can look at System.IConvertible in the Class Browser for the methods on the interface.
-Shelley
Actually it's the OPOS_Constants class that implements IConvertible.
-Shelley
The code below works for me in 10.2B04 - it's pretty close to what Shelley suggested.
using POS.Devices.OPOS_Constants.
DEF VAR iReturnCode AS INTEGER NO-UNDO.
DEF VAR iSuccessEnumValue as integer.
iSuccessEnumValue = System.Convert:ToInt32(OPOS_Constants:OPOS_SUCCESS).
iReturnCode = Printer:Open("myPrinter").
/* If succeeded, then claim. */
IF iReturnCode eq iSuccessEnumValue then
Open("Printer").
Well, the Enum bits anyway. I couldn't get the Printer bit to compile, but I figured you'd already got that working.
Got lots of help from http://msdn.microsoft.com/en-us/library/system.enum.aspx and the DLLs from http://monroecs.com/posfordotnet/opos_dotnet.htm .
-- peter
Thanks Shelley!!
Roger Blanchard
It was actually Peter Judge that figured it out.
Thanks to Peter!!
Thanks for the sample Peter, I now have it working. I do have a follow up question though. In your sample you converted the OPOS_SUCCESS at the top of the program using:
iSuccessEnumValue = System.Convert:ToInt32(OPOS_Constants:OPOS_SUCCESS).
Is there a benefit to that over what I have below? The reason I ask is there are hundreds of CONSTANTS and it would be easier to do as I did instead of having to convert each one.
iReturnCode = oPrinter:Open(THIS-OBJECT:PrinterName).
IF iReturnCode = System.Convert:ToInt32(OPOS_Constants:OPOS_SUCCESS) THEN
Roger Blanchard
Mike,
Thanks for the help as well.
Roger Blanchard
Is there a benefit to that over what I have below? The reason I ask is there
are hundreds of CONSTANTS and it would be easier to do as I did instead of
having to convert each one.
The main reason I would think would be that you'd probably get a performance benefit from working with a stored-in-a-variable value rather havin to make a System.Convert:ToINt32() call every time, which would be relative expensive.
Are you checking each of the 100's of members each time, or just a few per method? I think I'd have a variable for those that I use in a particular method. If you need all bajillion of them in multiple places, it might be useful to store the integer values in a TT, but I would strongly recommend testing the relative performance of all these approaches. I can imagine that in a POS system, time really is money
using POS.Devices.OPOSPOSPrinterClass.
using Progress.Util.*.
def var oValues as System.Array.
def var iEnumValue as int .
def var oEnum as POS.Devices.OPOS_Constants.
def var oType as System.Type.
def var i as int.
oType = Progress.Util.TypeHelper:GetType('POS.Devices.OPOS_Constants').
oValues = System.Enum:GetValues(oType).
do i = 0 to oValues:Length - 1:
oEnum = cast(oValues:GetValue(i), OPOS_Constants).
/* create tt, add values */
end.
-- peter
Thanks peter. I will test each approach.
Peter,
Your insight would be great on this as well.
C# Code
// Wire the StatusUpdateEvent to the class.
_IOPOSPOSPrinterEvents_StatusUpdateEventEventHandler SUEH = new _IOPOSPOSPrinterEvents_StatusUpdateEventEventHandler(PrinterStatusUpdateHandler );
Printer.StatusUpdateEvent += SUEH;
ABL Code?
DEFINE
PRIVATE PROPERTY oStatusUpdateEventHandler AS POS.Devices._IOPOSPOSPrinterEvents_StatusUpdateEventEventHandler NO-UNDO GET.SET.oStatusUpdateEventHandler =
The above NEW chokes with mismatched number of parameters. If you look at the Class Browser for the StatusUpdateEventHandler it shows the following but the C# sample only passes one parameter.
CONSTRUCTOR PUBLIC FINAL _IOPOSPOSPrinterEvents_StatusUpdateEventEventHandler (p1 AS CLASS System.Object, p2 AS CLASS System.UIntPtr)
Member of POS.Devices._IOPOSPOSPrinterEvents_StatusUpdateEventEventHandler
Summary:
When the delegate would follow the standard .NET event signature (sender as System.Object, e as System.EventArgs derived type) it would be a :EventName:Subscribe (EventhandlerMethod)
http://msdn.microsoft.com/en-US/library/ms852896(v=WinEmbedded.10).aspx#Y66
public delegate void StatusUpdateEventHandler(
object sender,
StatusUpdateEventArgs e
);
So a normal SUBSCRIBE of the StatusUpdateEvent event to an ABL Event handling method should work.
METHOD PRIVAT VOID StatusUpdateEventHandler (sender AS System.Object, e AS Microsoft.PointOfService.StatusEventArgs)
Thanks for the sample Mike. We are not using Pos for .NET but instead OPOS for .NET...similar but different. I will give this a try and see if it will work with the OPOS for .NET.
Roger Blanchard
Mike,
This did not work using the OPOS for .NET so I tried the Microsoft POS for .NET.
I added the following to my definitions:
DEFINE PUBLIC EVENT StatusUpdateEventHandler DELEGATE Microsoft.PointOfService.StatusUpdateEventHandler.
I added this in my CONSTRUCTOR.
StatusUpdateEventHandler:Subscribe (THIS-OBJECT:MyStatusUpdateEventHandler ).
I added this as my METHOD to handle the event.
METHOD PRIVATE VOID MyStatusUpdateEventHandler (sender AS System.Object, e AS StatusUpdateEventArgs ):
MESSAGE e:EventId
VIEW-AS ALERT-BOX.
RETURN.
FINALLY:
DELETE OBJECT e NO-ERROR.
END FINALLY.
END METHOD.
Unfortunately it does not appear to work.
Roger Blanchard
DEFINE PUBLIC EVENT StatusUpdateEventHandler DELEGATE Microsoft.PointOfService.StatusUpdateEventHandler.
I though you wanted to subscribe to an event, not define a new one? What's your exact plan?
If you want to handle an event of a .NET class, use
:StatusUpdateEvent:Subscribe (THIS-OBEJCT:MyStatusUpdateEventhandler) .
My plan was to simply subscribe to the event of the .NET class. I think I have been looking at too many C#/VB.NET samples.
I removed the definition of the new EVENT and added the Subscribe as you suggested and it appears to work!!
THANKS FOR THE HELP!!
oExplorer = NEW Microsoft.PointOfService.PosExplorer ( ).
oDeviceCollection = oExplorer:GetDevices().
/*
DO iCnt = 0 TO (oDeviceCollection:COUNT - 1):
MESSAGE
oDeviceCollection[iCnt]:Description
oDeviceCollection[iCnt]:ManufacturerName
oDeviceCollection[iCnt]:ServiceObjectName
VIEW-AS ALERT-BOX.
END.
*/
oDeviceInfo = oExplorer:GetDevice(DeviceType:PosPrinter, THIS-OBJECT:PrinterName).
oPrinter = CAST (oExplorer:CreateInstance( THIS-OBJECT:oDeviceInfo), PosPrinter).
oPrinter:StatusUpdateEvent:Subscribe ( THIS-OBJECT:OnStatusUpdateEvent) .
Roger Blanchard