Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Make my own modal window
#11
The other feature I am looking for is how to make the modal dialog blocking. For example, in a VCL application I can write

result:=InputQuery(a,b,c)

or better yet I can have my own form with an .Execute method, and the Execute method calls showModal and does not return until the modalResult is set.

and the code wont continue until the user presses ok or cancel on dialog.

The examples I have seen launch the modal dialog in some button click, but then continues processing in the OnClose of the modal window. However, it is annoying to have to code that way, i.e. have to continue processing in another method from the one that generated the dialog.

Is there a way to mimic the standard modal dialog approach of the VCL with intraweb? Especially when I have custom search dialogs etc where I want to do something like

if SeachParamsForm.Execute then
begin
// get the search criteria from the form
//execute the search
end
Reply
#12
(03-29-2018, 04:14 AM)davenovo Wrote: The other feature I am looking for is how to make the modal dialog blocking. For example, in a VCL application I can write

result:=InputQuery(a,b,c)

or better yet I can have my own form with an .Execute method, and the Execute method calls showModal and does not return until the modalResult is set.

and the code wont continue until the user presses ok or cancel on dialog.

The examples I have seen launch the modal dialog in some button click, but then continues processing in the OnClose of the modal window. However, it is annoying to have to code that way, i.e. have to continue processing in another method from the one that generated the dialog.

Is there a way to mimic the standard modal dialog approach of the VCL with intraweb? Especially when I have custom search dialogs etc where I want to do something like

if SeachParamsForm.Execute then
begin
 // get the search criteria from the form
 //execute the search
end

Like calling a modal query (a la "Abort, Retry, Cancel") then return and continue the original code with the response.  I've been calling that "code modal" myself (I don't know why but it seemed to fit). 

Unfortunately, that's not going to happen in a web environment like this anytime soon.    The trouble is that you'd have to save the session state, run off and do the modal code, then come back (many independent threads later) and return session state.  On a client application, you just push that stuff on a stack and pop it off again.

In a web environment like this, the mechanisms just aren't built in (or easy to reproduce).  It's not technically impossible, but it's very difficult to do without breaking a lot of stuff.  Worse, once you put that in then you've made future enhancements a minefield as well.

That said, we have our own application scripting language and did reproduce that kind of behavior in our script.  It was a real PITA, but when you write the scripting engine you can manage what it does.  Did I mention that it was a PITA?

Dan
Reply
#13
I have seen your previous posts about "code modal" over the years with a hope that something new was available.

I will point out that UniGui does have a built in ShowModal on any "TUniForm". I have no technical information how it works, aside from the fact that it does allocate a thread for each modal form until the modal form is "completed". From the developers point of view it works just like the VCL (code modal as you say).

In anticipation of the feedback to this, I will say I totally understand and agree that "burning" threads waiting for the modal response to return is not "scalable". HOWEVER, a quick google search indicates that Widows server allows at least 10,000 threads per process. In my application, there will be 100 concurrent users max. Even if I am wrong by a factor of 10, and there are 1000 users concurrently one day, they would all have to be waiting on many modal dialogs each at the same time to worry about a thread limit on a single server. Of course, in that case I would simply load balance and alleviate the issue.

There is no way that we will ever get close burning out the # of threads. I understand if I was writing GMail in intraweb, with expectation of 10,000,000 concurrent users it would be stupid to do this. But for my app, the convenience of having "code modal" far outweights the performance issues.

You always have to design your system for your intended use. If my app did have 10000x the users that it does now, I would have to design it totally differently, and the modal threads would be the least of my issues.

While I understand the purist approach of it not being a good idea because it won't scale to a huge volume, the pragmatic approach of having the convenience of a proper "code modal" would be very helpful under a wide variety of circumstances and applications.
Reply
#14
(03-22-2018, 06:37 AM)DanBarclay Wrote:
(03-20-2018, 04:30 AM)davenovo Wrote: Hi Daniel,

To each their own I suppose. If you want to keep 7 dialogs worth of controls on a single form and it works for you, that is awesome. Now, for those that want to keep a single dialogs worth of controls on a single form, and just open that form modally instead of just calling .Show, I am wondering if there is a way to do that.

I do it the way you are talking about and it works fine.  I create my dialogs separately, then load them onto the form during the OnCreate.  I don't do it just to avoid having to deal with a busy design time form (though that is helpful), I do it so that I can use "common dialogs" (of my own requirements) on multiple forms easily.

