How Can I Comprehensively Manage my VBA UserForm's Properties? - vba

I am writing my first VBA Add-In under Microsoft Office Word 2007 with Windows 7 Pro/64. Part of this Add-In is a UserForm. Using the Visual Basic editor that runs from Word, I find there are two ways of viewing, and two ways of modifying a UserForm's properties:
View all properties from Object Browser (F2)
View some properties and edit them from Properties Window (F4)
Manually enter and edit any property from the Code window (F7)
Here is a screenshot of my Properties and Code windows:
A problem I find is that the Properties Window contains only a subset of the UserForm's properties (notice that CanPaste, CanRedo, and CanUndo don't appear in Properties), and changes made in the Properties Window are overridden by changes made in the Code window (e.g., at runtime, Me.Caption from the Code window above overrides the Caption field in Properties).
I suppose I should avoid using Properties at all then, and enter all settings via UserForm_Initialize as shown above. But (a) for some settings, Properties makes several settings at once. For example, selecting Verdana Bold from Properties equals Font = Verdana and Font.Bold = True in Code. And (b) it seems Properties sets the subset of properties it controls to defaults of its choosing, and if I change them I can't see what they started out as.
I therefore desire unified and comprehensive access to all my UserForm's properties at once, including the aforementioned default settings. Does anyone know how to reveal a UserForm's default settings as code, or to automatically open all its current settings in the Code window? Is there an umbrella mechanism I'm not aware of?
I'm not a veteran VBA programmer, but I can't believe my experience is unique. I've searched the 'net in vain for a solution. How do you with more experience manage this dilemma?

You use the Properties window to set appearance-related properties at design time. Those property values will then always apply unless you explicitly change them at run-time with VBA code.
Properties that don't relate to appearance, such as CanPaste and CanRedo relate to the state of the form at run-time, so it doesn't make sense to have them configurable at design-time.
You can change nearly all of the properties at run-time, whether it is in the Initialize event or elsewhere. You can even add controls at run-time, but your changes won't be persisted once the instance of the form terminates.

Related

How to implement advanced custom properties in VB6 usercontrols?

