I have a bunch of Dock Widgets that the User is free to close and want to provide a menu in my QMenuBar that reopens each of them individually. So possibly every time the menu is opened, the list of options will be different.
Is there any event or hook that I can use to recreate the menu whenever it is opened? The only thing I could find was the triggered event, but that is only generated after I already selected something.
Otherwise I would have to monitor all dock widget actions or I could use a timer that periodically recreates the menu - both solutions don't sound very appealing.
Related
Gtk 3.0 application (with C++ and GtkMM). I use set_menubar() to set the menu bar for the main window (loaded from a resource file, i.e. a "*.ui" XML file).
At run time, I want to be able to enable/disable (gray out) menu items in accordance with availability. I know that I can use "add_action()" and "remove_action()" to associate/dissociate the actions, which will have the desired effect. However it is complicated and expensive to add/remove the actions dynamically considering that the only time it matters which actions are available is when the user has opened the menu and is looking at it.
So I was thinking that I should be able to connect to an "activate" signal of the menu bar items to adjust the appearance of their menu each time the user clicks on an item, just before the corresponding menu is displayed to the user. Any idea how I can get to the signal from the Gio::Menu resource? Is this possible in theory but an unfortunate omission in the Glib API? Or is there something I don't understand?
I know that with GLUT, I can create a Pop-up Menu with glutCreateMenu, glutAddMenuEntry, glutAttachMenu.
And there are three events can be used with glutAttachMenu -- "GLUT_RIGHT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_LEFT_BUTTON".
However, I want this Pop-up menu show when some other event happens, such as double-click (assuming that I have written a function DoubleClick() which will return true if there is a double-click).
How can I implement this?
I have dialog box and in it, it has OK and Cancel buttons then it also has a ListBox to display text in two columns. I would like to continue adding text into the ListBox after the dialog box is shown. How can I do that? Because after I call DoModal() to show the dialog box, the code does not continue to execute. Or should I create two threads (one is display dialog box while another thread continues adding text to dialog box)?
Make your dialog 'pull' the data it needs, maybe polling the data source with window messages every second, or every 100ms or so. Or, if you go the 'two threads' route (the better but more complicated option), have your data source post a window message to your dialog when there is new data, and then have the dialog fetch the data it needs. The reason for this is that it's much easier to use the existing CDialog infrastructure to get a window that behaves like an actual dialog, compared to building a modal window that acts like a dialog but isn't really.
If you do go the two threads route, your division of labor should be: one thread that does all the UI work (including showing the dialog), and one that 'generates' data and lets the UI know when there is new data. So the worker thread should not do anything related to the UI, nor call any methods on the dialog directly - you can't access windows from several threads. The only cross-thread window communication should happen through window message (i.e., use ::SendMessage()). So certainly don't do something like myDialog->m_theList.AddString("blah") from another thread, or something like it.
Showing a dialog box modally halts further execution until you close the box. Instead of showing it modal, show it normal but make it always on top so you can continue executing the code after the call to DoModal(). Alternatively, populate the box with all the info it will need before you call DoModal().
If you decide to take the "two threads" approach you will discover that the controls on MFC dialogs should not be updated or accessed from a thread other than the one that created the dialog. Even if you have pointers to these controls available in another thread it is not thread-safe to access them. This rule applies whether or not the dialog is modal.
Instead, your second thread would need to PostMessage or SendMessage to the dialog window, so the updates occur on the thread that created the dialog (most likely the main UI thread of the application).
I have an application that hooks into another application via an API. My application launches a modal window which prevents keypresses to reach the parent as one would expect.
However due to limitations in the API I need to click one of the parents toolbar buttons from time to time (yes it's a kludge).
I wonder if this is possible while still having the modal window of my application active? Is it perhaps possible to send the required command directly into the parent command queue?
Clicking the button programmatically with no modal window should not be a problem, one could go by this link for example: http://forums.codeguru.com/showthread.php?307633-How-to-run-a-very-long-SQL-statement. But I would prefer not having to close my window each time I have to click the button.
Although the fifth answer is what I find interesting as I'm thinking this could make it possible to send the command without having to close my modal window first. Also it feels an ever so small bit less ugly.
First of all, when a modal dialog is shown, it runs its own message pump. So any attempt to fake input messages will land in the modal dialog message pump. Which is no good to you. So, you'd have to send a message rather than fake input.
However, when a modal dialog is shown, its owning windows are disabled. Which means that these windows will not respond to any messages you send. So I guess that means that you could:
Enable the owning top-level window that you hosts the toolbar in question.
Send the message to the toolbar button.
Disable the owning window again.
Not the prettiest way to go about things, but you did ask!
I currently have some toolbar buttons with a small arrow on the side (TBSTYLE_EX_DRAWDDARROWS) that, when clicked, result in a popup context menu being displayed under the button. This is done by constructing a custom popup menu and calling TrackPopupMenu.
The client now wants to be able to select multiple options from the menu before it closes, so that multiple options can be be modified without the need to re-open the menu and wait for an intermediate redraw between each change.
For example:
User clicks dropdown button
Dropdown menu appears (modal, waits indefinitely for user action)
User clicks some item (e.g., toggle a checkmark)
Timer (e.g., 500ms) starts
If timer expires, the menu is closed and all selected actions are executed.
User clicks another item before the timer expires, go back to 4.
The best I can come up with is to redisplay the menu by calling TrackPopupMenu multiple times. This makes the menu "flicker" when you select an item, and will probably require me to start a thread in order to do the timeouts, which I would rather avoid.
Rather than a menu, put up a dialog box with the options on it. A dialog can easily do all that is required.
A menu that doesn't close when you click it will just seem wrong. A dialog that closes by itself will seem wrong too, but it's probably the least of two evils.
Edit: If there's anything I've learned with Microsoft, it's don't try to fight the default behavior. You're asking for trouble if you do.
If you're building your menu dynamically I can see how automatic sizing can be handy, but it's not hard to do in a dialog either - make the dialog really big and before it becomes visible, enumerate the children and take a union of all their rectangles, then resize to that. Checking the boundaries to make sure they're on-screen is just a few if statements with OffsetRect. Checkboxes are trivial; icons less so, but still not bad.
One additional enhancement that would be easy to add is to dismiss the dialog immediately on a double-click.
Following #Mark Ransom's answer, you should put up a dialog box. But you can make the dialog modeless and make it close itself when you click outside of it (i.e., the dialog loses focus). That way it could behave more like a menu.
Notice that normal menus never go away by themselves, you always have to click somewhere outside the menu (or one of its options) to make it disappear.