I create my dialog "content" as frames.  As usual, fill the frame with a region then put your stuff on the region.  During form OnCreate I call a procedure that creates the frame (from the frame design time class) on the form, sets Parent to the form, Visible to false, and the frames' region visible to false.  Then you can use the regions in dialogs.  Don't forget to set RenderInvisibleControls to True on the dialogs.

It has been a while since I did all that, but I'll try to respond if you run into problems with it.  It should work without too much difficulty.

Dan

Hi Dan, I followed your hint but I have a strange result...

In IWAppFormCreate eventi I have added this code:

 // Create first frame
 FFrameInput:=TIWFrameInput.Create(WebApplication);
 FFrameInput.Name:='FrameInput';
 FFrameInput.Top := 0;
 FFrameInput.Left := 0;
 FFrameInput.IWFrameRegion.Parent:=Self;
 FFrameInput.IWFrameRegion.Visible:=False;
 // Create second frame
 FFrameFiltro:=TIWFrameFiltro.Create(Self);
 FFrameFiltro.Name:='FrameFiltro';
 FFrameFiltro.Top := 0;
 FFrameFiltro.Left := 0;;
 FFrameFiltro.IWFrameRegion.Parent:=Self;
 FFrameFiltro.IWFrameRegion.Visible:=False;

Then I attempt to display the FFrameFiltro using this code when I press a button in main form:

      RenderInvisibleControls:=True;
      with IWModalWindow1 do
       begin
        Reset;
        Buttons.CommaText := '&Ok,&Cancel';
        Title := 'Filter';
        ContentElement :=FFrameFiltro.IWFrameRegion;
        OnAsyncClick := FrameFiltroDoOnAsyncClick;
        Show;
       end;

But instead the FFrameFiltro the system displays the other one, the FFrameInput !

In IWAppFormCreate eventi I add only this code:

 // Create second frame
 FFrameFiltro:=TIWFrameFiltro.Create(Self);
 FFrameFiltro.Name:='FrameFiltro';
 FFrameFiltro.Top := 0;
 FFrameFiltro.Left := 0;;
 FFrameFiltro.IWFrameRegion.Parent:=Self;
 FFrameFiltro.IWFrameRegion.Visible:=False;

the system display correctly the dialog...

Hot it's possible ? Any idea ?

Francesco
Reply
#15
Depending on the one you want to show, assign the region for that dialog to the TIWModalWindow.ContentElement instance on your form.  You can make/change that assignment during execution.

Note that the RenderInvisibleControls must be set prior to creating the form itself, not when you try to show the dialog if you are async.

Sorry for the short answers.  I don't have any simple code to post, and I'm reworking my machine right now anyway.  SSD's are wonderful.


 
Code:
    with IWModalWindow1 do
       begin
        Reset;
        Buttons.CommaText := '&Ok,&Cancel';
        Title := 'Filter';
        if FiltroStuff then 
          begin
            ContentElement :=FFrameFiltro.IWFrameRegion;
            OnAsyncClick := FrameFiltroDoOnAsyncClick;
          end
         else
          begin
            ContentElement :=SomeOtherDialog.IWFrameRegion;
            OnAsyncClick := SomeOtherDialogClick;
           end;
        Show;
       end;

Dan
Reply
#16
(05-31-2019, 03:20 AM)DanBarclay Wrote: Depending on the one you want to show, assign the region for that dialog to the TIWModalWindow.ContentElement instance on your form.  You can make/change that assignment during execution.

Note that the RenderInvisibleControls must be set prior to creating the form itself, not when you try to show the dialog if you are async.

Sorry for the short answers.  I don't have any simple code to post, and I'm reworking my machine right now anyway.  SSD's are wonderful.


 
Code:
    with IWModalWindow1 do
       begin
        Reset;
        Buttons.CommaText := '&Ok,&Cancel';
        Title := 'Filter';
        if FiltroStuff then 
          begin
            ContentElement :=FFrameFiltro.IWFrameRegion;
            OnAsyncClick := FrameFiltroDoOnAsyncClick;
          end
         else
          begin
            ContentElement :=SomeOtherDialog.IWFrameRegion;
            OnAsyncClick := SomeOtherDialogClick;
           end;
        Show;
       end;

Dan

The problem is that I assign to ContentElement the FFrameFiltro.IWFramaRegion, but is displayed the FFrameInput.IWFrameRegion....
It looks that creation and initialization of more than a frame gives problems....
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)