2009-09-26 10 views
0

Je suis en train de créer un système de transaction de fichiers (via FTP) en utilisant wxWidgets pour l'interface graphique et une classe multithread de CodeProject (http://www.codeproject.com/KB/threads/SynchronizedThreadNoMfc.aspx) - Veuillez lire l'article en premier pour référence.Comment appeler une variable de membre de classe instanciée à l'aide d'une autre fonction sans rapport avec la classe?

Dans mon interface graphique, j'ai une zone de texte (wxTextCtrl) qui stocke le chemin de fichier qui voulait être envoyé au serveur FTP, et je voulais obtenir sa valeur grâce à la fonction multi-thread.

Voici mon code à ce jour: (simplifié, plusieurs fichiers)

/////// Organizer.h // Main header file that utilizes all other headers 
#include <wx/wx.h> 
#include <wx/datectrl.h> 
#include <wininet.h> 
#pragma comment(lib, "wininet.lib") 
#include "Threading.h" 
#include "MainDlg.h" 
#include "svDialog.h" 

///////// Threading.h // Please read the article given above 
#include "ou_thread.h" 
using namespace openutils; 

extern HINTERNET hInternet; // both declared in MainDlg.cpp 
extern HINTERNET hFtpSession; 

class svThread : public Thread 
{ 
private: 
    char* ThreadName; 
public: 
    svThread(const char* szThreadName) 
    { 
    Thread::setName(szThreadName); 
    this->ThreadName = (char*)szThreadName; 
    } 
    void run() 
    { 
    if(this->ThreadName == "Upload") 
    { 
    hInternet = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); 
    hFtpSession = InternetConnect(hInternet, L"myserver.com", INTERNET_DEFAULT_FTP_PORT, L"user", L"pass", INTERNET_SERVICE_FTP, 0, 0); 

    std::string filenameOnServer((char*)tb_file->GetValue().c_str()); // HERE..the tb_file.. 
    std::vector<std::string> filepathParts; 
    __strexp(filenameOnServer, "\\", filepathParts); // this is user-defined function that will split a string (1st param) with the given delimiter (2nd param) to a vector (3rd param) 
    filenameOnServer = filepathParts.at(filepathParts.size() - 1); // get only the filename 

    if(FtpPutFile(hFtpSession, tb_file->GetValue().c_str(), (LPCWSTR)filenameOnServer.c_str(), FTP_TRANSFER_TYPE_BINARY, 0)) 
    { 
     MessageBox(NULL, L"Upload Complete", L"OK", 0); 
    } 
    else 
    { 
     MessageBox(NULL, L"Upload Failed", L"OK", 0); 
    } 
    } 
    } 
}; 

////////// svDialog.h 
class svDialog : public wxFrame 
{ 
public: 
    svDialog(const wxString &title); 
    void InitializeComponent(); 
    void ProcessUpload(wxCommandEvent &event); // function (button event) that will start the UPLOAD THREAD 
    wxTextCtrl *tb_file; // this is the textbox 
    //....other codes 
}; 

///////////svDialog.cpp 
#include "Organizer.h" 
Thread *UploadRoutine; 

svDialog::svDialog(const wxString &title) : wxFrame(...) // case unrelated 
{ 
    InitializeComponent(); 
} 
void svDialog::InitializeComponent() 
{ 
    tb_file = new wxTextCtrl(...); 
    //......other codes 
} 
void svDialog::ProcessUpload(wxCommandEvent &event) 
{ 
    UploadRoutine = new svThread("Upload"); 
    UploadRoutine->start(); 
    //......other codes 
} 

////// MainDlg.cpp // (MainDlg.h only contains the MainDlg class declaration and member function prototypes) 
#include "Organizer.h" 

HINTERNET hInternet; 
HINTERNET hFtpSession; 
IMPLEMENT_APP(MainDlg) // wxWidgets macro 

bool MainDlg::OnInit() // wxWidgets window initialization function 
{ 
    //......other codes 
} 

Eh bien, comme vous pouvez le voir dans mon code ci-dessus, je voulais obtenir le contenu de tb_file (avec tb_file-> GetValue ()) et passez-la à la fonction multi-threading (void run()) pour être téléchargée plus tard.

Toute sorte d'aide serait appréciée!

Merci. (et désolé pour le code long ..)

Répondre

3

Il est tout à fait simple.

Vous devez créer une fonction de démarrage qui prend une chaîne std :: string (ou tout autre paramètre) et la stocke (eux) dans l'objet svThread. Ensuite, vous pouvez y accéder à la fonction d'exécution:

class svThread : public Thread 
{ 
    private: 
     char* ThreadName; 
     std::string FileName; 

    public: 
     svThread(const char* szThreadName) 
     { 
     Thread::setName(szThreadName); 
     this->ThreadName = (char*)szThreadName; 
     } 

     void Start(const std::string& filename) 
     { 
     this->FileName = filename; 
     Thread::Start(); 
     } 

     void Run() 
     { 
     // ... 
     if(FtpPutFile(hFtpSession, FileName,(LPCWSTR)filenameOnServer.c_str(), FTP_TRANSFER_TYPE_BINARY, 0)) 
     // ... 
     } 
}; 

Dans votre classe de dialogue il vous suffit de lancer votre fil comme ceci:

UploadRoutine = new svThread("Upload"); 
UploadRoutine->start(tb_file->GetValue().c_str()); 
0

Toutes les données que vous voulez run peuvent être stockées en tant que données de membre de classe svThread. Un bon moyen de l'obtenir en tant que données de membre serait de le passer en paramètre au constructeur svThread.

1

Vous devez stocker les données, le fil a besoin en tant que variables membres du fil, .: par exemple

class svThread : public Thread 
{ 
private: 
    const std::string filename_; 
public: 
    svThread(const std::string& filename) 
     : filename_(filename) 
    {} 
    void run() 
    { 
     // ... 
      __strexp(filename_, /* ... */); 
     // ... 
    } 
}; 

void svDialog::ProcessUpload(wxCommandEvent &event) 
{ 
    UploadRoutine = new svThread(tb_file->GetValue()); 
    // ... 
} 
0

Je voudrais aussi faire HINTERNET et hFTPSession pas globale et passer à chaque fil. De cette façon, vous n'aurez pas de problèmes plus tard lorsque vous utilisez plusieurs sessions ftp par exemple. Je préfère aussi ne pas les déclarer dans maindlg.cpp, la boîte de dialogue principale est une partie graphique, et ces variables n'ont pas grand chose à voir avec le gui.

BTW quel est le but de

if(this->ThreadName == "Upload") 

Je veux dire, si le fil est conçu pour le téléchargement, pourquoi devrait-il revérifier que contre elle est chaîne de nom?

+0

J'ai dit que c'est SIMPLIFIÉ. Je n'ai ajouté aucun autre code indépendant. –

Questions connexes