2

This is only part of a larger project. I have a text box on a form and when the command button next to it is clicked, I want to bring up a form that looks aligned to the text box. The idea is to make it look like a drop-down box. But the only thing is that this 'drop-down' is another form and a modal one.

This is what I've done so far and the form shows fine.

procedure TfrmSetupTaxes.cmdChangeParentClick(Sender: TObject);
var
  Res : Integer;
  frmPopUp : TForm;

begin
  frmPopUp := TfrmTreePopUp.Create(nil);

  frmPopUp.Parent := Self;
  frmPopUp.Top:= self.rp.Top + self.EditItemCat.Top +
                 self.txtSelParentName.Top + self.txtSelParentName.Height + 3;
  frmPopUp.Left:= self.rp.Left + self.EditItemCat.left + self.txtSelParentName.Left;

  Res := frmPopUp.ShowModal;
end;   

Note: 'rp' is a panel and 'EditITemCat' is a tabsheet. These are merely used for positioning.

Now, here's my problem...

Although the form shows up, it seems frozen. It does not respond, neither does the parent form. Since I'm on the IDE, I just close it.

Can someone please show me what I'm missing here?

Thanks!

itsols
  • 5,406
  • 7
  • 51
  • 95

2 Answers2

2

What you're missing is how modality works. When there's a modal window in an application, you cannot interact with other windows because these other windows are disabled.

When you call ShowModal on frmPopup, the TfrmSetupTaxes form is disabled for the above reason. Since you've made frmPopup a child of frmSetupTaxes, it also gets disabled.

You cannot workout this design by using modality, you have to devise another mechanism.

Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
  • +1 for your wonderful explanation although it's not the solution. I know now that I must not waste time on this technique. Thanks! – itsols Jan 09 '13 at 06:10
  • 1
    @itsols - You're welcome! I didn't mention about possible solutions because it's more complicated then it seems. The drop-down form will probably be *owned* by the parent form to be in front of it (popupparent property), then you'll have at least two other problems, timely deactivation, and a non-activated look. Have a look at [this](http://stackoverflow.com/questions/2178494/how-to-show-a-window-that-acts-like-a-popup-menu) question, it's Delphi tagged, but related nevertheless. – Sertac Akyuz Jan 09 '13 at 09:33
  • 1
    +1 for this wonderful thought. I'm surprised as to why such an elementary task hasn't been made available in a language with so many widgets and DB interfaces. – itsols Jan 09 '13 at 10:17
  • @itsols - Is there any aspect of your *question* that this answer does not cover? – Sertac Akyuz Jan 10 '13 at 18:34
  • Your explanation is superb but it did not fix my problem yet because I cannot use any Windows APIs or Win-specific methods. The idea of me using Lazarus is to be able to easily port the application between different OSs. Nevertheless, I love the answer and that's why I +1'd it. It gives me direction on where NOT to look. But I'm onto something right now and I think I'm getting it. I'll post it here once I make sure. Cheers! – itsols Jan 11 '13 at 03:27
0

This is one of the best findings, at least to me ;)

After a lot of digging and direction, I realised that it was beyond me. I could not figure out the 'right' way that would work for the various OSs (at least Windows and Ubuntu).

Finally I hired an expert (no, not from any forum site) and paid him to show me this. And with the hope that it may help other developers, I thought it would be best to post it here.

Before the answer, I need to give a big thank you to Sertac-Akyuz who showed me that certain things were impossible. I also found through their links that there were some solutions but they did not fit my needs.

Now, before the answer, here are my rules I had to stick to.

  1. I should not use Any Windows-specific functions or APIs because I want to be able to port my work between Windows and Ubuntu (at least for now).

  2. There no MDI forms in use. Again for cross-platform reasons.

  3. There are no 3rd party plugins or products in use.

Now the answer...

procedure TfrmSetupTaxes.cmdChangeParentClick(Sender: TObject);
var
  Res : Integer;
  frmPopUp : TForm;
  pt: TPoint;
begin

  frmPopUp := TfrmTreePopUp.Create(self);

  pt := txtSelParentName.ClientToScreen(Point(0, 0));

  frmPopUp.Top := pt.y + txtSelParentName.Height;
  frmPopUp.Left := pt.x;

  Res := frmPopUp.ShowModal;

end;

And that's it!

The key was in NOT setting the parent property of the popup. Then using ClientToScreen (a function I didn't even dream of using). It does the job beautifully.

itsols
  • 5,406
  • 7
  • 51
  • 95
  • I'm glad you've solved your problem, but to be fair, your post does not answer the question - which asks why does a modal-child form disables itself and its parent. – Sertac Akyuz Jan 11 '13 at 11:12