How Do I Do Cool Dialog Stuff (MFC) - winapi

Whether I have to use a dialog box or a message doesn't really matter but I need to somehow do the following:
I've got a dialog-based MFC application. The main dialog calls a procedure that creates a thread. The call to the procedure is inside while loop. (Basically it's a file processing program - spawning off a thread for doing the file saving. So, a thread is spawned for each file that is being saved.)
I am suspending and resuming the main thread properly. However, I don't know how to get a message box/dialog box to display saying something like "please wait" and still have the main dialog update... 0.o
Basically, I want to lock the main dialog from user interaction (like keeping them from selecting anything or clicking any buttons), but I want the progress bar on the dialog to update...
Any ideas?

A bit old but does the work:
microsoft.com/msj/0297/wicked/wicked0297.aspx

Well, this is very old app.
You do not need to follow this sample; however you can follow the idea.
You have two choices:
Create progress bar in the main dialog, disable all dialog but progress. Start thread passing dialog’s handle. From the thread use this handle to send a custom message to allow dialog advancing progress.
Another message would notify dialog that thread is done and enable all controls.
Another choice would be to spawn modeless dialog, start the thread passing modeless dialog’s handle and process as described above.
Pass main dialog pointer to the modeless dialog to be used to disable and enable main dialog upon modeless start (OnInitDialog) and enable upon receiving thread complete message, before destroying modeless dialog window.

Related

Is there an equivalent of an OnModal message in MFC?

My MFC application has multiple top level (parented to the desktop) windows, any one of which can host an external application which can launch a modal dialog. Is there a way for one the other top level windows to get a notification when any of the others becomes modal?
My specific problem is that one of the my windows is hosting an embedded PDF viewer and when the user clicks print, only the window hosting the viewer is locked, not the others.
When a modal dialog is shown EnableWindow(FALSE) is called for the parent. It is deactivated now and will not accept any mouse input. Also it will not receive the keyboard focus.
When EnableWindow(FALSE) is called WM_ENABLE with wParam==FALSE is sent to the window.
When your parent receives this message you can call EnableWindow(FALSE) for all your other windows too. Recursion might be a problem here, but you can use a private window message or flags to prevent this.
Before the modal dialog closes EnableWndow(TRUE) is called again and WM_ENABLE with wParam==TRUE is sent again.

What could prevent a window from being displayed in foreground?

What could prevent a dialog from being displayed modally in foreground in some circumstances?
A process (KeePass.exe) owns a hidden window. A global shortcut (CTRL+A) displays a dialog in foreground. This is done using the DoModal method. And it works.
However, in some circumstances which I do not know, the follwing happens: The window appears in the taskbar and only after clicking on it, it is shown. I created a plugin for KeePass which overwrites the WndProc and waits for a certain WM_COPYDATA message. If this message arrives, the dialog is shown using DoModal. However, in this case it is only displayed in the taskbar and not shown in foreground.
The WM_COPYDATA message is sent from a different process, but this should not matter right? What can be a reason for that?
I am struggling for so long on this, it's so weird that's even difficult to explain the problem.
I tried issuing SetForegroundWindow(hKeePassWindow) before showing the dialog but no change.

How do I create a custom modal NSWindow?

I want to create a custom NSWindow that acts as a modal dialog. By custom I mean it has normal user controls in the window, with a "OK" and "Cancel" buttons. The dialog will contain read only information, and have a few checkboxes, secure edit fields, etc.
The MainMenu.xib file will have the normal Window visible at launch, plus include the custom NSWindow (which is NOT visible at launch).
I am trying to find example code to launch the window in modal mode (after the app initializes and launches main window), and on "OK" run a process, and on success of that process hide the dialog. Or on failure, keep the dialog up, but show an error sheet on the dialog.
Any help is appreciated, thanks.
You want to look at NSApplication’s -runModalForWindow: and/or -runModalSession: methods. Note that using modal windows is generally a bad idea and if it’s at all possible to avoid doing so, you should; that said, sometimes needs must.
As far as launching a process, waiting for it to finish and so on, you can probably do what you need with NSTask, although you don’t provide sufficient detail to be certain. You’d probably want to observe NSTaskDidTerminateNotification to tell you when the task had finished.
See
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/OperatingSystem/OperatingSystem.html
for more on NSTask and
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/WinPanel/Concepts/UsingModalWindows.html%23//apple_ref/doc/uid/20000223-CJBEADBA
for more about modal NSWindow usage.
Have a look at NSApplication's -runModalForWindow: method, and "Using Application-Modal Dialogs."

Windows. Change drop-down menu position

Is there a way to change the position of the popup menu. With top-level windows I can do it by CBTProc Callback Function and MoveWindow. Can I do the same with menus? Needs to be done so that the pop-up menu is located only in the area of its parent window. Something like a light window manager.
Yes, in a WH_CBT hook callback, you'll be notified with an 'nCode' of HCBT_CREATEWND whenever a menu window is created. Test for the class name, standard menu/submenu windows would have a class name of '#32768'. You can then send a MN_GETHMENU message to the window to find out which menu is about to be activated. But as documented, it is too early to move the window when the notification is received, the menu is not even visible yet, so you might need to sub-class the window and process additional messages.
Note that you don't need a hook to be notified when a menu window is shown, you can put a handler for the WM_ENTERIDLE message, test for 'wParam' to see if a menu caused the message, get the menu window from 'lParam' and again send a 'MN_GETHMENU' to find out the specific menu. It is possible to move the window at this point without further message handling. Just be aware that 'WM_ENTERIDLE' will be called multiple times so you need to keep track of you've already moved a particular window or not.

How can i receive Notifications while a modal dialog is open

I need to send messages to the GUI thread which should be processed the next time the GUI thread is idle. This message can come from the GUI thread or background threads.
I tried a combination of a MachPort/Notification. But when i do a
[[NSNotificationQueue defaultQueue] enqueueNotification: my_notify postingStyle: NSPostASAP];
This is not dispatched if there is a modal dialog, i have to close the dialog before it is processed so this is not useable for me.
It's okay to not handle messages during menu selection or live resize, but modal dialogs is a little bit too much delay.
Short answer: Don't use modal dialogs.
Long answer: Modal dialogs are handled by a special run loop mode called NSModalPanelRunLoopMode, see here.
To schedule a call, one way is to use performSelectorOnMainThread:withObject:waitUntilDone:modes: explained in that document; don't forget to specify the modal mode and the default mode there.
You can also use NSNotificationCenter and specify the run loop modes, see the discussion here. But it's tricky to use NSNotificationCenter from the threaded environment to start with as described here, so I don't recommend it.
On 10.6, you can also use dispatch_async.

Resources