Board index » delphi » GPF Fault - Why?

GPF Fault - Why?

I have a small program I'm developing and I dynamically create a popup
menu, but my program crashes with a GPF fault every time I access the
popup menu on the third try.  I got this piece of code from the web and
only modified it slightly and see nothing wrong with it.  I compiled the
piece of code from the web and it works fine with no problems at all.  I
have all debugging info turned on and get no errors or warnings doing the
compile, so I'm really stumped.  Here is the code.

procedure TForm1.DBGridPopUp(Sender: TObject);
var
    MItem : TMenuItem;
    ICnt : Integer;
begin
    (* ******* Crashes on the next line ******* *)
    PopUpMenu := TPopUpMenu.Create(Self);

    if MyDBGrid.FieldCount > 0 then
    begin
        MItem := TMenuItem.Create(PopUpMenu);
        MItem.Caption := 'SortOn ' + MyDBGrid.SelectedField.FieldName;
        MItem.OnClick := MPopHandler;
        PopUpMenu.Items.Add(MItem);
    end;

    if IHidCols > 0 then begin
        MItem := TMenuItem.Create(PopUpMenu);
        MItem.Caption := '-';
        { Separator No OnClick Handler }
        PopUpMenu.Items.Add(MItem);

        For ICnt := 1 to IHidCols do Begin
            MItem := TMenuItem.Create(PopUpMenu);
            MItem.Caption := 'Show ' + HidCols[ICnt];
            MItem.OnClick := MPopHandler;
            PopUpMenu.Items.Add(MItem);
        end;
    end;

    if MyDBGrid.FieldCount > 0 then
    begin
        MItem := TMenuItem.Create(PopUpMenu);
        MItem.Caption := '-';
        { Separator No OnClick Handler }
        PopUpMenu.Items.Add(MItem);

        MItem := TMenuItem.Create(PopUpMenu);
        MItem.Caption := 'Hide ' + MyDBGrid.SelectedField.FieldName;
        MItem.OnClick := MPopHandler;
        PopUpMenu.Items.Add(MItem);
    end;

    PopUpMenu.Popup(P_Cur.X, P_Cur.Y);
end;

The code allows me to hide, show hidden columns, and sort by a selected
column, which seems to work except for the crashing problem.  I'm not
sure if I should free the popup menu when done with it, and if I do I
really don't know where to do it at, since it's created dynamically.

