使用PB未公开的INDIRECT关键字,定义自己的属性Property

 

fm: http://blog.csdn.net/huwenqing1971/article/details/3914052

作者:Réal Gagnon

 

INDIRECT declaration statement enables a function to be called indirectly by simply setting an instance or shared variable. With a simple INDIRECTed variable, we need to provide 2 functions. One to set the value and one to retrieve the value.

    
    
  1. [instance variable]  
  2. public:  
  3.  INDIRECT string i_username {of_SetUsername(*value),of_GetUsername()}  
  4.   
  5. private:  
  6.  string zis_username  
  7.   
  8. [Powerscript functions]  
  9. function integer of_SetUsername(string as_username)  
  10.   
  11.     IF NOT IsNull(as_username) THEN  
  12.        zis_username = upper(as_username)  
  13.     END IF  
  14.     RETURN 1  
  15.   
  16.   
  17. function String of_GetUsername()  
  18.     RETURN zis_username  
  19.   
  20. [test code]  
  21.   
  22. // the of_SetUsername() function is called by PB   
  23. i_username = "powerbuilder howto"  
  24.   
  25. // the of_GetUsername() function is called by PB   
  26. MessageBox("username", i_username)  

Here some notes from Jeremy Lakeman (thanks!).

  • INDIRECT variables only compile with 2 or 6 functions in the array otherwise the compiler will crash.
  • Arguments that start with a * will be replaced by the appropriate value at compile time and all arguments are optional, the compiler wont complain if you don't pass one of the valid values
  • Arguments can be supplied in any order
  • The compiler will crash if you define a function with an unsuported argument
  • Extra identifiers can be passed to each method, but only if they are valid in the context of the calling code
  • The argument names are :
    string *name the name of the variable (used with INDIRECT array)
    any *value the value being assigned
    long[] *args the array of array dimensions (used with INDIRECT array)
  • Where a value is supplied as an argument, the compiler will call any matching method. This means that you could override the set methods to allow multiple types of values to be assigned.

INDIRECT keyword when used with an array is a little bit more tricky, we need to define 6 functions.

In the following example, the INDIRECT array converts its member to uppercase. A userobject is used to hold our INDIRECT array and the 6 required functions.

[EXPORT .sru file, save into a file _n_cst_indirect.sru_ and then IMPORT it in PB]

    
    
  1. $PBExportHeader$n_cst_indirect.sru  
  2. forward  
  3. global type n_cst_indirect from nonvisualobject  
  4. end type  
  5. end forward  
  6.   
  7. global type n_cst_indirect from nonvisualobject  
  8. end type  
  9. global n_cst_indirect n_cst_indirect  
  10.   
  11. type variables  
  12.   
  13. indirect string x[] {&  
  14.         of_set_array(*name, *value), &  
  15.         of_set_item(*name, *args, *value), &  
  16.         of_get_array(*name), &  
  17.         of_get_item(*name, *args), &  
  18.         of_upperbound(), &  
  19.         of_lowerbound()}  
  20.   
  21. private:  
  22. string ix[]  
  23.   
  24. end variables  
  25. forward prototypes  
  26. public function integer of_lowerbound ()  
  27. public function integer of_upperbound ()  
  28. private function any of_get_array (string s)  
  29. private function string of_get_item &  
  30.               (string s, long al_dimensions[])  
  31. private subroutine of_set_item &  
  32.     (string s, long al_dimensions[], string as_value)  
  33. private subroutine of_set_array (string s, string as_values[])  
  34. end prototypes  
  35.   
  36. public function integer of_lowerbound ();  
  37. // provide the lower bound of the array   
  38. // can be defined with a *value argument   
  39. // but then must be called by lowerbound(x, 1)   
  40. // this method must be public   
  41.   
  42. return lowerbound(ix)  
  43. end function  
  44.   
  45. public function integer of_upperbound ();  
  46. // provide the upper bound of the array   
  47. // can be defined with a *value argument   
  48. // but then must be called by upperbound(x, 1)   
  49. // this method must be public   
  50.   
  51. return upperbound(ix)  
  52. end function  
  53.   
  54. private function any of_get_array (string s);  
  55. // return the entire array in an any variable   
  56. any la_ret  
  57.   
  58. la_ret=ix  
  59. return la_ret  
  60. end function  
  61.   
  62. private function string of_get_item &  
  63.      (string s, long al_dimensions[]);  
  64. // get an element of the array   
  65. return ix[al_dimensions[1]]  
  66. end function  
  67.   
  68. private subroutine of_set_item &  
  69.      (string s, long al_dimensions[], string as_value);  
  70. // set an element of the array   
  71. ix[al_dimensions[1]]=upper(as_value)  
  72. end subroutine  
  73.   
  74. private subroutine of_set_array (string s, string as_values[]);  
  75. integer i  
  76. String ls_blank[]  
  77.   
  78. ix = ls_blank  
  79. // set the entire array   
  80. FOR i = 1 TO upperbound(as_values)  
  81.    x[i] = as_values[i]  
  82. NEXT  
  83. end subroutine  
  84.   
  85. on n_cst_indirect.create  
  86. call super::create  
  87. TriggerEvent( this"constructor" )  
  88. end on  
  89.   
  90. on n_cst_indirect.destroy  
  91. TriggerEvent( this"destructor" )  
  92. call super::destroy  
  93. end on  
  94. To use the userobject from Powerscript :  
  95. integer i  
  96. n_cst_indirect lnv_i  
  97. String tmp[] = &  
  98.   { "the uppercase conversion", &  
  99.   "was done with the", &  
  100.   "INDIRECT keyword!"}  
  101.   
  102. lnv_i = create n_cst_indirect  
  103. lnv_i.x[1] = "powerbuilder howto"  
  104. MessageBox("", lnv_i.x[1])  
  105.   
  106. lnv_i.x[2] = "http://www.rgagnon.com"  
  107. MessageBox("", lnv_i.x[2])  
  108.   
  109. Messagebox("", string(upperbound(lnv_i.x)))  
  110.   
  111. lnv_i.x = tmp  
  112. FOR i = 1 TO Upperbound(lnv_i.x)  
  113.    MessageBox("", lnv_i.x[i])  
  114. NEXT  

