TreeView appears as CustomControl - cannot re-cast to TreeView - vba

I have a TreeView in a form (specifically Microsoft TreeView Control, version 6.0), and whilst it doesn't play so nicely with the VBE's Intellisense, I'm able to use all its properties, functions, etc.
Unfortunately, I seem unable to do this:
Dim tvw As TreeView
Set tvw = Me.MyTreeView 'The control on the form
I get a type mismatch error. So I fired up the Immediate window and had a look at the type of my form's TreeView:
? TypeName(Me.MyTreeView)
CustomControl
It seems that, for whatever reason, VBA is treating my TreeView object as a CustomControl object.
How can I convert CustomControl back to TreeView (or make VBA treat it as a 'TreeView' in the first place)? Type casting doesn't seem to exist in VBA (at least, VB's CType function does not work). I'm writing a wrapper class for the TreeView, so just treating it as a CustomControl won't work, as I need access to Treeview's events, etc.

A bit more digging, this answer on another question seems to have worked:
Dim tvw As TreeView
Set tvw = Me.MyTreeView.Object

Related

Access VBA control reference issue?

I'm trying to loop through all the controls on an Access form but for some reason the controls object is not giving me the correct properties.
When I select and right click on "Control" (in 'As Control') it says "identifier under cursor is not recognized".
I'm thinking it's a reference issue but I can't figure what's missing or incorrect. I don't get any syntax error so Control is a valid object.
I tried decompiling, repair and compacting just to be sure.
The generic control object doesn't have too many useful properties or methods.
It covers also things like lines or subform containers or tab cards, which don't have much in common.
The specific controls like Textboxes have all the properties you are probably looking for.
You still can loop over all controls, and set the usual properties that most controls have, like .Visible or .Locked. Even if Intellisense doesn't provide them.
ctl.Locked = bLocked will work.
But you should handle (On Error Goto) or ignore (On Error Resume Next) runtime errors that will occur, if one control doesn't have the property you want to set.
Bonus question to everyone: why does the generic control object have the .Dropdown method that applies only to combo boxes? Very strange.

What is the distinction between a CommandButton's .caption and .text properties in VBA?

I have a CommandButton in Excel and found that both the .Caption and .Text properties return the same visible text of the button. Here's the code I used to see the values:
Debug.Print ActiveSheet.Buttons("My_Command_Button").Caption
Debug.Print ActiveSheet.Buttons("My_Command_Button").Text
What is the distinction between these two properties and does the distinction matter?
Trick question. If you examine the CommandButton coclass definition in fm20.dll (or in the VBE's Object Browser, you'll find that it doesn't have a Text property:
The ActiveX controls are composited via extension at run-time, so properties that are specific to how the control is embedded in a spreadsheet, or a UserForm, (or anything else for that matter) are actually being driven by the OLE container that "owns" the object. It makes a certain amount of sense if you think about it - why should a CommandButton care what it's Left or Top property is? You shouldn't ever need to have a CommandButton that isn't the child of another parent window or container, and it isn't the responsibility of the CommandButton to determine where it is within the window - that's the window's job. It's part of the reason why they don't have public constructors:
Dim example As CommandButton
Set example = New CommandButton '<-- Nope.
If you were able to instantiate a parentless CommandButton, you'd find that the only way to set the text on the button would be to set the .Caption property. That's because at a deep down Windows API level, it is a window (in that it has an hWnd), and the convention is for windows to have a Caption property. How that is displayed is implementation specific. In this specific instance, they can be treated interchangeably, but the .Caption property is the "real one", and the .Text property mirrors it. Unless you're doing something extremely bizarre with it (like getting its hWnd and using that with the Windows API directly), they are for all intents and purposes the same thing.

Accessing a form's tooltip from another class in visual studio (vb.net)

I am quite new to visual studio. Developed previously with vba.
Encountering a problem writing a language translation class.
The language dependent values are stored in a localdb table every row having formname , controlname and controlproperty as wel as a column per language.
The Language class Handles the translations at runtime. For forms I use a Sub FormUpdate(frm as Form) called from the form's load event as FormUpdate(Me) it checks the form's language kept in a custom parameter against the current language and updates the .text property of the controls on the form that are exposing some language specific text (Buttons, Labels, Tabcontrol etc..).
However I could not solve how to access and update the form's Tooltip component from the language class. (in vba it was easy as every control was exposing it's Controltiptext property)
In the form's class you would use MyTooltip.Settooltip(CtrlName,Text) but I could not figure out how to do that from another class (the tooltip component is not part of the form's controls - and I could not figure out nor find info how to do it) ??
Could someone advise pls?
I was so focused on finding a similar way to the one I used before that I did not see the easy way to resolve it - not yet enough accustomed to the new environment.
Sure, I am interested in an answer to my question but instead of making it too complicated using external components I'll do it the easy way by overloading the FormUpdate sub adding a sub with an extra parameter as Tooltip.

vfp9 'THIS' equivalent to vb.net

In VFP9 there is an object reference THIS which provides a reference to the current object in event code or in a class definition. In vb.net there is ME but as i observed it referred to the actual form not the object itself.
VFP Code for button1 click:
this.caption = "CLICKED" <<OR>> thisform.button1.caption = "CLICKED"
VB Code
----------------------- <<OR>> Me.button1.text="CLICKED"
I want to know the dotted line equivalent in vb.net, a reference to the current object. We have an VFP9 system and I'm trying to convert it to vb.net.
VFP works based on nested object references for the controls and "this" allows the capability of relative reference. If you wanted to long-hand the VFP equivalent, it would be something like
Thisform.button1.Caption = "CLICKED"
Now, that said, you may encounter other controls downstream in your conversion that look something like...
this.Parent.otherControl.something...
The ".Parent" just refers to the parent control of the current object. So, say you have a form with a pageframe... On that are 3 pages. On Page 1 has a container. That container has a textbox and a button.
In the click of the button, you want to display a message of the value in the textbox control. The button may have something like
Messagebox( This.Parent.TheTextBoxControl.Text )
You don't have to know how deep the container is buried in the form, you just know that the textbox is relative to the button via the same parent control.

Find all ContextMenuStrips defined on a Windows Form (not necessarily attached at runtime)

In my winforms project, some of the forms have a set of ContextMenuStrips defined on them (through the visual studio designer).
Some of these contextmenustrips have been attached to controls, but others have not.
Now my problem is this: I need to go through all of the ContextMenuStrips at runtime, whether they are attached or not.
I've got some code that will recursively go through all controls and check the ContextMenuStrip property and this works fine.... However I can not get to the ContextMenuStrips that haven't been assigned to a control yet.
ContextMenuStrip components that you drop on a form with the designer are added to the "components" collection. You can find them back by iterating it:
For Each co As System.ComponentModel.Component In Me.components.Components
If TypeOf co Is ContextMenuStrip Then
Dim cms = DirectCast(co, ContextMenuStrip)
'' do something
End If
Next