[gelöst][wxWidgets] Key-Event kommt nicht an



  • Hallo,

    ich habe in einer älteren Version eines Programmes von mir die KeyEvents abgefangen um eine Steuerung zu bauen. Da klappt das auch super. Jetzt fange ich gerade an eine neue Version meines Programmes zu bauen, in dem die Steuerung komplett anders ist. Einziges was gleich bleibt ist, dass ich die Key-Events abfangen muss. Leider kommt aber kein Key-Event an. Ich hab jetzt im Internet geguckt und festgestellt, dass anscheinend KeyEvents von bestimmten Widgets verher schon agefangen werden. Allerdings kann ich bei mir auskommentieren was ich will, ich bekomme kein KeyEvent. Bitte um Hilfe.

    // Events
    BEGIN_EVENT_TABLE(mainFrame, wxFrame)
    EVT_KEY_DOWN(mainFrame::OnKeyDown)
    EVT_SPLITTER_SASH_POS_CHANGED(MAINFRAME_SPLITTER,mainFrame::splitter_resize)
    END_EVENT_TABLE()
    
    mainFrame::mainFrame(wxWindow* parent, const wxWindowID& id)
    : wxFrame(parent, id, _T("MyBand 3"), wxPoint(5,5), wxSize(1000,750))
    , mylogfile(0)
    {
    	Centre();
    
    	// Splitter
    	spliti = new wxSplitterWindow(this, MAINFRAME_SPLITTER);
    
    	// Linkes Window
    	wxPanel* left = new wxPanel(spliti, wxID_ANY);
    
    	// Logging mit Logfile
    	logging = new wxTextCtrl(left, wxID_ANY, wxEmptyString, wxPoint(0,0), wxSize(MAINFRAME_SPLITTER_BREIT,100), wxTE_MULTILINE | wxTE_READONLY);
    	wxFileName mylogname(wxStandardPaths::Get().GetExecutablePath());
    	mylogname.AppendDir(_T("gigs"));
    	try
    	{
    		mylogfile = new nmpLogfile();
    		mylogfile->DirectorySet(mylogname);
    		mylogfile->FileExtensionSet(_T("gig"));
    	}
    	catch(nmpError& error)
    	{
    		error.wxLogErrorShow();
    		Log(_T("Kein Logfile!"));
    	}
    	Log(_T("Starte MyBand3."));
    	if (mylogfile!=0)
    	{
    		Log(mylogfile->FileNameGet(false));
    	}
    
    	// Rechtes Window
    	wxListbook* right = new wxListbook(spliti, wxID_ANY);
    
    	// Grund-Dingens
    	grundsachen = new wxPanel(right, wxID_ANY);
    	right->AddPage(grundsachen, _T("(100)\nSettings"),true);
    
    	// Splitten
    	spliti->SplitVertically(left,right,MAINFRAME_SPLITTER_BREIT);
    }
    
    // Tastatur
    void mainFrame::OnKeyDown(wxKeyEvent &event)
    {
    	// Das Problem: Diese Funktion wird nie aufgerufen!
    	wxString s;
    	s << event.GetKeyCode();
    	wxLogMessage(s);
    	// Auswerten
    	switch (event.GetKeyCode())
    	{
    	case WXK_NUMPAD_ENTER: whoask->Go(); break;
    	case WXK_RETURN:	whoask->Go(); break;
    	case WXK_NUMPAD0:	whoask->AktAdd(0); break;
    	case WXK_NUMPAD1:	whoask->AktAdd(1); break;
    	case WXK_NUMPAD2:	whoask->AktAdd(2); break;
    	case WXK_NUMPAD3:	whoask->AktAdd(3); break;
    	case WXK_NUMPAD4:	whoask->AktAdd(4); break;
    	case WXK_NUMPAD5:	whoask->AktAdd(5); break;
    	case WXK_NUMPAD6:	whoask->AktAdd(6); break;
    	case WXK_NUMPAD7:	whoask->AktAdd(7); break;
    	case WXK_NUMPAD8:	whoask->AktAdd(8); break;
    	case WXK_NUMPAD9:	whoask->AktAdd(9); break;
    	case KEYDEGREE:		if (event.ControlDown()) { whoask->AktAdd(0); } break;
    	case KEY0:			if (event.ControlDown()) { whoask->AktAdd(0); } break;
    	case KEY1:			if (event.ControlDown()) { whoask->AktAdd(1); } break;
    	case KEY2:			if (event.ControlDown()) { whoask->AktAdd(2); } break;
    	case KEY3:			if (event.ControlDown()) { whoask->AktAdd(3); } break;
    	case KEY4:			if (event.ControlDown()) { whoask->AktAdd(4); } break;
    	case KEY5:			if (event.ControlDown()) { whoask->AktAdd(5); } break;
    	case KEY6:			if (event.ControlDown()) { whoask->AktAdd(6); } break;
    	case KEY7:			if (event.ControlDown()) { whoask->AktAdd(7); } break;
    	case KEY8:			if (event.ControlDown()) { whoask->AktAdd(8); } break;
    	case KEY9:			if (event.ControlDown()) { whoask->AktAdd(9); } break;
    	default: event.Skip();
    	}
    }
    
    /* Splitter */
    // Beim Resize
    void mainFrame::splitter_resize(wxSplitterEvent& WXUNUSED(event))
    {
    	spliti->SetSashPosition(MAINFRAME_SPLITTER_BREIT,false);
    }
    

    Was könnte mein KeyEvent abfangen? Ich finde es nicht und die Doku schweigt leider auch viel zu laut.



  • Ne Lösung hab ich noch nicht, aber eine "Ursache" hab ich schon. Solange das Frame leer ist, klappt mein KeyEvent. Sobald ich allerdings irgendwas darin postiere, klappt mein KeyEvent nicht mehr. Dabei ist es auch egal ob ich ein wxPanel, wxButton, wxTextCtrl oder ein wxStaticText in den Frame stecke. Sobald was drinnen ist, gehen die KeyEvents nicht mehr. Ich weiß jetzt irgendwie nicht mehr weiter. Bitte um Hilfe.


  • Mod

    Schau mal bei den Windowstyles, da gibts irgendwo wxWANTSCHAR oder so.
    Damit müsste es klappen. Evtl. suchst du mal zu dem Thema im wxForum, das ist etwas speziell.



  • Es liegt nicht an wxWANTS_CHAR. Aber danke für den Tipp, das war der Anfang der Lösungsfindung.

    Ich habe ein Programm unter wxWidgets 2.8.9 damit geht mein Programm einwandfrei. Ab wxWidgets 2.8.10 gehts es nicht mehr. Ich weiß nicht ob was geändert wurde, weil ich seit 2.8.10 auch mit Unicode arbeite und davor noch nicht.

    Ich hab jetzt die Samples nach wxEVT_KEY_DOWN durchsucht und hab im Sample "mediaplayer" etwas interessantes gefunden:

    wxTheApp->Connect(wxID_ANY, wxEVT_KEY_DOWN,
                      wxKeyEventHandler(wxMediaPlayerFrame::OnKeyDown),
                      (wxObject*)0, this);
    

    Das habe ich auf meinen Frame übertragen und siehe da, schon geht es. Allerdings ist zu beachten, dass wxTheApp erst nach IMPLEMENT_APP() vorhanden ist. Wenn man in einer externen Klasse ist und das IMPLEMENT_APP() noch nicht aufgerufen wurde, kann man über DECLARE_APP() seine wxApp-Klasse schon mal bekannt geben.

    Gruß,
    Stefan



  • Aus dem wxWidgetsSample mediaplayer, Datei: mediaplayer.cpp, Ab Zeile 550, wxWidgets 2.8.10

    //
    // Connect events.
    //
    // There are two ways in wxWidgets to use events -
    // Message Maps and Connections.
    //
    // Message Maps are implemented by putting
    // DECLARE_MESSAGE_MAP in your wxEvtHandler-derived
    // class you want to use for events, such as wxMediaPlayerFrame.
    //
    // Then after your class declaration you put
    // BEGIN_EVENT_TABLE(wxMediaPlayerFrame, wxFrame)
    // EVT_XXX(XXX)...
    // END_EVENT_TABLE()
    //
    // Where wxMediaPlayerFrame is the class with the DECLARE_MESSAGE_MAP
    // in it. EVT_XXX(XXX) are each of your handlers, such
    // as EVT_MENU for menu events and the XXX inside
    // is the parameters to the event macro - in the case
    // of EVT_MENU the menu id and then the function to call.
    //
    // However, with wxEvtHandler::Connect you can avoid a
    // global message map for your class and those annoying
    // macros. You can also change the context in which
    // the call the handler (more later).
    //
    // The downside is that due to the limitation that
    // wxWidgets doesn't use templates in certain areas,
    // You have to triple-cast the event function.
    //
    // There are five parameters to wxEvtHandler::Connect -
    //
    // The first is the id of the instance whose events
    // you want to handle - i.e. a menu id for menus,
    // a control id for controls (wxControl::GetId())
    // and so on.
    //
    // The second is the event id. This is the same
    // as the message maps (EVT_MENU) except prefixed
    // with "wx" (wxEVT_MENU).
    //
    // The third is the function handler for the event -
    // You need to cast it to the specific event handler
    // type, then to a wxEventFunction, then to a
    // wxObjectEventFunction - I.E.
    // (wxObjectEventFunction)(wxEventFunction)
    // (wxCommandEventFunction) &wxMediaPlayerFrame::MyHandler
    //
    // Or, you can use the new (2.5.5+) event handler
    // conversion macros - for instance the above could
    // be done as
    // wxCommandEventHandler(wxMediaPlayerFrame::MyHandler)
    // pretty simple, eh?
    //
    // The fourth is an optional userdata param -
    // this is of historical relevance only and is
    // there only for backwards compatibility.
    //
    // The fifth is the context in which to call the
    // handler - by default (this param is optional)
    // this. For example in your event handler
    // if you were to call "this->MyFunc()"
    // it would literally do this->MyFunc. However,
    // if you were to pass myHandler as the fifth
    // parameter, for instance, you would _really_
    // be calling myHandler->MyFunc, even though
    // the compiler doesn't really know it.
    //


Anmelden zum Antworten