The same technique but this time, our array type is long.

    
    
  1. $PBExportHeader$n_cst_indirect.sru  
  2. forward  
  3. global type n_cst_indirect from nonvisualobject  
  4. end type  
  5. end forward  
  6.   
  7. global type n_cst_indirect from nonvisualobject  
  8. end type  
  9. global n_cst_indirect n_cst_indirect  
  10.   
  11. type variables  
  12.   
  13. indirect long x[] {&  
  14.         of_set_array(*name, *value), &  
  15.         of_set_item(*name, *args, *value), &  
  16.         of_get_array(*name), &  
  17.         of_get_item(*name, *args), &  
  18.         of_upperbound(), &  
  19.         of_lowerbound()}  
  20.   
  21. private:  
  22. long ix[]  
  23.   
  24. end variables  
  25.   
  26. forward prototypes  
  27. public function integer of_lowerbound ()  
  28. public function integer of_upperbound ()  
  29. private function any of_get_array (string s)  
  30. private subroutine of_set_array (string s, long al_values[])  
  31. private function long of_get_item (string s, long al_dimensions[])  
  32. private subroutine of_set_item &  
  33.     (string s, long al_dimensions[], long al_value)  
  34. end prototypes  
  35.   
  36. public function integer of_lowerbound ();  
  37. return lowerbound(ix)  
  38. end function  
  39.   
  40. public function integer of_upperbound ();  
  41. return upperbound(ix)  
  42. end function  
  43.   
  44. private function any of_get_array (string s);  
  45. any la_ret  
  46.   
  47. la_ret=ix  
  48. return la_ret  
  49. end function  
  50.   
  51. private subroutine of_set_array (string s, long al_values[]);  
  52. ix=al_values  
  53. end subroutine  
  54.   
  55. private function long of_get_item (string s, long al_dimensions[]);  
  56. return ix[al_dimensions[1]]  
  57. end function  
  58.   
  59. private subroutine of_set_item &  
  60.         (string s, long al_dimensions[], long al_value);  
  61. ix[al_dimensions[1]]=al_value  
  62. end subroutine  
  63.   
  64. on n_cst_indirect.create  
  65. call super::create  
  66. TriggerEvent( this"constructor" )  
  67. end on  
  68.   
  69. on n_cst_indirect.destroy  
  70. TriggerEvent( this"destructor" )  
  71. call super::destroy  
  72. end on  

