i have a minimal exaple that demonstrates the following problem:
a) scrolling with the scrollbar triggers a thread
b) thread sends wxQueueEvent(scrollingWindow, new wxThreadEvent(wxEVT_THREAD, 5)) back to the scrolling window
c) Problem: the wxThreadEvent only gets executed AFTER scrolling has ended and the left mouse button is lifted.
in the documentation for QueueEvent it sais "Finally notice that this method automatically wakes up the event loop if it is currently idle". but the event loop obviously starts only after the left mouse button is lifted.
how can i make the scrollingWindow event loop run the wxThreadEvent while scrolling?
thank you!
app.h
Code: Select all
#pragma once
#include <wx/thread.h>
class MyFrame1;
class threadClass : public wxThread {
public:
threadClass(MyFrame1 *mf) : myframe(mf) {
sema = new wxSemaphore();
}
~threadClass() {
delete sema;
}
virtual void *Entry();
wxSemaphore *sema = nullptr;
MyFrame1 *myframe = nullptr;
};
class MyFrame1 : public wxFrame
{
public:
MyFrame1( wxWindow* parent = NULL,
wxWindowID id = wxID_ANY,
const wxString& title = wxEmptyString,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxSize( 200,100 ),
long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
~MyFrame1() {
thread->sema->Post();
if(thread->Delete() != wxTHREAD_NO_ERROR )
OutputDebugString(wxT("Can't delete the thread!\n"));
}
private:
threadClass *thread = nullptr;
void onThreadEvent(wxThreadEvent &evt) {
OutputDebugString(wxT("onThreadEvent\n"));
}
void onScroll(wxScrollEvent &evt) {
wxScrolled<wxPanel>*obj = (wxScrolled<wxPanel>*)evt.GetEventObject();
OutputDebugString(wxT("onScroll\n"));
static_cast<MyFrame1*>(obj->GetParent())->thread->sema->Post();
}
};
class App : public wxApp {
virtual bool OnInit();
virtual int OnExit();
};
Code: Select all
#include "app.h"
#include <wx/scrolwin.h>
bool App::OnInit() {
MyFrame1 *mainFrame = new MyFrame1();
mainFrame->Show();
SetTopWindow(mainFrame);
return TRUE;
}
int App::OnExit() {
return 0;
}
IMPLEMENT_APP(App)
MyFrame1::MyFrame1( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) :
wxFrame( parent, id, title, pos, size, style )
{
wxBoxSizer *siz = new wxBoxSizer(wxHORIZONTAL);
wxScrolled<wxPanel> *scrPanel = new wxScrolled<wxPanel>(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL);
scrPanel->Connect(wxEVT_SCROLLWIN_THUMBTRACK, wxScrollEventHandler(MyFrame1::onScroll));
scrPanel->SetScrollbars(1, 0, 1500, 0, 0, 0, true);
wxStaticText *text1 = new wxStaticText(scrPanel, wxID_ANY, wxT("asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf"));
scrPanel->SetSizer(new wxBoxSizer(wxHORIZONTAL));
scrPanel->GetSizer()->Add(text1, 0, wxEXPAND);
siz->Add(scrPanel, 1, wxEXPAND);
SetSizer(siz);
thread = new threadClass(this);
thread->Run();
Connect(wxEVT_THREAD, wxThreadEventHandler(MyFrame1::onThreadEvent));
}
void *threadClass::Entry()
{
while (!TestDestroy()) {
sema->Wait();
OutputDebugString(wxT("queuing thread event\n"));
wxQueueEvent(myframe, new wxThreadEvent(wxEVT_THREAD, 5));
}
return nullptr;
}