<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://dataflex.wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Pinkynarf</id>
	<title>DataFlex Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://dataflex.wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Pinkynarf"/>
	<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Special:Contributions/Pinkynarf"/>
	<updated>2026-04-30T15:15:17Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://dataflex.wiki/index.php?title=AJAX_-_Return_Arrays_and_Structs_to_your_JavaScript_with_XML&amp;diff=2229</id>
		<title>AJAX - Return Arrays and Structs to your JavaScript with XML</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=AJAX_-_Return_Arrays_and_Structs_to_your_JavaScript_with_XML&amp;diff=2229"/>
		<updated>2008-11-20T18:47:01Z</updated>

		<summary type="html">&lt;p&gt;Pinkynarf: New page: = Functionality =  The VDF AJAX Library provides the functionality for developers to call published methods within a WBO and receive a return value (for Functions). This is done using a Re...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Functionality =&lt;br /&gt;
&lt;br /&gt;
The VDF AJAX Library provides the functionality for developers to call published methods within a WBO and receive a return value (for Functions). This is done using a Remote Method Invokation (RMI). Using  RMI&#039;s for returning a single datatype is fairly straight-forward. If you want to return a Struct, Array , or an Array of Structs you need to do some more work. Remember, you are returning these datatypes to JavaScript and there is no direct translation from a Windows Struct or Array to a JavaScript Struct or Array.&lt;br /&gt;
&lt;br /&gt;
= The Solution =&lt;br /&gt;
&lt;br /&gt;
The solution is to return the data in an XML document. XML can be formatted to return a Struct of data, and Array, or an Array of Structs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Calling the WBO Function from JavaScript =&lt;br /&gt;
&lt;br /&gt;
This is an example of a JavaScript function using the RMI to call a function of the webapp. It called the Function NameCasing of the oMyWBO. It passes a single argument of sName. When the Function returns, it will call the JavaScript method onNameCasing.&lt;br /&gt;
&lt;br /&gt;
 function nameCasing(sName) {&lt;br /&gt;
   var oRMI = new VdfRemoteMethodInvocation(true, &amp;quot;oMyWBO&amp;quot;, &amp;quot;get_NameCasing&amp;quot;, null, onNameCasing);&lt;br /&gt;
   oRMI.addParameter(sName);&lt;br /&gt;
   oRMI.sendCall();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Creating the XML in the WBO =&lt;br /&gt;
&lt;br /&gt;
1) create an XML document&amp;lt;br/&amp;gt;&lt;br /&gt;
2) add elements to the XML&amp;lt;br/&amp;gt;&lt;br /&gt;
3) get the memory address of the XML document&amp;lt;br/&amp;gt;&lt;br /&gt;
4) destroy the VDF connection to the address&amp;lt;br/&amp;gt;&lt;br /&gt;
5) return the memory address. This will return the XML document to the JavaScript&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 { Published = True  }&lt;br /&gt;
 { Description = &amp;quot;&amp;quot;  }&lt;br /&gt;
 Function NameCasing String sName Returns Address&lt;br /&gt;
   Handle hoRoot hoXML hoEvent&lt;br /&gt;
   Address aXml&lt;br /&gt;
   // create xml document&lt;br /&gt;
   Get Create U_cXMLDOMDocument                            to hoXML&lt;br /&gt;
   Set pbValidateOnParse of hoXML                          to False&lt;br /&gt;
   Get CreateDocumentElement of hoXML &amp;quot;response&amp;quot;           to hoRoot&lt;br /&gt;
   Send AddElement of hoRoot &amp;quot;lowercase&amp;quot; (lowercase(sName))&lt;br /&gt;
   Send AddElement of hoRoot &amp;quot;uppercase&amp;quot; (Uppercase(sName))&lt;br /&gt;
   Send AddElement of hoRoot &amp;quot;propercase&amp;quot; (Uppercase(Left(sName,1))+lowercase(Right(sName,(length(sName)-1))))&lt;br /&gt;
   Get paXml of hoXml to aXml&lt;br /&gt;
   Send Destroy of hoRoot&lt;br /&gt;
   Send Destroy of hoXML&lt;br /&gt;
   Function_Return aXML&lt;br /&gt;
 End_Function   // NameChanges&lt;br /&gt;
