Board index » delphi » manually using popup menus?

manually using popup menus?

I am trying to make a simple standalone function that
will take a list of strings, popup a menu that contains
those strings, and then return the string selected
by the user (or nothing if cancelled).  Getting
the pop-up to display my strings has been easy.  But
I cannot figure out how to get the selection (would
be nice if the Popup method was a function that would
return selected index or string).  I have tried setting
the popup click handler for the menu items to point to
a procedure that isn't a method of any object that will
simply set a global for me to return in my function...
but the compiler whines and complains that it is an
invalid function or procedure reference.

Here is a snippet of my test code (hopefully not to
mangled by newsreader wrapping)...

CONST SelString : STRING = '';

PROCEDURE PopupProc( Sender : TObject );
 BEGIN
   SelString := TMenuItem( Sender ).Name;
 END;

FUNCTION StrFromPopupScroll( aParent : Pointer;
                             X, Y    : INTEGER;
                             TheList : TdStrCollection ) : PChar;
 VAR Temp   : TPopupMenu;
     Items  : ARRAY[1..2] OF TMenuItem;
 BEGIN
   { temporary test stubs to be replaced by building Items from passed
in TheList... }

    { compiler halts on PopupProc as invalid function or procedure
reference... }
    Items[1] := NEWItem( 'Item1Caption', 0, FALSE, TRUE, PopUpProc, 0,
'Item1Name' );

    { nor will compiler let me set popupproc like this... }
    Items[2] := NEWITem( 'Item2Caption', 0, FALSE, TRUE, NIL, 0,
'Item2Name' );
    Item1[2].OnClick:= PopupProc;

   { make the menu }
    Temp := NewPopupMenu( aParent, 'MenuName', paLeft, FALSE, Items);

   SelString := '';

   { pop it up and doesn't return until selection is made }
    Temp.Popup( iX, iY );

   { Selstring should be set by now if selection is made...}
     return the selected string as pchar, or NIL if cancelled }
    StrFromPopupScroll := AllocPChar( SelString );

   { destroy the menu }
    Temp.Destroy;
 END;

What am I doing wrong?  
It would be nice if I could just not use callback proc method
but simply query the popupmenu for what the selection was after
Popup is executed, but I cannot find a means to do so (Borland's
documentation is pretty incomplete).

How might I get the functionality I desire
(remember, I don't want this to rely on any
other objects/components but be standalone)?

-Erik Johnson
e...@phidias.colorado.edu
http://phidias.colorado.edu/vgallery.html

 

Re:manually using popup menus?


I posted here earlier today on the subject of
popup menus, haven't receieved a response.

Pop up menus suck.  Okay, enough venting.

I cannot get my popup menu clicks to be handled
by anything, anywhere, anytime.  

Since trying what was in my previous post,
I have tried fielding the menuitem's clickon
from a generic component, through a method
on a subclass of menuitem (that I initted
instead), and a through a method on the parent
form.  Nothing gets called. Borland's
documentation on the subject suckS, very little
about how to field these events, and everything
assumes you are working with the automatically
generated code which requires the window to know
the specifics of everything (pretty poor for code
reuse), oh, I said enough venting didn't I.

My previous post went into much greater detail
of my problem and what I'm trying to do.

Gee, I've ported most of an 80k line OWL
app that I wrote (including popup menus) to
VCL in about a week, have encountered and
overcome numerous issues with Delphi classes,
to be so thoroughly stuck (6hrs now) on such
a seemingly simple (but crucial) thing as a
popup menu is pretty disheartening. Curses
on Delphi for going to so much effort to be
automatic and intuitive that suddenly doing
anything 'manually' becomes entirely
counterintuitive, gads I'm venting again.

Can anyone help?  I'm at the end of my rope.

-Erik Johnson
e...@phidias.colorado.edu
http://phidias.colorado.edu/vgallery.html

Re:manually using popup menus?


On Wed, 11 Dec 1996 18:42:08 +0000, Erik Johnson observed that:-

Quote
>Pop up menus suck.  Okay, enough venting.
>I cannot get my popup menu clicks to be handled
>by anything, anywhere, anytime.  

[huge snip!]

I don't have delphi with me here, so I can't test this, but here we
go...

(1) Do it all in an object (component/form/direct TObject descendant)
and then do exactly what you said in your code, but with a method of
this object.

(2) Set the tag property of each MenuItem to the index of the string
in the list.

(3) In the event handler which is a method of your object you are
doing this from, set a variable of your object to whatever (Sender as
TMenuItem).Tag is.

(4) After the call to MyMenu.Popup(x,y), check the value of the
variable.

The most important thing is that the method you reference which gets
called as the event handler MUST be in an object because TNotifyEvent
is a

type TNotifyEvent procedure (Sender: TObject) of object;
                                              ^^^^^^^^^^

Phew. Hope this helped!

--
Ian E. Hickson              

Re:manually using popup menus?


Thanks to those who have been attempting to help
me with getting popup menus to work the way I want
them to.

I have made a breakthrough, and have gotten
my onclick handler to be called.  It required
initting the tpopupmenu from the event handling
form's constructor.  But I'm not out of the woods
yet there is a catch.

Since I reuse the same popup menu over and over
for a given window, but my menus will be dynamically
different depending on what the mouse is over within
the window... I have to clear the popup menu items
when done or each popup menu use will cause more
and more strings to appear.  Right, makes sense.

But, the second I add code to delete even one of
the menuitems at the end of my function, the event
handler stops getting called... *BEFORE* the line
to delete the item from the popup is ever called!

So how is it that a line of code that hasn't been
executed can prevent my event handler from working?

Most perplexing.  Any ideas?

-Erik Johnson
e...@phidias.colorado.edu
http://phidias.colorado.edu/vgallery.html

Re:manually using popup menus?


On Wed, 11 Dec 1996 18:42:08 +0000, Erik Johnson observed that:-

Quote
>Pop up menus suck.  Okay, enough venting.
>I cannot get my popup menu clicks to be handled
>by anything, anywhere, anytime.  

[huge snip!]

I don't have delphi with me here, so I can't test this, but here we
go...

(1) Do it all in an object (component/form/direct TObject descendant)
and then do exactly what you said in your code, but with a method of
this object.

(2) Set the tag property of each MenuItem to the index of the string
in the list.

(3) In the event handler which is a method of your object you are
doing this from, set a variable of your object to whatever (Sender as
TMenuItem).Tag is.

(4) After the call to MyMenu.Popup(x,y), check the value of the
variable.

The most important thing is that the method you reference which gets
called as the event handler MUST be in an object because TNotifyEvent
is a

type TNotifyEvent procedure (Sender: TObject) of object;
                                              ^^^^^^^^^^

Phew. Hope this helped!

--
Ian E. Hickson              

Other Threads