Any help will be greatly appreciated.

                                   .                        
 ___           ___         .               .                
 \o      o      o/    .       Tim Hosfelt      .         {~|
  \    \/|      |  . HOSFELT....@epamail.epa.gov .   .    ~|
  |\.    |\.   /|.                                 .   ....|

 

Re:GPF Fault - Why?


Quote
thosf...@lys.vnet.net (thosfelt) wrote:
>I have a small program I'm developing and I dynamically create a popup
>menu, but my program crashes with a GPF fault every time I access the
>popup menu on the third try.  I got this piece of code from the web and
>only modified it slightly and see nothing wrong with it.  I compiled the
>piece of code from the web and it works fine with no problems at all.  I
>have all debugging info turned on and get no errors or warnings doing the
>compile, so I'm really stumped.  Here is the code.

>procedure TForm1.DBGridPopUp(Sender: TObject);
>var
>    MItem : TMenuItem;
>    ICnt : Integer;
>begin
>    (* ******* Crashes on the next line ******* *)
>    PopUpMenu := TPopUpMenu.Create(Self);

>    if MyDBGrid.FieldCount > 0 then
>    begin
>        MItem := TMenuItem.Create(PopUpMenu);
>        MItem.Caption := 'SortOn ' + MyDBGrid.SelectedField.FieldName;
>        MItem.OnClick := MPopHandler;
>        PopUpMenu.Items.Add(MItem);
>    end;

>  ........  Code abbreviated .....
>    if IHidCols > 0 then begin
>        MItem := TMenuItem.Create(PopUpMenu);
>        MItem.Caption := '-';
>        { Separator No OnClick Handler }
>        PopUpMenu.Items.Add(MItem);

>        MItem := TMenuItem.Create(PopUpMenu);
>        MItem.Caption := 'Hide ' + MyDBGrid.SelectedField.FieldName;
>        MItem.OnClick := MPopHandler;
>        PopUpMenu.Items.Add(MItem);
>    end;

>    PopUpMenu.Popup(P_Cur.X, P_Cur.Y);
>end;

>The code allows me to hide, show hidden columns, and sort by a selected
>column, which seems to work except for the crashing problem.  I'm not
>sure if I should free the popup menu when done with it, and if I do I
>really don't know where to do it at, since it's created dynamically.

I'm not sure why it is cashing after three tries but the first thing I
would do is to change the constructor calls for the TMenuItem.  It should
be:
        MItem := TMenuItem.Create(self);
instead of:

        MItem := TMenuItem.Create(PopUpMenu);

You might also think about adding a TPopupMenu to the main class that
represents  the form (TForm1) instead of constructing it on each call to
DBGridPopUp.  This will allow you to delete the contents of PopUpMenu an
then to rebuild it.  For example,

type
  TForm1 = class(TForm)
   ...
   ...
  private
    PopUpMenu: TPopupMenu;
  ....
end;

On the Form Create call the constructor to TPopupMenu and assign
PopupMenu to the PopupMenu property of the DBGrid and lastly assign
DBGridPopUp to the OnPopup event of the PopupMenu.  

PopupMenu := TPupuMenu.Create(self);
DBGrid1.PopupMenu := PopupMenu;
PopupMenu.OnPopup := DBGridPopUp;

On each call to DBGridPopUp remove any existing MenuItems. For example,

while PopupMenu.Items.Count > 0 do
  PopupMenu.Items.Delete(PopuMenu.Items.Count -1 );

{ Next construct the list }

Hope this helps

Regards,

Kevin

Re:GPF Fault - Why?


On 14 Apr 1996 09:10:56 -0400, thosf...@lys.vnet.net (thosfelt) wrote:

Quote
>I have a small program I'm developing and I dynamically create a popup
>menu, but my program crashes with a GPF fault every time I access the
>popup menu on the third try.  I got this piece of code from the web and
>only modified it slightly and see nothing wrong with it.  I compiled the
>piece of code from the web and it works fine with no problems at all.  I
>have all debugging info turned on and get no errors or warnings doing the
>compile, so I'm really stumped.  Here is the code.

>procedure TForm1.DBGridPopUp(Sender: TObject);
>var
>    MItem : TMenuItem;
>    ICnt : Integer;
>begin
>    (* ******* Crashes on the next line ******* *)
>    PopUpMenu := TPopUpMenu.Create(Self);

>    if MyDBGrid.FieldCount > 0 then
>    begin
>        MItem := TMenuItem.Create(PopUpMenu);
>        MItem.Caption := 'SortOn ' + MyDBGrid.SelectedField.FieldName;
>        MItem.OnClick := MPopHandler;
>        PopUpMenu.Items.Add(MItem);
>    end;

>    if IHidCols > 0 then begin
>        MItem := TMenuItem.Create(PopUpMenu);
>        MItem.Caption := '-';
>        { Separator No OnClick Handler }
>        PopUpMenu.Items.Add(MItem);

>        For ICnt := 1 to IHidCols do Begin
>            MItem := TMenuItem.Create(PopUpMenu);
>            MItem.Caption := 'Show ' + HidCols[ICnt];
>            MItem.OnClick := MPopHandler;
>            PopUpMenu.Items.Add(MItem);
>        end;
>    end;

>    if MyDBGrid.FieldCount > 0 then
>    begin
>        MItem := TMenuItem.Create(PopUpMenu);
>        MItem.Caption := '-';
>        { Separator No OnClick Handler }
>        PopUpMenu.Items.Add(MItem);

>        MItem := TMenuItem.Create(PopUpMenu);
>        MItem.Caption := 'Hide ' + MyDBGrid.SelectedField.FieldName;
>        MItem.OnClick := MPopHandler;
>        PopUpMenu.Items.Add(MItem);
>    end;

>    PopUpMenu.Popup(P_Cur.X, P_Cur.Y);
>end;

>The code allows me to hide, show hidden columns, and sort by a selected
>column, which seems to work except for the crashing problem.  I'm not
>sure if I should free the popup menu when done with it, and if I do I
>really don't know where to do it at, since it's created dynamically.

Yes you should free the Popup-Menu after you are done with it since
you create it at the begining of the procedure.  You are loosing
resources otherwise.  However, what I would do is create the popup
menu at startup (or drop one on the form) and then just dynamically
add and remove menu items as needed.

Everything else looks ok, it looks like the Popup Menu variable is
global so you will want to check the rest of your code and make sure
its not clobbering the pointer (not that it would matter since you
overwrite the pointer anyway).

Brien King
bk...@primenet.com

Re:GPF Fault - Why?


Quote
thosfelt wrote:

> I have a small program I'm developing and I dynamically create a popup
> I'm not
> sure if I should free the popup menu when done with it, and if I do I
> really don't know where to do it at, since it's created dynamically.

> Any help will be greatly appreciated.

I haven't used that particular component but I am fairly positive that
you _shouldn't_ create it every time you call it.

Move the  "PopUpMenu := TPopUpMenu.Create(Self);" statement from the body
of "procedure TForm1.DBGridPopUp(Sender: TObject);"

Put it in your form Oncreate event (e.g "procedure
TFMain.FormCreate(Sender: TObject);") instead.

Add a "PopUpMenu.free;" statement to your form onClose event to free the
object.

Cheers,

Rudi
--
My opinions are my own and do not in any way reflect
those of my employer.
-

Other Threads