Frage zum Handling CString



  • Hallo,

    laut meinem derzeitigen Wissenstand sind Variabeln die innerhalb einer Klasse und ausserhalb von Methoden definiert sind sog. Klassenvariabeln. Diese sind in jeder Methode der Klasse verfügbar.

    Nun gibt es bei MFC eine Klasse die sich CString nennt. Diese Klasse lässt u.A. ein einfacheres arbeiten mit Strings zu als bei Ansi C.

    Jetzt habe ich u.A. in einer Header Datei 2 Variablentypen der Sorte CString definiert welche ich in einer Methode mit Inhalt füttere. In anderen Methoden dagegen bekomme ich keinerlei Inhalt mehr angezeigt obwohl kein Compiler Error zu stande kommt.

    Könnte mir vielleicht Jemand aufklären wie ich dieses Problem in den Griff bekommen kann? Habe nämlich meine eBooks Hände ringend durchgeschaut und keinen Hinweis bekommen. Ich habe lediglich die Vermutung das CString 2 Objekte erstellt, so dass ich in der zweiten Methode ein komplett neues Objekt erhalten.

    Oder liege ich falsch?


  • Mod

    Dann zeige uns doch mal ein Stück Code. Wie sich das anhört hast Du eher die Variablen in einem globalen Scope angelegt und nichtin einer Klasse.



  • // e2dkcollecter.h : Haupt-Header-Datei für die Anwendung E2DKCOLLECTER
    //
    
    #ifndef __AFXWIN_H__
    	#error include 'stdafx.h' before including this file for PCH
    
    #endif
    
    #include "resource.h"		// Hauptsymbole
    #include "e2dkcollecterDlg.h"
    
    /////////////////////////////////////////////////////////////////////////////
    // CE2dkcollecterApp:
     // Siehe e2dkcollecter.cpp für die Implementierung dieser Klasse
    //
    
    class CE2dkcollecterApp : public CWinApp
    {
    public:
    	CE2dkcollecterApp();
    
    public:
    	virtual BOOL InitInstance();
    	CString strPath;
    	CString strBackupPath;
    	CString strCmdline;
    	unsigned char szED2KAssoc[MAX_REGVAL_LEN];
    	unsigned char szE2DKcollecter[MAX_REGVAL_LEN];
    
    private:
    	bool bProgramLoaded;
    
    DECLARE_MESSAGE_MAP()
    protected:
    	bool linkassoc();
    	bool writelink();
    };
    
    // e2dkcollecter.cpp : Legt das Klassenverhalten für die Anwendung fest.
    //
    
    #include "stdafx.h"
    #include "e2dkcollecter.h"
    #include "e2dkcollecterDlg.h"
    
    BOOL CE2dkcollecterApp::InitInstance()
    {
    
    //GET CmDLine
    	strCmdline=theApp.m_lpCmdLine;
    	if(strCmdline.Left(1) == "\"")
    	  strCmdline = strCmdline.Mid(1,strCmdline.GetLength()-2);
    	strCmdline+="\n";
    
    if ( !bProgramLoaded )
    	{
    		wc.lpszClassName = "e2dkcollector dialog";
    		AfxRegisterClass(&wc);
    		InitCommonControls();
    		CWinApp::InitInstance();
    		CE2dkcollecterDlg dlg;
    		m_pMainWnd = &dlg;
    		linkassoc();
    		int nResponse = dlg.DoModal();
    	}
    	else
    	{
    		if( strlen(theApp.m_lpCmdLine) == 0 )
    		  MessageBox(NULL,"Bitte das Programm nur einmal starten",NULL,MB_OK);
    		else
    		  writelink();
       }
    }
    
    bool CE2dkcollecterApp::linkassoc()
    {
    	TCHAR szFullPath[MAX_PATH];
    	TCHAR szFilename[_MAX_FNAME];
    	TCHAR szDir[_MAX_DIR];
    	TCHAR szDrive[_MAX_DRIVE];
    
    	// Get application's full path;
    	::GetModuleFileName(NULL, szFullPath, MAX_PATH);
    	// Break full path into separate components;
    	_tsplitpath(szFullPath, szDrive, szDir, szFilename, NULL);
    	strPath.Format(_T("%s%s"), szDrive, szDir);
    	strBackupPath = strPath + "ed2k links backup.txt";
    	strPath += "ed2klinks.txt";
    //Registry
    
    }
    
    bool CE2dkcollecterApp::writelink()
    {
    MessageBox(NULL,strPath,"Versuch",MB_ICONINFORMATION);
    	CStdioFile LinkFile;
    		LinkFile.Open("Y:\\E2dkcollecter\\Debug\\e2dklinks.txt", CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite | CFile::typeText);
    		LinkFile.SeekToEnd();
    		LinkFile.WriteString(strCmdline);
    		LinkFile.Close();
    }
    

    Faszinierend ist jetzt
    strPath was in der Methode linkassoc(); Werte bekommt und strCmdline was in Methode Initinstance(); einen Wert bekommt. Beide haben die Gemeinsamkeit, dass sie in der Methode writelink(); verwendet werden. Wobei strPath in dieser Methode leer ist und strCmdline nicht 😮



  • Ich kürze mal die InitInstance etwas:

    BOOL CE2dkcollecterApp::InitInstance()
    {
    strCmdline=theApp.m_lpCmdLine;
    strCmdline+="\n";
    
    if ( !bProgramLoaded )
    {
        //...
        linkassoc();
    }
    else
    {
        if( strlen(theApp.m_lpCmdLine) == 0 )
        {
             MessageBox(NULL,"Bitte das Programm nur einmal starten",NULL,MB_OK);
        }
        else
             writelink();
    }
    

    linkassoc() wird aufgerufen, wenn "ProgramLoaded" false ist, danach verschwindest du in der doModal().
    writelink() wird aufgerufen, wenn "ProgramLoaded" true ist - in dem Fall hast du jedoch niemals linkassoc() aufgerufen, um die Path-Variablen zu belegen.



  • CStoll schrieb:

    linkassoc() wird aufgerufen, wenn "ProgramLoaded" false ist, danach verschwindest du in der doModal().
    writelink() wird aufgerufen, wenn "ProgramLoaded" true ist - in dem Fall hast du jedoch niemals linkassoc() aufgerufen, um die Path-Variablen zu belegen.

    Das ist so nicht richtig, ich habe den Code gekürzt. Ich weiss 100%ig das er reinläuft ist auch nicht meine erste Sprache

    BOOL CE2dkcollecterApp::InitInstance()
    {
    	#ifdef _AFXDLL
    		Enable3dControls();			// Diese Funktion bei Verwendung von MFC in gemeinsam genutzten DLLs aufrufen
    	#else
    		Enable3dControlsStatic();	// Diese Funktion bei statischen MFC-Anbindungen aufrufen
    	#endif
    
    	//GET CmDLine
    	strCmdline=theApp.m_lpCmdLine;
    	if(strCmdline.Left(1) == "\"")
    	{
    		strCmdline = strCmdline.Mid(1,strCmdline.GetLength()-2);
    	}
    	strCmdline+="\n";
    
    	// Check if Program already loaded
    	HWND main_dlg;
    	if( main_dlg = FindWindow("e2dkcollector dialog","e2dkcollector") )
    	{
    		bProgramLoaded = TRUE;
    	}
    	else
    	{
    		bProgramLoaded = FALSE;
    	}
    
    	//eigener Klassennamen registrieren
    	WNDCLASS wc;
    
    	// #32770 is the default class name for dialogs boxes.
    	::GetClassInfo(AfxGetInstanceHandle(), "#32770", &wc);
    
    	if ( !bProgramLoaded )
    	{
    		wc.lpszClassName = "e2dkcollector dialog";
    		AfxRegisterClass(&wc);
    		InitCommonControls();
    		CWinApp::InitInstance();
    		CE2dkcollecterDlg dlg;
    		m_pMainWnd = &dlg;
    		linkassoc();
    		int nResponse = dlg.DoModal();
    	}
    	else
    	{
    		if( strlen(theApp.m_lpCmdLine) == 0 )
    		{
    			MessageBox(NULL,"Bitte das Programm nur einmal starten",NULL,MB_OK);
    		}
    		else
    			writelink();
    	}
    
    	// Register this class so that MFC can use it.
    
    	/*
    	if (nResponse == IDOK)
    	{
    	}
    	else if (nResponse == IDCANCEL)
    	{
    	}
    	*/
    	// Da das Dialogfeld geschlossen wurde, FALSE zurückliefern, so dass wir die
    	//  Anwendung verlassen, anstatt das Nachrichtensystem der Anwendung zu starten.
    	return FALSE;
    }
    

    Ich gehe mal kurz auf das Programm ein. Dieses Programm arbeitet mit zwei Programminstanzen.
    Die erste Programminstanz registriert einen eigenen Klassennamen, ruft den Dialog auf und fügt anschließend via linkassoc() ein paar Änderungen in der Registry durch und ermittelt dazu noch den Startpfad des Programmes. In strPath wird u.A. ein Verzeichnis zusammengestellt. Welches innerhalb dieser Methode auch 100%ig ok ist.

    Nachdem dann nun die erste Programminstanz aktiv ist, prüfe ich wenn das Programm nochmal aufgerufen wird ob meine eigene Klasse vorhanden ist mit FindWindow(); Wenn diese existiert trifft mein Programm die Annahme das es sich beim zweiten Aufruf entweder um einen nochmaligen Aufruf seitens des Benutzers handelt oder um den Arbeitsprozess.

    Wird der zweiten Programminstanz keine Befehlskette angehängt, ermittelt das Programm einen mehrfach Aufruf des Progammes und weisst den Benutzer daraufhin. Danach wird der Prozess beendet.

    Wird die Programminstanz stattdessen mit einer Befehlskette aufgerufen sprich es steht etwas in der Commandline wird die Methode writelink(); aufgerufen. Nach Abarbeitung ist auch dieser Prozess wieder beendet.

    Da ich definitiv weiss, dass mein Programm mit einem statischen Pfad funktioniert. Ist meine Logik dies betreffend korrekt.
    strPath wird lediglich in Methode linkassoc(); verwendet....

    Ohh, ich glaube ich habe das Problem erkannt.
    linkassoc(); wird in der ersten Programminstanz aufgerufen, wo auch die Variable ihren Wert bekommt. In der zweiten Programminstanz dagegen sind diese Daten nicht mehr vorhanden oder nicht mehr erreichbar.

    Die Frage ist jetzt ob ich diesen Teil der Pfadermittelung gesondert in eine Methode auslagere und mehrmals aufrufe oder aber herausbekomme wie ich einen geteilten Speicherbereich erstelle.
    Für letzteres bin ich zu grün hinter den Ohren 😞
    Und ersteres ist totaler Unfug, da auf x Prozesse x Ermittelungen des Pfades gemacht wird.


  • Mod

    Lass diesen Quatsch in dieser Form zu prüfen ob das Programm schon läuft.
    http://www.flounder.com/nomultiples.htm


Anmelden zum Antworten