&lt;br /&gt;
= Parsing the XML in JavaScript =&lt;br /&gt;
&lt;br /&gt;
1) check to see if there were any errors&amp;lt;br/&amp;gt;&lt;br /&gt;
2) make sure we have a return value&amp;lt;br/&amp;gt;&lt;br /&gt;
3) create the XML parser object&amp;lt;br/&amp;gt;&lt;br /&gt;
4) get the values from the XML&lt;br /&gt;
&lt;br /&gt;
 function onNameCasing(oRMI) {&lt;br /&gt;
   // If no errors&lt;br /&gt;
   if (oRMI.iErrorNumber==0){&lt;br /&gt;
     if (oRMI.sReturnValue!=null){&lt;br /&gt;
       // create XML parser&lt;br /&gt;
       try { // code for IE&lt;br /&gt;
         xmlDoc=new ActiveXObject(&amp;quot;Microsoft.XMLDOM&amp;quot;);&lt;br /&gt;
         xmlDoc.async=&amp;quot;false&amp;quot;;&lt;br /&gt;
         xmlDoc.loadXML(oRMI.sReturnValue);&lt;br /&gt;
       } catch(e) { // code for Mozilla, Firefox, Opera, etc.&lt;br /&gt;
         try {&lt;br /&gt;
           parser=new DOMParser();&lt;br /&gt;
           xmlDoc=parser.parseFromString(oRMI.sReturnValue,&amp;quot;text/xml&amp;quot;);&lt;br /&gt;
         } catch(e) {&lt;br /&gt;
           alert(e.message);&lt;br /&gt;
           return;&lt;br /&gt;
         }&lt;br /&gt;
       }&lt;br /&gt;
     }&lt;br /&gt;
     if (xmlDoc!=null){&lt;br /&gt;
       var sLower=&amp;quot;&amp;quot;, sUpper=&amp;quot;&amp;quot;, sProper=&amp;quot;&amp;quot;;&lt;br /&gt;
       sLower=xmlDoc.getElementsByTagName(&amp;quot;lowercase&amp;quot;)[0].childNodes[0].nodeValue;&lt;br /&gt;
       sUpper=xmlDoc.getElementsByTagName(&amp;quot;uppercase&amp;quot;)[0].childNodes[0].nodeValue;&lt;br /&gt;
       sProper=xmlDoc.getElementsByTagName(&amp;quot;propercase&amp;quot;)[0].childNodes[0].nodeValue;&lt;br /&gt;
       //todo: do something with these values&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[[Category:Web Programming]]&lt;br /&gt;
[[Category:AJAX]]&lt;/div&gt;</summary>
		<author><name>Pinkynarf</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=AJAX_Library_for_Visual_DataFlex&amp;diff=2228</id>
		<title>AJAX Library for Visual DataFlex</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=AJAX_Library_for_Visual_DataFlex&amp;diff=2228"/>
		<updated>2008-11-20T18:14:08Z</updated>

		<summary type="html">&lt;p&gt;Pinkynarf: /* Examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{underconst}}&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;AJAX Library for Visual Dataflex&#039;&#039;&#039; allow developers to develop web applications using the latest AJAX technologies.&lt;br /&gt;
&lt;br /&gt;
The goal of the Visual DataFlex AJAX library is to bring the experience from the Windows version of Visual DataFlex to the web using [[AJAX]] techniques.&lt;br /&gt;
&lt;br /&gt;
You probably already now how to create a datamodel [[Using DataDictionaries]] from earlier [[Visual DataFlex]] programming experience. &lt;br /&gt;
&lt;br /&gt;
Now just attach your [[Data Dictionaries]] [[Using AJAX Web Browser Objects]] - this brings your existing datamodel to the ajax world. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
*[[Using DataDictionaries]]&lt;br /&gt;
*[[How to develop ASP pages]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Frequent issues ==&lt;br /&gt;
*[[Adding the AJAX Library to your application]]&lt;br /&gt;
*[[Creating a AJAX Web application]]&lt;br /&gt;
*[[Using AJAX Web Browser Objects]]&lt;br /&gt;
*[[Creating a AJAX Form]]&lt;br /&gt;
*[[AJAX Remote Method Invocation ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
*[[AJAX Rating Example]]&lt;br /&gt;
*[[AJAX - Return Arrays and Structs to your JavaScript with XML]]&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
*[[Using cAjaxSessionManager]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
*[http://www.visual-dataflex.co.uk/1seater.asp?pageid=948 Library Download]&lt;br /&gt;
&lt;br /&gt;
[[Category:Web Programming]]&lt;br /&gt;
[[Category:AJAX]]&lt;/div&gt;</summary>
		<author><name>Pinkynarf</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Calculating_the_cost_of_inventory_kits&amp;diff=2107</id>
		<title>Calculating the cost of inventory kits</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Calculating_the_cost_of_inventory_kits&amp;diff=2107"/>
		<updated>2008-09-04T18:28:19Z</updated>

		<summary type="html">&lt;p&gt;Pinkynarf: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Below is the logic which can be used to calculate the cost of an inventory item (kit) which is made up of other inventory items. The cost of these kits will change when the parts used to make them change. To get the cost, we use a function that calls itself.&lt;br /&gt;
&lt;br /&gt;
Look at the code sample below. We first call this function with the inventory part number that is a kit. The function will then loop through the kit table to find all the inventory items which are used in this kit. For each item in the kit, it calls itself. We do this because a kit can be used as a part for a different kit.&lt;br /&gt;
&lt;br /&gt;
== Code Sample ==&lt;br /&gt;
&lt;br /&gt;
  Function GetPartCost Integer iPartNum Returns Number&lt;br /&gt;
    Number nCost nTotal&lt;br /&gt;
    Clear Inv&lt;br /&gt;
    Move iPartNum to Inv.Number&lt;br /&gt;
    Find eq Inv by Index.1&lt;br /&gt;
    If (Found) Begin&lt;br /&gt;
        If (Inv.Kit=&amp;quot;Y&amp;quot;) Begin&lt;br /&gt;
            Clear Kit&lt;br /&gt;
            Move Inv.Number to Kit.PartNum&lt;br /&gt;
            Find ge Kit by Index.1&lt;br /&gt;
            If (Found) Indicate Found as (Kit.PartNum=Inv.Number)&lt;br /&gt;
            While (Found)&lt;br /&gt;
                // Function calls itself with new part number&lt;br /&gt;
                // beware of kits containing themself.&lt;br /&gt;
                Get GetPartCost Kit.KitPartNum to nCost&lt;br /&gt;
                Add (Kit.Qty*nCost) to nTotal&lt;br /&gt;
                Find gt Kit by Index.1&lt;br /&gt;
                If (Found) Indicate Found as (Kit.PartNum=Inv.Number)&lt;br /&gt;
            Loop&lt;br /&gt;
            // Return the kit&#039;s total cost&lt;br /&gt;
            Function_Return nTotal&lt;br /&gt;
        End&lt;br /&gt;
        Else Begin&lt;br /&gt;
            // Return the item&#039;s cost&lt;br /&gt;
            Function_Return Inv.Cost&lt;br /&gt;
        End&lt;br /&gt;
    End&lt;br /&gt;
    Else Begin&lt;br /&gt;
        Error 999 (&amp;quot;Part not found: &amp;quot;+String(iPartNum)) &lt;br /&gt;
        Function_Return 0&lt;br /&gt;
    End&lt;br /&gt;
  End_Function&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
You are a restaurant owner and you want to know what each of your meals cost. One of the items on your menu is a hamburger. The logic might look something like this:&lt;br /&gt;
&lt;br /&gt;
 Famous Dave&#039;s Sliders&lt;br /&gt;
     1 Homemade Kaiser Roll&lt;br /&gt;
     1/3 pound Ground Sirloin&lt;br /&gt;
     1 slice of American Cheese&lt;br /&gt;
     1 slice of Sharp Cheddar Cheese&lt;br /&gt;
       Lettuce&lt;br /&gt;
     2 slices of Tomato&lt;br /&gt;
     3 ounces of Secret Sauce&lt;br /&gt;
     8 ounces of Steak Fries&lt;br /&gt;
     1 Pickle Wedge  &lt;br /&gt;
&lt;br /&gt;
The Kaiser Roll and the Special Sauce are kits, because you make them. So you also need to determine their cost.&lt;br /&gt;
&lt;br /&gt;
 Kaiser Rolls&lt;br /&gt;
     1 pound Flour&lt;br /&gt;
     2 cups Water&lt;br /&gt;
     1/3 cup Sugar&lt;br /&gt;
     12 ounces of yeast&lt;br /&gt;
     1/4 cup Extra Virgin Olive Oil&lt;br /&gt;
&lt;br /&gt;
 Special Sauce&lt;br /&gt;
    1 Tbsp Ingredient A&lt;br /&gt;
    1 cup Ingredient B&lt;br /&gt;
    1/2 Tbsp Ingredient C&lt;br /&gt;
    1/2 Tbsp Ingredient D&lt;br /&gt;
    3 ounces Ingredient E&lt;br /&gt;
    1 Tbsp Ingredient F&lt;br /&gt;
    1 tsp Ingredient G&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
So, by calling the GetPartCost of the main menu item, it will automatically traverse all kits to get to the root items and return their cost.&lt;br /&gt;
&lt;br /&gt;
 GetPartCost Famous Dave&#039;s Sliders&lt;br /&gt;
   GetPartCost Homemade Kaiser Roll&lt;br /&gt;
     GetPartCost Flour&lt;br /&gt;
     GetPartCost Water&lt;br /&gt;
     GetPartCost Sugar&lt;br /&gt;
     GetPartCost Yeast&lt;br /&gt;
     GetPartCost Olive Oil&lt;br /&gt;
   GetPartCost Ground Sirloin&lt;br /&gt;
   GetPartCost American Cheese&lt;br /&gt;
   GetPartCost Sharp Cheddar Cheese&lt;br /&gt;
   GetPartCost Lettuce&lt;br /&gt;
   GetPartCost Tomato&lt;br /&gt;
   GetPartCost Secret Sauce&lt;br /&gt;
     GetPartCost Ingredient A&lt;br /&gt;
     GetPartCost Ingredient B&lt;br /&gt;
     GetPartCost Ingredient C&lt;br /&gt;
     GetPartCost Ingredient D&lt;br /&gt;
     GetPartCost Ingredient E&lt;br /&gt;
     GetPartCost Ingredient F&lt;br /&gt;
     GetPartCost Ingredient G&lt;br /&gt;
   GetPartCost Steak Fries&lt;br /&gt;
   GetPartCost Pickle Wedge&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: Visual Dataflex]]&lt;/div&gt;</summary>
		<author><name>Pinkynarf</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Calculating_the_cost_of_inventory_kits&amp;diff=2106</id>
		<title>Calculating the cost of inventory kits</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Calculating_the_cost_of_inventory_kits&amp;diff=2106"/>
		<updated>2008-09-04T18:26:54Z</updated>

		<summary type="html">&lt;p&gt;Pinkynarf: New page: Below is the logic which can be used to calculate the cost of an inventory item (kit) which is made up of other inventory items. The cost of these kits will change when the parts used to m...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Below is the logic which can be used to calculate the cost of an inventory item (kit) which is made up of other inventory items. The cost of these kits will change when the parts used to make them change. To get the cost, we use a function that calls itself.&lt;br /&gt;
&lt;br /&gt;
Look at the code sample below. We first call this function with the inventory part number that is a kit. The function will then loop through the kit table to find all the inventory items which are used in this kit. For each item in the kit, it calls itself. We do this because a kit can be used as a part for a different kit.&lt;br /&gt;
&lt;br /&gt;
== Code Sample ==&lt;br /&gt;
&lt;br /&gt;
  Function GetPartCost Integer iPartNum Returns Number&lt;br /&gt;
    Number nCost nTotal&lt;br /&gt;
    Clear Inv&lt;br /&gt;
    Move iPartNum to Inv.Number&lt;br /&gt;
    Find eq Inv by Index.1&lt;br /&gt;
    If (Found) Begin&lt;br /&gt;
        If (Inv.Kit=&amp;quot;Y&amp;quot;) Begin&lt;br /&gt;
            Clear Kit&lt;br /&gt;
            Move Inv.Number to Kit.PartNum&lt;br /&gt;
            Find ge Kit by Index.1&lt;br /&gt;
            If (Found) Indicate Found as (Kit.PartNum=Inv.Number)&lt;br /&gt;
            While (Found)&lt;br /&gt;
                // Function calls itself with new part number&lt;br /&gt;
                // beware of kits containing themself.&lt;br /&gt;
                Get GetPartCost Kit.KitPartNum to nCost&lt;br /&gt;
                Add (Kit.Qty*nCost) to nTotal&lt;br /&gt;
                Find gt Kit by Index.1&lt;br /&gt;
                If (Found) Indicate Found as (Kit.PartNum=Inv.Number)&lt;br /&gt;
            Loop&lt;br /&gt;
            // Return the kit&#039;s total cost&lt;br /&gt;
            Function_Return nTotal&lt;br /&gt;
        End&lt;br /&gt;
        Else Begin&lt;br /&gt;
            // Return the item&#039;s cost&lt;br /&gt;
            Function_Return Inv.Cost&lt;br /&gt;
        End&lt;br /&gt;
    End&lt;br /&gt;
    Else Begin&lt;br /&gt;
        Error 999 (&amp;quot;Part not found: &amp;quot;+String(iPartNum)) &lt;br /&gt;
        Function_Return 0&lt;br /&gt;
    End&lt;br /&gt;
  End_Function&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
You are a restaurant owner and you want to know what each of your meals cost. One of the items on your menu is a hamburger. The logic might look something like this:&lt;br /&gt;
&lt;br /&gt;
 Famous Dave&#039;s Sliders&lt;br /&gt;
     1 Homemade Kaiser Roll&lt;br /&gt;
     1/3 pound Ground Sirloin&lt;br /&gt;
     1 slice of American Cheese&lt;br /&gt;
     1 slice of Sharp Cheddar Cheese&lt;br /&gt;
       Lettuce&lt;br /&gt;
     2 slices of Tomato&lt;br /&gt;
     3 ounces of Secret Sauce&lt;br /&gt;
     8 ounces of Steak Fries&lt;br /&gt;
     1 Pickle Wedge  &lt;br /&gt;
&lt;br /&gt;
The Kaiser Roll and the Special Sauce are kits, because you make them. So you also need to determine their cost.&lt;br /&gt;
&lt;br /&gt;
 Kaiser Rolls&lt;br /&gt;
     1 pound Flour&lt;br /&gt;
     2 cups Water&lt;br /&gt;
     1/3 cup Sugar&lt;br /&gt;
     12 ounces of yeast&lt;br /&gt;
     1/4 cup Extra Virgin Olive Oil&lt;br /&gt;
&lt;br /&gt;
 Special Sauce&lt;br /&gt;
    1 Tbsp Ingredient A&lt;br /&gt;
    1 cup Ingredient B&lt;br /&gt;
    1/2 Tbsp Ingredient C&lt;br /&gt;
    1/2 Tbsp Ingredient D&lt;br /&gt;
    3 ounces Ingredient E&lt;br /&gt;
    1 Tbsp Ingredient F&lt;br /&gt;
    1 tsp Ingredient G&lt;br /&gt;
&lt;br /&gt;
So, by calling the GetPartCost of the main menu item, it will automatically traverse all kits to get to the root items and return their cost.&lt;br /&gt;
&lt;br /&gt;
 GetPartCost Famous Dave&#039;s Sliders&lt;br /&gt;
   GetPartCost Homemade Kaiser Roll&lt;br /&gt;
     GetPartCost Flour&lt;br /&gt;
     GetPartCost Water&lt;br /&gt;
     GetPartCost Sugar&lt;br /&gt;
     GetPartCost Yeast&lt;br /&gt;
     GetPartCost Olive Oil&lt;br /&gt;
   GetPartCost Ground Sirloin&lt;br /&gt;
   GetPartCost American Cheese&lt;br /&gt;
   GetPartCost Sharp Cheddar Cheese&lt;br /&gt;
   GetPartCost Lettuce&lt;br /&gt;
   GetPartCost Tomato&lt;br /&gt;
   GetPartCost Secret Sauce&lt;br /&gt;
     GetPartCost Ingredient A&lt;br /&gt;
     GetPartCost Ingredient B&lt;br /&gt;
     GetPartCost Ingredient C&lt;br /&gt;
     GetPartCost Ingredient D&lt;br /&gt;
     GetPartCost Ingredient E&lt;br /&gt;
     GetPartCost Ingredient F&lt;br /&gt;
     GetPartCost Ingredient G&lt;br /&gt;
   GetPartCost Steak Fries&lt;br /&gt;
   GetPartCost Pickle Wedge&lt;/div&gt;</summary>
		<author><name>Pinkynarf</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Portal:Windows_Applications&amp;diff=2105</id>
		<title>Portal:Windows Applications</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Portal:Windows_Applications&amp;diff=2105"/>
		<updated>2008-09-04T18:00:25Z</updated>

		<summary type="html">&lt;p&gt;Pinkynarf: /* Advanced */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;Visual Dataflex Portal&#039;&#039;&#039; is the place to come for articles and tutorials on developing [http://en.wikipedia.org/wiki/Microsoft_Windows Windows] applications with &#039;&#039;&#039;[[Visual DataFlex]]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Before beginning the more advanced stuff you should consider reading [http://www.visual-dataflex.co.uk/1seater.asp?pageid=1028 Vincent&#039;s book] or attend a 5 days training. Now - on with the show:&lt;br /&gt;
&lt;br /&gt;
==Articles==&lt;br /&gt;
*&#039;&#039;&#039;[[Visual DataFlex]]&#039;&#039;&#039; (covering the basic stuff)&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
*How to add &#039;&#039;&#039;[[Add Workspace Parameter|Workspace Parameters]]&#039;&#039;&#039; using [[cIniFile]]&lt;br /&gt;
*[[Running_VDF_programs_as_Windows_Services]]&lt;br /&gt;
*[[Using On_key for undefined keys]]&lt;br /&gt;
*[[Passing the workspace as a parameter]]&lt;br /&gt;
*[[Add Workspace Parameter|Adding Workspace Parameters]] using the [[cIniFile]] class&lt;br /&gt;
*Adding [[SMTP Email]] to your application using an [[ActiveX]] control&lt;br /&gt;
*[[Run only one instance of your application]]&lt;br /&gt;
*[[Customize prompt lookup behavior in a dbgrid]]&lt;br /&gt;
*[[Print the content of an embedded IE html control]]&lt;br /&gt;
*[[Return data from every object in a dbView]]&lt;br /&gt;
*[[Print to a file using reports]]&lt;br /&gt;
*[[Visual Modelling of multiple visual objects]]&lt;br /&gt;
*[[ExpressConnectivity]]&lt;br /&gt;
&lt;br /&gt;
==Advanced==&lt;br /&gt;
* [[Add icons with subset of images to CodeJock CommandBars]]&lt;br /&gt;
* [[Programmatically edit a treeview label]]&lt;br /&gt;
* [[Muli-row select for Grid control]]&lt;br /&gt;
* [[Calculating the cost of inventory kits]] - Functions that call themselves&lt;br /&gt;
&lt;br /&gt;
==External links==&lt;br /&gt;
* http://www.vdf-guidance.com&lt;br /&gt;
* http://visualdataflexdeveloper.org/ &lt;br /&gt;
* http://www.visualdataflex.com&lt;br /&gt;
* http://www.visualdataflex.ru (Russian)&lt;br /&gt;
* http://www.dataaccess.com&lt;br /&gt;
* http://www.dataaccess.nl&lt;br /&gt;
* [http://www.sture.com/wasp/ WASP Newsgroup search] engine&lt;br /&gt;
* [http://www.starzen.com StarZen Technologies] Addon Tools, Books, Magazines, Consulting&lt;br /&gt;
* [http://www.redeemedsoftware.com Redeemed Software] Crystal Report Utilities, Autocomplete, and more&lt;br /&gt;
* [http://www.redeemedhosting.com Redeemed Hosting] VDF Webapp Hosting and Virtual Servers&lt;br /&gt;
&lt;br /&gt;
==Requested Articles / Works in progress==&lt;br /&gt;
&lt;br /&gt;
*[[Converting from DOS to Windows]]&lt;br /&gt;
*[[COM|Using COM Objects]] (reuse existing functionality)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Portals]]&lt;br /&gt;
[[Category:DataFlex (Character Mode)]]&lt;/div&gt;</summary>
		<author><name>Pinkynarf</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=User:Pinkynarf&amp;diff=2104</id>
		<title>User:Pinkynarf</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=User:Pinkynarf&amp;diff=2104"/>
		<updated>2008-09-04T06:26:18Z</updated>

		<summary type="html">&lt;p&gt;Pinkynarf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;David Martinko&amp;lt;br/&amp;gt;&lt;br /&gt;
Custom Software Developer&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.redeemedsoftware.com Redeemed Software Company] Crystal Tools, Custom Software (windows, webapps, webservices)&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.redeemedhosting.com Redeemed Hosting] Electos Website hosting, VDF Webapp Hosting, Virtual Servers&lt;/div&gt;</summary>
		<author><name>Pinkynarf</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=User:Pinkynarf&amp;diff=2103</id>
		<title>User:Pinkynarf</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=User:Pinkynarf&amp;diff=2103"/>
		<updated>2008-09-04T06:25:48Z</updated>

		<summary type="html">&lt;p&gt;Pinkynarf: New page: David Martinko Custom Software Developer [http://www.redeemedsoftware.com Redeemed Software Company] Crystal Tools, Custom Software (windows, webapps, webservices) [http://www.redeemedhost...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;David Martinko&lt;br /&gt;
Custom Software Developer&lt;br /&gt;
[http://www.redeemedsoftware.com Redeemed Software Company] Crystal Tools, Custom Software (windows, webapps, webservices)&lt;br /&gt;
[http://www.redeemedhosting.com Redeemed Hosting] Electos Website hosting, VDF Webapp Hosting, Virtual Servers&lt;/div&gt;</summary>
		<author><name>Pinkynarf</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Portal:Development_Tools&amp;diff=2083</id>
		<title>Portal:Development Tools</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Portal:Development_Tools&amp;diff=2083"/>
		<updated>2008-09-04T05:01:19Z</updated>

		<summary type="html">&lt;p&gt;Pinkynarf: /* Other Tools */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;For any Dataflex Developer there are a range of tools useful for many situations.&lt;br /&gt;
&lt;br /&gt;
==Data Access Tools==&lt;br /&gt;
[[Data Access]] provide a core of development tools vital to Dataflex development.&lt;br /&gt;
*[[Visual DataFlex Studio]]&lt;br /&gt;
*[[Database Builder]]&lt;br /&gt;
*[[Database Explorer]]&lt;br /&gt;
&lt;br /&gt;
==Third Party Development Environments==&lt;br /&gt;
Other tools have been developed by the dataflex community over the years.  These tools frequently take inspiration from the larger development community and often preview features which eventually make it into the official VDF Studio.&lt;br /&gt;
*[[Eclipse]]&lt;br /&gt;
*[[The Hammer]]&lt;br /&gt;
&lt;br /&gt;
==Dataflex Libraries==&lt;br /&gt;
*[[VDFQuery]]&lt;br /&gt;
*[[StarZen&#039;s Wizard]]&lt;br /&gt;
*[[StarZen&#039;s Date form control]]&lt;br /&gt;
*[[Evolution]]&lt;br /&gt;
*[[cWindowsEx Framework]]&lt;br /&gt;
&lt;br /&gt;
== Crystal Report Tools ==&lt;br /&gt;
*[[Mass Verify]] Change database locations, Verify Database on hundreds of reports,...&lt;br /&gt;
*[[Crystal Spellcheck]] Check Crystal Reports for Typo&#039;s&lt;br /&gt;
*[[Mass Convert]] Convert Native DF Crystal Reports to SQL&lt;br /&gt;
*[[Mass S&amp;amp;R]] Search and Replace text in your Crystal Reports&lt;br /&gt;
&lt;br /&gt;
==Other Tools==&lt;br /&gt;
*[[VDF Structure Viewer]]&lt;br /&gt;
*[[Version Control]]&lt;br /&gt;
*[[File Comparison]]&lt;br /&gt;
*[[Text Editors]]&lt;br /&gt;
*[[SFS Compare]] Compare and Modify Database Structures&lt;br /&gt;
&lt;br /&gt;
[[Category:Development Tools]]&lt;/div&gt;</summary>
		<author><name>Pinkynarf</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Multi-row_select_for_Grid_control&amp;diff=2082</id>
		<title>Multi-row select for Grid control</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Multi-row_select_for_Grid_control&amp;diff=2082"/>
		<updated>2008-09-04T04:52:45Z</updated>

		<summary type="html">&lt;p&gt;Pinkynarf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Functionality ==&lt;br /&gt;
This code demonstrates how to select multiple rows in a Grid. The code will work no matter how many columns. The object of this code is to allow the user to use the SHIFT+RCLICK or CTRL+RCLICK key to select multiple rows just like a spreadsheet program. &lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
Paste this code into a test view to test it and see how it works. Once compiled, you will see a narrow column on the left that acts as a margin. Clicking this gray cell will highlight the row. Using SHIFT or CTRL and clicking another gray cell will select multiple rows.&lt;br /&gt;
&lt;br /&gt;
  Object oGrid1 is a Grid&lt;br /&gt;
    Set Location to 7 26&lt;br /&gt;
    Set Size to 116 207&lt;br /&gt;
    Set Line_Width to 4 0&lt;br /&gt;
    Set Form_Width    0 to 8&lt;br /&gt;
    Set Header_Label  0 to &amp;quot;&amp;quot;&lt;br /&gt;
    Set Form_Width    1 to 60&lt;br /&gt;
    Set Header_Label  1 to &amp;quot;Column 1&amp;quot;&lt;br /&gt;
    Set Form_Width    2 to 60       &lt;br /&gt;
    Set Header_Label  2 to &amp;quot;Column 2&amp;quot;&lt;br /&gt;
    Set Form_Width    3 to 60       &lt;br /&gt;
    Set Header_Label  3 to &amp;quot;Column 3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    // BEGIN MULTI-SELECT CODE&lt;br /&gt;
    // DO NOT MODIFY&lt;br /&gt;
    Set Select_Mode to Multi_Select&lt;br /&gt;
    Property Integer[] paiSelected&lt;br /&gt;
    Property Integer piLastSelected 0&lt;br /&gt;
    Procedure Select_Toggling Integer iItem Integer iState&lt;br /&gt;
        Integer iCurrent iCol iLast iCount iFrom iTo iRet iUpdate&lt;br /&gt;
        Integer[] aiSelected aiEmpty&lt;br /&gt;
        //&lt;br /&gt;
        Get Dynamic_Update_State to iUpdate&lt;br /&gt;
        Set Dynamic_Update_State to False&lt;br /&gt;
        // Get base item&lt;br /&gt;
        Move (Current_Item(Self)) to iCurrent&lt;br /&gt;
        Move (Mod(iCurrent , Line_Size(Self))) to iCol&lt;br /&gt;
        Subtract iCol from iCurrent&lt;br /&gt;
        // get list of selected items&lt;br /&gt;
        Move (paiSelected(Self)) to aiSelected&lt;br /&gt;
        Move (SizeOfArray(aiSelected)) to iCount&lt;br /&gt;
        //&lt;br /&gt;
        Move (GetAsyncKeyState(VK_CONTROL)) to iRet&lt;br /&gt;
        If (iRet&amp;lt;&amp;gt;0) Begin&lt;br /&gt;
            If (iState) Begin&lt;br /&gt;
                // add selected item&lt;br /&gt;
                Move iCurrent to aiSelected[iCount]&lt;br /&gt;
                // Update last selected with this item&lt;br /&gt;
                Set piLastSelected to iCurrent&lt;br /&gt;
                // Select Current row&lt;br /&gt;
                For iCol from 0 to (Line_Size(Self)-1)&lt;br /&gt;
                    Forward Send Select_Toggling (iCurrent+iCol) iState&lt;br /&gt;
                Loop&lt;br /&gt;
            End&lt;br /&gt;
            Else Begin&lt;br /&gt;
                // remove selected item&lt;br /&gt;
                For iItem from 0 to (iCount-1)&lt;br /&gt;
                    Move aiSelected[iItem] to iLast&lt;br /&gt;
                    If (iLast=iCurrent) Move -1 to aiSelected[iItem]&lt;br /&gt;
                Loop&lt;br /&gt;
                // Update last selected with this item&lt;br /&gt;
                Set piLastSelected to -1&lt;br /&gt;
            End&lt;br /&gt;
        End&lt;br /&gt;
        Else Begin&lt;br /&gt;
            // If shift is used, we will ignore&lt;br /&gt;
            // the state of the clicked row&lt;br /&gt;
            // unselect everything&lt;br /&gt;
            For iItem from 0 to (iCount-1)&lt;br /&gt;
                Move aiSelected[iItem] to iLast&lt;br /&gt;
                For iCol from 0 to (Line_Size(Self)-1)&lt;br /&gt;
                    Forward Send Select_Toggling (iLast+iCol) False&lt;br /&gt;
                Loop&lt;br /&gt;
            Loop&lt;br /&gt;
            Move aiEmpty to aiSelected&lt;br /&gt;
            //&lt;br /&gt;
            Move (GetAsyncKeyState(VK_SHIFT)) to iRet&lt;br /&gt;
            If ((iRet&amp;lt;&amp;gt;0) and (piLastSelected(Self)&amp;lt;&amp;gt;-1)) Begin&lt;br /&gt;
                // select everything in between&lt;br /&gt;
                // do not mark this as the last current row,&lt;br /&gt;
                // the first item of the shift remains&lt;br /&gt;
                If (iCurrent &amp;gt; piLastSelected(Self)) Begin&lt;br /&gt;
                    Move (piLastSelected(Self)) to iFrom&lt;br /&gt;
                    Move iCurrent to iTo&lt;br /&gt;
                End&lt;br /&gt;
                Else Begin&lt;br /&gt;
                    Move iCurrent to iFrom&lt;br /&gt;
                    Move (piLastSelected(Self)) to iTo&lt;br /&gt;
                End&lt;br /&gt;
                Move 0 to iCount&lt;br /&gt;
                For iItem from iFrom to (iTo+3)&lt;br /&gt;
                    // Add to array&lt;br /&gt;
                    Move iItem to aiSelected[iCount]&lt;br /&gt;
                    Increment iCount&lt;br /&gt;
                    // select&lt;br /&gt;
                    For iCol from 0 to (Line_Size(Self)-1)&lt;br /&gt;
                        Forward Send Select_Toggling (iItem+iCol) True&lt;br /&gt;
                    Loop&lt;br /&gt;
                    // next row&lt;br /&gt;
                    Add 3 to iItem&lt;br /&gt;
                Loop&lt;br /&gt;
            End&lt;br /&gt;
            Else Begin&lt;br /&gt;
                // no shift or control key was pressed&lt;br /&gt;
                // Update last selected with this item&lt;br /&gt;
                Move iCurrent to aiSelected[0]&lt;br /&gt;
                Set piLastSelected to iCurrent&lt;br /&gt;
                // Select Current item&lt;br /&gt;
                For iCol from 0 to (Line_Size(Self)-1)&lt;br /&gt;
                    Forward Send Select_Toggling (iCurrent+iCol) iState&lt;br /&gt;
                Loop&lt;br /&gt;
            End&lt;br /&gt;
        End&lt;br /&gt;
        Set Dynamic_Update_State to iUpdate&lt;br /&gt;
        Set paiSelected to aiSelected&lt;br /&gt;
    End_Procedure // Select_Toggling&lt;br /&gt;
&lt;br /&gt;
    Procedure Mouse_Up Integer iWindowNumber Integer iPosition&lt;br /&gt;
        Integer iCol&lt;br /&gt;
        Move (Mod(iWindowNumber , Line_Size(Self))) to iCol&lt;br /&gt;
        Forward Send Mouse_Up iWindowNumber iPosition&lt;br /&gt;
        If (iCol&amp;lt;&amp;gt;1) Send Select_Toggling 0 False&lt;br /&gt;
    End_Procedure // Mouse_Up&lt;br /&gt;
    // END MULTI-SELECT CODE&lt;br /&gt;
&lt;br /&gt;
    //Sample method of how to fill a grid&lt;br /&gt;
    Procedure DoFillGrid&lt;br /&gt;
        Integer iRow iMaxRows&lt;br /&gt;
        Move 20 to iMaxRows&lt;br /&gt;
        For iRow from 0 to iMaxRows&lt;br /&gt;
            Send Add_Item Msg_None &amp;quot;&amp;quot;&lt;br /&gt;
            Send Add_Item Msg_None (&amp;quot;Col 1, row &amp;quot; + String (iRow))&lt;br /&gt;
            Send Add_Item Msg_None (&amp;quot;Col 2, row &amp;quot; + String (iRow))&lt;br /&gt;
            Send Add_Item Msg_None (&amp;quot;Col 3, row &amp;quot; + String (iRow))&lt;br /&gt;
            Set Entry_State item (iRow*4) to False&lt;br /&gt;
            Set ItemColor item (iRow*4) to clBtnFace&lt;br /&gt;
        Loop&lt;br /&gt;
    End_Procedure // DoFillgrid&lt;br /&gt;
    Send DoFillgrid&lt;br /&gt;
  End_Object // oGrid1&lt;br /&gt;
&lt;br /&gt;
  Object oButton1 is a Button&lt;br /&gt;
    Set Size to 14 70&lt;br /&gt;
    Set Location to 151 44&lt;br /&gt;
    Set Label to &amp;quot;Show Selection&amp;quot;&lt;br /&gt;
    // Example on how to get selected rows&lt;br /&gt;
    Procedure OnClick&lt;br /&gt;
        Integer[] aiSelected&lt;br /&gt;
        Integer iItem iCount&lt;br /&gt;
        Get paiSelected of oGrid1 to aiSelected&lt;br /&gt;
        Move (SizeOfArray(aiSelected)) to iCount&lt;br /&gt;
        Showln &amp;quot;Selected Row base_item(s) are&amp;quot;&lt;br /&gt;
        For iItem from 0 to (iCount-1)&lt;br /&gt;
            Showln (Character(9)) aiSelected[iItem]&lt;br /&gt;
        Loop&lt;br /&gt;
    End_Procedure // OnClick&lt;br /&gt;
  End_Object // oButton1&lt;br /&gt;
&lt;br /&gt;
[[Category: Visual Dataflex]]&lt;/div&gt;</summary>
		<author><name>Pinkynarf</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Multi-row_select_for_Grid_control&amp;diff=2081</id>
		<title>Multi-row select for Grid control</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Multi-row_select_for_Grid_control&amp;diff=2081"/>
		<updated>2008-09-04T04:40:31Z</updated>

		<summary type="html">&lt;p&gt;Pinkynarf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This code demonstrates how to select multiple rows in a Grid. The code will work no matter how many columns. The object of this code is to allow the user to use the SHIFT+RCLICK or CTRL+RCLICK key to select multiple rows just like a spreadsheet program. Paste this code into a test view to test it and see how it works. Once compiled, you will see a narrow column on the left that acts as a margin. Clicking this gray cell will highlight the row. Using SHIFT or CTRL and clicking another gray cell will select multiple rows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Object oGrid1 is a Grid&lt;br /&gt;
    Set Location to 7 26&lt;br /&gt;
    Set Size to 116 207&lt;br /&gt;
    Set Line_Width to 4 0&lt;br /&gt;
    Set Form_Width    0 to 8&lt;br /&gt;
    Set Header_Label  0 to &amp;quot;&amp;quot;&lt;br /&gt;
    Set Form_Width    1 to 60&lt;br /&gt;
    Set Header_Label  1 to &amp;quot;Column 1&amp;quot;&lt;br /&gt;
    Set Form_Width    2 to 60       &lt;br /&gt;
    Set Header_Label  2 to &amp;quot;Column 2&amp;quot;&lt;br /&gt;
    Set Form_Width    3 to 60       &lt;br /&gt;
    Set Header_Label  3 to &amp;quot;Column 3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    // BEGIN MULTI-SELECT CODE&lt;br /&gt;
    // DO NOT MODIFY&lt;br /&gt;
    Set Select_Mode to Multi_Select&lt;br /&gt;
    Property Integer[] paiSelected&lt;br /&gt;
    Property Integer piLastSelected 0&lt;br /&gt;
    Procedure Select_Toggling Integer iItem Integer iState&lt;br /&gt;
        Integer iCurrent iCol iLast iCount iFrom iTo iRet iUpdate&lt;br /&gt;
        Integer[] aiSelected aiEmpty&lt;br /&gt;
        //&lt;br /&gt;
        Get Dynamic_Update_State to iUpdate&lt;br /&gt;
        Set Dynamic_Update_State to False&lt;br /&gt;
        // Get base item&lt;br /&gt;
        Move (Current_Item(Self)) to iCurrent&lt;br /&gt;
        Move (Mod(iCurrent , Line_Size(Self))) to iCol&lt;br /&gt;
        Subtract iCol from iCurrent&lt;br /&gt;
        // get list of selected items&lt;br /&gt;
        Move (paiSelected(Self)) to aiSelected&lt;br /&gt;
        Move (SizeOfArray(aiSelected)) to iCount&lt;br /&gt;
        //&lt;br /&gt;
        Move (GetAsyncKeyState(VK_CONTROL)) to iRet&lt;br /&gt;
        If (iRet&amp;lt;&amp;gt;0) Begin&lt;br /&gt;
            If (iState) Begin&lt;br /&gt;
                // add selected item&lt;br /&gt;
                Move iCurrent to aiSelected[iCount]&lt;br /&gt;
                // Update last selected with this item&lt;br /&gt;
                Set piLastSelected to iCurrent&lt;br /&gt;
                // Select Current row&lt;br /&gt;
                For iCol from 0 to (Line_Size(Self)-1)&lt;br /&gt;
                    Forward Send Select_Toggling (iCurrent+iCol) iState&lt;br /&gt;
                Loop&lt;br /&gt;
            End&lt;br /&gt;
            Else Begin&lt;br /&gt;
                // remove selected item&lt;br /&gt;
                For iItem from 0 to (iCount-1)&lt;br /&gt;
                    Move aiSelected[iItem] to iLast&lt;br /&gt;
                    If (iLast=iCurrent) Move -1 to aiSelected[iItem]&lt;br /&gt;
                Loop&lt;br /&gt;
                // Update last selected with this item&lt;br /&gt;
                Set piLastSelected to -1&lt;br /&gt;
            End&lt;br /&gt;
        End&lt;br /&gt;
        Else Begin&lt;br /&gt;
            // If shift is used, we will ignore&lt;br /&gt;
            // the state of the clicked row&lt;br /&gt;
            // unselect everything&lt;br /&gt;
            For iItem from 0 to (iCount-1)&lt;br /&gt;
                Move aiSelected[iItem] to iLast&lt;br /&gt;
                For iCol from 0 to (Line_Size(Self)-1)&lt;br /&gt;
                    Forward Send Select_Toggling (iLast+iCol) False&lt;br /&gt;
                Loop&lt;br /&gt;
            Loop&lt;br /&gt;
            Move aiEmpty to aiSelected&lt;br /&gt;
            //&lt;br /&gt;
            Move (GetAsyncKeyState(VK_SHIFT)) to iRet&lt;br /&gt;
            If ((iRet&amp;lt;&amp;gt;0) and (piLastSelected(Self)&amp;lt;&amp;gt;-1)) Begin&lt;br /&gt;
                // select everything in between&lt;br /&gt;
                // do not mark this as the last current row,&lt;br /&gt;
                // the first item of the shift remains&lt;br /&gt;
                If (iCurrent &amp;gt; piLastSelected(Self)) Begin&lt;br /&gt;
                    Move (piLastSelected(Self)) to iFrom&lt;br /&gt;
                    Move iCurrent to iTo&lt;br /&gt;
                End&lt;br /&gt;
                Else Begin&lt;br /&gt;
                    Move iCurrent to iFrom&lt;br /&gt;
                    Move (piLastSelected(Self)) to iTo&lt;br /&gt;
                End&lt;br /&gt;
                Move 0 to iCount&lt;br /&gt;
                For iItem from iFrom to (iTo+3)&lt;br /&gt;
                    // Add to array&lt;br /&gt;
                    Move iItem to aiSelected[iCount]&lt;br /&gt;
                    Increment iCount&lt;br /&gt;
                    // select&lt;br /&gt;
                    For iCol from 0 to (Line_Size(Self)-1)&lt;br /&gt;
                        Forward Send Select_Toggling (iItem+iCol) True&lt;br /&gt;
                    Loop&lt;br /&gt;
                    // next row&lt;br /&gt;
                    Add 3 to iItem&lt;br /&gt;
                Loop&lt;br /&gt;
            End&lt;br /&gt;
            Else Begin&lt;br /&gt;
                // no shift or control key was pressed&lt;br /&gt;
                // Update last selected with this item&lt;br /&gt;
                Move iCurrent to aiSelected[0]&lt;br /&gt;
                Set piLastSelected to iCurrent&lt;br /&gt;
                // Select Current item&lt;br /&gt;
                For iCol from 0 to (Line_Size(Self)-1)&lt;br /&gt;
                    Forward Send Select_Toggling (iCurrent+iCol) iState&lt;br /&gt;
                Loop&lt;br /&gt;
            End&lt;br /&gt;
        End&lt;br /&gt;
        Set Dynamic_Update_State to iUpdate&lt;br /&gt;
        Set paiSelected to aiSelected&lt;br /&gt;
    End_Procedure // Select_Toggling&lt;br /&gt;
&lt;br /&gt;
    Procedure Mouse_Up Integer iWindowNumber Integer iPosition&lt;br /&gt;
        Integer iCol&lt;br /&gt;
        Move (Mod(iWindowNumber , Line_Size(Self))) to iCol&lt;br /&gt;
        Forward Send Mouse_Up iWindowNumber iPosition&lt;br /&gt;
        If (iCol&amp;lt;&amp;gt;1) Send Select_Toggling 0 False&lt;br /&gt;
    End_Procedure // Mouse_Up&lt;br /&gt;
    // END MULTI-SELECT CODE&lt;br /&gt;
&lt;br /&gt;
    //Sample method of how to fill a grid&lt;br /&gt;
    Procedure DoFillGrid&lt;br /&gt;
        Integer iRow iMaxRows&lt;br /&gt;
        Move 20 to iMaxRows&lt;br /&gt;
        For iRow from 0 to iMaxRows&lt;br /&gt;
            Send Add_Item Msg_None &amp;quot;&amp;quot;&lt;br /&gt;
            Send Add_Item Msg_None (&amp;quot;Col 1, row &amp;quot; + String (iRow))&lt;br /&gt;
            Send Add_Item Msg_None (&amp;quot;Col 2, row &amp;quot; + String (iRow))&lt;br /&gt;
            Send Add_Item Msg_None (&amp;quot;Col 3, row &amp;quot; + String (iRow))&lt;br /&gt;
            Set Entry_State item (iRow*4) to False&lt;br /&gt;
            Set ItemColor item (iRow*4) to clBtnFace&lt;br /&gt;
        Loop&lt;br /&gt;
    End_Procedure // DoFillgrid&lt;br /&gt;
    Send DoFillgrid&lt;br /&gt;
  End_Object // oGrid1&lt;br /&gt;
&lt;br /&gt;
  Object oButton1 is a Button&lt;br /&gt;
    Set Size to 14 70&lt;br /&gt;
    Set Location to 151 44&lt;br /&gt;
    Set Label to &amp;quot;Show Selection&amp;quot;&lt;br /&gt;
    // Example on how to get selected rows&lt;br /&gt;
    Procedure OnClick&lt;br /&gt;
        Integer[] aiSelected&lt;br /&gt;
        Integer iItem iCount&lt;br /&gt;
        Get paiSelected of oGrid1 to aiSelected&lt;br /&gt;
        Move (SizeOfArray(aiSelected)) to iCount&lt;br /&gt;
        Showln &amp;quot;Selected Row base_item(s) are&amp;quot;&lt;br /&gt;
        For iItem from 0 to (iCount-1)&lt;br /&gt;
            Showln (Character(9)) aiSelected[iItem]&lt;br /&gt;
        Loop&lt;br /&gt;
    End_Procedure // OnClick&lt;br /&gt;
  End_Object // oButton1&lt;/div&gt;</summary>
		<author><name>Pinkynarf</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Multi-row_select_for_Grid_control&amp;diff=2080</id>
		<title>Multi-row select for Grid control</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Multi-row_select_for_Grid_control&amp;diff=2080"/>
		<updated>2008-09-04T04:38:47Z</updated>

		<summary type="html">&lt;p&gt;Pinkynarf: New page:   This code demonstrates how to select multiple rows in a Grid. The code will work no matter how many columns. The object of this code is to allow the user to use the SHIFT+RCLICK or CTRL+...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;  This code demonstrates how to select multiple rows in a Grid. The code will work no matter how many columns. The object of this code is to allow the user to use the SHIFT+RCLICK or CTRL+RCLICK key to select multiple rows just like a spreadsheet program. Paste this code into a test view to test it and see how it works. Once compiled, you will see a narrow column on the left that acts as a margin. Clicking this gray cell will highlight the row. Using SHIFT or CTRL and clicking another gray cell will select multiple rows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Object oGrid1 is a Grid&lt;br /&gt;
    Set Location to 7 26&lt;br /&gt;
    Set Size to 116 207&lt;br /&gt;
    Set Line_Width to 4 0&lt;br /&gt;
    Set Form_Width    0 to 8&lt;br /&gt;
    Set Header_Label  0 to &amp;quot;&amp;quot;&lt;br /&gt;
    Set Form_Width    1 to 60&lt;br /&gt;
    Set Header_Label  1 to &amp;quot;Column 1&amp;quot;&lt;br /&gt;
    Set Form_Width    2 to 60       &lt;br /&gt;
    Set Header_Label  2 to &amp;quot;Column 2&amp;quot;&lt;br /&gt;
    Set Form_Width    3 to 60       &lt;br /&gt;
    Set Header_Label  3 to &amp;quot;Column 3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    // BEGIN MULTI-SELECT CODE&lt;br /&gt;
    // DO NOT MODIFY&lt;br /&gt;
    Set Select_Mode to Multi_Select&lt;br /&gt;
    Property Integer[] paiSelected&lt;br /&gt;
    Property Integer piLastSelected 0&lt;br /&gt;
    Procedure Select_Toggling Integer iItem Integer iState&lt;br /&gt;
        Integer iCurrent iCol iLast iCount iFrom iTo iRet iUpdate&lt;br /&gt;
        Integer[] aiSelected aiEmpty&lt;br /&gt;
        //&lt;br /&gt;
        Get Dynamic_Update_State to iUpdate&lt;br /&gt;
        Set Dynamic_Update_State to False&lt;br /&gt;
        // Get base item&lt;br /&gt;
        Move (Current_Item(Self)) to iCurrent&lt;br /&gt;
        Move (Mod(iCurrent , Line_Size(Self))) to iCol&lt;br /&gt;
        Subtract iCol from iCurrent&lt;br /&gt;
        // get list of selected items&lt;br /&gt;
        Move (paiSelected(Self)) to aiSelected&lt;br /&gt;
        Move (SizeOfArray(aiSelected)) to iCount&lt;br /&gt;
        //&lt;br /&gt;
        Move (GetAsyncKeyState(VK_CONTROL)) to iRet&lt;br /&gt;
        If (iRet&amp;lt;&amp;gt;0) Begin&lt;br /&gt;
            If (iState) Begin&lt;br /&gt;
                // add selected item&lt;br /&gt;
                Move iCurrent to aiSelected[iCount]&lt;br /&gt;
                // Update last selected with this item&lt;br /&gt;
                Set piLastSelected to iCurrent&lt;br /&gt;
                // Select Current row&lt;br /&gt;
                For iCol from 0 to (Line_Size(Self)-1)&lt;br /&gt;
                    Forward Send Select_Toggling (iCurrent+iCol) iState&lt;br /&gt;
                Loop&lt;br /&gt;
            End&lt;br /&gt;
            Else Begin&lt;br /&gt;
                // remove selected item&lt;br /&gt;
                For iItem from 0 to (iCount-1)&lt;br /&gt;
                    Move aiSelected[iItem] to iLast&lt;br /&gt;
                    If (iLast=iCurrent) Move -1 to aiSelected[iItem]&lt;br /&gt;
                Loop&lt;br /&gt;
                // Update last selected with this item&lt;br /&gt;
                Set piLastSelected to -1&lt;br /&gt;
            End&lt;br /&gt;
        End&lt;br /&gt;
        Else Begin&lt;br /&gt;
            // If shift is used, we will ignore&lt;br /&gt;
            // the state of the clicked row&lt;br /&gt;
            // unselect everything&lt;br /&gt;
            For iItem from 0 to (iCount-1)&lt;br /&gt;
                Move aiSelected[iItem] to iLast&lt;br /&gt;
                For iCol from 0 to (Line_Size(Self)-1)&lt;br /&gt;
                    Forward Send Select_Toggling (iLast+iCol) False&lt;br /&gt;
                Loop&lt;br /&gt;
            Loop&lt;br /&gt;
            Move aiEmpty to aiSelected&lt;br /&gt;
            //&lt;br /&gt;
            Move (GetAsyncKeyState(VK_SHIFT)) to iRet&lt;br /&gt;
            If ((iRet&amp;lt;&amp;gt;0) and (piLastSelected(Self)&amp;lt;&amp;gt;-1)) Begin&lt;br /&gt;
                // select everything in between&lt;br /&gt;
                // do not mark this as the last current row,&lt;br /&gt;
                // the first item of the shift remains&lt;br /&gt;
                If (iCurrent &amp;gt; piLastSelected(Self)) Begin&lt;br /&gt;
                    Move (piLastSelected(Self)) to iFrom&lt;br /&gt;
                    Move iCurrent to iTo&lt;br /&gt;
                End&lt;br /&gt;
                Else Begin&lt;br /&gt;
                    Move iCurrent to iFrom&lt;br /&gt;
                    Move (piLastSelected(Self)) to iTo&lt;br /&gt;
                End&lt;br /&gt;
                Move 0 to iCount&lt;br /&gt;
                For iItem from iFrom to (iTo+3)&lt;br /&gt;
                    // Add to array&lt;br /&gt;
                    Move iItem to aiSelected[iCount]&lt;br /&gt;
                    Increment iCount&lt;br /&gt;
                    // select&lt;br /&gt;
                    For iCol from 0 to (Line_Size(Self)-1)&lt;br /&gt;
                        Forward Send Select_Toggling (iItem+iCol) True&lt;br /&gt;
                    Loop&lt;br /&gt;
                    // next row&lt;br /&gt;
                    Add 3 to iItem&lt;br /&gt;
                Loop&lt;br /&gt;
            End&lt;br /&gt;
            Else Begin&lt;br /&gt;
                // no shift or control key was pressed&lt;br /&gt;
                // Update last selected with this item&lt;br /&gt;
                Move iCurrent to aiSelected[0]&lt;br /&gt;
                Set piLastSelected to iCurrent&lt;br /&gt;
                // Select Current item&lt;br /&gt;
                For iCol from 0 to (Line_Size(Self)-1)&lt;br /&gt;
                    Forward Send Select_Toggling (iCurrent+iCol) iState&lt;br /&gt;
                Loop&lt;br /&gt;
            End&lt;br /&gt;
        End&lt;br /&gt;
        Set Dynamic_Update_State to iUpdate&lt;br /&gt;
        Set paiSelected to aiSelected&lt;br /&gt;
    End_Procedure // Select_Toggling&lt;br /&gt;
&lt;br /&gt;
    Procedure Mouse_Up Integer iWindowNumber Integer iPosition&lt;br /&gt;
        Integer iCol&lt;br /&gt;
        Move (Mod(iWindowNumber , Line_Size(Self))) to iCol&lt;br /&gt;
        Forward Send Mouse_Up iWindowNumber iPosition&lt;br /&gt;
        If (iCol&amp;lt;&amp;gt;1) Send Select_Toggling 0 False&lt;br /&gt;
    End_Procedure // Mouse_Up&lt;br /&gt;
    // END MULTI-SELECT CODE&lt;br /&gt;
&lt;br /&gt;
    //Sample method of how to fill a grid&lt;br /&gt;
    Procedure DoFillGrid&lt;br /&gt;
        Integer iRow iMaxRows&lt;br /&gt;
        Move 20 to iMaxRows&lt;br /&gt;
        For iRow from 0 to iMaxRows&lt;br /&gt;
            Send Add_Item Msg_None &amp;quot;&amp;quot;&lt;br /&gt;
            Send Add_Item Msg_None (&amp;quot;Col 1, row &amp;quot; + String (iRow))&lt;br /&gt;
            Send Add_Item Msg_None (&amp;quot;Col 2, row &amp;quot; + String (iRow))&lt;br /&gt;
            Send Add_Item Msg_None (&amp;quot;Col 3, row &amp;quot; + String (iRow))&lt;br /&gt;
            Set Entry_State item (iRow*4) to False&lt;br /&gt;
            Set ItemColor item (iRow*4) to clBtnFace&lt;br /&gt;
        Loop&lt;br /&gt;
    End_Procedure // DoFillgrid&lt;br /&gt;
    Send DoFillgrid&lt;br /&gt;
  End_Object // oGrid1&lt;br /&gt;
&lt;br /&gt;
  Object oButton1 is a Button&lt;br /&gt;
    Set Size to 14 70&lt;br /&gt;
    Set Location to 151 44&lt;br /&gt;
    Set Label to &amp;quot;Show Selection&amp;quot;&lt;br /&gt;
    // Example on how to get selected rows&lt;br /&gt;
    Procedure OnClick&lt;br /&gt;
        Integer[] aiSelected&lt;br /&gt;
        Integer iItem iCount&lt;br /&gt;
        Get paiSelected of oGrid1 to aiSelected&lt;br /&gt;
        Move (SizeOfArray(aiSelected)) to iCount&lt;br /&gt;
        Showln &amp;quot;Selected Row base_item(s) are&amp;quot;&lt;br /&gt;
        For iItem from 0 to (iCount-1)&lt;br /&gt;
            Showln (Character(9)) aiSelected[iItem]&lt;br /&gt;
        Loop&lt;br /&gt;
    End_Procedure // OnClick&lt;br /&gt;
  End_Object // oButton1&lt;/div&gt;</summary>
		<author><name>Pinkynarf</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Portal:Windows_Applications&amp;diff=2079</id>
		<title>Portal:Windows Applications</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Portal:Windows_Applications&amp;diff=2079"/>
		<updated>2008-09-04T04:07:53Z</updated>

		<summary type="html">&lt;p&gt;Pinkynarf: /* Advanced */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;Visual Dataflex Portal&#039;&#039;&#039; is the place to come for articles and tutorials on developing [http://en.wikipedia.org/wiki/Microsoft_Windows Windows] applications with &#039;&#039;&#039;[[Visual DataFlex]]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Before beginning the more advanced stuff you should consider reading [http://www.visual-dataflex.co.uk/1seater.asp?pageid=1028 Vincent&#039;s book] or attend a 5 days training. Now - on with the show:&lt;br /&gt;
&lt;br /&gt;
==Articles==&lt;br /&gt;
*&#039;&#039;&#039;[[Visual DataFlex]]&#039;&#039;&#039; (covering the basic stuff)&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
*How to add &#039;&#039;&#039;[[Add Workspace Parameter|Workspace Parameters]]&#039;&#039;&#039; using [[cIniFile]]&lt;br /&gt;
*[[Running_VDF_programs_as_Windows_Services]]&lt;br /&gt;
*[[Using On_key for undefined keys]]&lt;br /&gt;
*[[Passing the workspace as a parameter]]&lt;br /&gt;
*[[Add Workspace Parameter|Adding Workspace Parameters]] using the [[cIniFile]] class&lt;br /&gt;
*Adding [[SMTP Email]] to your application using an [[ActiveX]] control&lt;br /&gt;
*[[Run only one instance of your application]]&lt;br /&gt;
*[[Customize prompt lookup behavior in a dbgrid]]&lt;br /&gt;
*[[Print the content of an embedded IE html control]]&lt;br /&gt;
*[[Return data from every object in a dbView]]&lt;br /&gt;
*[[Print to a file using reports]]&lt;br /&gt;
*[[Visual Modelling of multiple visual objects]]&lt;br /&gt;
*[[ExpressConnectivity]]&lt;br /&gt;
&lt;br /&gt;
==Advanced==&lt;br /&gt;
* [[Add icons with subset of images to CodeJock CommandBars]]&lt;br /&gt;
* [[Programmatically edit a treeview label]]&lt;br /&gt;
* [[Muli-row select for Grid control]]&lt;br /&gt;
&lt;br /&gt;
==External links==&lt;br /&gt;
* http://www.vdf-guidance.com&lt;br /&gt;
* http://visualdataflexdeveloper.org/ &lt;br /&gt;
* http://www.visualdataflex.com&lt;br /&gt;
* http://www.visualdataflex.ru (Russian)&lt;br /&gt;
* http://www.dataaccess.com&lt;br /&gt;
* http://www.dataaccess.nl&lt;br /&gt;
* [http://www.sture.com/wasp/ WASP Newsgroup search] engine&lt;br /&gt;
* [http://www.starzen.com StarZen Technologies] Addon Tools, Books, Magazines, Consulting&lt;br /&gt;
* [http://www.redeemedsoftware.com Redeemed Software] Crystal Report Utilities, Autocomplete, and more&lt;br /&gt;
* [http://www.redeemedhosting.com Redeemed Hosting] VDF Webapp Hosting and Virtual Servers&lt;br /&gt;
&lt;br /&gt;
==Requested Articles / Works in progress==&lt;br /&gt;
&lt;br /&gt;
*[[Converting from DOS to Windows]]&lt;br /&gt;
*[[COM|Using COM Objects]] (reuse existing functionality)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Portals]]&lt;br /&gt;
[[Category:DataFlex (Character Mode)]]&lt;/div&gt;</summary>
		<author><name>Pinkynarf</name></author>
	</entry>
	<entry>
		<id>https://dataflex.wiki/index.php?title=Portal:Windows_Applications&amp;diff=2078</id>
		<title>Portal:Windows Applications</title>
		<link rel="alternate" type="text/html" href="https://dataflex.wiki/index.php?title=Portal:Windows_Applications&amp;diff=2078"/>
		<updated>2008-09-04T04:06:31Z</updated>

		<summary type="html">&lt;p&gt;Pinkynarf: /* External links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;&#039;Visual Dataflex Portal&#039;&#039;&#039; is the place to come for articles and tutorials on developing [http://en.wikipedia.org/wiki/Microsoft_Windows Windows] applications with &#039;&#039;&#039;[[Visual DataFlex]]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Before beginning the more advanced stuff you should consider reading [http://www.visual-dataflex.co.uk/1seater.asp?pageid=1028 Vincent&#039;s book] or attend a 5 days training. Now - on with the show:&lt;br /&gt;
&lt;br /&gt;
==Articles==&lt;br /&gt;
*&#039;&#039;&#039;[[Visual DataFlex]]&#039;&#039;&#039; (covering the basic stuff)&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
*How to add &#039;&#039;&#039;[[Add Workspace Parameter|Workspace Parameters]]&#039;&#039;&#039; using [[cIniFile]]&lt;br /&gt;
*[[Running_VDF_programs_as_Windows_Services]]&lt;br /&gt;
*[[Using On_key for undefined keys]]&lt;br /&gt;
*[[Passing the workspace as a parameter]]&lt;br /&gt;
*[[Add Workspace Parameter|Adding Workspace Parameters]] using the [[cIniFile]] class&lt;br /&gt;
*Adding [[SMTP Email]] to your application using an [[ActiveX]] control&lt;br /&gt;
*[[Run only one instance of your application]]&lt;br /&gt;
*[[Customize prompt lookup behavior in a dbgrid]]&lt;br /&gt;
*[[Print the content of an embedded IE html control]]&lt;br /&gt;
*[[Return data from every object in a dbView]]&lt;br /&gt;
*[[Print to a file using reports]]&lt;br /&gt;
*[[Visual Modelling of multiple visual objects]]&lt;br /&gt;
*[[ExpressConnectivity]]&lt;br /&gt;
&lt;br /&gt;
==Advanced==&lt;br /&gt;
* [[Add icons with subset of images to CodeJock CommandBars]]&lt;br /&gt;
* [[Programmatically edit a treeview label]]&lt;br /&gt;
&lt;br /&gt;
==External links==&lt;br /&gt;
* http://www.vdf-guidance.com&lt;br /&gt;
* http://visualdataflexdeveloper.org/ &lt;br /&gt;
* http://www.visualdataflex.com&lt;br /&gt;
* http://www.visualdataflex.ru (Russian)&lt;br /&gt;
* http://www.dataaccess.com&lt;br /&gt;
* http://www.dataaccess.nl&lt;br /&gt;
* [http://www.sture.com/wasp/ WASP Newsgroup search] engine&lt;br /&gt;
* [http://www.starzen.com StarZen Technologies] Addon Tools, Books, Magazines, Consulting&lt;br /&gt;
* [http://www.redeemedsoftware.com Redeemed Software] Crystal Report Utilities, Autocomplete, and more&lt;br /&gt;
* [http://www.redeemedhosting.com Redeemed Hosting] VDF Webapp Hosting and Virtual Servers&lt;br /&gt;
&lt;br /&gt;
==Requested Articles / Works in progress==&lt;br /&gt;
&lt;br /&gt;
*[[Converting from DOS to Windows]]&lt;br /&gt;
*[[COM|Using COM Objects]] (reuse existing functionality)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Portals]]&lt;br /&gt;
[[Category:DataFlex (Character Mode)]]&lt;/div&gt;</summary>
		<author><name>Pinkynarf</name></author>
	</entry>
</feed>