Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Modal Form Won't Close? 1

Status
Not open for further replies.

BoMi

Programmer
Jul 20, 2006
39
RS
Hi, again, uh...believe me, I would like I haven't asked all those newbie questions so far. I always try to find answer somehow else and not to bother you guys here.
But, I'm still pretty new to Delphi and even OOP, so please forgive me if I ask too much (or I ask stupid questions).
Problem:
I have two forms, second one modal, not autocreated (except first-main)(but it seems to me that even they are both autocreated the problem stands still); modal form has two speedbuttons; on modal form OnActivate event it starts to do something with picture on it (checking pixel's color etc.)(loops inside); on speedbutton1 click-doing something else(also with loops); both operations are very cpu intensive (cpu use about 100%);speedbutton2 click sets ModalResult:=mrAbort; and modal form won't close.
I even put Application.ProcessMessages; but nothing.
My question:
how can I close my second (modal) form clicking speedbutton2,as it should be, and is, if I do not do anything on the form.
Please, without using threads, I like them, but I need explanation why this above doesn't work assuming this:
(from Delphi help file)

To close a modal form, set its ModalResult property to a nonzero value.

Note: If the form contains buttons with a ModalResult property set to a value other than mrNone, the form automatically closes when the user clicks one of those buttons and returns the ModalResult value as the return value of ShowModal.

And if there is explanation, maybe there is a solution, too?
Any help or try will be highly appreciated...
 
Probably your form is not being able to poll the message loop (to get the button message) due to the work it is doing.

Show us some code, please.

Note: OnActivate fires any time the form receives focus; it is not a good place to do the work (but it is not the problem you are having now).

buho (A).
 
Here's the code:

-modal form call (from the main form)
Code:
procedure TForm1.CallModalExecute(Sender: TObject);
var
ScanMsk:TForm2;
begin
ScanMsk:=TForm2.Create(nil);
try
Hide;
if (ScanMsk.ShowModal=mrAbort) then
Show;
finally
ScanMsk.Release;
end;
end;

-modal form
Code:
procedure TForm2.FormActivate(Sender: TObject);

var
Row, hght, wdth, Col, k:Integer;
sl:PByteArray;
R, G, B:Byte;
ScanImg:TBitmap;

begin

WindowState:=wsMaximized;
DoubleBuffered:=True;
ScanImg:=TBitmap.Create;

try

ScanImg.LoadFromFile(ExtractFileDir(Application.ExeName) +
                     'Mas.bmp');
ScanImg.PixelFormat:=pf24bit;
Image1.Picture.Create;
Image1.Picture.Graphic:=ScanImg;

hght:=ScanImg.Height;
wdth:=ScanImg.Width;

for Row:=0 to (hght-1) do    
begin   
     sl:=ScanImg.ScanLine[Row];
     k:=0;
for Col:=0 to wdth-1 do
begin 
    B:=sl[Col*3];
    G:=sl[Col*3+1];
    R:=sl[Col*3+2];
 if (R>=148) and (G>=148) and (B>=148) then
      begin
         ScanImg.Canvas.Pen.Color:=clRed;
         ScanImg.Canvas.MoveTo(k,Row);
         ScanImg.Canvas.LineTo(Col,Row);
         Application.ProcessMessages; 
         k:=Col; 
      end;
end; 
end;
finally
ScanImg.Free;
end;
end;

procedure TForm2.StopBtnClick(Sender: TObject);
begin
ModalResult:=mrAbort;
end;
Code above was written just for fun, practising some image-pixel-stuff, it doesn't do anything useful, as you see. (it's not good, too, but it's just preparation for something bigger)
It does some drawing on Image component, which is very intensive, and during that peiod Stop button doesn't work, after process is finished, Stop works fine.
 
Sorry, put this:
Code:
Image1.Canvas.Pen.Color:=clRed;
Image1.Canvas.MoveTo(k,Row);
Image1.Canvas.LineTo(Col,Row);

instead of this
Code:
ScanImg.Canvas.Pen.Color:=clRed;
ScanImg.Canvas.MoveTo(k,Row);
ScanImg.Canvas.LineTo(Col,Row);

Sorry again, I changed some names just to show you which components I used and made mistake while overwriting.
 
The problem:

The form is not going to end the modal state while an event handler is running. You need to break the handler loop, using a Cancel flag as discussed in our other thread.

Marginally:

ProcessMessages is being called only if (R, G, B) is true. Depending on your bitmap, a lot of looping can be done without calling it.

Moving the ProcessMessages call outside the "if" may make your code a little more responsive.

Code:
//-------------------------------
// FCancel is a member of TForm2
//-------------------------------

procedure TForm2.StopBtnClick(Sender: TObject);
  begin
    ModalResult := mrAbort;
    FCancel := True;
  end;

procedure TForm2.FormActivate(Sender: TObject);
  begin
    ...
    try
      for Row
        for Col
          Application.ProcessMessages;
          if FCancel 
            then Exit
            else if (r, g, b) 
              then
                begin
                  ...
                end {if}
          end {Col}
        end {Row}
    finally
      ...
    end;
  end;

buho (A).
 
Thanks buho.
Actually, you already showed me the solution in the other thread, as you mentioned (I thought about that myself), but I thought there are maybe some other problems in this case.
Just to mention, that Application.ProcesssMesages call was for drawing (otherwise it just showes final picture, without showing the process of drawing).
Anyway, you saved me again and thanks for that very much.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top