PlanetSquires Forums

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: FB and ByRef dot syntax limitations  (Read 337 times)

Paul Squires

  • Administrator
  • Guru Member
  • *****
  • Posts: 9206
  • Windows 10
    • PlanetSquires Software
FB and ByRef dot syntax limitations
« on: March 03, 2020, 04:33:14 PM »

Well, I swear I could have had the visual designer library finished months and months ago if I had just simply used pointers and the -> syntax. Using ByRef objects and the dot syntax has proven to be challenging. A couple of limitations like not BYREF variables in TYPE declarations, or ByRef arrays, has made things a little challenging.

Today, I found another pain. If you have TYPEs that have Get/Set properties and one TYPE variable is included int he other variable, then the compiler will throw Error 8, undefined symbol if you attempt to call a getter (the compiler defaults to using the setter first). There are several posts on the FB forum about this.

- I have a TYPE called wfxTreeNode
- I have the main TYPE wfxTreeView
- In the wfxTreeView I have a get/set property for a "SelectedNode" that is of type wfxTreeNode

You can not assign a reference to the SelectedNode because BYREF is not allowed as a declare in the TYPE wfxTreeView. I have to make a copy of the node that is selected. I worked around this by also tracking the pointer via another TYPE field (pNodeSelected). When doing operations on the SelectedNode I have to switch out to the pointer to ensure that the original treeview node data gets updated (e.g. SelectedNode.Text = "My node text").

A bigger irritation is that I can not do this without getting the compiler error:

frmMain.TeeeView1.SelectedNode.Remove

The problem is that the compiler can not resolve that I want to use the Getter version of the property. I want to "get" the SelectedNode and then call the Remove method. The compiler works left to right and fails by trying to "set" during the SelectedNode call.

If change the line to an expression then the compiler realizes that the Get should be used. Sooooo.... wrapping the line in parenthesis will allow the compile and work as expected, but as you can imagine, I don't want the user to have to do this:

(frmMain.TeeeView1.SelectedNode.Remove)

A workaround would be to assign to a temp variable:
dim as wfxTreeNode TreeNode = frmMain.TeeeView1.SelectedNode
TreeNode.Remove

Once again, that's an extra step that shouldn't be needed.

I'll probably end up having to convert the properties to be something like:
frmMain.TeeeView1.GetSelectedNode.
frmMain.TeeeView1.SetSelectedNode.

Too bad.
Logged
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

  • Administrator
  • Guru Member
  • *****
  • Posts: 9206
  • Windows 10
    • PlanetSquires Software
Re: FB and ByRef dot syntax limitations
« Reply #1 on: March 03, 2020, 07:31:01 PM »

Oh, and I almost forgot this one which I would love to have: Being able to have a ByRef variable that does not contain a reference. Soemthing like an empty reference.

Code: [Select]
#Define UNICODE
#Define _WIN32_WINNT &h0602 

#include once "windows.bi"
#include once "Afx\CWindow.inc"


type wfxTreeNode
   Text as wstring * 260
end type

' ByRef variables must have a reference assigned. They
' can not be empty or null (sadly)
dim byref as wfxTreeNode TreeNode = null

' Would be nice to do a test like this.
if IsEmpty(TreeNode) then
   ' TreeNode has a valid reference to it...
else
   ' TreeNode does not point to a valid object   
end if

' If we were able to assign Null to the ByRef variable
' then it would be nice if the following would fail
' gracefully/silently (or maybe a runtime error that
' could be checked). Not having to do an explicit test
' would kind of treat the ByRef variable almost like
' a Smart Pointer.
TreeNode.Text = "This will not assign because TreeNode is Null."


sleep

Logged
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

  • Administrator
  • Guru Member
  • *****
  • Posts: 9206
  • Windows 10
    • PlanetSquires Software
Re: FB and ByRef dot syntax limitations
« Reply #2 on: March 03, 2020, 09:23:23 PM »

Apparently, you can use Static byref in a Type. I will try that tomorrow to see if it helps to simplify my code.

Type
   static byref ref as wfxSelectedNode
End Type
Logged
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Josť Roca

  • Guru Member
  • *****
  • Posts: 3255
Re: FB and ByRef dot syntax limitations
« Reply #3 on: March 04, 2020, 01:34:08 AM »

> frmMain.TeeeView1.SelectedNode.Remove

It can never work. In the way you have designed the classes, Remove is a method of the wfxTreeNodeCollection. Therefore, you need to do

frmMain.TreeView1.Nodes

to get a reference to the wfxTreeNodeCollection and be able to call Remove

Remove also needs an index, which is a long value, but SelectedNode returns a reference to a wfxTreeNode class, not an index.

Therefore, you will need something like

frmMain.TreeView1.Nodes.Remove(frmMain.Treeview1.SelectedNode.Index)

Josť Roca

  • Guru Member
  • *****
  • Posts: 3255
