"Sticky" MFC popup menu - mfc

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.

Related

Qt bug where model dialog moves behind main window

I have a bug that I am having a hard time solving. I have two windows.
Window A is the main window that contains a text box (in this simplified version). The user is able to edit the contents of this text box by clicking on it where Window B appears as a keypad. Besides the buttons for the numbers, there are 2 additional buttons, Enter and Done. If the user changes the value and presses Enter, then the value in the text box is immediately updated. Pressing Done will then exit the window.
However, if the user presses done without having first pressing enter, then a modal dialog will appear asking the user if they would like to save the value. Once a selection has been made, the model dialog and Window B will exit.
The bug occurs when the user enters a value and presses the Done button. When the modal dialog appears, Window B moves behind Window A. What should happen is that Window B stays ontop of Window A. Interestingly enough, when I step through the code, this bug never happens which is making it tricky to pinpoint.
Has anyone every ran into this issue before?
I am currently running Qt 5.9 on the latest version of Linux Mint (as of this writing)
Also, I have prepared a sample project that demonstrates this bug. Due to the larger complexity of it, I was unable to fit it into 1 file. If needed, I might be able to find some time this week to move everything in one file. However, I can post the Dropbox link if permitted.
Maybe the problem stems from a wrong setting of the parent child relationship of the [QDialog][1] classes.
The following passage might be crucial for your application, but it is hard to say, if you don't show a minimal-reproducible-example.
Note: The parent relationship of the dialog does not imply that the
dialog will always be stacked on top of the parent window. To ensure
that the dialog is always on top, make the dialog modal. This also
applies for child windows of the dialog itself. To ensure that child
windows of the dialog stay on top of the dialog, make the child
windows modal as well.

MFC - Deactivating all buttons except one

I have a legacy C++ MFC application with a complex GUI with Ribbons. I have a use case as follows : User clicks button A on a ribbon panel and does some work. After his work is done, before he can exercise the rest of the GUI controls, he absolutely must click button B on the same ribbon panel, and failing to click button B in this manner results in a crash if the user exercises some other controls.
Hence, in order to deal with this use case, I figured it would solve my problem if I could disable all of program's GUI controls in Button A's event handler except button B. Button B's event handler then enables the rest of the GUI controls. This way, I ensure that button B always gets pressed after button A.
Hence, my question to you is as follows : Is there a way to disable all GUI controls in one fell swoop, and then enable and disable controls individually?
I know how to enable or disable controls individually, but I have not yet come across an API that allows one to disable all controls.
This way, you get all IDs of the ribbon buttons:
CList<UINT, UINT>& lstItems;
CMFCRibbonBar *pRibbon = ((CMDIFrameWndEx*) AfxGetMainWnd())->GetRibbonBar();
pRibbon->GetItemIDsList(lstItems);
Put the three lines in your view's OnInitialUpdate() handler.
Then use the list to compare the IDs coming through your OnCmdMsg() handler to disable all the buttons (except button B).

How do I get a Maximise button and a What's This button on a Qt Dialog?

I currently have a Qt::Dialog with a What's This help button, and a close button in the title bar.
I tried modifying the window hint flags to include the maximise and minimise buttons as well.
This worked but removed the What's This button, even if I explicitly included the flag for the what's this button as well.
Is there any way that I can have a dialog with maximise and minimise buttons but keep the What's this functionality?
If you don't mind where the What's this button appears, you can create a new button anywhere (probably called "What's This" or just "?").
This new button must be connected to a slot that includes the function:
`QWhatsThis::enterWhatsThisMode();`
which will perform the same function as the now missing What's This button in the title bar.
It probably is the only function the slot needs to call.
This action can even be called from a menu, and if required from a key combination.

Programmatically clicking toolbar button in parent of modal window

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!

Replace system menu popup on windows

I want to replace the default sys menu(Restore, Move, Size etc.) with my custom entries. The menu I'm talking about can be opened either by clicking left button on window icon or by clicking right button on window title.
I can remove all the items and populate this menu with my own entries. But if I remove all entries then minimize, maximize and close buttons become inactive. So they depend on those menu items.
I want to have min, max, close buttons working as usual but system menu which contains my own items(like it is done in Windows Media Player).
I'm using Qt, but I'm almost sure it can't be done with it so any solution would be appreciated.
Do not remove Min/Max/Close items from system menu. It's much better to process WM_SYSCOMMAND message instead (SC_MINIMIZE, SC_MAXIMIZE, SC_RESTORE, SC_CLOSE).