Am totusi o problema. Aplicatia imi da mereu crash, cu exit code 3, dupa ce termina executia membrului void test2Frame::OnbCopiazaClick(wxCommandEvent& event). Daca merg cu step in eroarea se pare ca apare cand executia ajunge in user32.dll
Acestia sunt ulti 5 pasi pe care ii face aplicatia inainte sa dea eroare:
Code: Select all
At C:\wxWidgets-2.8.12\build\msw/../../src/msw/window.cpp:2622
At C:\wxWidgets-2.8.12\build\msw/../../src/msw/window.cpp:2623
In USER32!GetDC () (C:\WINDOWS\system32\user32.dll)
In ntdll!RtlDecompressBuffer () (C:\WINDOWS\system32\ntdll.dll)
In USER32!GetDC () (C:\WINDOWS\system32\user32.dll)
Sunt destul de sigur ca fac ceva gresit in utilizarea wxThread si a eventului, totusi nu reusesc sa imi dau seama.
wxWidgets a fost compilat cu mingw utilizat wxMSW, cu librari shared, nonmonolitic.
Proiectul este format din 4 fisiere. Le aveti mai jos.
test2App.h
Code: Select all
/***************************************************************
* Name: test2App.h
* Purpose: Defines Application Class
* Author: me (me)
* Created: 2012-03-20
* Copyright: me ()
* License:
**************************************************************/
#ifndef TEST2APP_H
#define TEST2APP_H
#include <wx/app.h>
class test2App : public wxApp
{
public:
virtual bool OnInit();
};
#endif // TEST2APP_H
Code: Select all
/***************************************************************
* Name: test2App.cpp
* Purpose: Code for Application Class
* Author: me (me)
* Created: 2012-03-20
* Copyright: me ()
* License:
**************************************************************/
#include "test2App.h"
//(*AppHeaders
#include "test2Main.h"
#include <wx/image.h>
//*)
IMPLEMENT_APP(test2App);
bool test2App::OnInit()
{
//(*AppInitialize
bool wxsOK = true;
wxInitAllImageHandlers();
if ( wxsOK )
{
test2Frame* Frame = new test2Frame(0);
Frame->Show();
SetTopWindow(Frame);
}
//*)
return wxsOK;
}
Code: Select all
/***************************************************************
* Name: test2Main.h
* Purpose: Defines Application Frame
* Author: me (me)
* Created: 2012-03-20
* Copyright: me ()
* License:
**************************************************************/
#ifndef TEST2MAIN_H
#define TEST2MAIN_H
//(*Headers(test2Frame)
#include <wx/menu.h>
#include <wx/panel.h>
#include <wx/button.h>
#include <wx/frame.h>
#include <wx/statusbr.h>
//*)
#include <wx/thread.h>
#include <iostream>
#include <string>
#include <fstream>
#include <wx/filedlg.h>
// clasa frame - fereastra aplicatiei, cu toate butoanele si membrii necesari
class test2Frame: public wxFrame
{
public:
test2Frame(wxWindow* parent,wxWindowID id = -1);
virtual ~test2Frame();
private:
//(*Handlers(test2Frame)
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnbSelFisIntClick(wxCommandEvent& event);
void OnbSelFisIesClick(wxCommandEvent& event);
void OnbCopiazaClick(wxCommandEvent& event);
//*)
void onThreadFinished(wxEvent& event);
//(*Identifiers(test2Frame)
static const long ID_BSelFisInt;
static const long ID_bSelFisIes;
static const long ID_BCopiaza;
static const long ID_PANEL1;
static const long idMenuQuit;
static const long idMenuAbout;
static const long ID_STATUSBAR1;
//*)
//(*Declarations(test2Frame)
wxPanel* Panel1;
wxButton* bCopiaza;
wxButton* bSelFisInt;
wxStatusBar* StatusBar1;
wxButton* bSelFisIes;
//*)
std::string m_PathFisierIntrare;
std::string m_PathFisierIesire;
wxCriticalSection m_CritSec;
DECLARE_EVENT_TABLE()
};
// definitia clasei derivata din wxThread - aceasta e clasa care va face, in cazul meu, copiera din un fisier in altul
class workerThread: public wxThread
{
std::string m_PathFisIntrare;
std::string m_PathFIsIesire;
test2Frame* m_frame;
virtual void* Entry();
virtual void* onExit();
public:
workerThread(std::string pathFisierIntrare, std::string pathFisierIesire, test2Frame* frame);
};
#endif // TEST2MAIN_H
Code: Select all
/***************************************************************
* Name: test2Main.cpp
* Purpose: Code for Application Frame
* Author: me (me)
* Created: 2012-03-20
* Copyright: me ()
* License:
**************************************************************/
#include "test2Main.h"
#include <wx/msgdlg.h>
//(*InternalHeaders(test2Frame)
#include <wx/intl.h>
#include <wx/string.h>
//*)
//helper functions
enum wxbuildinfoformat {
short_f, long_f };
wxString wxbuildinfo(wxbuildinfoformat format)
{
wxString wxbuild(wxVERSION_STRING);
if (format == long_f )
{
#if defined(__WXMSW__)
wxbuild << _T("-Windows");
#elif defined(__UNIX__)
wxbuild << _T("-Linux");
#endif
#if wxUSE_UNICODE
wxbuild << _T("-Unicode build");
#else
wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
}
return wxbuild;
}
using std::endl;
using std::getline;
using std::string;
using std::ifstream;
using std::ofstream;
//(*IdInit(test2Frame)
const long test2Frame::ID_BSelFisInt = wxNewId();
const long test2Frame::ID_bSelFisIes = wxNewId();
const long test2Frame::ID_BCopiaza = wxNewId();
const long test2Frame::ID_PANEL1 = wxNewId();
const long test2Frame::idMenuQuit = wxNewId();
const long test2Frame::idMenuAbout = wxNewId();
const long test2Frame::ID_STATUSBAR1 = wxNewId();
//*)
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_LOCAL_EVENT_TYPE(wxEVT_THREAD_FINISHED, 7777)
END_DECLARE_EVENT_TYPES()
DEFINE_EVENT_TYPE(wxEVT_THREAD_FINISHED)
BEGIN_EVENT_TABLE(test2Frame,wxFrame)
//(*EventTable(test2Frame)
//*)
EVT_CUSTOM(wxEVT_THREAD_FINISHED, wxID_ANY, test2Frame::onThreadFinished) // eventul costum - este chemat atunci cand threadul a terminat de copiat
END_EVENT_TABLE()
test2Frame::test2Frame(wxWindow* parent,wxWindowID id)
{
//(*Initialize(test2Frame)
wxMenuItem* MenuItem2;
wxMenuItem* MenuItem1;
wxMenu* Menu1;
wxMenuBar* MenuBar1;
wxMenu* Menu2;
Create(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("id"));
Panel1 = new wxPanel(this, ID_PANEL1, wxPoint(152,328), wxDefaultSize, wxTAB_TRAVERSAL, _T("ID_PANEL1"));
bSelFisInt = new wxButton(Panel1, ID_BSelFisInt, _("Selecteaza Fisier Intrare"), wxPoint(72,72), wxSize(264,23), 0, wxDefaultValidator, _T("ID_BSelFisInt"));
bSelFisIes = new wxButton(Panel1, ID_bSelFisIes, _("Selecteaza fisier iesire"), wxPoint(72,136), wxSize(264,23), 0, wxDefaultValidator, _T("ID_bSelFisIes"));
bCopiaza = new wxButton(Panel1, ID_BCopiaza, _("Copiaza"), wxPoint(72,272), wxSize(264,23), 0, wxDefaultValidator, _T("ID_BCopiaza"));
bCopiaza->Disable();
MenuBar1 = new wxMenuBar();
Menu1 = new wxMenu();
MenuItem1 = new wxMenuItem(Menu1, idMenuQuit, _("Quit\tAlt-F4"), _("Quit the application"), wxITEM_NORMAL);
Menu1->Append(MenuItem1);
MenuBar1->Append(Menu1, _("&File"));
Menu2 = new wxMenu();
MenuItem2 = new wxMenuItem(Menu2, idMenuAbout, _("About\tF1"), _("Show info about this application"), wxITEM_NORMAL);
Menu2->Append(MenuItem2);
MenuBar1->Append(Menu2, _("Help"));
SetMenuBar(MenuBar1);
StatusBar1 = new wxStatusBar(this, ID_STATUSBAR1, 0, _T("ID_STATUSBAR1"));
int __wxStatusBarWidths_1[1] = { -1 };
int __wxStatusBarStyles_1[1] = { wxSB_NORMAL };
StatusBar1->SetFieldsCount(1,__wxStatusBarWidths_1);
StatusBar1->SetStatusStyles(1,__wxStatusBarStyles_1);
SetStatusBar(StatusBar1);
Connect(ID_BSelFisInt,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&test2Frame::OnbSelFisIntClick);
Connect(ID_bSelFisIes,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&test2Frame::OnbSelFisIesClick);
Connect(ID_BCopiaza,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&test2Frame::OnbCopiazaClick);
Connect(idMenuQuit,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&test2Frame::OnQuit);
Connect(idMenuAbout,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&test2Frame::OnAbout);
//*)
}
test2Frame::~test2Frame()
{
//(*Destroy(test2Frame)
//*)
}
void test2Frame::OnQuit(wxCommandEvent& event)
{
Close();
}
void test2Frame::OnAbout(wxCommandEvent& event)
{
wxString msg = wxbuildinfo(long_f);
wxMessageBox(msg, _("Welcome to..."));
}
// constructorul clasei workerThread
workerThread::workerThread(string pathFisierIntrare, string pathFisieriesire, test2Frame* frame) : wxThread()
{
m_PathFisIntrare = pathFisierIntrare; // adresa fisierului de intrare
m_PathFIsIesire = pathFisieriesire; // adresa fisierului de iesire
m_frame = frame; // pointer catre test2frame - catre fereastra din care a fost apelat threadul
}
// functia unde munca threadului este executata
void* workerThread::Entry()
{
if(TestDestroy())
{
return NULL;
}
ifstream fIn;
ofstream fOut;
fIn.open(m_PathFisIntrare.c_str());
fOut.open(m_PathFIsIesire.c_str());
if(fIn.is_open() && fOut.is_open())
{
while(fIn.good())
{
string temp;
getline(fIn, temp);
fOut << temp << endl;
}
}
fIn.close();
fOut.close();
//m_frame = NULL;
wxCommandEvent evt(GetId(), wxEVT_THREAD_FINISHED);
//wxPostEvent(m_frame, evt);
m_frame->AddPendingEvent(evt);
return NULL;
}
// functie apelata la apasarea butonului "Selecteaza fisier intrare"
void test2Frame::OnbSelFisIntClick(wxCommandEvent& event)
{
wxFileDialog selFisInt(this, _T("Selecteaza fisier intrare."), "", "", "TXT Files(*.txt)|*.txt", wxFD_FILE_MUST_EXIST);
if(selFisInt.ShowModal() == wxID_OK)
{
m_PathFisierIntrare = string(selFisInt.GetPath().mb_str());
}
if(!m_PathFisierIesire.empty() &&!m_PathFisierIntrare.empty())
{
bCopiaza->Enable(true);
}
wxMessageBox(_T(m_PathFisierIntrare.c_str()));
}
// functie apelata la apasarea butonului "Selecteaza fisier iesire"
void test2Frame::OnbSelFisIesClick(wxCommandEvent& event)
{
wxFileDialog selFisIes(this, _T("Selecteaza fisier iesire."), "", "", "TXT Files (*.txt)|*.txt", wxFD_DEFAULT_STYLE);
if(selFisIes.ShowModal() == wxID_OK)
{
m_PathFisierIesire = string(selFisIes.GetPath().mb_str());
}
if(!m_PathFisierIesire.empty() &&!m_PathFisierIntrare.empty())
{
bCopiaza->Enable(true);
}
wxMessageBox(_T(m_PathFisierIesire.c_str()));
}
// functie apelata la terminarea executiei threadului
void test2Frame::onThreadFinished(wxEvent& event)
{
bSelFisIes->Enable(true);
bSelFisInt->Enable(true);
wxMessageBox("Am terminat.");
}
// functie apelata la apasarea butonului Copiaza
// functia creeaza thread-ul si il ruleaza
// dezactiveaza cele 3 butoane pentru siguranta
void test2Frame::OnbCopiazaClick(wxCommandEvent& event)
{
bCopiaza->Enable(false);
bSelFisIes->Enable(false);
bSelFisInt->Enable(false);
//m_CritSec.Enter();
workerThread thread(m_PathFisierIntrare, m_PathFisierIesire, this);
thread.Create();
thread.Run();
//m_CritSec.Leave();
}
// functie goala, apelata la terminarea executiei threadului
void* workerThread::onExit()
{
}
Eventual daca aveti niste resurse care sa explice mai pe intelesul unui incepator cu ce se mananca threadurile, si in special wxThread. Am citit atat pe wiki-ul wxWidgets, cat si in carte dar ... nu m-au luminat .
Multumesc pentru timpul acordat.