Sorry I don't know how to name it other than "advanced custom properties". If I know, I would search it first.
I am dealing with a legacy code using 3-rd party controls.
In VB6, When you drag that control onto the form, you can see all the properties supported by the control in the "Properties" window. Such as MarginLeft, MarginRight etc. etc.
That's no problem.
In the "Property" window, the top-most property is generally the "(Name)" field, which is the name of the control.
But the 3-rd party control I am using, has another two "fake properties" above "(Name)", which are "(About)" and "(Custom)".
When you click "(About)", there will be a dialog box showing the company info. When you click "(Custom)", there will be another dialog box showing more properties. These dialog boxes are shown in VB6.
In the "(Custom)" dialog box, you can modify normal properties (same as modifying directly in the Property window). You can do more. There are more properties that are not normal properties (at least you cannot find anything in the Property window).
When you save this form, for normal properties, everything are saved into .FRM file. E.g.,
Control1.MarginLeft = 5
Control1.Text = "I am a control"
However, for the "advanced properties" edited in the (Custom) dialog box, they are not saved in .FRM, they are saved in .FRX in binary format.
E.g., in (Custom) dialog box, you can edit a property called "Caption", which includes text of this caption, the font, the weight, the display style, and a lot of similar properties for Caption. In .FRM, it is something like,
Control1.Caption = "frmForm1.frx":013F
All the text and related properties of Caption are saved in binary format in .FRX file.
Note that, there's no Caption property in the normal Property window, you can only edit it in the "(Custom)" dialog box.
My question is as follows,
How to implement such a (Custom) dialog box that can be shown in VB6?
How to let VB6's Property window display (About) and (Custom)?
How to tell VB6 that Caption property shall not be displayed in Property window, but you can use directly in code as Control1.Caption = xxxx.frx:offset?
How to tell VB6 that this Caption property shall be saved in .FRX, and how to tell VB6 the size of the data, so that VB6 can manages the offset automatically?
How to load the data automatically via VB6 so that the correct values can be displayed in (Custom) dialog box?
As far as I know, .frx formats are secrets, there are a lot of ppl digging into various .frx for standard controls such as Binary(images), List, and Text. I am curious how can a 3-rd party control utilizing .frx, shall the 3-rd party control define its own .frx format? Including for example, how many bytes in front for Length (or no length field at all, it's fixed length), how many bytes for style1, how many bytes for style2, etc.
Thanks a lot. If you know what proper name it is for this "advanced properties", just tell me the name and I can search myself.
I tried to search for advanced properties but didn't really get anything I want to know.
The frx files are for binary or other non-basic data types. The frm will store the simple properties. What you need to do is to hook into the UserControl events WriteProperties and ReadProperties. You don't need to know where the backing storage is (frm vs frx)., you just need to access the PropBag to read and write your data.
Google is your friend to find the documentation:
https://msdn.microsoft.com/en-us/library/aa242140(v=vs.60).aspx
Or additional information on the topic:
http://www.vbforums.com/showthread.php?365735-Classic-VB-How-do-the-ReadProperties-and-WriteProperties-work-(PropertyBags)&s=3cfbd675928ad1eb94f68fbfb13ccd88&p=3672781&viewfull=1#post3672781
Good luck!

VBA Adding a User Defined Control to Userform at Runtime

So I've made the following control in Design Mode then added the control to a new page Custom in my toolbox.
Now, what would I use for the progID parameter in Controls.Add()? How do I look up this value? Controls.Add("Forms.Frame.1") adds a regular frame, not the desired custom control.
As far as I am aware, you do not generate a new progID with a custom control. Per the MSDN documentation for custom/modified controls:
Note: When you drag a control onto the Control Toolbox, you only transfer the advanced property values.
So only the properties are transferred; the actual control is still of the same type/s as the one you created it from. Further, it looks like this progID is "a unique system-wide string that the Windows operating system can use to identify your control's type." So unless you are up to coding your own control, it looks as though you're just passing properties to the custom toolbox controls you create there.
You'll have to just replicate the custom control each time you want to add it. Just create a sub with all the correct properties and call it. Not what you were looking for, but it'll get the job done.

Unable to Move Control on Windows Form Designer [duplicate]

Setup:
I have created a Form that I wish to have serve as the base from which I will inherit other forms. This base form serves as a "template" of sorts, but it also provides a good deal of functionality related to the structure, as well as the interrelation of all of the controls provided.
A primer for the images that follow... The top info-colored bar is a custom control inherited from ToolStrip. The bottom strip is another custom, again inherited from ToolStrip. The left white block is a TreeView and the right block is a TabControl (having deleted all TabPages from it...I intend for these to be added in the inherited forms).
Image of base form in designer:
Image of inherited form in designer:
Clearly, the only difference is that when I open the inherited form, I get a little box icon superimposed over each control, and when I click them, I get the padlock telling me I cannot edit.
The problems:
All controls on the inherited form are locked. I have researched the issue of visual inheritance, and as far as I can tell, I'm not using any controls that expressly do not support it, as this link suggests there are. In this Q&A, Hans suggests changing the modifier on those controls, which I have done. In fact, I tried both Public and Protected, all to no good result.
I am stumped.
This is a technical restriction in the designer, it is specific to the SplitContainer control you are using. And some other ones. The trouble-maker is the ISupportInitialize interface.
Controls use this interface when they can't afford the properties of the control to be assigned in an arbitrary order. The designer helps when it sees that the control implements this interface, it calls the BeginInit() method when it starts assigning properties, EndInit() when it is done. The control uses these methods to delay the side-effect of property assignments, the EndInit() method makes them effective. Important for SplitContainer, the minimum sizes of the panels also affect the splitter position.
Perhaps you can see the rub, the InitializeComponent() method in the base form class has already called ISupportInitialize.EndInit(). So modifying properties again in the derived form class is unlikely to turn out well. The designer protects the control from this by locking it.
Very inconvenient, there is no simple workaround. If modifying the SplitContainer in the derived form class is a hard requirement then you'll have to give up on inheriting it or write the code by hand in the derived class constructor.

How to identify a specific ActiveX Interface based on limited information

I am in the process of developing an ActiveX control for embedding in Rockwell Automation's Factory Talk View. (See ActiveX DLL Error: Solved to see how great a start I got off to!)
At the moment I have an ActiveX control that seems to embed into the host system OK, but is not fully integrated into the VBA process. I believe that this is because I have not implemented some specific COM interface that is required, but I have no documentation as to what that is. I do know that standard MS controls like the Microsoft Forms 2.0 controls do implement the required interface and fully integrate.
The key functionality I am missing relates to a property that I need to set in order for my VBA code to actually see the ActiveX object. This property can be seen when opening the property panel for any activeX control placed on a Factory Talk screen, but NOT when looking at the properties of ActiveX controls embedded in (for example) Excel. Thus I am probably trying to chase down some custom Rockwell implementation. I am hoping that SO might be able to give me some aid into how to track down what I want based on recognizing the functionality it implements.
Now to the actual property. In Factory Talk the property is called "ExposeToVBA", and has a type "long". You have a choice of 3 values selected from a drop down list:
Not Exposed - When set to this, the controls name is not even visible to VBA code
Type Info Extension - Not sure what this does
VBA Control - VBA code can see and interact with the control.
When I select anything other than "Not Exposed" for my control, I get a warning dialog box with no text on it. For other controls I need to set it to "VBA Control" in order to interact with it in the VBA code (d'oh)
I suspect that the value of this property is translated into some calls to an ActiveX interface on the target control.
The Question
What I want to do is identify what interfaces something like a "Forms 2.0 Label" implements that would match the above functionality. And also perhaps how I could translate this into my C# based control (based on C# ActiveX control (CSActiveX))
I know its a long shot, but I'd appreciate any and all suggestions
This became moot when I found a canned Active-x control that had the functionality that I needed.
FWIW This is what I believe that I used: DMGraph

Refreshing the ribbon interface after a call from a macro in an excel sheet

Here is my scenario:
I have an old excel project with macros that I've imported in a vsto project.
I have designed a custom ribbon (startFromScratch = true) to make it look like a dictator application.
I still want to use the existing macro code since it would take too much time to translate all the vba code in c# code
I have a class that is marked with the [ComVisible(true)] attribute so that I can call vsto methods from the vba code.
The problem is that I can't hide tabs, I can't get the ribbon to refresh. I can change the state of other controls (e.g. set checked state for CheckBox), but I can't hide or disable my custom tabs.
I have tried PerformLayout(), PerformDynamicLayout() on the ribbon, ribbon.RibbonUI.Invalidate(), but nothing works, the tab never changes state, although in code I set its visible property to false.
What do I need to do in order to refresh the ribbon at runtime?
Edit:
I just tried the same thing by exporting the ribbon to xml and the Invalidate() method works as expected. Is there any way to accomplish this for a ribbon designed with the visual editor?
I've replicated your problem when I set the StartFromScratch property of the ribbon to True, but it goes away when I set it to False. This is confirmed by MSDN.
You cannot change the visibility of custom tabs at run time if this property is set to true.
As a workaround, set StartFromScratch to False, add in a tab for each default tab, setting the ControlIdType of each to Office and the OfficeId of each to their default name (TabHome, TabFormulas, etc.), then set each of these built-in tab's visibility to False. (MSDN has made available a full list of control IDs for their Office apps for easy reference.)