I want to browse a directory where many Matlab GUI's (.fig files and their related .m files) are stored and change them systematically. For each, I want to search for a certain popup menu and, if it exists, delete some specific options.
I usually use get() and set() or similar functions to fiddle with GUI's, but these functions require handles, and I don't know how to get handles when not running the GUI, and also I wouldn't know how to save the changes.
If I open a .fig as text it is unintelligible.
I'm considering opening each at a time in guide (Matlab's GUI development environment) and changing it manually, but really would like to avoid it. I'm talking about tens of files, and my action might have to change in the future.
Maybe there would be a way to control guide from the command line? Or another solution?
You can load the .fig files using hgload or openfig. Both these functions return the figure's handle.
Once you have the figure's handle you can use findobj to get the popup menu's handle. Then set and get as normal to change the menu's options, and then save the modified figure using hgsave.
For example:
f = hgload('file.fig');
menuH = findobj(f, 'Type', 'popup');
set(menuH, 'String', new_options);
hgsave(f, 'file.fig');
gcf() immediately after open() gets the handles and can be done programatically for many figures.
Related
I have a system that allows users to create multiple diagrams. I want to be able to copy a part of one diagram, close it, run another and paste in what I have copied. The problem is that the diagram.copy() and diagram.paste() functions use an internal clipboard which is lost when I close the original diagram, so there's nothing to paste when I open the other one.
I'm very new to Telerik, so I don't really know how to approach this. I tried digging through the documentation, but I couldn't see any way to interact with the internal clipboard other than the two functions.
Preferably I'd like to be able to read the internal clipboard, copy it to a global variable and then read the variable back when opening the destination diagram.
Or maybe there's a way to read the selected shapes into a variable without using the copy() function?
Reading the source code, I've found it's stored in the variable diagram._clipboard . You can run this sample and inspect: https://dojo.telerik.com/onunEkib
However, as an undocumented feature, this can change and break when upgrading your Kendo version. Plus, as this is the diagram's internal data, it can be invalid for the target diagram.
What I'd do is a custom copy button that gets the current selection through the select method.
I have a GUI menu on Matlab with 4 buttons (menu.fig). Then I have 4 .fig file that I want to open when I click on the buttons. Here it's all ok, when I open a .fig from menu and insert value to do a plot I get this error:
???? Attempt to reference field of non-structure array.
If I try to open 1.fig directly, everything works perfectly.
I read that the problem is with eval(), but I can't solve it.
I changed the variable names on each .fig file
One 1.fig:
function pbutton1_Callback(hObject, eventdata, handles)
A1=get(handles.edtSAmp,'String');
f1=get(handles.edtSFreq, 'String');
fi1=get(handles.edtSFase, 'String');
t1=get(handles.popTipo, 'Value');
A1=str2double(A1);
f1=str2double(f1);
fi=str2double(fi1);
SinalSinusoidal(A1,f1,fi,t1);
I got the error on the that 1st line.
I guess this is something MATLAB GUI not handled well. I know it used to work, but when you tweaking your UI or UI related code a bit and accidentally you modified some area MATLAB told you not to touch, this kind of issue begin to happen.
The workaournd is to start the GUI from M editor by clicking run
I know it works, but originally, when I directly lauch it , it works too. so, this is not the end of it, people are just not getting to the end of it.
The problem is with probably with handles1. It's not a structure array like you expect it to be. In GUI's created with GUIDE, this variable is usually called handles, if you have both handles and handles1 make sure handles1 contains handles to the objects in the figure. If you're using handles1 only, make sure you're initializing it properly.
We have an in house button control, and quite frankly it sucks. I'd like to replace it but I don't want to go onto every form in our project and delete/add a new control. It seems to me that if I design a new button that has all the same properties as the old one then I ought to be able to give it the same name as the old one and just replace all the reference lines in the vbp files to point to the new control.
Has anyone tried this (better yet have you heard of a tool that will do it for you) and if so what 'gotchas' should I be on the look out for?
Thanks!
The *.vbp files are one place you'll need to change. There are also references to the used control libraries in the files containing GUIs -- that's form (*.frm), control (*.ctl), and property page (*.pag) files. These files are in a plain text format and you can see the references at the top. They look like this:
Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; "mscomctl.ocx"
Those refs will need to be added or updated in all relevant files if the new control is a compiled OCX. If it's in the same project I don't think it needs any reference there, and if it's in a different project in the same project group I'm not sure. Save a test form with the new control to see.
Note that you don't have to keep the same control class name. Inside the *.frm/ctl/pag files, instances of individual controls on them are represented by a simple format like this:
Begin VB.CommandButton Command2
Caption = "Cancel"
Height = 375
Left = 2460
TabIndex = 1
Top = 2400
Width = 1455
End
The syntax of the first line there is "Begin LibraryOrProjectName.ClassName NameOfThisInstance". So, provided the offending control's name is distinctive it should be easy to search & replace references to it both in the BASIC source and in the GUI layouts. You might want a plain text editor that can perform search and replace across multiple files (Notepad++ is one).
Some control properties are stored like this:
Picture = "frmMain.frx":292F
These correspond to the *.frx, *.ctx, and *.pgx files, which contain binary data for the values of certain control properties. I don't think these files should need altering or cause any problems. They don't appear to contain control names.
Use a full compile (Ctrl+F5) to be sure no problems linger in parts of the source afterward.
Never tried it. Good luck.
There is only one tip to be added to the accepted answer.
If you need to replace any generic VB control with 3rd party or custom ActiveX control you must replace the:
BeginProperty Font
with
BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851}
Omiting to do so results with run-time error 713 when trying to edit/open the form.
If there is no BeginProperty statement in the block then control uses default font and this replacement is not needed.
An additional scenario to look for is if the classes in the OCX are referenced directly in code.
In other words, if the control class was ABCButton then you need to look for ABCButton in all .BAS and .CLS files as well, and make appropriate changes.
I have to maintain a large MATLAB GUI, containing quite a few callback functions, each of which gets called at many points. At some point, I decided to rename one of the callbacks; in order not to have to go through GUIDE to manually modify each of the UI that calls it, I used the excellent gencode program to "unwrap" the .fig file, s/old_name/new_name/g, and recreate the .fig.
This seems to work well, except for one thing: when clicking on a button in a button group, I got a message telling me that the function manageButtons is unknown. After a bit of googling, I find that manageButtons is a nested function in childAddedCbk, which, I assume, is called by GUIDE as the GUI is created. Now, trying to move just manageButtons outside to its own, in-the-path file doesn't work either: the hgroup passed to it is an invalid handle object.
So... does anyone has a workaround for that? Any of the following will be appreciated:
changing all the callbacks in a GUI in a semi-automatic way, or
making the manageButtons get a valid handle, or
having gencode not break all that.
Thanks,
Antony
You can export the FIG + M file to single .m file. You will lose the ability to edit this with guide, but you will be able to do a simple regular expression replace on the resulting .m file.
In order to do so - use on the menu of GUIDE -> File -> Export.
My project has maybe 130 controls (total of all labels, textboxes, etc.) in an SSTab (4 tabs). The project loads fine, it runs fine, I don't see a single error or warning at any point, but when I save the form with the SStab on it, the SStab data isn't saved (it is completely gone). Normally the relevant portion of the .frm file looks like this:
Begin TabDlg.SSTab SSTab1
Height = 8895
[1550 more lines of code for all the controls]
Width = 540
End
Begin VB.Menu FileMenu
But lately it's getting cropped to:
Begin TabDlg.SSTab SSTab1
Begin VB.Menu FileMenu
This is very frustrating! In my VB IDE, the frame, sstab, and all the controls are there, editable, running/compiling fine, no error messages at any point, but when you save the file, 1550 lines of precious sstab data just disappears - again, with no warning or error messages. So if you exit and restart the IDE, you get a form load error because 60% of the code is now missing. The log file points to the first error it finds (in this case a Begin TabDlg with no End) - there's no other info in it. (The log file was generated after the code was deleted and saved, so it makes sense that it wouldn't be helpful.)
When I first posted this question, I thought it had to do with the number of controls, because it appeared after I added a control, and in my first few tests, seemed to disappear when that control (or other controls) was deleted. Now I can't seem to get that form to save under any circumstances, even when I delete many controls (bringing the number of controls far below where it was when it was last stable).
I also tried deleting the SStab and moving all the controls to 4 different frames. I successfully did that in the IDE, but when I saved, a huge chunk of the data (starting with a slider control) was missing. So I have no fraking idea what is going on.
The problem is reproducible on two different PCs, so it doesn't appear to be a hardware/corrupt software VB install issue.
Has anyone else run into something like this?
Create a UserControl for each tab. That makes editing MUCH easier. It also allows you to nicely modularize the code, so each tab lives in its own file, and it'll allow you to reuse tabs elsewhere if you want.
Sounds horrible, never heard of anything like that.
Presumably you aren't getting an error log file from VB6 when you load the form into the IDE before it gets corrupted? The log file has the same filename as the form file but with a .log filename extension. For example, if errors occurred when loading Myform.frm, Visual Basic would create a log file named Myform.log. The error messages you might see there are documented in the manual.
Have a look in the Windows Event Log, see whether it records any interesting problems against the VB6 IDE?
Are you using any weird controls? Maybe one of them is somehow corrupting the FRM or FRX. FRM files are just text as you obviously know & the format is documented in the VB6 manual. Can you see any corruption in the FRM in a text editor? If you remove any properties defined in the FRX, does it still fail.
I think I would try creating a new project and a new form, and then use the IDE to copy and paste all the control definitions into it - no code. Play with the new form, see whether it has the same problem. Maybe you can recreate the form this way without the problem. If the new form does have the problem, do the same thing but only take half the controls. Maybe you can find a problem control by "binary search".
I get the same problem when attempting to save a form when the .FRM is writable but the .FRX is read-only
Not sure if this is the issue, but on a VB6 form, there is a limit to 255 (or is it 256) named controls. Perhaps you are running into that?
One way around that limitation is to use control arrays. For example, if you had 10 labels, instead of label1, label2, label3, etc, you could do label(0) through label(9), and use up only one named control.
The other thing worth mentioning about the SSTAB is the way it shows/hides controls. While it may appear that the controls are on separate tabs, what is really happening is that the controls are getting moved waaaayyyyy to the left (and consequently out of view). Perhaps with so many components, the SSTAB is choking on this in the IDE as it tries to render the controls in design view?
Again, not sure if this is the issue, but I know these two tidbits are relatively unknown.
So the SAVE function is not working.
I suspect one of the components you are placing on the tab strip is the culprit.
So ..
1) Take an inventory of each and every kind of component you are placing on the form
2) eliminate one (kind), SAVE
3) Did it SAVE?
-> Yes = that was the problematic control
-> No = return to step 2, but pick another kind
Of course, its important to remove all controls of a certain kind in step #2 (for example, ALL labels, or ALL textboxes, etc).
I have never heard of this happening however.
You are not alone! I've seen this problem. . .in fact I'm dealing it right now, which is what brought me to this site.
I've been working with VB since '94 (VB3) and I first saw this problem about 5 or 6 years ago, while using VB6. My solution then, was not unlike some of the suggestions that you have recieved from the good folks who've responded above: throw out the existing file and rebuild the form in a new file. I did that back and the affected form has worked ever since.
My current problem is appearing in another, much newer form, and the replace/rebuild option (performed about a month ago) only worked for about three weeks. Now the problem is back and each new iteration of the file gets corrupted very quickly. Following the reply above regarding the total number of allowable controls, I'm looking into just how many controls I have. . .and, as it happens, I was in the process of consolidating the primary the buttons and menus into control arrays, simply because it was going to streamline their management.
I can also confirm your observations about moving the project to a second PC. . . I've done that too, and problem persists. Moreover, I can add that I have moved the project from one shared storage system to another to no avail. (The original storage location was on a drive mounted to a Win-tel system and the new location is on a UNIX-based NAS!)
Just rebuilt the file again and checked: Controls.Count = 62, so I am no where near the 255 control limit mentioned previously. This is indeed strange! (Not to mention furstrating!)