Almost working modeless dialog: just not receiving events

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
User avatar
bsenftner
Experienced Solver
Experienced Solver
Posts: 85
Joined: Thu May 26, 2016 9:19 pm

Almost working modeless dialog: just not receiving events

Post by bsenftner »

After various versions, working from examples and samples, I have the following nearly working modeless dialog.

Searching this forum, I found a fix to the controls not rendering - which is a call to Update() after Show().

This "works" except there are no events being passed back. I thought button clicks would work at least, if not dragging the dialog, but nothing.

The class definition for a modeless dialog that is a user alert of an event in the software, with the program continuing after the notification:

Code: Select all

class CX_MatchAlarmDlg : public wxDialog
{
	DECLARE_DYNAMIC_CLASS(CX_MatchAlarmDlg)
	DECLARE_EVENT_TABLE()

public:
	CX_MatchAlarmDlg(wxWindow* parent, wxWindowID id, const wxString& title, 
		cx_real matchScore, std::string& name, cx_int personId);
	~CX_MatchAlarmDlg();

	void OnButton(wxCommandEvent& event);
};
Here's the modeless dialog class implementation:

Code: Select all

#include "CX_matchAlarmDlg.h" // the class definition 

static const long ID_MODELESS_OK_BUTTON = wxNewId();

IMPLEMENT_CLASS(CX_MatchAlarmDlg, wxDialog)

BEGIN_EVENT_TABLE(CX_MatchAlarmDlg, wxDialog)
	EVT_BUTTON(ID_MODELESS_OK_BUTTON, CX_MatchAlarmDlg::OnButton)
END_EVENT_TABLE()

///////////////////////////////////////////////////////////////////
CX_MatchAlarmDlg::CX_MatchAlarmDlg(wxWindow* parent, wxWindowID id, const wxString& title, 
	cx_real matchScore, std::string& name, cx_int personId, wxSound* sound)
	: wxDialog(parent, id, title)
{

	wxBoxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);

	wxString msg;
	msg.Printf("PersonId: '%d', name '%s', match score: '%1.2f", personId, name.c_str(), matchScore);

	wxStaticText* msgTxt = new wxStaticText(this, wxID_ANY, msg, wxDefaultPosition, wxDefaultSize);

	wxButton *okButton = new wxButton(this, ID_MODELESS_OK_BUTTON, wxT("Ok"), wxDefaultPosition, wxDefaultSize);

	sizerTop->Add(msgTxt, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
	sizerTop->Add(okButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);

        // not sure if needed, thought that the event table above handled this...
	Connect(ID_MODELESS_OK_BUTTON, wxEVT_BUTTON, (wxObjectEventFunction)&CX_MatchAlarmDlg::OnButton);

	SetSizerAndFit(sizerTop);

	m_sound = sound;
}

///////////////////////////////////////////////////////////////////
CX_MatchAlarmDlg::~CX_MatchAlarmDlg() { }

///////////////////////////////////////////////////////////////////
void CX_MatchAlarmDlg::OnButton(wxCommandEvent& WXUNUSED(event))
{
	Hide();  // I'll do something more sophisticated when this starts getting called!
}
And here is how it is called, with the undocumented Update() call that triggers the controls to render correctly:

Code: Select all

m_alarm_dialog = new CX_MatchAlarmDlg(this, wxID_ANY, "Verified Gallery Match", matchScore, personName, personId, m_alarm_sound);
m_alarm_dialog->Show();
m_alarm_dialog->Update();
Any idea why this is not receiving any events?
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Almost working modeless dialog: just not receiving events

Post by doublemax »

I tested the code and it works for me (The dialog hides when you click the button).

Are you sure the button event handler is not called? Maybe just the Hide() didn't work for whatever reason. Even the Update() call should not be necessary and this could indicate that something else is wrong somewhere.

Besides, i highly recommend to use a wxFrame instead of a wxDialog. If you want a something modal, use wxDialog. For something modeless use wxFrame.
Use the source, Luke!
User avatar
bsenftner
Experienced Solver
Experienced Solver
Posts: 85
Joined: Thu May 26, 2016 9:19 pm

Re: Almost working modeless dialog: just not receiving events

Post by bsenftner »

I am working in Visual Studio, and have placed breakpoints in the onButton() callback, and it is not being triggered...

I tried to convert to a wxFrame by changing the 4 different references to wxDialog to be wxFrame. That behaves in a similar manner, meaning I get no interactivity. I can't drag the window, and the button nor the close box work... (I tried adding a close callback.)

I have both the event table def as well as a call to Connect() the button (by id) to it's callback. Only one of those is needed, correct? Could you try commenting out the Connect() and see if your version still works?
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Almost working modeless dialog: just not receiving events

Post by doublemax »

I have both the event table def as well as a call to Connect() the button (by id) to it's callback. Only one of those is needed, correct?
Yes.
Could you try commenting out the Connect() and see if your version still works?
Yes, each one of them alone works too.

