朱仙生 發表於 2021-8-16 15:29:00

Delphi遍历枚举

<p>------Delphi7<br>--这里只对正常情况下的枚举举例子,Delphi正常情况下的枚举类型占用一个字节,<br>C中的枚举不是占一个字节,C可能要用到Delphi的枚举,所以Delphi用编译指令可以把枚举类型的大小改变,也可能占用2字节、4字节</p>
<p>请参考:https://bbs.csdn.net/topics/320097250?list=10622938<br>type<br>{$Z+}// 4字节</p>
<p>TMyEnum = (.....);</p>
<p>{$Z-} // 还原1字节</p>
<p>{$A4} // 4字节对其</p>
<p>TMyRecord = record<br>.....<br>end;</p>
<p>{$A-} //还原</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><br>需要引用:TypInfo单元</p>
<p>!(https://img2020.cnblogs.com/blog/811422/202108/811422-20210826175552368-248041904.png)</p>
<p><br>-----------------<br>--Unit开始--<br>unit Unit1;</p>
<p>interface</p>
<p>uses<br>Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>Dialogs, StdCtrls, TypInfo;</p>
<p>type<br>TForm1 = class(TForm)<br>    Memo1: TMemo;<br>    Button1: TButton;<br>    procedure Button1Click(Sender: TObject);<br>private<br>    { Private declarations }<br>public<br>    { Public declarations }<br>end;</p>
<p>EMyEnum=(AA,BB,CC,DD,EE,FF);//声明枚举<br>var<br>Form1: TForm1;</p>
<p>implementation</p>
<p><br>{$R *.dfm}</p>
<p>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>vEnumStr:string;<br>venum:EMyEnum;<br>vP:PTypeInfo;<br>i:Integer;<br>begin<br>Memo1.Clear;<br>//遍历枚举<br>vP:=TypeInfo(EMyEnum);<br>for venum:=Low(EMyEnum) to High(EMyEnum) do<br>begin<br>    vEnumStr:=GetEnumName(vP,Byte(venum));//枚举最多256个元素,因为只占一个字节,为此猜测Byte(venum)可以得到下标<br>    Memo1.Lines.Add(vEnumStr);<br>end;<br><br>//测试别的<br>Memo1.Lines.Add('-----------------');<br>i:=GetEnumValue(vp,'CC');<br>Memo1.Lines.Add(IntToStr(i));<br>if EMyEnum(i)=CC then<br>    Memo1.Lines.Add('CC');<br>end;</p>
<p>end.</p>
<p><br>--Unit结束</p>
<p>-----Form开始------<br>object Form1: TForm1<br>Left = 498<br>Top = 418<br>BorderStyle = bsDialog<br>Caption = 'Form1'<br>ClientHeight = 327<br>ClientWidth = 218<br>Color = clBtnFace<br>Font.Charset = DEFAULT_CHARSET<br>Font.Color = clWindowText<br>Font.Height = -11<br>Font.Name = 'MS Sans Serif'<br>Font.Style = []<br>OldCreateOrder = False<br>PixelsPerInch = 96<br>TextHeight = 13<br>object Memo1: TMemo<br>    Left = 8<br>    Top = 8<br>    Width = 185<br>    Height = 225<br>    ImeName = '中文(简体) - 搜狗拼音输入法'<br>    TabOrder = 0<br>end<br>object Button1: TButton<br>    Left = 72<br>    Top = 264<br>    Width = 75<br>    Height = 25<br>    Caption = 'Button1'<br>    TabOrder = 1<br>    OnClick = Button1Click<br>end<br>end<br>-----Form结束-----</p>
<p>&nbsp;</p>
<p>---------------------------------------------------其他资料---------------------------------------------<br>来源:Delphi整理五(枚举、子界、集合)http://www.delphitop.com/html/jichu/3345.html<br>枚举、子界与集合</p>
<p>枚举</p>
<p>type<br>&lt;类型名称&gt;=(&lt;标识符1&gt;,&lt;标识符2&gt;...&lt;标识符n&gt;);<br>1<br>2<br>1)类型名称:自定义枚举类型名称 <br>2)标识符:常量元素,个数有限 <br>3)一个枚举类型中,枚举常量不允许重复出现,也不允许同一枚举出现在不同类型中 <br>例如,自动以7个常量的枚举类型</p>
<p>Type<br>Weekday=(Sun,Mon,Tue,Wed,Thu,Fri,Sat)   <br>1<br>2<br>枚举规则:先定义类型在定义变量</p>
<p>varw1,w2,w3:weekday;<br>   a,b,c:integer;<br>1<br>2<br>枚举运算:</p>
<p>1)用pred函数求枚举值的前导。pred(mon)的值为sun,sun没有前导 <br>2)用succ函数求枚举值的后继。succ(sun)的值为mon,sat没有后继 <br>3)用ord函数求枚举值的序号。ord(sun)为0 <br>4)用low函数得第一个枚举值。low(weekday)的值为sun.low(w1)和low(w2)也为sun <br>5)用high函数求最后一个枚举值 <br>6)使用关系运算符比较枚举值的大小。sun&gt;mon的值为false;tue&gt;=sun的值为true。</p>
<p>子界类型</p>
<p>type<br>&lt;类型名称&gt;=&lt;常量1&gt;...&lt;常量2&gt;;<br>1<br>2<br>1)&lt;类型名称&gt;是子界类型的名称。 <br>2)&lt;常量1&gt;是子界的下界,&lt;常量2&gt;是子界类型的上界,之间为相同的有序类型(同为整型或同为字符型) <br>3)子界的上界大于或者等于下界 <br>例,</p>
<p>type<br>month=1..12;<br>weekday=(sun,mon,tue,wed,thu,fri,sat);<br>workday=mon..fri;<br>1<br>2<br>3<br>4<br>子界类型变量的定义</p>
<p>规则:先定义类型,再定义变量</p>
<p>type<br>month=1..12;<br>weekday=(sun,mon,tue,wed,thu,fri,sat);<br>workday=mon..fri;<br>var<br>m1,m2:month;<br>w1,w2:workday;<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>不建议:m1,m2:1..12;</p>
<p>集合整型</p>
<p>1)集合中的元素是相异的。(不重复) <br>2)集合中的元素是没有顺序的 <br>3)集合中的元素不能超过256个</p>
<p>集合的定义:</p>
<p>type<br>&lt;类型名称&gt;=set of&lt;基类型&gt;;<br>1<br>2<br>1)&lt;类型名称&gt;是用户所定义的集合类型的名称 <br>2)&lt;基类型&gt;是集合中元素的类型,可以是字符、布尔、枚举、子界等类型,不能是整型、实型 <br>例,</p>
<p>type<br>days=set of 28..31;<br>ch=set of 'A'..'Z';<br>weekday=(sun,tue,wed,thu,fri,sat);<br>workday=set of weekday;<br>1<br>2<br>3<br>4<br>5<br>集合类型变量的定义:</p>
<p>先定义集合类型</p>
<p>type<br>days=set of 28..31;<br>ch=set of 'A'..'Z';<br>weekday=(sun,...,sat);<br>workday=set of weekday;<br>1<br>2<br>3<br>4<br>5<br>再定义集合类型的变量</p>
<p>var<br>ch1,ch2:ch;<br>wo1,wo2:workday;<br>d1,d2:days;<br>1<br>2<br>3<br>4<br>集合类型的取值和运算</p>
<p>集合的取值称之为集合的值。</p>
<p>type<br>weekday=(sun,mon,tue,wed,thu,fir,sat);<br>workday=set of weekday;<br>var<br>wo1,wo2:workday;<br>wo1的值可以为[]、、...<br>1<br>2<br>3<br>4<br>5<br>6<br>1)一个集合的基类型有n个值,那么集合变量的取值有2的n次方个。 <br>2)[]是空集合 <br>3)集合元素连续出现,可以写成子界形式。1..12等价于1到12</p>
<p>集合的运算</p>
<p>交、差、并运算和集合间的关系运算 <br>前者得到的集合类型或者是boolean类型 <br>1)集合的并。两个集合的所有元素组成(去掉重复的) <br>2)集合的交运算。两集合公有的 <br>3)集合的差。一个集合去掉公有的 []()<br>4)相等运算返回false or true <br>5)不相等运算(&lt;&gt;)返回false or true <br>6)包含运算。后者有的前者全有都有(&gt;=)false or true <br>7)被包含运算。前者有的后者都有(&lt;=)false or true <br>8)元素与集合的运算,判断元素是否在集合中。2 in的值为true</p>
<p><br>------------<br>发现这个也有遍历枚举:Delphi7遍历枚举,子界 - kiny - 博客园https://www.cnblogs.com/kiny/articles/2676628.html</p>
<p>-------------------------------------------------------</p>
<p>-----------------------结束---------------------------------</p>
<p><br>-----新篇------------<br>-------------------------------------------------------------------------------------</p>
<p>--------------------字符串转枚举(利用泛型)----------------<br></p>
<p>需要Uses:&nbsp;TypInfo,&nbsp; SysConst</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> TEnumConvert&lt;T&gt; = <span style="color: rgba(0, 0, 255, 1)">class</span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span>   <span style="color: rgba(0, 0, 255, 1)">public</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span>   <span style="color: rgba(0, 0, 255, 1)">class</span> <span style="color: rgba(0, 0, 255, 1)">function</span> StrToEnumType(<span style="color: rgba(0, 0, 255, 1)">const</span> S: <span style="color: rgba(0, 0, 255, 1)">string</span>): T; <span style="color: rgba(0, 0, 255, 1)">overload</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>   <span style="color: rgba(0, 0, 255, 1)">class</span> <span style="color: rgba(0, 0, 255, 1)">function</span> StrToEnumType(<span style="color: rgba(0, 0, 255, 1)">const</span> S: <span style="color: rgba(0, 0, 255, 1)">string</span>; Default: T): T; <span style="color: rgba(0, 0, 255, 1)">overload</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>   <span style="color: rgba(0, 0, 255, 1)">class</span> <span style="color: rgba(0, 0, 255, 1)">function</span> EnumToString(Value: T): <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span>   <span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span>
<span style="color: rgba(0, 128, 128, 1)">11</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 255, 1)">implementation</span>
<span style="color: rgba(0, 128, 128, 1)">13</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)"> TEnumConvert&lt;T&gt; </span><span style="color: rgba(0, 128, 0, 1)">}</span>
<span style="color: rgba(0, 128, 128, 1)">15</span>
<span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 255, 1)">class</span> <span style="color: rgba(0, 0, 255, 1)">function</span> TEnumConvert&lt;T&gt;.EnumToString(Value: T): <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 255, 1)">var</span>
<span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 0, 1)">v: Integer;
</span><span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 0, 255, 1)">begin</span>
<span style="color: rgba(0, 128, 128, 1)">20</span>   <span style="color: rgba(0, 0, 255, 1)">case</span> PTypeInfo(TypeInfo(T))^.Kind <span style="color: rgba(0, 0, 255, 1)">of</span>
<span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)">    tkEnumeration:
</span><span style="color: rgba(0, 128, 128, 1)">22</span>   <span style="color: rgba(0, 0, 255, 1)">case</span> TypInfo.GetTypeData(TypeInfo(T))^.OrdType <span style="color: rgba(0, 0, 255, 1)">of</span>
<span style="color: rgba(0, 128, 128, 1)">23</span>       otUByte, otSByte: v :=<span style="color: rgba(0, 0, 0, 1)"> PByte(@Value)^;
</span><span style="color: rgba(0, 128, 128, 1)">24</span>       otUWord, otSWord: v :=<span style="color: rgba(0, 0, 0, 1)"> PWord(@Value)^;
</span><span style="color: rgba(0, 128, 128, 1)">25</span>       otULong, otSLong: v :=<span style="color: rgba(0, 0, 0, 1)"> PInteger(@Value)^;
</span><span style="color: rgba(0, 128, 128, 1)">26</span>   <span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">27</span>   <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)">28</span>   <span style="color: rgba(0, 0, 255, 1)">raise</span><span style="color: rgba(0, 0, 0, 1)"> EInvalidCast.CreateRes(@SInvalidCast);
</span><span style="color: rgba(0, 128, 128, 1)">29</span>   <span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">30</span>   Result :=<span style="color: rgba(0, 0, 0, 1)"> TypInfo.GetEnumName(TypeInfo(T), v);
</span><span style="color: rgba(0, 128, 128, 1)">31</span>   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Result := TValue.From&lt;T&gt;(Value).ToString;//Rtti</span>
<span style="color: rgba(0, 128, 128, 1)">32</span> <span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">33</span>
<span style="color: rgba(0, 128, 128, 1)">34</span> <span style="color: rgba(0, 0, 255, 1)">class</span> <span style="color: rgba(0, 0, 255, 1)">function</span> TEnumConvert&lt;T&gt;.StrToEnumType(<span style="color: rgba(0, 0, 255, 1)">const</span> S: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">): T;
</span><span style="color: rgba(0, 128, 128, 1)">35</span> <span style="color: rgba(0, 0, 255, 1)">begin</span>
<span style="color: rgba(0, 128, 128, 1)">36</span>   <span style="color: rgba(0, 0, 255, 1)">case</span> PTypeInfo(TypeInfo(T))^.Kind <span style="color: rgba(0, 0, 255, 1)">of</span>
<span style="color: rgba(0, 128, 128, 1)">37</span> <span style="color: rgba(0, 0, 0, 1)">    tkEnumeration:
</span><span style="color: rgba(0, 128, 128, 1)">38</span>   <span style="color: rgba(0, 0, 255, 1)">case</span> TypInfo.GetTypeData(TypeInfo(T))^.OrdType <span style="color: rgba(0, 0, 255, 1)">of</span>
<span style="color: rgba(0, 128, 128, 1)">39</span>       otUByte, otSByte: PByte(@Result)^ :=<span style="color: rgba(0, 0, 0, 1)"> GetEnumValue(TypeInfo(T), S);
</span><span style="color: rgba(0, 128, 128, 1)">40</span>       otUWord, otSWord: PWord(@Result)^ :=<span style="color: rgba(0, 0, 0, 1)"> GetEnumValue(TypeInfo(T), S);
</span><span style="color: rgba(0, 128, 128, 1)">41</span>       otULong, otSLong: PInteger(@Result)^ :=<span style="color: rgba(0, 0, 0, 1)"> GetEnumValue(TypeInfo(T), S);
</span><span style="color: rgba(0, 128, 128, 1)">42</span>   <span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">43</span>   <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)">44</span>   <span style="color: rgba(0, 0, 255, 1)">raise</span><span style="color: rgba(0, 0, 0, 1)"> EInvalidCast.CreateRes(@SInvalidCast);
</span><span style="color: rgba(0, 128, 128, 1)">45</span>   <span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">46</span> <span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">47</span>
<span style="color: rgba(0, 128, 128, 1)">48</span> <span style="color: rgba(0, 0, 255, 1)">class</span> <span style="color: rgba(0, 0, 255, 1)">function</span> TEnumConvert&lt;T&gt;.StrToEnumType(<span style="color: rgba(0, 0, 255, 1)">const</span> S: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">; Default: T): T;
</span><span style="color: rgba(0, 128, 128, 1)">49</span> <span style="color: rgba(0, 0, 255, 1)">begin</span>
<span style="color: rgba(0, 128, 128, 1)">50</span>   <span style="color: rgba(0, 0, 255, 1)">if</span> S &lt;&gt; <span style="color: rgba(128, 0, 0, 1)">''</span> <span style="color: rgba(0, 0, 255, 1)">then</span>
<span style="color: rgba(0, 128, 128, 1)">51</span>   Result :=<span style="color: rgba(0, 0, 0, 1)"> StrToEnumType(S)
</span><span style="color: rgba(0, 128, 128, 1)">52</span>   <span style="color: rgba(0, 0, 255, 1)">else</span>
<span style="color: rgba(0, 128, 128, 1)">53</span>   Result :=<span style="color: rgba(0, 0, 0, 1)"> Default;
</span><span style="color: rgba(0, 128, 128, 1)">54</span> <span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/dmqhjp/p/15148096.html
頁: [1]
查看完整版本: Delphi遍历枚举