INFDS光标定位的探索
RPG CODE:
IINFDS DS
I B 370 3710WKCRSR
C WKCRSR DIV 256 ROW 40
C MVR COL 40
大家对这段代码肯定不陌生吧,是获取屏幕光标的位置。今天想要讨论的不是怎么样使用这段代码,而是为什么这样计算就可以获取光标的位置?
首先information data structure 的370—371位存储的是2 bytes 长度,用16进制表示的坐标值。370 是行数,371是列数。
我曾经想,IBM为什么不用10进制来表示行和列?10进制直观,不用转换,可以直接取过来用,例如:
IINFDS DS
I P 370 3700 ROW
I P 371 3710 COL
但是后来发现,这里面涉及每个数据类型占用的字节数和取值范围问题。比如以上定义,P表示的是压缩10进制,即每一个数字占用1个byte,那么ROW和COL分别只有1byte的长度,所能表示的取值范围就是(9,9),远远于*DS3(24,80)和*DS34(27,132)这两种屏幕类型的取值范围,所以,P类型不可取。而S是区位10进制,每个数字占2个byte,更不可取了。而对于2进制说,1byte=8bit,所表示的范围是28=256。所以,把370—371的16进制转换成2进制的话,可以表示的范围就是(256,256),足够表示光标的范围了。
但是还有一点,在RPG中,B类型的字段只能占2个byte,或者4byte,所以不能这样定义:
IINFDS DS
I B 370 3700 ROW
I B 371 3710 COL
虽然这样定义是最简单的,但是系统会提示每个B类型的变量的长度错误。所以只能从整体上把370—371这2 byte长度的16进制转成2进制。也就引出了下面的问题:为什么要除以256才能得到行和列的值呢?
是因为在2 byte长度的16进制转换成2进制的过程中,行数(370)相当于扩大了256倍,举个例子说明下:
IAA DS
I P 1 6 0 YYYYMM
如果想要取得年份和月份的话,用数学的方法,要怎样取?是不是这样:
C YYYYMM DIV 100 YYYY
C MVR MM
这里YYYY相当于扩大了100倍,所以,要除以100。同理可得,16进制的字段扩大了256倍,要除以256。.如果RPG中可以定义B类型为1byte长度的话,那么就可以直接分割INFDS了,就不用这么麻烦了。
讨论到这里,我想你已经明白了,在RPG中如何用information data structure 获取光标值了。下面,再讨论下RPGLE中通过information data structure获取光标的方法,要比RPG简单、省事的多,当然,这多了RPGLE新曾的几种数据类型。
RPGLE CODE:
D INFDS1 DS
D ROW 370 370I 0
D COL 371 371I 0
或者
D INFDS1 DS
D ROW 370 370U 0
D COL 371 371U 0
这样就获取了光标值了,不用做DIV & MVR了,这又是什么原因呢?
先来看看I类型和U类型的说明:
Integer Format
The integer format is similar to the binary format with two exceptions:
The integer format allows the full range of binary values
The number of decimal positions for an integer field is always zero.
The length of an integer field is defined in terms of number of digits; it can be 3, 5, 10, or 20 digits long. A 3-digit field takes up 1 byte of storage; a 5-digit field takes up 2 bytes of storage; a 10-digit field takes up 4 bytes; a 20-digit field takes up 8 bytes. The range of values allowed for an integer field depends on its length.
Field length Range of Allowed Values
3-digit integer -128 to 127
5-digit integer -32768 to 32767
10-digit integer -2147483648 to 2147483647
Unsigned Format
The unsigned integer format is like the integer format except that the range of values does not include negative numbers.
The length of an unsigned field is defined in terms of number of digits; it can be 3, 5, 10, or 20 digits long. A 3-digit field takes up 1 byte of storage; a 5-digit field takes up 2 bytes of storage; a 10-digit field takes up 4 bytes; a 20-digit field takes up 8 bytes. The range of values allowed for an unsigned field depends on its length.
Field length Range of Allowed Values
3-digit unsigned 0 to 255
5-digit unsigned 0 to 65535
10-digit unsigned 0 to 4294967295
I是整形,U是无符号整形,它们都有一个共通的特点,A 3-digit field takes up 1 byte of storage。3个数字才占用1 byte。1byte的I和U类型表示的范围分别是(-128—127)和(0—255)
所以可以用I和U类型的变量直接分割INFDS,而不用担心范围取值范围过小。
这就是RPGLE如此简单就可以获取光标值的原因了。
PS:1byte长度的I类型的范围是-128—127,对于*DS3(24,80)是够用的,但是对于*DS34(27,132)就不够用了。
注:以上内容本人未经过严格测试,仅供参考,欢迎指正。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
回复 2# insmile
可惜,我们还一直用绿屏。。。莫非落后于时代了???
lz很有研究精神。。。。。。
400已经不合适做界面了
很多软件现在都是分离了
400现在主要做数据处理
界面操作更多的是用java之类写的前端
用户对绿屏的界面已经深深厌恶了