0

Is there a property that tells if a form is deactivated by other form ShowModal procedure ?

EDIT : My program has a tray icon that brings to front the main form when it's clicked. I want to disable this when another window is shown in modal state. Because not doing so the main form (which is disable) will cover the modal form and completly block my program.

Marus Gradinaru
  • 2,824
  • 1
  • 26
  • 55
  • Something from your main form opens that modal dialog, doesn't it ? Because if so, disable that stuff from there. – TLama Jul 24 '14 at 13:18
  • I'm confused by your wording here. The form is automatically disabled when you call ShowModal on another form. Then you say, "I want to disable some actions" on that form. WTF? It makes a beep to signify that it's disabled and cannot receive focus. If you don't want to disable the form, call Show instead of ShowModal and implement whatever logic you want when the user clicks on the form while the other one is visible. – David Schwartz Jul 24 '14 at 16:22
  • You ask for a property but your description sounds like you want a notification. Which is it? – Sertac Akyuz Jul 24 '14 at 16:54
  • My program has a tray icon that brings to front the main form when it's clicked. I want to disable this when another windows is shown in modal state. Because not doing so the main form (which is disable) will cover the modal form and completly block my program. – Marus Gradinaru Jul 24 '14 at 18:21
  • @marus - Thanks for information. I posted an answer which I believe would be suitable for this case. – Sertac Akyuz Jul 24 '14 at 18:41

2 Answers2

2

This behaviour is to be expected. When a modal form is shown, the other forms are disabled. You don't need to disable anything at all, the framework already handles it all for you. The beep is sounding because you are attempting to interact with a disabled form.

If you want to be notified when your window has been disabled, for any reason, not just because a modal form has been shown, listen to the WM_ENABLE message. To test whether or not your main form has been disabled. Do that by calling the IsWindowEnabled Win32 function.

Having said that I feel that it is likely you've not diagnosed the issue correctly. It sounds like you might be suffering from window ownership problems, which are common in Delphi 6. Or perhaps you are attempting to restore the application incorrectly from your notification icon code. Use Application.BringToFront for that.


The VCL's handling of modal dialogs seem very mixed up. When you show a system provided modal dialog, e.g. MessageBox, windows are disabled whether or not they are visible. However, the VCL only disables visible windows when ShowModal is called. What's more, you cannot use Enabled to test whether or not the window is disabled, you must use the IsWindowEnabled Win32 function.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Yes! `IsWindowEnabled` is exactly what I was looking for. I'm sorry for the confusion. I do not know verry well to speak in english and explaining is even harder to me. – Marus Gradinaru Jul 24 '14 at 21:20
  • I'm guessing as to what the real problem is. Some code would have helped us. I wonder if the real solution is not to worry about enabled at all and call `Application.BringToFront` rather than `MainForm.BringToFront`. – David Heffernan Jul 24 '14 at 21:30
  • > *`IsWindowEnabled`* ... > Yes, the form is never disabled, only the window is. – Sertac Akyuz Jul 24 '14 at 21:56
  • @Sertac It's odd that there's a difference. I would hope that for a child, e.g. a TButton, Enabled and IsWindowEnabled would be equivalent. – David Heffernan Jul 25 '14 at 06:38
1

You can test Application.ModalLevel at any point in time to find out if there's a modal form. E.g.:

if Application.ModalLevel = 0 then
  MainForm.Visible := True;

Note that non-TCustomForm descendants will not set modal level, API dialogs like a file open dialog or MessageBox for instance. If there's a possibility of such a thing, you might surround code that runs those dialogs with ModalStarted and ModalFinished.

It doesn't seem necessary in your case, but if you somehow need to be notified that a form/dialog is going modal, you can attach a handler to Application.OnModalBegin and Application.OnModalEnd events. You can use an TApplicationEvents component for that.

Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
  • 1
    Unfortunately, `ModalLevel` has been added later. – TLama Jul 24 '14 at 18:57
  • 1
    @TLama - Bummer! Thanks for telling me. – Sertac Akyuz Jul 24 '14 at 19:00
  • 1
    Indeed. I don't have `ModalLevel` in my `TApplication` and I'm using Delphi 6. But you give me an idea about what should I do. I will create myself that property and each time, before I call ShowModal, I will set it to true and when ShowModal exits I'll set it to false. – Marus Gradinaru Jul 24 '14 at 19:09
  • This isn't the way to deal with the scenario described in the comment to the question. – David Heffernan Jul 24 '14 at 19:20
  • @David - You're wrong (solution in your answer). An invisible window will not be disabled by showing another form modal. – Sertac Akyuz Jul 24 '14 at 19:43
  • That's kind of odd. Where does the beep come from. Of course, a definite problem is that the question we now seem to be answering only exists in a comment. – David Heffernan Jul 24 '14 at 19:52
  • @David - Hmm, you may be right about the beep. I thought the tray icon is hiding the mainform, maybe not. Or DisableTaskWindows is perhaps different in D6... – Sertac Akyuz Jul 24 '14 at 19:54
  • @David - I think the question title and the question (first sentence) is fine. The explanation coming after confuses things. – Sertac Akyuz Jul 24 '14 at 19:56
  • I'm quite confident that owner windows are disabled when modal forms are shown. – David Heffernan Jul 24 '14 at 19:59
  • @David - See code in `DoDisableWindow` which is the callback for `EnumThreadWindows` in `DisableTaskWindows`. Owner is not queried, visibility is. – Sertac Akyuz Jul 24 '14 at 20:03
  • That seems odd. Why would invisible windows be special? I'd call that a VCL bug. Behaves differently with `MessageBox`. And you have to test `IsWindowEnabled` to find out whether or not a window is enabled. – David Heffernan Jul 24 '14 at 20:13
  • If we treat the question as "Is there a property that tells if a form is deactivated by other form ShowModal procedure?", then `IsWindowEnabled` is a pretty good answer right? I don't really enjoy answer questions where the question is not written in the question but is posed cryptically in comments. So, I'll leave it at that. – David Heffernan Jul 24 '14 at 20:19
  • @David - I think so, although you can disable a window without showing another modal form. Not that I can think of why would that happen, but if there's a one to one dependency it would be preferred. I agree that the context in the comment could be incorporated in the question. Would be best if that information was available at time the question was asked of course. I wouldn't query in the comments if the question did not confuse me. – Sertac Akyuz Jul 24 '14 at 20:30