wxNotebook on MS-Windows 7 : Won't change panel
wxNotebook on MS-Windows 7 : Won't change panel
My main dialog window contains a wxNotebook.
The wxNotebook contains 3 panels, which of course can be navigated through by using the 3 tabs at the top of the notebook.
My program works absolutely fine on Linux (wxGTK).
However, I complied it on MS-Windows 7 Ultimate, ran it, but the wxNotebook doesn't work properly. When you click on a tab, the notebook actually changes tab (and it sends the events CHANGING and CHANGED), but it still displays the previous panel... it won't display the new panel corresponding to the tab you clicked???
Has anyone else seen behaviour like this?
I thought it might be something in my code that was causing this, so I decided to create a new empty project in Codeblocks, and I copied my wxFormbuilder project file into the new project. I compiled the program, and again, the same problem with the wxNotebook.
I'm using Ubuntu right now to type this post so I can't post a minimal program that exhibits the problem, but I'll boot into MS-Windows later on and post a small code snippet that shows the problem.
I tried using the wxAuiNotebook in MS-Windows and it works fine, but I wanna use the plain old wxNotebook for simplicity.
The wxNotebook contains 3 panels, which of course can be navigated through by using the 3 tabs at the top of the notebook.
My program works absolutely fine on Linux (wxGTK).
However, I complied it on MS-Windows 7 Ultimate, ran it, but the wxNotebook doesn't work properly. When you click on a tab, the notebook actually changes tab (and it sends the events CHANGING and CHANGED), but it still displays the previous panel... it won't display the new panel corresponding to the tab you clicked???
Has anyone else seen behaviour like this?
I thought it might be something in my code that was causing this, so I decided to create a new empty project in Codeblocks, and I copied my wxFormbuilder project file into the new project. I compiled the program, and again, the same problem with the wxNotebook.
I'm using Ubuntu right now to type this post so I can't post a minimal program that exhibits the problem, but I'll boot into MS-Windows later on and post a small code snippet that shows the problem.
I tried using the wxAuiNotebook in MS-Windows and it works fine, but I wanna use the plain old wxNotebook for simplicity.
I checked the code that was auto-generated by wxFormBuilder:
Everything looks alright (...unless you notice something?)
I'll try the wxNotebook sample on Win7 later.
Code: Select all
m_notebook1 = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM );
m_panel_socket = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_notebook1->AddPage( m_panel_socket, wxT("Step 1: Open Network Interface"), true );
m_panel_arp = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_notebook1->AddPage( m_panel_arp, wxT("Step 2: Send ARP Requests"), false );
m_panel_probe = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_notebook1->AddPage( m_panel_probe, wxT("Step 3: Send Internet Probes"), false );
m_notebook1->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( Dialog_Main__Auto_Base_Class::On_Tab_Already_Changed ), NULL, this );
m_notebook1->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, wxNotebookEventHandler( Dialog_Main__Auto_Base_Class::On_Try_Change_Tab ), NULL, this );
I'll try the wxNotebook sample on Win7 later.
I figured out the problem.
In my code, I processed two events from the notebook:
OnNotebookPageChanged
OnNotebookPageChanging
Here's my code for "OnNotebookPageChanged":
This code works absolutely fine on GTK, but it's problematic on MS-Windows 7 Ultimate because it doesn't display the newly selected panel (the tab changes but it still displays the old panel).
The remedy is to add the following line to the end of that function:
This makes it work properly on MS-Windows 7 Ultimate.
Is this behaviour "acceptable" on the MS-Windows port of wxWidgets?
How should I know when to call Skip and when not to call Skip when I handle an event?
I decided to write "event.Skip()" at the end of my other event handler too (the event handler of PageChanging), but ironically this broke my program! If I call Skip at the end of the Page_Changing event handler, it ignores the previous call I made to event.Veto() and the tab control navigates to a tab which is supposed to be off-limits!
In my code, I processed two events from the notebook:
OnNotebookPageChanged
OnNotebookPageChanging
Here's my code for "OnNotebookPageChanged":
Code: Select all
void Dialog_Main::OnNotebook1_Page_Changed( wxNotebookEvent& event )
{
/* All this function does is set the
default button whenever a new tab
is selected.
*/
switch ( event.GetSelection() )
{
case 0: /* Step 1: Open Network Interface */
m_button_Toggle_Open_Interface->SetDefault();
m_combo_NetworkInterface->SetFocus();
break;
case 1: /* Step 2: Send ARP Requests */
m_arptab_button_Toggle_Send_ARPs->SetDefault();
m_arptab_txt_networks->SetFocus();
break;
case 2: /* Step 3: Send Internet Probes */
m_probetab_button_Toggle_Send_Probes->SetDefault();
m_probetab_txt_mac_src->SetFocus();
break;
default:
assert("What the $%^&'s going on?!" == 0);
}
}
The remedy is to add the following line to the end of that function:
Code: Select all
event.Skip();
Is this behaviour "acceptable" on the MS-Windows port of wxWidgets?
How should I know when to call Skip and when not to call Skip when I handle an event?
I decided to write "event.Skip()" at the end of my other event handler too (the event handler of PageChanging), but ironically this broke my program! If I call Skip at the end of the Page_Changing event handler, it ignores the previous call I made to event.Veto() and the tab control navigates to a tab which is supposed to be off-limits!
There must be something else going on, you shouldn't need event.Skip() here.
I checked one of my projects with a wxNoteBook and the wxWidgets notebook sample, and they both work fine on Windows 7 (without event.Skip() )
Try comparing your code to the sample, maybe you can spot a difference.
I checked one of my projects with a wxNoteBook and the wxWidgets notebook sample, and they both work fine on Windows 7 (without event.Skip() )
Try comparing your code to the sample, maybe you can spot a difference.
Use the source, Luke!
OK I've tried to put together minimalistic code that demonstrates this problem.
First of all let me tell you what I did on MS-Windows 7 Ultimate. I downloaded the code for wxMSW, and I compiled it as follows:
I used wxFormBuilder to design a simple dialog box containing a wxNotebook, and I took the code from it and used it to make a little sample program which exhibits the problem I've described.
Here's the code for my sample program (I've condensed it into one source file):
I compiled it in Release Mode on my own computer running MS-Windows 7, here's the executable:
http://virjacode.com/stuff/Notebook_Problem.exe
If I edit the code so that the PAGE_CHANGED event gets Skip'ed at the end, the problem goes away.
First of all let me tell you what I did on MS-Windows 7 Ultimate. I downloaded the code for wxMSW, and I compiled it as follows:
Code: Select all
mingw32-make -f makefile.gcc BUILD=debug UNICODE=1 SHARED=0 RUNTIME_LIBS=static
mingw32-make -f makefile.gcc BUILD=release UNICODE=1 SHARED=0 RUNTIME_LIBS=static
Here's the code for my sample program (I've condensed it into one source file):
Code: Select all
#ifdef WX_PRECOMP
#include "wx_pch.h"
#endif
#include <wx/app.h>
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/string.h>
#include <wx/button.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/combobox.h>
#include <wx/checkbox.h>
#include <wx/notebook.h>
#include <wx/dialog.h>
class Dialog_Main : public wxDialog {
protected:
wxNotebook* m_notebook1;
wxPanel* m_panel1;
wxButton* m_button3;
wxPanel* m_panel2;
wxComboBox* m_comboBox1;
wxPanel* m_panel3;
wxCheckBox* m_checkBox1;
virtual void OnClose( wxCloseEvent& event )
{
Destroy();
}
void OnNotebook_Page_Changed( wxNotebookEvent& event )
{
/* event.Skip(); */
/* We don't Skip the event */
}
public:
Dialog_Main( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("wxWidgets Application Template"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 366,308 ), long style = wxDEFAULT_DIALOG_STYLE );
~Dialog_Main()
{
m_notebook1->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( Dialog_Main::OnNotebook_Page_Changed ), NULL, this );
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( Dialog_Main::OnClose ) );
}
};
Dialog_Main::Dialog_Main( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* bSizer1;
bSizer1 = new wxBoxSizer( wxHORIZONTAL );
m_notebook1 = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_panel1 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer3;
bSizer3 = new wxBoxSizer( wxVERTICAL );
m_button3 = new wxButton( m_panel1, wxID_ANY, wxT("MyButton"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer3->Add( m_button3, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
m_panel1->SetSizer( bSizer3 );
m_panel1->Layout();
bSizer3->Fit( m_panel1 );
m_notebook1->AddPage( m_panel1, wxT("Panel has button"), true );
m_panel2 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer4;
bSizer4 = new wxBoxSizer( wxVERTICAL );
m_comboBox1 = new wxComboBox( m_panel2, wxID_ANY, wxT("Combo!"), wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
bSizer4->Add( m_comboBox1, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_panel2->SetSizer( bSizer4 );
m_panel2->Layout();
bSizer4->Fit( m_panel2 );
m_notebook1->AddPage( m_panel2, wxT("Panel has combo box"), false );
m_panel3 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer5;
bSizer5 = new wxBoxSizer( wxVERTICAL );
m_checkBox1 = new wxCheckBox( m_panel3, wxID_ANY, wxT("Check Me!"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer5->Add( m_checkBox1, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_panel3->SetSizer( bSizer5 );
m_panel3->Layout();
bSizer5->Fit( m_panel3 );
m_notebook1->AddPage( m_panel3, wxT("Panel has check box"), false );
bSizer1->Add( m_notebook1, 1, wxEXPAND | wxALL, 5 );
this->SetSizer( bSizer1 );
this->Layout();
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( Dialog_Main::OnClose ) );
m_notebook1->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( Dialog_Main::OnNotebook_Page_Changed ), NULL, this );
}
class Notebook_ProblemApp : public wxApp
{
public:
virtual bool OnInit()
{
Dialog_Main *dlg = new Dialog_Main(0L);
if (!dlg)
return false;
dlg->Show();
return true;
}
};
IMPLEMENT_APP(Notebook_ProblemApp);
http://virjacode.com/stuff/Notebook_Problem.exe
If I edit the code so that the PAGE_CHANGED event gets Skip'ed at the end, the problem goes away.
Your sample showed the problem even on XP.
I don't know why it makes a difference, but it started working when i changed this:To:
Maybe wxDialog has some additional default event processing or so, i really have no idea.
BTW: The Disconnect() calls in the dtor are unnecessary because the objects get destroyed anyway.
I don't know why it makes a difference, but it started working when i changed this:
Code: Select all
m_notebook1->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( Dialog_Main::OnNotebook_Page_Changed ), NULL, this );
Code: Select all
this->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( Dialog_Main::OnNotebook_Page_Changed ));
BTW: The Disconnect() calls in the dtor are unnecessary because the objects get destroyed anyway.
Use the source, Luke!
Just so you know, that code was generated by wxFormBuilder.
When you use wxFormBuilder to handle events, it automatically writes the code, and for the PAGE_CHANGED event it came out with:
Instead of:
I'm pretty new to wxWidgets and I don't know much at all about how it works under-the-hood, so really I haven't a clue what's going on.
Thanks for the tip about not having to Disconnect (wxFormBuilder wrote that code for me, but it gives an option where you can tell it not to Disconnect).
When you use wxFormBuilder to handle events, it automatically writes the code, and for the PAGE_CHANGED event it came out with:
Code: Select all
m_notebook1->Connect(...
Code: Select all
this->Connect(...
Thanks for the tip about not having to Disconnect (wxFormBuilder wrote that code for me, but it gives an option where you can tell it not to Disconnect).
This is very subtle behavior; if no one else here knows, I may recommend asking on the mailing list, where you can reach wxWidgets authors.
Another possibility, if you can, is to try the code under another platform; if there is a different behavior between platform then it is almost always right to open a bug report
Another possibility, if you can, is to try the code under another platform; if there is a different behavior between platform then it is almost always right to open a bug report
"Keyboard not detected. Press F1 to continue"
-- Windows
-- Windows
I've tried it on Ubuntu Lucid Lynx using wxGTK, and this weird behaviour doesn't happen at all.Auria wrote:This is very subtle behavior; if no one else here knows, I may recommend asking on the mailing list, where you can reach wxWidgets authors.
Another possibility, if you can, is to try the code under another platform; if there is a different behavior between platform then it is almost always right to open a bug report
So far I've only seen it on wxMSW.