On Wed, 12 Mar 2025 11:00:30 GMT, Prasanta Sadhukhan <psadhuk...@openjdk.org> 
wrote:

>> When JRadioButtonMenuItem is called with imageIcon, then only imageIcon is 
>> shown without radiobutton in WIndowsLookAndFeel as there was no provision of 
>> drawing the radiobutton alongside icon.
>> If icon is not there, the radiobutton is drawn. Added provision of drawing 
>> the radiobutton windows Skin even when imageIcon is present.
>
> Prasanta Sadhukhan has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Review comments fix

I refined the example program and submitted a support case to Microsoft.
I'll attach to the JBS issue that version of the test case (rbm.cpp) and then
one (rbma.cpp) showing where we've got to.

First there are several elements to understand about menu items
https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-menuiteminfoa

(1) The menu item can have a string as the "item" (dwTypeData)
(2) The menu item can have a bitmap as the "item" (hbmpItem)
- Historically you could only have ONE of these because the field used to 
specify them is the same. Now by using the new MIIM* values you can have both. 
And - I don't quite understand this - using the old MFT_STRING didn't seem to 
work at all for me I had to use MIIM_STRING.

As well as those you can specify the images to use for the check state
- hbmpChecked - if the item is selected
- hbmpUnchecked - if it is not selected.


Some questions and some answers with Microsoft

Q. Why is the highlighting background gone in Windows 11 ?

A. That background was part of the “Reveal” lighting effect used by the old 
Fluent-Design menus in Windows 10. As of WinUI 2.6 (the style set shipped with 
Windows 11) the UI team removed that effect across context-menus and other 
pop-ups to achieve a flatter look that meets new contrast guidelines. So it’s 
an intentional theme change, not a GDI regression.

 
Q. Why does the item image draw over the default radio button. How can this be 
anything except a bug ?

A. The Win32 menu engine draws the default bullet/checkmark at X = 0 unless you 
reserve a check-mark column by supplying hbmpChecked (and optionally 
hbmpUnchecked).
When an hbmpItem is also present, both bitmaps occupy the same origin, so the 
icon ends up covering the bullet. This rule has been in place since the Windows 
9x/NT days—older SDK samples illustrate the same overlap if you omit the custom 
check bitmaps. Because the behaviour is longstanding and documented indirectly 
(see the remarks under SetMenuItemBitmaps and the SM_CXMENUCHECK metric), the 
shell team classifies it as by design rather than a bug.

Q. Why isn't space automatically left for the default rendering of the 
checkmark ? Another bug ?

A. For historical reasons the menu layout engine only allocates the check-mark 
column when it has a concrete size for that column, i.e. when hbmpChecked is 
non-NULL. If you ask for the default glyph while also providing an item icon, 
Windows assumes you are handling layout yourself. The docs don’t call this out 
explicitly (agreed, that would be helpful), but the behaviour is consistent and 
the same on every supported version of Windows, so it is not tracked as a GDI 
defect.

So .. in summary, two things that have been a bug so long they are considered a 
feature are at the root of this and the visual "cue" we've relied on for in 
Windows 10 was just an accident of some theming that is now gone.

So GDI really does make it hard to have all 3 of these. And maybe we should 
just not support it ?

But if  (as GDI programmers) we want an item string and bitmap, and expect 
feedback that an item is selected, we seem to be forced into needing to specify 
bitmaps for the checked and un-checked state. But then you lose the default 
rendering of the bullet that Windows provides !

There's some hoops we can jump through to get close
- Use a transparent bitmap for hbmpUnchecked
- Use a GDI API - DrawFrameControl - to render a bullet image into a bitmap we 
use for hbmpChecked. Prasanta previously noted that AWT uses this API already)

rbma.cpp illustrates this.

This still isn't perfect - the bullet is too large.

I'll leave it to others to figure out how we make use of this in the Swing 
rendering case.
Are there any unanswered questions ? This is a long PR so perhaps ..

-------------

PR Comment: https://git.openjdk.org/jdk/pull/23324#issuecomment-2859773998

Reply via email to