Array with multi-dimensions needs functions with different signatures :

    
    
  1. $PBExportHeader$n_cst_indirect.sru  
  2. forward  
  3. global type n_cst_indirect from nonvisualobject  
  4. end type  
  5. end forward  
  6.   
  7. global type n_cst_indirect from nonvisualobject  
  8. end type  
  9. global n_cst_indirect n_cst_indirect  
  10.   
  11. type variables  
  12.   
  13. indirect long x[1,2,3] {&  
  14.         of_set_array(*name, *value, *eoseq), &  
  15.         of_set_item(*name, *nargs, *args, *value, *eoseq), &  
  16.         of_get_array(*name, *eoseq), &  
  17.         of_get_item(*name, *nargs, *args, *eoseq), &  
  18.         of_upperbound(*dims), &  
  19.         of_lowerbound(*dims)}  
  20.   
  21. private:  
  22. long ix[]  
  23.   
  24. /* 
  25.     indirect variables only compile with 2 or 6 functions in the array 
  26.     otherwise the compiler will crash 
  27.  
  28.     arguments that start with a * will be replaced by the appropriate 
  29.     value at compile time 
  30.     all arguments are optional, the compiler wont complain if you don't 
  31.     expect one of the valid values 
  32.     arguments can be supplied in any order 
  33.     the compiler will crash if you define a function with an unsuported 
  34.     argument 
  35.     extra identifiers can be passed to each method, but only if they are 
  36.     valid in the context of the calling code 
  37.     Eg you could pass "this" as an argument 
  38.  
  39.     string  *name   the name of the variable 
  40.     any     *value  the value being assigned 
  41.     long[]  *args   the array of array dimensions 
  42.     long    *nargs  the number of elements in *args 
  43.     boolean *eoseq  end of sequence 
  44.                       used to indicate if this is the end of a dot notation 
  45.                       sequence 
  46.     integer *dims   dimension for lower or upper bound? 
  47.                       the compiler doesn't seem to care which named value 
  48.                       you actually use though 
  49.  
  50.     Where a value is supplied as an argument, the compiler will call any 
  51.     matching method. This means that you could override the set methods 
  52.     to allow multiple types of values to be assigned. 
  53. */  
  54.   
  55. end variables  
  56. forward prototypes  
  57. public function integer of_upperbound (integer al_dims)  
  58. public function integer of_lowerbound (integer al_dims)  
  59. private subroutine of_set_array &  
  60.    (string as_name, long al_values[], boolean ab_eoseq)  
  61. private function any of_get_array (string as_name, boolean ab_eoseq)  
  62. private function long of_get_item &  
  63.    (string as_name, long al_n_dimensions, &  
  64.     long al_dimensions[], boolean ab_eo_seq)  
  65. private subroutine of_set_item &  
  66.   (string as_name, long al_n_dimensions, &  
  67.    long al_dimensions[], long al_value, boolean ab_eoseq)  
  68. end prototypes  
  69.   
  70. public function integer of_upperbound (integer al_dims);  
  71. // provide the upper bound of the array   
  72. // can be defined with a * argument doesn't seem to care which one   
  73. // but then must be called by upperbound(x, 1)   
  74. // this method must be public   
  75.   
  76. return upperbound(ix)  
  77. end function  
  78.   
  79. public function integer of_lowerbound (integer al_dims);  
  80. // provide the lower bound of the array   
  81. // can be defined with a * argument doesn't seem to care which one   
  82. // but then must be called by lowerbound(x, 1)   
  83. // this method must be public   
  84.   
  85. return lowerbound(ix)  
  86. end function  
  87.   
  88. private subroutine of_set_array &  
  89.     (string as_name, long al_values[], boolean ab_eoseq);  
  90. // set the entire array   
  91. ix=al_values  
  92. end subroutine  
  93.   
  94. private function any of_get_array (string as_name, boolean ab_eoseq);  
  95. // return the entire array in an any variable   
  96. any la_ret  
  97.   
  98. la_ret=ix  
  99. return la_ret  
  100. end function  
  101.   
  102. private function long of_get_item &  
  103.   (string as_name, long al_n_dimensions, long al_dimensions[],&  
  104.     boolean ab_eo_seq);  
  105. // get an element of the array   
  106. return ix[al_dimensions[1]]  
  107. end function  
  108.   
  109. private subroutine of_set_item &  
  110.   (string as_name, long al_n_dimensions, long al_dimensions[], &  
  111.    long al_value, boolean ab_eoseq);  
  112. // set an element of the array   
  113. ix[al_dimensions[1]]=al_value  
  114. end subroutine  
  115.   
  116. on n_cst_indirect.create  
  117. call super::create  
  118. TriggerEvent( this"constructor" )  
  119. end on  
  120.   
  121. on n_cst_indirect.destroy  
  122. TriggerEvent( this"destructor" )  
  123. call super::destroy  
  124. end on  

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值