Hi Jose,
I hope you are reading this because I'm a little stuck.
First off thank you VERY much for everything you've done for the community. All your hard work is very much appreciated. Perhaps there is some way I could buy you a beer over PayPal or something ;)
Ok here's my issue...
1. I have a base class "CLayer"
2. I also have some other classes "CBackground", "CBorder", etc... (these INHERIT CLayer, ILayer)
How can I make an array of generic interfaces that can, at run time, be set to any one of my other classes "CBackground", "CBorder"
Here's what I would like to do in code...
#COMPILER PBCC
#COMPILE EXE
#DIM ALL
CLASS CBackground
INSTANCE dwColor AS DWORD
INTERFACE IBackground:INHERIT CLayer, ILayer
END INTERFACE
END CLASS
CLASS CBorder
INSTANCE dwColor AS DWORD
INSTANCE dWidth AS DOUBLE
INSTANCE lStyle AS LONG
INTERFACE IBorder:INHERIT CLayer, ILayer
END INTERFACE
END CLASS
CLASS CLayer
INSTANCE szName AS STRING
INTERFACE ILayer:INHERIT IUNKNOWN
END INTERFACE
END CLASS
FUNCTION PBMAIN () AS LONG
DIM Layer(2) AS IUNKNOWN
Layer(0) = CLASS "CLayer"
Layer(1) = CLASS "CBackground"
Layer(2) = CLASS "CBorder"
STDOUT"Press ANY key to continue."
WAITKEY$
END FUNCTION
I guess this would be like using a UNION but I'm not sure how to go about doing this.
Thanks!
Forgive me for stepping in here and José can correct me if I am wrong.
There is really no Pb supported documented way to create generic cases. You do have a couple alternatives; Containment or the POKE .AddRef method.
Containment is where you create the Class you want inside the now derived class instead of inheriting from it.
The other is detailed in my example code on PowerBASIC web site.
I'll post a couple of examples later if wanted?
James
I think this is backward of what you wanted but it may give you some ideas??
James
#COMPILER PBCC
#COMPILE EXE
#DIM ALL
CLASS cBackground
INSTANCE dwColor AS DWORD
INTERFACE iBackground : INHERIT IUNKNOWN
PROPERTY GET dwColor() AS DWORD
PROPERTY = dwColor
END PROPERTY
PROPERTY SET dwColor(BYVAL Param AS DWORD)
dwColor = Param
END PROPERTY
END INTERFACE
END CLASS
CLASS cBorder
INSTANCE dwColor AS DWORD
INSTANCE dwWindth AS DOUBLE
INSTANCE lStyle AS LONG
INTERFACE iBorder : INHERIT IUNKNOWN
PROPERTY GET dwColor() AS DWORD
PROPERTY = dwColor
END PROPERTY
PROPERTY SET dwColor(BYVAL Param AS DWORD)
dwColor = Param
END PROPERTY
END INTERFACE
END CLASS
' Init in CLASS METHOD Create so don't use as a base class
CLASS cLayer
INSTANCE szName AS STRING
INSTANCE oBackground AS iBackGround
INSTANCE oBorder AS iBorder
CLASS METHOD CREATE
oBackground = CLASS "cBackground"
oBorder = CLASS "cBorder"
END METHOD
INTERFACE iLayer : INHERIT IUNKNOWN
PROPERTY GET Background() AS iBackground
PROPERTY = oBackground
END PROPERTY
PROPERTY GET BORDER() AS iBorder
PROPERTY = oBorder
END PROPERTY
END INTERFACE
END CLASS
FUNCTION PBMAIN () AS LONG
REDIM oLayer(2) AS iLayer
LOCAL oBorder AS iBorder
LOCAL dwColor AS DWORD
oLayer(0) = CLASS "cLayer"
IF ISNOTHING(oLayer(0)) THEN
PRINT " No oLayer(0)"
END IF
oLayer(1) = CLASS "cLayer"
oLayer(2) = CLASS "cLayer"
oLayer(0).Border.dwColor = &HC0C0C0
dwColor = oLayer(0).Border.dwColor
PRINT "dwColor = ";dwColor
WAITKEY$
END FUNCTION
Hi James,
Thanks for stepping in!
More examples are always appreciated, if you have time ;)
Here is how I was doing this before objects...
#COMPILE EXE
#DIM ALL
TYPE LAYER_BACKGROUND
dwColor AS DWORD
END TYPE
TYPE LAYER_BORDER
dwColor AS DWORD
dWidth AS DOUBLE
lStyle AS LONG
END TYPE
UNION LAYER_UNION
mBackground AS LAYER_BACKGROUND
mBorder AS LAYER_BORDER
END UNION
TYPE LAYER
szName AS ASCIIZ * 256
lType AS LONG '0 = Undefined, 1 = Background, 2 = Border
LAYER_UNION
END TYPE
FUNCTION PBMAIN () AS LONG
DIM Layer(1) AS LAYER
Layer(0).szName = "Background"
Layer(0).lType = 1
Layer(0).mBackground.dwColor = RGB(255, 255, 255)
Layer(1).szName = "Border"
Layer(1).lType = 2
Layer(1).mBorder.dwColor = RGB(255, 255, 255)
Layer(1).mBorder.dWidth = 1
Layer(1).mBorder.lStyle = 0
END FUNCTION
Hey James,
So if I understand correctly, what you have done there is a compound object reference?
1. I make a base layer class
2. Inside the base class I have variables/instances for each layer type (background, border, etc...)
3. Use compound object reference to get to each layer type
Yes you understand correctly but I'm not sure this is a good candidate for an object?
I haven't had a chance to look at your last code closely.
James
Hey James,
Well the code I posted wasn't the full "Object". The entire project I think will benefit from objects.
The software I've been writing is a CAD package for geologists.
The same drawing engine is used in multiple places/programs.
Well.Canvas.OpenGL
Well.Canvas.DirectX
Well.Canvas.PDF
Well.Canvas.GDI
Well.Chart(Index).Track(Index).Layer(Index)
Well.DataSource.Cache
Well.DataSource
Well.SecureData
These objects seem to be a great way to write it all once and reuse them for the CAD, Server and Viewer software.
This is the way I would attack it with the code you posted:
James
#COMPILER PBCC
#COMPILE EXE
#DIM ALL
%LAYERBACKGROUND = 1
%LAYERBORDER = 2
%LAYERERROR = -1
CLASS cLayer
INSTANCE sName AS STRING
INSTANCE dwColor AS DWORD
INSTANCE dWidth AS DOUBLE
INSTANCE lType,lStyle AS LONG
INTERFACE iLayer : INHERIT IUNKNOWN
PROPERTY GET TYPE() AS LONG
PROPERTY = lType
END PROPERTY
PROPERTY SET TYPE(BYVAL Param AS LONG)
lType = Param
END PROPERTY
PROPERTY GET COLOR() AS DWORD
PROPERTY = dwColor
END PROPERTY
PROPERTY SET COLOR(BYVAL Param AS DWORD)
dwColor = Param
END PROPERTY
PROPERTY GET WIDTH() AS DOUBLE
IF lType = %LAYERBORDER THEN
PROPERTY = dWidth
ELSE
PROPERTY = %LAYERERROR
END IF
END PROPERTY
PROPERTY SET WIDTH(BYVAL Param AS DOUBLE)
dWidth = Param
END PROPERTY
PROPERTY GET STYLE() AS LONG
IF lType = %LAYERBORDER THEN
PROPERTY = lStyle
ELSE
PROPERTY = %LAYERERROR
END IF
END PROPERTY
PROPERTY SET STYLE(BYVAL Param AS LONG)
lStyle = Param
END PROPERTY
PROPERTY GET NAME() AS STRING
PROPERTY = sName
END PROPERTY
PROPERTY SET NAME(BYVAL Param AS STRING)
sName = Param
END PROPERTY
END INTERFACE
END CLASS
FUNCTION PBMAIN () AS LONG
REDIM oLayer(2) AS iLayer
LOCAL dwColor AS DWORD
LOCAL dWidth AS DOUBLE
oLayer(0) = CLASS "cLayer"
IF ISNOTHING(oLayer(0)) THEN
PRINT " No oLayer(0)"
END IF
oLayer(1) = CLASS "cLayer"
IF ISNOTHING(oLayer(1)) THEN
PRINT " No oLayer(1)"
END IF
oLayer(0).NAME = "Background"
oLayer(0).TYPE = 1
oLayer(0).COLOR = RGB(255, 255, 255)
oLayer(1).NAME = "Border"
oLayer(1).TYPE = 2
oLayer(1).COLOR = RGB(255, 255, 255)
oLayer(1).WIDTH = 1
oLayer(1).STYLE = 0
dwColor = oLayer(1).COLOR
?"DwColor = ";dwColor
dWidth = oLayer(0).WIDTH
IF dWidth = %LAYERERROR THEN
? "Not A Border Layer"
ELSE
?"Border Width = ";dWidth
END IF
dWidth = oLayer(1).WIDTH
IF dWidth = %LAYERERROR THEN
? "Not A Border Layer"
ELSE
?"Border Width = ";dWidth
END IF
WAITKEY$
END FUNCTION
Quote
Forgive me for stepping in here and José can correct me if I am wrong.
Don't be afraid in stepping in. I have expertise in COM programming, but OOP is new to me. We have got the same compiler, but we are using it for different purposes.