views:

160

answers:

4

Can I, from a modal form, activate an existing nonmodal window? I use Delphi.

In our application the users can edit reports in a nonmodal window. This is usually done by selecting "Edit reports" from the main window. But there is also a possibility to open a report from a modal print dialog. This leads to the following problem: A user opens a report for editing from the main window. He makes some changes, but doesn't save it (he minimizes it or something). Then, from the print dialog, he opens the same report again, forgetting that it's already opened or believing it's the old window, and makes some changes and saves it. Now we have a problem. Either these changes will be lost (when he remembers and opens the old edit window and saves his changes), or the old changes will be lost (when he remebers the old window and closes it without saving)

What I want is to open the old edit window when the user initiates an edit from the print dialog. I already have code to find the old edit window, but how do I activate it?

+1  A: 

Assuming your form variable is called ReportForm:

The normal way is to just call the ReportForm.Show method again. Or set ReportForm.WindowState to wsNormal for minimized windows. Or call ShowWindow(ReportForm.Handle, SW_RESTORE); which will put a minimized window back in it's original shape.

You can also force the ReportForm to the front, but because it's non-modal, it won't respond to anything, making your application behave as if it's hanging. To do this, use:

  ReportForm.FormStyle := fsStayOnTop;
  ReportForm.Show;
  ReportForm.FormStyle := fsNormal;

It works, bringing ReportForm back to the foreground. You might want to preserve the old FormStyle value, though. And yeah, it's a bit of a hack. Furthermore, the form will not respond to the mouse or keyboard simply because the modal form is still demanding attention in the background! (It will sooner or later return to the foreground again.)
A modal form will demand all attention from the Windows messages. This trick will just temporary hide the modal form.
Btw, the simplest way to find that form is by using a global variable in your project and assign the report form to that variable. Then you can just call if Assigned(YourForm) then YourForm.Show; when you need to display it again. (Plus the other two lines, if need be.)


So, best solution would be the ShowWindow(ReportForm.Handle, SW_RESTORE); which should work, I think... It will pop back behind the modal form, where it's supposed to be.

Workshop Alex
I should have been more specific in my question :-) Yes, the problem is that the window is not responding. I can show it, but that's no good.
Svein Bringsli
And you will not be able to show it until the modal form is closed. Modal forms just eat all messages. The only option would be to close the modal form, bring the report to the foreground and then re-open the modal form as a non-modal form.But maybe it helps to make the report form itself modal...
Workshop Alex
It's not entirely true that a modal form eats all messages. I can make a new form from the modal form, and that will work just fine. But I would like to take a form that already exists and is active, and use that instead.
Svein Bringsli
True, you can create new forms from the modal window, but they would all be in the same modal scope of the modal window itself. You can't jump to forms outside this modal scope.
Workshop Alex
A: 

What about the following flow:

  • Before opening the report in modal mode for printing, check whether the same report is already open (you alread have this).
  • If there is an open form, capture its state (into a string, an object or record, a stream, whatever)
  • Close the non modal form
  • Create a new, modal report form and initialize it with the captured state.
nang
Unfortunately, we don't know which reports the user will print. Typically an installation will have 50+ reports, which the user can select from while in the report dialog.
Svein Bringsli
+1  A: 

If you're using D2005 or newer, I think you can use RecreateAsPopup on the 'ReportForm' passing the modal form's handle as the parameter. The documentation on this one is a bit scarce though, so try it at your own risk. :)

Sertac Akyuz
Scarce documentation indeed, but it actually seems to work. Outstanding! I've never even heard of the method before. Thank you :-)
Svein Bringsli
+1  A: 

In researching non-modal windows, I came across the following information that seems to be exactly what you're looking for. I don't know of the relative pros and cons of this method compared to using RecreateAsPopup.

http://blogs.teamb.com/deepakshenoy/2006/08/21/26864

Chad N B