Re: FB and ByRef dot syntax limitations
« Reply #4 on: March 04, 2020, 02:03:50 AM »

A way to simplify frmMain.TreeView1.Nodes.Remove(frmMain.Treeview1.SelectedNode.Index) can be to add a RemoveNode mehod to the wfxTreeView class, e.g.:

frmMain.TreeView1.RemoveNode (<node to remove>)

Paul Squires

  • Administrator
  • Guru Member
  • *****
  • Posts: 9206
  • Windows 10
    • PlanetSquires Software
Re: FB and ByRef dot syntax limitations
« Reply #5 on: March 04, 2020, 09:07:20 AM »

Hi Jose, you probably don't have access yet to the code that I wrote for the Remove (I don't think that I uploaded it yet to GitHub). For the TreeView, the TYPE has a collection of root TreeView nodes. Each TreeNode also has a Nodes collection as part of its TYPE. Basically, every TreeNode has a collection of child TreeNodes. (hope I described that correctly).

For each TreeNode, I have methods implemented such as Remove, Expand, ExpandAll, and Collapse. This allows you to perform the action on the TreeNode itself rather than having to go through the more cumbersome approach of using the Nodes collections. So, if I retrieve the SelectedNode (wfxTreeNode class), then I should be able to call the Remove method on it. My (newest) code passes down a pointer to the main TreeView type to allow its TreeNodes and Nodes collections to have access to the top level TreeView class. This allows me to call methods on the main TreeView class (in this case, when TreeNode.Remove is called I simply need to call TreeNode.pTreeView->Remove( address of treenode) and do a recursive search from the main branches of the tree until I find the node to delete). The problem is that SelectedNode is a copy of the node so the address that I pass to remove has be the actual TreeNode (which I store in a variable called pSelectedNode). I will investigate using Static ByRef because that should be able tohold the reference to the actual node and might allow me to dispense with using pSelectedNode pointer.

All of this is tough to visualize without the code so I have attached the latest working copy of the code for your reading pleasure. LOL  :-)
« Last Edit: March 04, 2020, 09:09:08 AM by Paul Squires »
Logged
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

  • Administrator
  • Guru Member
  • *****
  • Posts: 9206
  • Windows 10
    • PlanetSquires Software
Re: FB and ByRef dot syntax limitations
« Reply #6 on: March 04, 2020, 11:19:19 AM »

I changed the "SelectedNode" properties to the following functions: GetSelectedNode and SetSelectedNode. These changes work perfectly well (although they are not as aesthetically pleasing to the eye as simply using SelectedNode).

Code: [Select]
      Declare function GetSelectedNode() byref as wfxTreeNode
      declare function SetSelectedNode( byval hItem as HTREEITEM ) as Long
      Declare function SetSelectedNode( byref nValue as wfxTreeNode ) as Long

function wfxTreeView.GetSelectedNode() byref as wfxTreeNode
   dim pTreeViewNode as wfxTreeNode ptr
   dim as HTREEITEM hItem
   if this.hWindow then
      hItem = TreeView_GetSelection( this.hWindow )
      if hItem then
         pTreeViewNode = cast(wfxTreeNode ptr, TreeView_GetlParam( this.hWindow, hItem))
         if pTreeViewNode then
            _SelectedNode = *pTreeViewNode
            this.pSelectedNode = pTreeViewNode
         end if   
      end if
   end if
   if (hItem = 0) or (pTreeViewNode = 0) then
      ' Need to return a reference otherwise crash if trying to access the return reference.
      static tvNode as wfxTreeNode
      _SelectedNode = tvNode
   end if
   _SelectedNode.pTreeView = @this
   function = _SelectedNode
end function

function wfxTreeView.SetSelectedNode( byval hItem as HTREEITEM ) as Long
   if this.hWindow then
      TreeView_SelectItem( this.hWindow, hItem )
      dim pTreeViewNode as wfxTreeNode ptr = cast(wfxTreeNode ptr, TreeView_GetlParam( this.hWindow, hItem))
      if pTreeViewNode then _SelectedNode = *pTreeViewNode
   end if
   function = 0
end function

function wfxTreeView.SetSelectedNode( byref tvNode as wfxTreeNode ) as Long
   if this.hWindow then
      TreeView_SelectItem( this.hWindow, tvNode.hNode )
   end if
   _SelectedNode = tvNode
   function = 0
end function

Logged
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

  • Administrator
  • Guru Member
  • *****
  • Posts: 9206
  • Windows 10
    • PlanetSquires Software
Re: FB and ByRef dot syntax limitations
« Reply #7 on: March 04, 2020, 11:46:16 AM »

...and I added node sorting as well so the only major missing feature at this point is images for the nodes. I don't plan on adding that support for the first version as I expect that there will be enough to test and flush out prior to adding the additional layer of complexity with images.

I plan to add the Help file documentation and then will release another version.
Logged
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer