Jump to content
PeterPanettone

Highlight a specific popup menu item?

Recommended Posts

In a project where I try to create a kind of "sticky popup menu simulation", I have the problem of highlighting a specific popup menu item:

 

StickyPopupMenuSimulation.zip

 

This problem is also being discussed at StackOverflow:

 

https://stackoverflow.com/questions/60850050/how-to-highlight-a-specific-popup-menu-item

 

...where Remy Lebeau has provided an answer. Unfortunately, that answer does not work in my project.

 

So I invite everybody to check out my project and to test the answer from StackOverflow.

 

(I politely ask for dispassionate answers).

Edited by PeterPanettone

Share this post


Link to post

The way you are using SetMenuItemInfo() and HiliteMenuItem() in the DropdownMenuShow() method will not work.  You are calling them after TPopupMenu.Popup() has exited.  Popup() is a blocking method, it does not exit until the popup menu has been dismissed.

 

The TPopupMenu.OnPopup event is fired while Popup() is running.  However, upon further review, OnPopup is fired BEFORE the menu is made visible, and TPopupMenu may recreate the menu AFTER OnPopup has been called and BEFORE the menu is actually shown.

 

So, your best bet is likely to subclass the TPopupList window so you can intercept the WM_ENTERMENULOOP message, then customize your menu items at that point.  For example:

type
  TPopupListEx = class(TPopupList)
  protected
    procedure WndProc(var Message: TMessage); override;
  end;

procedure TPopupListEx.WndProc(var Message: TMessage);
begin
  inherited;
  if (Message.Msg = WM_ENTERMENULOOP) and (Message.WParam = 1) then
  begin
    // customize pmTest items as needed...
  end;
end;

initialization
  Popuplist.Free; //free the "default", "old" list
  PopupList := TPopupListEx.Create; //create the new one
  // The new PopupList will be freed by
  // finalization section of Menus unit.
end.

 

Edited by Remy Lebeau
  • Like 2

Share this post


Link to post

Remy, with your hints, it is now partially working:

 

procedure TPopupListEx.WndProc(var Message: TMessage);
var
  mii: MENUITEMINFO;
begin
  inherited;
  if (Message.Msg = WM_ENTERMENULOOP) and (Message.WParam = 1) then
  begin
    // customize pmTest items as needed...

    ZeroMemory(@mii, sizeof(mii));
    mii.cbSize := sizeof(mii);
    mii.fMask := MIIM_STATE;
    mii.fState := MFS_HILITE;

    Winapi.Windows.SetMenuItemInfoW(Form1.pmTest.Handle, 1, True, mii);
  end;
end;

 

Now, when I show the popup menu the first time, the menu item with index 1 is highlighted:

 

image.png.79b3cebd1166f8855ce8091299db2e1d.png

 

But then, when I hover the mouse over the first menu item, BOTH menu-items are highlighted:

 

image.png.2941c2fc1b64a6920de7d8c92cc5b789.png

 

Instead, the second menu-item should become un-highlighted when the first menu-item becomes highlighted. Why this is not the case?

 

Only when I hover the mouse over the second menu-item and then back to the first menu item, the second menu-item becomes un-highlighted:

 

image.png.e2de5490f0a110653d4ed95cf5906624.png        image.png.c885628ce3ee2d2c76d24e37b46f3676.png

 

So I repost here the changed source-code, so everybody can see how the code looks in detail:

 

StickyPopupMenuSimulation_2.zip

Share this post


Link to post

Side note: if you don't have to support old compilers, using Default() intrinsic instead of ZeroMemory is less error-prone.

Share this post


Link to post
1 minute ago, Fr0sT.Brutal said:

Side note: if you don't have to support old compilers, using Default() intrinsic instead of ZeroMemory is less error-prone.

Thanks. Can you please show a short code example in the context of the above project?

Share this post


Link to post

Pros:

* Type check => less error-prone

* Takes care of existing managed fields if any

* For tiny records is replaced with several CPU instructions instead of calling function with all the overhead => faster

Contras:

* None IMHO. One very rare case is if you alloc a record with managed fields in a heap without zeroing, then it probably fail on attempt of disposing these fields before assignment (fields will contain random garbage)

Edited by Fr0sT.Brutal
"less error-prone"

Share this post


Link to post
6 hours ago, Fr0sT.Brutal said:

* Type check => error-prone

Maybe you meant *LESS* error prone?

6 hours ago, Fr0sT.Brutal said:

* Takes care of existing managed fields if any

That is a biggy.

6 hours ago, Fr0sT.Brutal said:

One very rare case is if you alloc a record with managed fields in a heap without zeroing, then it probably fail on attempt of disposing these fields before assignment (fields will contain random garbage)

You don't need heap allocation to get into that situation, but it is harder to do without manually coercing the type system.

Share this post


Link to post
7 hours ago, Remy Lebeau said:

Maybe you meant *LESS* error prone?

Sure you're right

7 hours ago, Remy Lebeau said:

That is a biggy

I don't get it 😞 what do you mean?

7 hours ago, Remy Lebeau said:

You don't need heap allocation to get into that situation

Could you make an example?

Share this post


Link to post

Let it be known that out of curiosity I compiled your project 3 with D10.2.3

and it does nothing except showing 01234...

Share this post


Link to post
1 hour ago, limelect said:

Let it be known that out of curiosity I compiled your project 3 with D10.2.3

and it does nothing except showing 01234...

What do you want it to do? Making coffee? :classic_smile:

Share this post


Link to post
10 hours ago, Fr0sT.Brutal said:

I don't get it 😞 what do you mean?

I simply mean that properly managing managed fields (strings, interfaces, variants, etc) is an important pro for using Default() vs ZeroMemory().  But, if the type has no managed fields, then it doesn't really matter which one you use, though Default() does make for cleaner code.

 

Edited by Remy Lebeau

Share this post


Link to post
1 hour ago, limelect said:

Blue color on the dropdown.

It does not, just show the numbers. No blue color !

Thanks for the information.

 

When you hover the mouse pointer over a menu-item (and move the mouse a little bit), does that menu-item get highlighted?

 

Can you please show a screenshot?

Share this post


Link to post
10 hours ago, PeterPanettone said:

Blue color on the dropdown.

It does not, just show the numbers. No blue color !

Can you please show a screenshot while you hover the mouse pointer over a menu-item (and move the mouse a little bit), does that menu-item get highlighted? Thank you!

Share this post


Link to post
2 hours ago, PeterPanettone said:

Can you please show a screenshot while you hover the mouse pointer over a menu-item (and move the mouse a little bit), does that menu-item get highlighted? Thank you!

No, it does not.

It seems you think I am a novice.

See my About

http://limelect.com/about-us/

And here you have a lot of goodies for free

Some are very popular

http://limelect.com/free-programs/

 

And finally good luck

 

Share this post


Link to post

Well, it does show some bluish color but so faint that it is almost not there.

Maybe this helps you.

Share this post


Link to post
1 hour ago, limelect said:

Well, it does show some bluish color but so faint that it is almost not there.

Could you please show me a screenshot of that "bluish color but so faint that it is almost not there".

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×