I've uploaded a small utility (PowerBuilder source code) to CodeXchange here that you can run on the menus in your applications and create RibbonBar XML based on them. It's intended to quick start your migration from existing menus to the RibbonBar I'm expecting that you're going to want to tweak the output somewhat after it's generated. however, it is a whole lot better from having to create them from scratch.
You can see it in operation in the short video below. I want to explain how it works, and in the process explain some assumptions I've made about how it should operate that you may want to modify.
When you select the Select Menu button the first thing it does is prompts you to select the target file for the application. It then parses the target file to find all the PBLs that make up the application. Note: The code I've written assumes that all of the PBLs are in the same directory or a sub-directory of the directory that the target file is in. If that is not the case for your application, you may want to modify the of_gettarget function to handle it, ore move the PBLs so they are where the utility expects them.
There are two reasons that it needs the list of PBLs. The first is so that it can loop through them searching for menus and display a list of them to the user. The second is that in order to deal with inherited menus it adds the PBLs from the application the user selected to the library list for the utility and later create an instance of the menu they selected in order to parse it. Note: Since the AddToLibraryList function only works in a compiled application, you must compile the application and then run that in order to use it. It won't work if you try to run it out of the development environment.
After the list of menus is shown to the user and they select one, the utility then creates that menu dynamically in a script. It then loops through the Item array for the menu to get the menu and toolbar options defined in the menu. It keeps looping through the Item array of the first level items and so on in order to get all of the menu and toolbar items defined in the menu.
For each menu item, it reads Text, Tag and ToolbarItemName attributes of the menu item. It then creates an app button menu items using those values. When you access a menu item that has a short cut defined, it is added to the Text value separated by a tab character. So the utility looks for that tab character and if it finds it, strips the shortcut out of the Text value and instead includes it in the ShortCut attribute for the app menu item.
The utility then loops through the menu items again, this time creating categories on the RibbonBar for the top level menu items and then large RibbonBar buttons within each category for the menu items underneath each top level menu item. Note that this essentially flattens the menu hierarchy. I assumed that you would create panels, change some buttons to small buttons, etc. once the initial XML file was generated.
A final note on a major difference between what is generated for you, for example, by the Appeon template and what this generates. It has to do with the events that the app button menu items and ribbon buttons call. With the template that Appeon provides, each different app button menu item and toolbar button calls a different event. The problem I have with that is that those events are sent to the parent RibbonBar control, and where I want to respond to them is the window the RibbonBar control is in. It seems with that approach you would need to create an event on the RibbonBar control for every menu item and ribbon button, and then have those events all call similar events on the parent window. It seemed like a lot of tedious work to me.
What I want instead is a generic approach. I want to only have one (or as it turns out two) events on the RibbonBar control and for the RibbonBar control to then relay the event to a number of different events on the window. As it turns out, app button menu items require an event to be created on the RibbonBar control that take 3 arguments ( long al_handle, long al_index, long al_subindex ) whereas RibbonBar buttons require an event that only takes one ( al_handle ). So I created two events on a custom class user object inherited from RibbonBar:
And then call that from the events passing the arguments received (in the case of ue_tabbutton I pass 0 for the last two arguments). I then have the following code in the user function to figure out where the event came from, pull the tab attribute off that item, and then dynamically trigger an event on the parent window whose name is based off the tag attribute.
That means I can drop that user object on any window and not bother with it anymore. It means that all the app button menu items call the ue_appbutton event and all the RibbonBar buttons call the ue_tabbutton event. The only thing I need to do to hook up the RibbonBar items to the parent window is:
What you'll see when you look at the XML this utility generates is that it only uses those two events. If you want to use the Appeon template style approach, you'll either need to modify the XML or modify the utility to generate the event names you want.
Hi Bruce,
Does the ribbonbar generator only work for PB 2019 R3? When I try to run I get an error that the runtime path does not exist C:\Program Files (x86)\Appeon\Common\PowerBuilder\Runtime 19.2.0.2556. I changed the path in the ribbonbarmenugenerator.xml to my current path (ie. C:\Program Files (x86)\Appeon\Shared\PowerBuilder) and I get library load failed! dll name: pbvm.dll. The pbvm file installed on my machine is pbvm190.dll. What do I need to do to run the generator?
Thank you,
Teresa
Did you download it recently? I originally created it with a beta version of R3. I updated it later with the GA version.
In addition, you can just recompile it yourself using whatever build you have.
The sequence of numbers generated by repeated calls to the Rand function is a pseudorandom sequence. You can control whether the sequence is different each time your application runs by calling the Randomize function to initialize the random number generator.
The starting value (seed) for the randomnumber generator. When n is 0, PowerBuildertakes the seed from the system clock and begins a nonrepeatablesequence. A nonzero number generates a different but repeatablesequence for each seed value. n cannot exceed 32,767.
The sequence of numbers generated by repeated calls to the Rand functionis a computer-generated pseudorandom sequence. You can use the Randomize functionto initialize the random number generator with a value from the systemclock, or some other changing value, so that the sequence is always different.For testing purposes, you can select a specific seed value, whichyou can reuse to make the pseudorandom sequence repeatable eachtime you run the application.
In my last article, Power BI Desktop Interactive chord diagrams, we learned about customized visualizations in Power BI Desktop. These visualizations are free to install and we can use them with our data set and customize charts as per our requirements.
A Word Cloud is a visualization that draws an image from frequently appearing words in the data set. These words are arranged in a cloud shape. The size of the words in the cloud image is proportional to its frequency.
In this example, some of the fields contain blank values as well. Therefore, we do not want those blank values data to create our Word cloud generator. Now click on Edit to make changes in the data.
Now in the Power BI Desktop, Click on custom visual section From File. We get a warning message that the custom visuals are not provided by Microsoft and we should consider security or compliance risks before proceeding.
By default, the Word cluster looks for the first word in the value section in Word Cloud Generator. It does not look the entire word as a single word. If we want to create a Word cloud generator for the complete name, go to General ->Word-breaking. By default, it is turned on. Move the slider and turn off the word breaking.
We can now observe the Word cluster; this is now showing the complete name of the author. If we look at our data table, Steinbeck John is having the highest count and it reflects in the Word cluster. The font size of Steinbeck John is largest in the visual.
We normally use some common words, for example, a, an, the, etc. Sometimes we do not want these words to appear in the Word cluster since they are commonly used words and if our dataset contains these words, it would be difficult to get a true picture of Word cluster by showing frequently used words.
Word Cloud Generator in Power BI offers an interactive method to do the analysis for frequently used words, text with customization. In this article, we reviewed how to create a Word cloud generator with Power BI Desktop. Explore these techniques with your own data sets and enjoy clouding!
Hi! I am Rajendra Gupta, Database Specialist and Architect, helping organizations implement Microsoft SQL Server, Azure, Couchbase, AWS solutions fast and efficiently, fix related issues, and Performance Tuning with over 14 years of experience.I am the author of the book "DP-300 Administering Relational Database on Microsoft Azure". I published more than 650 technical articles on MSSQLTips, SQLShack, Quest, CodingSight, and SeveralNines.I am the creator of one of the biggest free online collections of articles on a single topic, with his 50-part series on SQL Server Always On Availability Groups.Based on my contribution to the SQL Server community, I have been recognized as the prestigious Best Author of the Year continuously in 2019, 2020, and 2021 (2nd Rank) at SQLShack and the MSSQLTIPS champions award in 2020.Personal Blog: am always interested in new challenges so if you need consulting help, reach me at rajendra...@gmail.com View all posts by Rajendra Gupta
b1e95dc632