Compile Subroutine SRP_Set_Prop_Array(PropArray) ************************************************************************************************ * * This program is proprietary and is not to be used by or disclosed to others, nor is it to * be copied without written permission from SRP Computer Solutions, Inc. * * Name : SRP_Set_Prop_Array * * Description: * * Sets multiple properties over multiple controls in one data structure. The * structure is in a column/row format where rows are @FM delimited and columns * are @VM delimited. The first row always specifies the properties. Each property * may optionally include the angle-bracket syntax denoting that a particular * column of values belongs in a Field, Value, etc. of a given procedure. For * example, "SIZE<1>" indicates that all values represent the controls X position. * This, "SIZE<2>":@VM:"SIZE<3>":@VM:"SIZE<4>" could be added with "SIZE<1>" to * produce all fields of the property. * * The first column is always the control name with the left most 'cell' being the * window name to which the controls belong. If you place a value in the left cell, * then that value is prefixed to all of the following control names. If not, then * the control names are used as is. (NOTE: you don't need to append a "." to the window * name. If the top cell is not null, then this function will add the "." for you. So, * you can set the top cell to @Window -- not @Window:".") Below is an example array for a * series of buttons: * * PropArray = @Window :@VM: "ENABLED" :@VM: "SIZE<1>" :@VM: "SIZE<2>" :@VM: "SIZE<3>" :@VM: "SIZE<4>" * PropArray<-1> = "BUTTON_1" :@VM: 0 :@VM: 10 :@VM: 10 :@VM: 100 :@VM: 100 * PropArray<-1> = "BUTTON_2" :@VM: 0 :@VM: 20 :@VM: 20 :@VM: 100 :@VM: 100 * PropArray<-1> = "BUTTON_3" :@VM: 0 :@VM: 30 :@VM: 30 :@VM: 100 :@VM: 100 * PropArray<-1> = "BUTTON_4" :@VM: 0 :@VM: 40 :@VM: 40 :@VM: 100 :@VM: 100 * * You can optionally use this method to set many properties of one control. To * do this, set the first value in the first field to the control name ensuring that there * are absolutely no other value marks in the first row. When you have done this, then each * following row represents a property/value pair delimited by @VM. Just like before * you can use the angle-bracket syntax to denote property fields, values, etc. For * example: * * PropArray = @Window:".BUTTON_1" * PropArray<-1> = "ENABLED" :@VM: 0 * PropArray<-1> = "SIZE<1>" :@VM: 0 * PropArray<-1> = "SIZE<2>" :@VM: 0 * PropArray<-1> = "SIZE<3>" :@VM: 0 * PropArray<-1> = "SIZE<4>" :@VM: 0 * * This function also allows you to combine both formats for a powerful and flexible * way to initialize a set of similar controls. In the first example above, notice that * all values are the same for the ENABLED, SIZE<3>, and SIZE<4> properties. To save time * and space, your array can also have a "Shared Properties" section. The section follows * main array and separated by a field containing a single @RM. The section is formatted * like the second example above. Each row in the section contains a property name and * a value. The function will use these property/value pairs to set the same value for all * controls in the preceding section. Here is first example rewritten to take advantage * of this functionality: * * PropArray = @Window :@VM: "SIZE<1>" :@VM: "SIZE<2>" * PropArray<-1> = "BUTTON_1" :@VM: 10 :@VM: 10 * PropArray<-1> = "BUTTON_2" :@VM: 20 :@VM: 20 * PropArray<-1> = "BUTTON_3" :@VM: 30 :@VM: 30 * PropArray<-1> = "BUTTON_4" :@VM: 40 :@VM: 40 * PropArray<-1> = @RM ;*<-- Notice that one row contains an @RM only * PropArray<-1> = "ENABLED" :@VM: 0 * PropArray<-1> = "SIZE<3>" :@VM: 100 * PropArray<-1> = "SIZE<4>" :@VM: 100 * * For any value you want to "Leave Alone", pass "" (case insensative). Also, note * that ommitting a field of a multivalue property will also "leave it alone". "Leaving it alone" is * the equivalent of reading the property, changing those values you wish to change, and setting * the property again. The following example leave's the control width alone and also leaves * a couple other values alone as well: * * * Set all but SIZE<3> * PropArray = @Window :@VM: "SIZE<1>" :@VM: "SIZE<2>" :@VM: "SIZE<4>" * PropArray<-1> = "BUTTON_1" :@VM: 10 :@VM: 10 :@VM: 100 * PropArray<-1> = "BUTTON_2" :@VM: "" :@VM: 20 :@VM: 100 * PropArray<-1> = "BUTTON_3" :@VM: 30 :@VM: "" :@VM: 100 * PropArray<-1> = "BUTTON_4" :@VM: 40 :@VM: 40 :@VM: "" * * Finally, you can also use this function to qualify events. To do so, simply specify "QUALIFY_EVENT" * as a property. The value to this property will be a comma delimited list of events to be * qualified. It only qualifies events, there is no rerouting of events involved. The following * example qualifies events for OLE controls * * * Init OLE Buttons * PropArray = @Window :@VM: "OLE.Style" :@VM: "QUALIFY_EVENT" * PropArray<-1> = "OLE_BUTTON1" :@VM: "Standard" :@VM: "OnClick" * PropArray<-1> = "OLE_BUTTON2" :@VM: "XP" :@VM: "OnClick,OnDblClick" * PropArray<-1> = "OLE_BUTTON3" :@VM: "XP Toolbar" :@VM: "" * PropArray<-1> = "OLE_BUTTON4" :@VM: "Office XP Toolbar" :@VM: "ALL_OLES" * * * Init a single OLE Edit Table * PropArray = @Window:".OLE_EDITTABLE" * PropArray<-1> = "Dimension<1>" :@VM: 10 * PropArray<-1> = "Dimension<2>" :@VM: 10 * PropArray<-1> = "QUALIFY_EVENT" :@VM: "PosChanging,PosChanged,BeforeUpdate,AfterUpdate" * * Parameters: * PropArray [in] -- The controls, properties, and values in one array * * History (Date, Initials, Notes) * 04/06/2004 KRF Initial Programmer * ************************************************************************************************ Declare subroutine Set_Property, Send_Message Declare function Get_Property, Extract, Replace, Delete * debug * Prepare input If Assigned(PropArray) else PropArray = "" If PropArray then CtrlList = "" PropList = "" ValueList = "" UsedProps = "" MV_Val = "" Shared_MV_Val = "" PrevProp = "" PrevCtrl = "" SharedPrevProp = "" If Count(PropArray<1>, @VM) EQ 0 then * One control ------------------------------------------------ Ctrl = Extract(PropArray, 1, 0, 0) PropArray = Delete(PropArray, 1, 0, 0) * Set each property NumProps = Count(PropArray, @FM) + 1 For i = 1 to NumProps Prop = PropArray Val = PropArray GoSub Process_Property next i * Just in case last property was MV If MV_Val then GoSub Add_MV_Property end end else * Many controls ---------------------------------------------- If Index(PropArray, @RM, 1) then SharedProps = PropArray[-1, "B":@RM] PropArray = PropArray[1, "F":@RM] If SharedProps[1, 1] EQ @FM then SharedProps[1, 1] = "" If PropArray[-1, 1] EQ @FM then PropArray[-1, 1] = "" end else SharedProps = "" end SharedCtrlList = "" * First set individual properties TopRow = Extract(PropArray, 1, 0, 0) NumProps = Count(TopRow, @VM) + 1 PropArray = Delete(PropArray, 1, 0, 0) Window = TopRow<1, 1> if Window then Window := "." * Set each property NumCtrls = Count(PropArray, @FM) + 1 For iCtrl = 1 to NumCtrls Ctrl = Window:PropArray If SharedProps NE "" then SharedCtrlList<-1> = Ctrl For i = 2 to NumProps Prop = TopRow<1, i> Val = PropArray GoSub Process_Property If iCtrl EQ 1 then Locate Prop in UsedProps using @FM setting Pos else UsedProps<-1> = Prop end end next i next iCtrl * How many properties are there? NumProps = Count(UsedProps, @FM) + 1 * Just in case last property was MV If MV_Val then GoSub Add_MV_Property end * now set shared properties If SharedProps NE "" AND PropArray NE "" then Convert @FM to @RM in SharedCtrlList NumSharedProps = Count(SharedProps, @FM) + 1 For iSharedProp = 1 to NumSharedProps SharedProp = SharedProps SharedVal = SharedProps GoSub Process_Shared_Property next iSharedProp * Just in case last shared property was MV If MV_Val then GoSub Add_Shared_MV_Property end end end * Set the properties CtrlList[-1, 1] = "" PropList[-1, 1] = "" ValueList[-1, 1] = "" Set_Property(CtrlList, PropList, ValueList) end Return Process_Property: * Params: [IN]Ctrl, [IN]Prop, [IN]Val, [IN]MV_Val, [IN|OUT]CtrlList, [IN|OUT]PropList, [IN|OUT]ValueList GoSub Get_MV_Structure If Prop NE PrevProp AND MV_Val NE "" then GoSub Add_MV_Property MV_Val = "" end If Prop EQ "QUALIFY_EVENT" then If VAL NE "" AND Val _NEC "" then NumEvents = Count(Val, ",") + 1 For iEvent = 1 to NumEvents Send_Message(Ctrl, "QUALIFY_EVENT", Field(Val, ",", iEvent), 1) next iEvent end end else If Field then If MV_Val EQ "" then MV_Val = Get_Property(Ctrl, Prop) end If Val _NEC "" then MV_Val = Replace(MV_Val, Field, Value, SubValue, Val) end else If Val _NEC "" then GoSub Add_Property end end PrevProp = Prop PrevCtrl = Ctrl return Get_MV_Structure: * Params: [IN]AnglePos, [IN|OUT]Prop, [OUT]Field, [OUT]Value, [OUT]SubValue Field = 0; Value = 0; SubValue = 0; AnglePos = Index(Prop, "<", 1) If AnglePos then Suffix = Prop[AnglePos + 1, "F>"] Prop = Prop[1, "F<"] Convert Char(9):" " to "" in Suffix Field = Field(Suffix, ",", 1) Value = Field(Suffix, ",", 2) SubValue = Field(Suffix, ",", 3) end return Add_Property: * Params: [IN]Ctrl, [IN]Prop, [IN]Val, [IN|OUT]CtrlList, [IN|OUT]PropList, [IN|OUT]ValueList CtrlList := Ctrl:@RM PropList := Prop:@RM ValueList := Val:@RM return Add_MV_Property: * Params: [IN]PrevCtrl, [IN]PrevProp, [IN]MV_Val, [IN|OUT]CtrlList, [IN|OUT]PropList, [IN|OUT]ValueList CtrlList := PrevCtrl:@RM PropList := PrevProp:@RM ValueList := MV_Val:@RM return Process_Shared_Property: * Params: [IN]NumCtrls, [IN]SharedCtrlList, [IN]SharedProp, [IN]SharedVal, [IN]Shared_MV_Val, [IN|OUT]CtrlList, [IN|OUT]PropList, [IN|OUT]ValueList GoSub Get_Shared_MV_Structure If SharedProp NE SharedPrevProp AND Shared_MV_Val NE "" then GoSub Add_Shared_MV_Property Shared_MV_Val = "" end If SharedProp EQ "QUALIFY_EVENT" then If SharedVal NE "" AND SharedVal _NEC "" then NumEvents = Count(SharedVal, ",") + 1 For iCtrl = 1 to NumCtrls CurrSharedCtrl = Field(SharedCtrlList, @RM, iCtrl) For iEvent = 1 to NumEvents Send_Message(CurrSharedCtrl, "QUALIFY_EVENT", Field(SharedVal, ",", iEvent), 1) next iEvent next iCtrl end end else If Field then If Shared_MV_Val EQ "" then Locate SharedProp in UsedProps using @FM setting Pos then For iCtrl = 1 to NumCtrls Data = Field(ValueList, @RM, Pos) Data = Replace(Data, Field, Value, SubValue, SharedVal) ValueList = FieldStore(ValueList, @RM, Pos, 1, Data) Pos += NumProps next iCtrl end else Shared_MV_Val = Get_Property(SharedCtrlList, SharedProp) end end If Shared_MV_Val NE "" AND SharedVal _NEC "" then For iCtrl = 1 to NumCtrls Data = Field(Shared_MV_Val, @RM, iCtrl) Data = Replace(Data, Field, Value, SubValue, SharedVal) Shared_MV_Val = FieldStore(Shared_MV_Val, @RM, iCtrl, 1, Data) next i end end else If SharedVal _NEC "" then GoSub Add_Shared_Property end end SharedPrevProp = SharedProp return Get_Shared_MV_Structure: * Params: [IN]AnglePos, [IN|OUT]SharedProp, [OUT]Field, [OUT]Value, [OUT]SubValue Field = 0; Value = 0; SubValue = 0; AnglePos = Index(SharedProp, "<", 1) If AnglePos then Suffix = SharedProp[AnglePos + 1, "F>"] SharedProp = SharedProp[1, "F<"] Suffix = Trim(Suffix) Field = Field(Suffix, ",", 1) Value = Field(Suffix, ",", 2) SubValue = Field(Suffix, ",", 3) end return Add_Shared_Property: * Params: [IN]SharedCtrlList, [IN]SharedProp, [IN]SharedVal, [IN|OUT]CtrlList, [IN|OUT]PropList, [IN|OUT]ValueList CtrlList := SharedCtrlList:@RM PropList := Str(SharedProp:@RM, NumCtrls) ValueList := Str(SharedVal:@RM, NumCtrls) return Add_Shared_MV_Property: * Params: [IN]SharedCtrlList, [IN]SharedPrevProp, [IN]Shared_MV_Val, [IN|OUT]CtrlList, [IN|OUT]PropList, [IN|OUT]ValueList CtrlList := SharedCtrlList:@RM PropList := Str(SharedPrevProp:@RM, NumCtrls) ValueList := Shared_MV_Val:@RM return