I'm attaching the modified "minimal" sample that i used to test your code. If this works for you, you know the problem is somewhere else. (Open the dialog through Help -> About in the menu)
Attachments
minimal.cpp
(8.14 KiB) Downloaded 81 times
Use the source, Luke!
User avatar
bsenftner
Experienced Solver
Experienced Solver
Posts: 85
Joined: Thu May 26, 2016 9:19 pm

Re: Almost working modeless dialog: just not receiving events

Post by bsenftner »

Thank you for this. I'm still having issues.

I am starting to suspect I have a flaky build of the wx libraries. I thought I'd built an x64, unicode monolithic library, but seems like something is misconfigured because my visual studio library is vc_lib and not vc_x64_lib as I see in some of the setups I'm reviewing as I try to figure this out. After about 45 minutes of fussing with the visual studio project settings, I was unable to resolve the link errors on that working minimal program you gave. It ultimately gives me:

Code: Select all

1>------ Build started: Project: ModelessDialog, Configuration: Debug x64 ------
1>wxbase30ud.lib(utilscmn.obj) : error LNK2001: unresolved external symbol _wenviron
1>wxbase30ud.lib(extended.obj) : error LNK2001: unresolved external symbol _HUGE
1>C:\Users\Blake\Source\Repos\April2016\code2013\blakeWxWork\ModelessDialog\x64\Debug\ModelessDialog.exe : fatal error LNK1120: 2 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I don't understand why the samples dialog program works just fine, but my modeless based on it needs that extra Refresh(), yet there's no events...

You were able to drag the dialog around? And when mousing over the button it provided feedback of being active? Mine are just static.

My existing application has a main frame, with a notebook holding 3 tabs, each with moderately decent working toolbars, sub frames, buttons, menus and other working GUI crud. I am really flummoxed. What would cause a loss of events to that window?

I hope a shift to using wxFrames fixes this, as my application will have a series of modeless interfaces. I can't spend so much time on issues like this.
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Almost working modeless dialog: just not receiving events

Post by doublemax »

Which Visual Studio and wxWidgets version are you using?

Building a 64bit build with VS doesn't require fiddling with any project files, you just select "x64" as platform. You're also talking about a monolithic library. The solution files that come with wxWidgets don't have an option for that, so did you build wxWidgets from the command line?

I think you should rebuild the libraries from scratch and start with building the "minimal" sample that comes with wxWidgets. This should work out of the box without any issues. If that works replace the "minimal.cpp" with the one i uploaded.
Use the source, Luke!
User avatar
bsenftner
Experienced Solver
Experienced Solver
Posts: 85
Joined: Thu May 26, 2016 9:19 pm

Re: Almost working modeless dialog: just not receiving events

Post by bsenftner »

> Which Visual Studio and wxWidgets version are you using?

Visual Studio Community 2013, update 4
wxWidgets 3.0.2

I followed a guide from the wxWidgets.org site, and then I got DialogBlocks, which "took over" building the library. I don't use DialogBlocks often enough to be proficient using it, and I may have configured something wrong.

I have the Cross Platform GUI w/ wxWidgets book, which is helping. Yeah, I do need to rebuild the libs.
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Almost working modeless dialog: just not receiving events

Post by doublemax »

Visual Studio Community 2013, update 4
wxWidgets 3.0.2
Building wxWidgets with Visual Studio is the easiest of all options:

Navivate to <wxdir>/build/msw/
Open wx_vc12.sln
It should default to the configuration "Debug" / "Win32" (Shown in the toolbar)
Select "Rebuild solution". Depending on your machine, this will take from 2 to 10 minutes
Change configuration from "Debug" to "Release" and build again.
(If you want a 64bit build, change platform to from "Win32" to "x64" and do the same. But until everything else works, stick with 32bit for now).

Now for building the "minimal" sample:
Navigate to <wxdir>/samples/minimal/
wxWidgets 3.0.2 has no solution files for newer VS version, but you can open "minimal_vc9.vcproj" and it should be automatically converted.
From here the steps are the same as above.
Use the source, Luke!
User avatar
bsenftner
Experienced Solver
Experienced Solver
Posts: 85
Joined: Thu May 26, 2016 9:19 pm

Re: Almost working modeless dialog: just not receiving events

Post by bsenftner »

I'm going to rebuild wxWidgets, but I wanted to thank you because I did finally get this working.

I tried popping a wxMessageBox() at that same place in the logic, and that triggered an assert about being in the wrong thread.

Tracking down my context, I realized I was within a callback from a separate video library, and indeed in a "foreign" thread than that of wxWidgets.

So I set a flag that this situation occurred, retain some data, and with a wxTimer running off the same object as a toolbar I look at the flag and then build & display the dialog, receiving events just fine. No alterations to my code.

I tried a version where I build the dialog in the video callback, and only display it from the wxTimer event callback, but that did not work.

Long story short: only do GUI operations in the main thread where wxWidgets runs.
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Almost working modeless dialog: just not receiving events

Post by doublemax »

Long story short: only do GUI operations in the main thread where wxWidgets runs.
Indeed :)

I guess there is no need to rebuild the libraries then, the thread involvement can explain any kind of wrong or weird behavior.
Use the source, Luke!
Post Reply