lowlevel
asked on
SETs in COM
In an OLE automation object, I'd like to include a property that
behaves like a set. But how do I do this? I guess an interfaced enum,
but code like this won't compile:
options:=[RASEO_TerminalBe foreDial, RASEO_IpHeaderCompression] ;
options being an interfaced enum, with both values in the "set" actual
values that belong to the enum.
How do I get this to work?
behaves like a set. But how do I do this? I guess an interfaced enum,
but code like this won't compile:
options:=[RASEO_TerminalBe
options being an interfaced enum, with both values in the "set" actual
values that belong to the enum.
How do I get this to work?
This is the equivalent to a set...check out Windows.pas...This is how Windows does sets...
IDX_Prop1 = 1; //$00000001 000000001
IDX_Prop2 = 2; //$00000002 000000010
IDX_Prop3 = 4; //$00000004 000000100
IDX_Prop4 = 8; //$00000008 000001000
IDX_Prop5 = 16; //$00000010 000010000
IDX_Prop6 = 32; //$00000020 000100000
IDX_Prop7 = 64; //$00000040 001000000
IDX_Prop8 = 128;//$00000080 010000000
IDX_Prop9 = 256;//$00000100; 100000000
.
Just change everything to a constant...
Rick
IDX_Prop1 = 1; //$00000001 000000001
IDX_Prop2 = 2; //$00000002 000000010
IDX_Prop3 = 4; //$00000004 000000100
IDX_Prop4 = 8; //$00000008 000001000
IDX_Prop5 = 16; //$00000010 000010000
IDX_Prop6 = 32; //$00000020 000100000
IDX_Prop7 = 64; //$00000040 001000000
IDX_Prop8 = 128;//$00000080 010000000
IDX_Prop9 = 256;//$00000100; 100000000
.
Just change everything to a constant...
Rick
Here's an example...
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
const
IDX_Prop1 = 1; //$00000001 000000001
IDX_Prop2 = 2; //$00000002 000000010
IDX_Prop3 = 4; //$00000004 000000100
IDX_Prop4 = 8; //$00000008 000001000
IDX_Prop5 = 16; //$00000010 000010000
IDX_Prop6 = 32; //$00000020 000100000
IDX_Prop7 = 64; //$00000040 001000000
IDX_Prop8 = 128;//$00000080 010000000
IDX_Prop9 = 256;//$00000100; 100000000
type
TEnumProp = (Prop1, Prop2, Prop3, Prop4, Prop5, Prop6, Prop7, Prop8, Prop9);
TEnumPropSet = set of TEnumProp;
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
FEnumPropSet: TEnumPropSet;
protected
function GetEnumProp: integer;
public
{ Public declarations }
property EnumPropSet: TEnumPropSet read FEnumPropSet write FEnumPropSet;
property EnumPropValue: integer read GetEnumProp;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function TForm1.GetEnumProp: integer;
begin
result := 0;
if Prop1 in EnumPropSet then
Result := IDX_Prop1;
if Prop2 in EnumPropSet then
Result := Result + IDX_Prop2;
if Prop3 in EnumPropSet then
Result := Result + IDX_Prop3;
if Prop4 in EnumPropSet then
Result := Result + IDX_Prop4;
if Prop5 in EnumPropSet then
Result := Result + IDX_Prop5;
if Prop6 in EnumPropSet then
Result := Result + IDX_Prop6;
if Prop7 in EnumPropSet then
Result := Result + IDX_Prop8;
if Prop8 in EnumPropSet then
Result := Result + IDX_Prop8;
if Prop9 in EnumPropSet then
Result := Result + IDX_Prop9;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
EnumPropSet := [Prop1, Prop4, Prop5];
end;
procedure TForm1.Button1Click(Sender : TObject);
begin
Label1.Caption := IntToStr(EnumPropValue);
end;
end.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
const
IDX_Prop1 = 1; //$00000001 000000001
IDX_Prop2 = 2; //$00000002 000000010
IDX_Prop3 = 4; //$00000004 000000100
IDX_Prop4 = 8; //$00000008 000001000
IDX_Prop5 = 16; //$00000010 000010000
IDX_Prop6 = 32; //$00000020 000100000
IDX_Prop7 = 64; //$00000040 001000000
IDX_Prop8 = 128;//$00000080 010000000
IDX_Prop9 = 256;//$00000100; 100000000
type
TEnumProp = (Prop1, Prop2, Prop3, Prop4, Prop5, Prop6, Prop7, Prop8, Prop9);
TEnumPropSet = set of TEnumProp;
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
FEnumPropSet: TEnumPropSet;
protected
function GetEnumProp: integer;
public
{ Public declarations }
property EnumPropSet: TEnumPropSet read FEnumPropSet write FEnumPropSet;
property EnumPropValue: integer read GetEnumProp;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function TForm1.GetEnumProp: integer;
begin
result := 0;
if Prop1 in EnumPropSet then
Result := IDX_Prop1;
if Prop2 in EnumPropSet then
Result := Result + IDX_Prop2;
if Prop3 in EnumPropSet then
Result := Result + IDX_Prop3;
if Prop4 in EnumPropSet then
Result := Result + IDX_Prop4;
if Prop5 in EnumPropSet then
Result := Result + IDX_Prop5;
if Prop6 in EnumPropSet then
Result := Result + IDX_Prop6;
if Prop7 in EnumPropSet then
Result := Result + IDX_Prop8;
if Prop8 in EnumPropSet then
Result := Result + IDX_Prop8;
if Prop9 in EnumPropSet then
Result := Result + IDX_Prop9;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
EnumPropSet := [Prop1, Prop4, Prop5];
end;
procedure TForm1.Button1Click(Sender
begin
Label1.Caption := IntToStr(EnumPropValue);
end;
end.
opps... forgot the set value...
property EnumPropValue: integer read GetEnumProp write SetEnumProp;
procedure TForm1.SetEnumProp(value: integer);
begin
FEnumPropSet := [];
if (Value and IDX_Prop1)=IDX_Prop1 then
FEnumPropSet:= FEnumPropSet+ [Prop1];
if Value and IDX_Prop2= IDX_Prop2 then
FEnumPropSet:= FEnumPropSet+ [Prop2];
if Value and IDX_Prop3= IDX_Prop3 then
FEnumPropSet:= FEnumPropSet+ [Prop3];
if Value and IDX_Prop4= IDX_Prop4 then
FEnumPropSet:= FEnumPropSet+ [Prop4];
if Value and IDX_Prop5= IDX_Prop5 then
FEnumPropSet:= FEnumPropSet+ [Prop5];
if Value and IDX_Prop6= IDX_Prop6 then
FEnumPropSet:= FEnumPropSet+ [Prop6];
if Value and IDX_Prop7= IDX_Prop7 then
FEnumPropSet:= FEnumPropSet+ [Prop7];
if Value and IDX_Prop8= IDX_Prop8 then
FEnumPropSet:= FEnumPropSet+ [Prop8];
if Value and IDX_Prop9= IDX_Prop9 then
FEnumPropSet:= FEnumPropSet+ [Prop9];
end;
property EnumPropValue: integer read GetEnumProp write SetEnumProp;
procedure TForm1.SetEnumProp(value: integer);
begin
FEnumPropSet := [];
if (Value and IDX_Prop1)=IDX_Prop1 then
FEnumPropSet:= FEnumPropSet+ [Prop1];
if Value and IDX_Prop2= IDX_Prop2 then
FEnumPropSet:= FEnumPropSet+ [Prop2];
if Value and IDX_Prop3= IDX_Prop3 then
FEnumPropSet:= FEnumPropSet+ [Prop3];
if Value and IDX_Prop4= IDX_Prop4 then
FEnumPropSet:= FEnumPropSet+ [Prop4];
if Value and IDX_Prop5= IDX_Prop5 then
FEnumPropSet:= FEnumPropSet+ [Prop5];
if Value and IDX_Prop6= IDX_Prop6 then
FEnumPropSet:= FEnumPropSet+ [Prop6];
if Value and IDX_Prop7= IDX_Prop7 then
FEnumPropSet:= FEnumPropSet+ [Prop7];
if Value and IDX_Prop8= IDX_Prop8 then
FEnumPropSet:= FEnumPropSet+ [Prop8];
if Value and IDX_Prop9= IDX_Prop9 then
FEnumPropSet:= FEnumPropSet+ [Prop9];
end;
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
LowLevel...
Have you tried this out???Any problems???Any questions?
Rick
Have you tried this out???Any problems???Any questions?
Rick
ASKER
I have looked into it, but need more time (very busy here lately)..
I'll try to get it sorted this week.
I'll try to get it sorted this week.
ASKER
checked it, it works :)
still sucks that it isn't supported by COM, and that there isn't a language feature for it (xEnumValue in xEnum)..
but at least this works :)
still sucks that it isn't supported by COM, and that there isn't a language feature for it (xEnumValue in xEnum)..
but at least this works :)
LowLevel...
aww...but there is...
if xEnumValue and xEnum(xSet) then
works the same
as
if xEnumValue in xEnum(xSet) then
if you AND a value against another value it will return true if the value is part of the value...
example
if true and true then //true
bit pattern:
01 and 01 = 01
if true and false then //false
bit pattern:
01 and 00 = 00
if enum2+enum4 in [1,2,4] then//true
bit pattern:
001010 and 001011 = true (001010)
So you see Sets are just a more intuitive process when doing Bitwise manipulation...
Rick
aww...but there is...
if xEnumValue and xEnum(xSet) then
works the same
as
if xEnumValue in xEnum(xSet) then
if you AND a value against another value it will return true if the value is part of the value...
example
if true and true then //true
bit pattern:
01 and 01 = 01
if true and false then //false
bit pattern:
01 and 00 = 00
if enum2+enum4 in [1,2,4] then//true
bit pattern:
001010 and 001011 = true (001010)
So you see Sets are just a more intuitive process when doing Bitwise manipulation...
Rick
ASKER
oh, i knew all that :)
it's just that I'd like a "nice" language feature that allows me to evaluate "if enumvalue in enumtype then blah" as a boolean.
but i guess i can write a function around that...
it's just that I'd like a "nice" language feature that allows me to evaluate "if enumvalue in enumtype then blah" as a boolean.
but i guess i can write a function around that...
Normally, you will have to provide an enumeration procedure that steps through the members of the set.
For enumerated types, use the type TOLEEnum to be automation compatible.
Slash/d003303