Board index » delphi » Creating a "Modal" mdi form

Creating a "Modal" mdi form

Hi,

I am trying to make my app handle that one mdi form should be "modal" in
relation to another form. If you click on the first form the focus should
automatically shift to the second form (the modal one).

This part of it actually works allright - that is if you clicked on a button
or something like that that control actually handles that click before I can
break it off and send focus to the modal form.

I have tried to use the messages VM_Activate and overriding the Activate
method of the form but this seems to be to late to avoid the button from
handling the click.

So I wonder where should I plug in to be able to avoid any of the controls
on the form to handle the click event, before it is too late.

I have tried to use the "EnableWindow(Handle, False)" - but this is not what
I want, because I whant the Modal window automatically to get the focus If
the user tries to activate the window is is supposed to be modal for.

If anybody has any help to offer I would appriciate it!

-----------------------
Jens Dein
IPOS as, Norway

 

Re:Creating a "Modal" mdi form


Jens,

add a handler for the WM_MOUSEACTIVATE message to your forms. If the
handler fires and the "modal" form is up return msg.result :=
MA_NOACTIVATEANDEAT, then focus the "modal" form if it is not already
focussed; otherwise you call the inherited message handler to get the
default activation behaviour.

Peter Below (TeamB)  100113.1...@compuserve.com)
No e-mail responses, please, unless explicitely requested!

Re:Creating a "Modal" mdi form


Peter,

Thanks for your answer, but this dosen't work eiter, the buttons OnClick
event is still triggered.

Could you take a look at this code to see if you can find any obvious
errors?

procedure TFrwForm.WMMouseActivate(var Message:  WMMouseActivate);
var
  GoToForm : TFrwForm;
  I        : Integer;
begin
  GotoForm := nil;

  for i := 0 to ComponentCount-1 do
    if ((Components[i] is TFrwForm) and (TFrwForm(Components[i]).ModalMDI))
then
    begin
      GoToForm := TFrwForm(Components[i]);
      Break;
    end;

  if Assigned(GotoForm) then
    try
      Message.Result   := MA_NoActivateAndEat;
      GoToForm.WindowState := wsNormal;
      GoToForm.BringToFront;
      GoToForm.SetFocus;
    except
    end
  else
    inherited;
end;

Re:Creating a "Modal" mdi form


Quote
In article <6to95c$2...@forums.borland.com>, Jens Dein wrote:
> Thanks for your answer, but this dosen't work eiter, the buttons OnClick
> event is still triggered.

Jens,

that's a pity. Does the WM_MOUSEACTIVATE handler even fire when you click
on the button?

The only other approach i can come up with is to hook into
Application.OnMessage. This allows you to get at the mouse messages before
they are delivered to the target control. The target controls handle comes
with the message. Use the FindControl function to get a TWinControl
reference for the control, then the GetPArentControl function to get the
controls parent form. If that is not the modal form set the Handled
parameter of the OnMessage event handler to True to swallow the message,
then focus the modal form, otherwise let the message fall through by
leaving Handled at false. You need to handle several messages:
WM_LBUTTONDOWN,UP, DBLCLK, the matching RBUTTON messages and
WM_NCLBUTTONDOWN/UP etc..

Processing you do in an OnMessage handler can seriously impact the
responsiveness of your app. You should use a global flag (or a field of the
main form, the event handler should belong to the main form) to signal that
the modal form is up and the special processing should take place. This way
the first instruction in the message handler can be a test of this flag,
which avoids lengthy code execution if the modal form is not up.
Peter Below (TeamB)  100113.1...@compuserve.com)
No e-mail responses, please, unless explicitely requested!

Re:Creating a "Modal" mdi form


If you guys are thinking about such complex problems you should find my problem

very simple :

In my MDI app I create the child forms at runtime (just like borland tells you
to)
But now I have a problem.... I open a form called something like 'edit
products' then in that form you can click a button to 'edit the prizes' of a
product. So from the main
form you go to a child form and with that child form I want to create a new
child form.

The problem is that the child form with whom I create the new child form is
destroyed
after the new Child form appears on the screen. This is not what I want.
I want the two child both on the screen.

Quote
Peter Below wrote:
> In article <6to95c$2...@forums.borland.com>, Jens Dein wrote:
> > Thanks for your answer, but this dosen't work eiter, the buttons OnClick
> > event is still triggered.

> Jens,

> that's a pity. Does the WM_MOUSEACTIVATE handler even fire when you click
> on the button?

> The only other approach i can come up with is to hook into
> Application.OnMessage. This allows you to get at the mouse messages before
> they are delivered to the target control. The target controls handle comes
> with the message. Use the FindControl function to get a TWinControl
> reference for the control, then the GetPArentControl function to get the
> controls parent form. If that is not the modal form set the Handled
> parameter of the OnMessage event handler to True to swallow the message,
> then focus the modal form, otherwise let the message fall through by
> leaving Handled at false. You need to handle several messages:
> WM_LBUTTONDOWN,UP, DBLCLK, the matching RBUTTON messages and
> WM_NCLBUTTONDOWN/UP etc..

> Processing you do in an OnMessage handler can seriously impact the
> responsiveness of your app. You should use a global flag (or a field of the
> main form, the event handler should belong to the main form) to signal that
> the modal form is up and the special processing should take place. This way
> the first instruction in the message handler can be a test of this flag,
> which avoids lengthy code execution if the modal form is not up.
> Peter Below (TeamB)  100113.1...@compuserve.com)
> No e-mail responses, please, unless explicitely requested!

Re:Creating a "Modal" mdi form


Quote
> In my MDI app I create the child forms at runtime (just like borland tells you
> to)
> But now I have a problem.... I open a form called something like 'edit
> products' then in that form you can click a button to 'edit the prizes' of a
> product. So from the main form you go to a child form and with that child form
> I want to create a new child form.

> The problem is that the child form with whom I create the new child form is
> destroyed after the new Child form appears on the screen. This is not what I
> want. I want the two child both on the screen.

Forms are not destroyed on their own. What you need to keep in mind, however, is
that *modal* forms (not MDI child forms, which cannot be modal, normal forms
shown with ShowModal) will close if you click any button on them that has a
Modalresult <> mrNone. So if you open a modal form with a button, in the buttons
OnClick show a seconds form via ShowModal then the first will close after the
ShowModal returns because the button click sets the forms Modalresult to the
buttons Modalresult, and if that is <> mrNone the form closes. You can prevent
this by either setting the buttons Modalresult to mrNone in the designer or by
setting the forms Modalresult to mrNone in the Buttons OnClick handler.

Peter Below (TeamB)  100113.1...@compuserve.com)
No e-mail responses, please, unless explicitely requested!

Other Threads