开发者

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

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 (whe开发者_高级运维n 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?


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. :)


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.


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


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.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