wxContextHelp not returning correct button id for toolbar buttons (Issue #25802)

35 views
Skip to first unread message

StevenPHirshman

unread,
Sep 16, 2025, 1:50:08 PM (9 days ago) Sep 16
to wx-...@googlegroups.com, Subscribed
StevenPHirshman created an issue (wxWidgets/wxWidgets#25802)

Description

Platform and version information

  • wxWidgets version you use: 3.3.1
  • wxWidgets port you use: wxMSW
  • OS and its version: Windows 10
    • Desktop environment : MS VS 2022

-Bug Description
When I click the context sensitive help button, the cursor turns into the correct ("?") one. If I click on a button that is NOT on the toolbar with this cursor, the resulting id for that button is correctly returned in the event.GetId() of my wxEVT_HELP handler. However, when I click on a toolbar button, the event.GetId() returns the ID of the TOOLBAR and NOT the ID of the clicked button.

-Expected vs observed behavior
I expect the ID of the toolbar button to be returned by the event.GetId(), and NOT the ID of the toolbar. This would be consistent with the button event handler invoked when clicking the button with the ordinary (not the context help) cursor.

-Details
I wrote a simple app with a main frame containing a sizer (with a single button) and a toolbar (with id = ID_Toolbar). The toolbar has a few buttons as shown here:

    void MyFrame::LoadToolBars()
    {
        wxToolBar *toolbar = new wxToolBar(this, ID_Toolbar, wxDefaultPosition, wxSize(16, 16));

        toolbar->AddTool(wxID_OPEN, "Open", wxBitmap("open.png", wxBITMAP_TYPE_PNG), "Open an existing file");
        toolbar->AddTool(wxID_HELP, "Help", wxBitmap("help.png", wxBITMAP_TYPE_PNG), "Open help");
        toolbar->AddTool(wxID_CONTEXT_HELP, "Context Help", wxBitmap("context.png", wxBITMAP_TYPE_PNG), "Open context help");

        toolbar->Realize();

        SetToolBar(toolbar);
    }

The event handlers are bound as follows:

       Bind(wxEVT_HELP, &MyFrame::OnHelpContext, this);        
       Bind(wxEVT_TOOL, &MyFrame::OnHelp, this, wxID_HELP);
       Bind(wxEVT_TOOL, &MyFrame::OnContextButtonClicked, this, wxID_CONTEXT_HELP);
       Bind(wxEVT_TOOL, &MyFrame::OnOpen, this, wxID_OPEN);

-Modification needed to get the button id when the context cursor clicks on the toolbar
Note in the code below for the wxEVT_HELP handler. when the toolbar button is clicked the event returns the ID_Toolbar for the toolbar. I added the code segment for the nID == ID_Toolbar if test to get the toolbar button ID. I don't think this should be necessary - the event.GetId() should return the button Id to be consistent with clicking with the non-context cursor.

void MyFrame::OnHelpContext(wxHelpEvent& event)
{
    //wxEVT_HELP handler - gets called by wxContextHelp when item clicked

    int nID = event.GetId();

    if (nID == ID_Toolbar)
    {
        wxPoint pt = event.GetPosition();
        wxToolBar *tb = GetToolBar();

        wxPoint pt1 = tb->ScreenToClient(pt);

        wxToolBarToolBase *base = tb->FindToolForPosition(pt1.x, pt1.y);

        if (base) nID = base->GetId();
    }

    wxString str = wxString::Format("OnHelpContext called: %d", nID);

    wxMessageBox(str);
    
}


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/25802@github.com>

VZ

unread,
Sep 16, 2025, 5:10:52 PM (8 days ago) Sep 16
to wx-...@googlegroups.com, Subscribed
vadz left a comment (wxWidgets/wxWidgets#25802)

I agree that it would be more useful to provide the ID of the tool in this event. We would probably need something like your code does in the event handler right now as I don't think Windows provides this information in HELPINFO struct we receive.

And this would probably need to be done for all platforms, as I suspect all of them behave like this right now.

PRs improving this would be welcome!


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/25802/3300364914@github.com>

StevenPHirshman

unread,
Sep 16, 2025, 6:20:14 PM (8 days ago) Sep 16
to wx-...@googlegroups.com, Subscribed
StevenPHirshman left a comment (wxWidgets/wxWidgets#25802)
I agree it would be useful to fix it for all platforms. In addition to the problem with the toolbar buttons that I mentioned, there is another problem which I don’t know how to fix. Namely, if you click one of the file menu headers with the context cursor, it won’t open to allow you to continue seeking context help for the menu items.

My hope would be that you could get the click in context mode to behave EXACTLY the same as the normal click


1. When you (context) click a button, whether it is on a toolbar or not, the ID returned is the id of the button, NOT the underlying toolbar.
2. When you (context) click a menu header, the menu should open so you can click one of the menu items to get context help.

As noted, neither of these work now in that way. What would you suggestion I submit as a PR? I don’t think my “fix” is all that great for the general case.

Thanks.

***@***.***

From: VZ ***@***.***>
Sent: Tuesday, September 16, 2025 5:11 PM
To: wxWidgets/wxWidgets ***@***.***>
Cc: StevenPHirshman ***@***.***>; Author ***@***.***>
Subject: Re: [wxWidgets/wxWidgets] wxContextHelp not returning correct button id for toolbar buttons (Issue #25802)

[Image removed by sender.]vadz left a comment (wxWidgets/wxWidgets#25802)<https://github.com/wxWidgets/wxWidgets/issues/25802#issuecomment-3300364914>

I agree that it would be more useful to provide the ID of the tool in this event. We would probably need something like your code does in the event handler right now as I don't think Windows provides this information in HELPINFO struct we receive.

And this would probably need to be done for all platforms, as I suspect all of them behave like this right now.

PRs improving this would be welcome!


Reply to this email directly, view it on GitHub<https://github.com/wxWidgets/wxWidgets/issues/25802#issuecomment-3300364914>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/BNH2DLE3QGZTEUIZOUGNQHL3TB4FNAVCNFSM6AAAAACGVTYY5GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTGMBQGM3DIOJRGQ>.
You are receiving this because you authored the thread.Message ID: ***@***.***>


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/25802/3300526025@github.com>

VZ

unread,
Sep 16, 2025, 6:56:28 PM (8 days ago) Sep 16
to wx-...@googlegroups.com, Subscribed
vadz left a comment (wxWidgets/wxWidgets#25802)

I agree it would be useful to fix it for all platforms. In addition to the problem with the toolbar buttons that I mentioned, there is another problem which I don’t know how to fix. Namely, if you click one of the file menu headers with the context cursor, it won’t open to allow you to continue seeking context help for the menu items.

I don't think we can do anything about this. It used to be common to show context help for the menu items in the status bar when they're highlighted, but now applications don't even have a status bar, typically, so I don't know what are you supposed to do.

As noted, neither of these work now in that way. What would you suggestion I submit as a PR? I don’t think my “fix” is all that great for the general case.

We need to add a virtual function, something like wxWindow::GetHelpIdAtPoint(), which would just return GetId() by default but could be overridden in wxToolBar using the code you showed to find the button at the given position and return its ID. I don't see any other/better way to do it.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/25802/3300599605@github.com>

StevenPHirshman

unread,
Sep 16, 2025, 9:20:09 PM (8 days ago) Sep 16
to wx-...@googlegroups.com, Subscribed
StevenPHirshman left a comment (wxWidgets/wxWidgets#25802)
There is a workaround that would work on all platforms and for all situations (buttons, toolbar buttons, menus). Not sure what the best way to implement it would be, but here is a description of my basic idea. Presently, when the context toolbar button is clicked to enter into context mode, the function

wxContextHelp contextHelp(this);

is invoked in the wxID_CONTEXT_HELP TOOL/MENU handler. Instead of doing that, my suggestion would be to set a bool

m_bContext = true;

AND to change the window cursor to the context (question mark) cursor.

Now the user can move the “context” cursor just like the normal one and can click any button, menu item, toolbar button, etc. When the associated handler is invoked, it would be necessary to add a check on the state of m_bContext. If it is true, set it back to false and perform the context help tasks using the CORRECT ID for the item clicked. If it is true, just invoke the handler for that item and skip the context help stuff. There must be a more elegant way to do this – maybe you have some thoughts.

If you like I can send you a short example to show you (zip the cpp file). I think your idea of adding the virtual function might also work but would it work only for buttons or also menu items.

Let me know what you think.
***@***.***

From: VZ ***@***.***>
Sent: Tuesday, September 16, 2025 6:56 PM
To: wxWidgets/wxWidgets ***@***.***>
Cc: StevenPHirshman ***@***.***>; Author ***@***.***>
Subject: Re: [wxWidgets/wxWidgets] wxContextHelp not returning correct button id for toolbar buttons (Issue #25802)

[Image removed by sender.]vadz left a comment (wxWidgets/wxWidgets#25802)<https://github.com/wxWidgets/wxWidgets/issues/25802#issuecomment-3300599605>

I agree it would be useful to fix it for all platforms. In addition to the problem with the toolbar buttons that I mentioned, there is another problem which I don’t know how to fix. Namely, if you click one of the file menu headers with the context cursor, it won’t open to allow you to continue seeking context help for the menu items.

I don't think we can do anything about this. It used to be common to show context help for the menu items in the status bar when they're highlighted, but now applications don't even have a status bar, typically, so I don't know what are you supposed to do.

As noted, neither of these work now in that way. What would you suggestion I submit as a PR? I don’t think my “fix” is all that great for the general case.

We need to add a virtual function, something like wxWindow::GetHelpIdAtPoint(), which would just return GetId() by default but could be overridden in wxToolBar using the code you showed to find the button at the given position and return its ID. I don't see any other/better way to do it.


Reply to this email directly, view it on GitHub<https://github.com/wxWidgets/wxWidgets/issues/25802#issuecomment-3300599605>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/BNH2DLGPLMUXX4VR5J4AS6D3TCIRLAVCNFSM6AAAAACGVTYY5GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTGMBQGU4TSNRQGU>.
You are receiving this because you authored the thread.Message ID: ***@***.***>


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/25802/3300853142@github.com>

StevenPHirshman

unread,
Sep 17, 2025, 8:17:46 AM (8 days ago) Sep 17
to wx-...@googlegroups.com, Subscribed
StevenPHirshman left a comment (wxWidgets/wxWidgets#25802)
I‘ve attached a small file which shows that context help for the toolbar buttons (and menu) can be handled by defining a local frame variable “m_bContext” which is set when the context toolbar button is clicked. There are two things that are not so elegant about that:


1. The “IsContext” function has to be added to EVERY menu/tool handler which could be exasperating for lots of handlers
2. The “?” context cursor – which is set when the context button is clicked and reset to the normal cursor when an item is clicked – disappears when the cursor is moved onto the menu. But it still works. For example, I can click on the File menu and then click on an item there, and the context help will pop up as it should. However, it would be nice to retain the “?” cursor during this process.

Please let me know if you plan to update the toolbar handler with the virtual function you suggested (or some other update). I am reluctant to make any changes to the wxWidgets code myself. Thank youl.

***@***.***

From: VZ ***@***.***>
Sent: Tuesday, September 16, 2025 6:56 PM
To: wxWidgets/wxWidgets ***@***.***>
Cc: StevenPHirshman ***@***.***>; Author ***@***.***>
Subject: Re: [wxWidgets/wxWidgets] wxContextHelp not returning correct button id for toolbar buttons (Issue #25802)

[Image removed by sender.]vadz left a comment (wxWidgets/wxWidgets#25802)<https://github.com/wxWidgets/wxWidgets/issues/25802#issuecomment-3300599605>

I agree it would be useful to fix it for all platforms. In addition to the problem with the toolbar buttons that I mentioned, there is another problem which I don’t know how to fix. Namely, if you click one of the file menu headers with the context cursor, it won’t open to allow you to continue seeking context help for the menu items.

I don't think we can do anything about this. It used to be common to show context help for the menu items in the status bar when they're highlighted, but now applications don't even have a status bar, typically, so I don't know what are you supposed to do.

As noted, neither of these work now in that way. What would you suggestion I submit as a PR? I don’t think my “fix” is all that great for the general case.

We need to add a virtual function, something like wxWindow::GetHelpIdAtPoint(), which would just return GetId() by default but could be overridden in wxToolBar using the code you showed to find the button at the given position and return its ID. I don't see any other/better way to do it.


Reply to this email directly, view it on GitHub<https://github.com/wxWidgets/wxWidgets/issues/25802#issuecomment-3300599605>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/BNH2DLGPLMUXX4VR5J4AS6D3TCIRLAVCNFSM6AAAAACGVTYY5GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTGMBQGU4TSNRQGU>.
You are receiving this because you authored the thread.Message ID: ***@***.***>

#include <wx/wx.h>
#include <wx/cshelp.h> // For wxContextHelp

class MyFrame : public wxFrame
{
public:

enum {ID_Toolbar = 1000, ID_Button = 1001};

MyFrame() : wxFrame(nullptr, wxID_ANY, "wxContextHelp Example", wxDefaultPosition, wxSize(400, 300))
{
LoadToolBars();
LoadMenuBar();
SetBackgroundColour(*wxCYAN);

// Add a button with context-sensitive help
wxButton* helpButton = new wxButton(this, ID_Button, "Test Button");
helpButton->SetSize(150, 150, 100, 35);

wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
sizer->AddSpacer(20);
sizer->Add(helpButton,0, wxALIGN_CENTER);

SetSizer(sizer);

m_bContext = false;
curStore = GetCursor();


// Add a context help button to the frame
// wxContextHelpButton* contextHelpButton = new wxContextHelpButton(this, 1002, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW);
// contextHelpButton->SetPosition(wxPoint(150, 200));

// Bind an event to activate context help mode
Bind(wxEVT_HELP, &MyFrame::OnHelpContext, this);
Bind(wxEVT_TOOL, &MyFrame::OnHelp, this, wxID_HELP);
Bind(wxEVT_TOOL, &MyFrame::OnContextButtonClicked, this, wxID_CONTEXT_HELP);
Bind(wxEVT_TOOL, &MyFrame::OnOpen, this, wxID_OPEN);
Bind(wxEVT_BUTTON, &MyFrame::OnButton, this, ID_Button);
}

private:
//sph091725: added
bool m_bContext;
wxCursor curStore;

void LoadMenuBar()
{
wxMenuBar* mb = new wxMenuBar;

wxMenu* fileMenu = new wxMenu;
fileMenu->Append(wxID_OPEN, _("&Open\tCtrl+O"), _("Open a File"));

mb->Append(fileMenu, _("&File"));

SetMenuBar(mb);
}

void LoadToolBars()
{
wxToolBar *toolbar = new wxToolBar(this, ID_Toolbar, wxDefaultPosition, wxSize(16, 16));

toolbar->AddTool(wxID_OPEN, "Open", wxBitmap("open.png", wxBITMAP_TYPE_PNG), "Open an existing file");
toolbar->AddTool(wxID_HELP, "Help", wxBitmap("help.png", wxBITMAP_TYPE_PNG), "Open help");
toolbar->AddTool(wxID_CONTEXT_HELP, "Context Help", wxBitmap("context.png", wxBITMAP_TYPE_PNG), "Open context help");

toolbar->Realize();

SetToolBar(toolbar);
}

bool IsContext(int nID, wxString& string)
{
if (m_bContext)
{
m_bContext = false;
SetCursor(curStore);
string = wxString::Format("Help Context ID: %d", nID);
return true;
}
else return false;
}


void OnContextButtonClicked(wxCommandEvent& WXUNUSED(event))
{
//sph REPLACE THIS CALL
//wxContextHelp contextHelp(this); // Activates context-sensitive help mode
m_bContext = true;
SetCursor(wxCURSOR_QUESTION_ARROW);
}

void OnHelpContext(wxHelpEvent& event)
{
//wxEVT_HELP handler - gets called by wxContextHelp when item clicked

int nID = event.GetId();

if (nID == ID_Toolbar)
{
wxPoint pt = event.GetPosition();
wxToolBar *tb = GetToolBar();

wxPoint pt1 = tb->ScreenToClient(pt);

wxToolBarToolBase *base = tb->FindToolForPosition(pt1.x, pt1.y);

if (base) nID = base->GetId();
}

wxString str = wxString::Format("OnHelpContext called: %d", nID);

wxMessageBox(str);

}

void OnButton(wxCommandEvent& event)
{
int nID = event.GetId();
wxString str;

//there should be a better way to do this
if (!IsContext(nID, str))
{
str = wxString::Format("Button clicked: %d", nID);
}
wxMessageBox(str);
}

void OnHelp(wxCommandEvent& event)
{
int nID = event.GetId();
wxString str;

//there should be a better way to do this
if (!IsContext(nID, str))
{
str = wxString::Format("OnHelp clicked: %d", nID);
}
wxMessageBox(str);
}

void OnOpen(wxCommandEvent& event)
{
int nID = event.GetId();
wxString str;

//there should be a better way to do this
if (!IsContext(nID, str))
{
str = wxString::Format("OnOpen ID: %d", nID);
}

wxMessageBox(str);
}

};

class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
wxInitAllImageHandlers();
MyFrame* frame = new MyFrame();
frame->Show(true);
return true;
}
};

wxIMPLEMENT_APP(MyApp);


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/25802/3302720341@github.com>

StevenPHirshman

unread,
Sep 17, 2025, 8:30:15 AM (8 days ago) Sep 17
to wx-...@googlegroups.com, Subscribed
StevenPHirshman left a comment (wxWidgets/wxWidgets#25802)
I tried changing the menu bar cursor to the context cursor, but that did not work.

wxMenuBar* mb = GetMenuBar();
mb->SetCursor(wxCURSOR_QUESTION_ARROW);


***@***.***

From: VZ ***@***.***>
Sent: Tuesday, September 16, 2025 6:56 PM
To: wxWidgets/wxWidgets ***@***.***>
Cc: StevenPHirshman ***@***.***>; Author ***@***.***>
Subject: Re: [wxWidgets/wxWidgets] wxContextHelp not returning correct button id for toolbar buttons (Issue #25802)

[Image removed by sender.]vadz left a comment (wxWidgets/wxWidgets#25802)<https://github.com/wxWidgets/wxWidgets/issues/25802#issuecomment-3300599605>

I agree it would be useful to fix it for all platforms. In addition to the problem with the toolbar buttons that I mentioned, there is another problem which I don’t know how to fix. Namely, if you click one of the file menu headers with the context cursor, it won’t open to allow you to continue seeking context help for the menu items.

I don't think we can do anything about this. It used to be common to show context help for the menu items in the status bar when they're highlighted, but now applications don't even have a status bar, typically, so I don't know what are you supposed to do.

As noted, neither of these work now in that way. What would you suggestion I submit as a PR? I don’t think my “fix” is all that great for the general case.

We need to add a virtual function, something like wxWindow::GetHelpIdAtPoint(), which would just return GetId() by default but could be overridden in wxToolBar using the code you showed to find the button at the given position and return its ID. I don't see any other/better way to do it.


Reply to this email directly, view it on GitHub<https://github.com/wxWidgets/wxWidgets/issues/25802#issuecomment-3300599605>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/BNH2DLGPLMUXX4VR5J4AS6D3TCIRLAVCNFSM6AAAAACGVTYY5GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTGMBQGU4TSNRQGU>.
You are receiving this because you authored the thread.Message ID: ***@***.***>


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/25802/3302762882@github.com>

StevenPHirshman

unread,
Sep 17, 2025, 2:13:28 PM (8 days ago) Sep 17
to wx-...@googlegroups.com, Subscribed
StevenPHirshman left a comment (wxWidgets/wxWidgets#25802)
Trying to set the toolbar help when it is created:

wxToolBar *toolbar = new wxToolBar(this, ID_Toolbar, wxDefaultPosition, wxSize(16, 16));

toolbar->SetHelpText("Toolbar1");

wxString strHelp = toolbar->GetHelpText();
wxMessageBox(strHelp, "Toolbar GetHelp Text");

But that just returns an empty string. Seems like a bug to me.


***@***.***

From: VZ ***@***.***>
Sent: Tuesday, September 16, 2025 6:56 PM
To: wxWidgets/wxWidgets ***@***.***>
Cc: StevenPHirshman ***@***.***>; Author ***@***.***>
Subject: Re: [wxWidgets/wxWidgets] wxContextHelp not returning correct button id for toolbar buttons (Issue #25802)

[Image removed by sender.]vadz left a comment (wxWidgets/wxWidgets#25802)<https://github.com/wxWidgets/wxWidgets/issues/25802#issuecomment-3300599605>

I agree it would be useful to fix it for all platforms. In addition to the problem with the toolbar buttons that I mentioned, there is another problem which I don’t know how to fix. Namely, if you click one of the file menu headers with the context cursor, it won’t open to allow you to continue seeking context help for the menu items.

I don't think we can do anything about this. It used to be common to show context help for the menu items in the status bar when they're highlighted, but now applications don't even have a status bar, typically, so I don't know what are you supposed to do.

As noted, neither of these work now in that way. What would you suggestion I submit as a PR? I don’t think my “fix” is all that great for the general case.

We need to add a virtual function, something like wxWindow::GetHelpIdAtPoint(), which would just return GetId() by default but could be overridden in wxToolBar using the code you showed to find the button at the given position and return its ID. I don't see any other/better way to do it.


Reply to this email directly, view it on GitHub<https://github.com/wxWidgets/wxWidgets/issues/25802#issuecomment-3300599605>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/BNH2DLGPLMUXX4VR5J4AS6D3TCIRLAVCNFSM6AAAAACGVTYY5GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTGMBQGU4TSNRQGU>.
You are receiving this because you authored the thread.Message ID: ***@***.***>


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/25802/3304074577@github.com>

VZ

unread,
Sep 17, 2025, 3:50:00 PM (8 days ago) Sep 17
to wx-...@googlegroups.com, Subscribed
vadz left a comment (wxWidgets/wxWidgets#25802)

Sorry, I don't have any plans to work on this myself in the observable future, all I can do is apply PRs improving this.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/25802/3304362961@github.com>

VZ

unread,
Sep 23, 2025, 9:10:51 AM (2 days ago) Sep 23
to wx-...@googlegroups.com, Subscribed

Closed #25802 as completed via cd5e67f.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issue/25802/issue_event/19866312725@github.com>

Reply all
Reply to author
Forward
0 new messages