klassen & funktionen... *Argh* help <anfänger>



  • Hi...
    also hab mir nun nen borland builder besorgt. bei www.winapi.net einen beispielsource gefunden und eigentlicht so wie ich ihn brauche kopiert und verändert und überhaupt. hab mich auch schon mit kumpels über ICQ beraten und wir wissen nicht mehr weiter........

    hier meine Codes:

    //---------------------------------------------------------------------------
    
    #ifndef Unit1H
    #define Unit1H
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <Menus.hpp>
    #include <stdio.h>
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published:	// Von der IDE verwaltete Komponenten
            TButton *Button1;
            TRadioButton *RadioButton1;
            TRadioButton *RadioButton2;
            TLabel *Label1;
            TLabel *Label2;
            TEdit *Edit1;
            TEdit *Edit2;
            TMainMenu *MainMenu1;
            TMenuItem *File1;
            TMenuItem *Exit1;
            TMenuItem *View1;
            TMenuItem *About1;
            void __fastcall Button1Click(TObject *Sender);
            void __fastcall About1Click(TObject *Sender);
            void __fastcall Exit1Click(TObject *Sender);
    private:	// Anwender-Deklarationen
    public:		// Anwender-Deklarationen
    
            __fastcall TForm1(TComponent* Owner);
    };
    
    FILE *pFile; //global definiert, damit alle funktionen&klassen draufzugreifen können.
    int nBaud, nBits, nStopp, nParity, nPort;
    char *buffer;
    
    //---------------------------------------------------------------------------
    
    class CSerial
    {
    
    public:
       CSerial(); // Konstruktor
       ~CSerial(); // Destructor
    
       BOOL Open    (int, int, int, int, int); // Öffnen 
       BOOL Close   (void); // Schließen
       BOOL ModeSet (int, int, int, int); // Änderung
    
       int ReadData(char*); // Lesen
    
    private:
       HANDLE hComm; // Handle für den Zugriff
       DCB dcb_alt; // Um die alten Parameter zu merken
       COMMTIMEOUTS timeouts_alt; // Um die alten Parameter zu merken
    };
    
    //---------------------------------------------------------------------------
    
    CSerial::CSerial() : hComm(INVALID_HANDLE_VALUE) //Konstruktor
    {
    }
    
    //---------------------------------------------------------------------------
    
    CSerial::~CSerial() //destruktor
    {
       Close ();
    }
    
    //---------------------------------------------------------------------------
    
    BOOL CSerial::ModeSet (int nBaud, int nBits, int nStopp, int nParity) 
    // Ändern von Baudrate (nBaud), Bits (nBits), Parität (nParity)
    {
       if (INVALID_HANDLE_VALUE == hComm) // COM-Port überhaupt geöffnet?
           return (FALSE);
    
       DCB dcb; // Struktur vom Typ DCB erzeugen
    
       ZeroMemory (&dcb, sizeof(dcb)); // ..und schön löschen (wichtig!)
    // Die bestehenden Parameter holen. Bei Fehler ist hier Schluss!
       if (!GetCommState (hComm, &dcb)) 
       {
          Close ();
          MessageBox (NULL, "Fehler beim Ändern der COM-Port Parameter\nGetCommState()", 
                      NULL, NULL);
          return (FALSE);
       }
    
       // neue Parameter in die Struktur kopieren (Baud: z.B. 9600)
       dcb.BaudRate = nBaud; 
       // neue Parameter in die Struktur kopieren (Bits: z.B. 7 oder 8)
       dcb.ByteSize = (BYTE)nBits; 
       // neue Parameter in die Struktur kopieren (Parität:(siehe MSDN))
       dcb.Parity   = (BYTE)nParity; 
       // Anzahl Stoppbits (siehe MSDN)
       dcb.StopBits = (BYTE)nStopp; 
    
       // neue Parameter setzen. Bei Fehler ist hier Schluss!
       if (!SetCommState (hComm, &dcb)) 
       {
          Close ();
          MessageBox (NULL, "Fehler beim Ändern der COM-Port Parameter\nSetCommState()", 
                      NULL, NULL);
          return (FALSE);
       }
    
       return (TRUE); // fertig
    }
    
    // Öffnen von / mit Portnummer (nPort), Baudrate (nBaud), Bits (nBits),
    //Stoppbits (nStopp), Parität (nParity)
    
    //---------------------------------------------------------------------------
    
    BOOL CSerial::Open (int nPort, int nBaud, int nBits, int nStopp, int nParity) 
    {
       if (INVALID_HANDLE_VALUE != hComm)  // COM-Port überhaupt geöffnet?
           return (TRUE);
    
       char szPort[15]; 
        // Aus einer "1" in nPort schreiben wir so "COM1" in szPort z.B..
       wsprintf (szPort, "\\\\.\\COM%d", nPort);
    
       hComm = CreateFile (szPort, // COM-Port öffnen
                           GENERIC_READ | GENERIC_WRITE, // wir wollen lesen und schreiben
                           0,
                           0,
                           OPEN_EXISTING,
                           FILE_ATTRIBUTE_NORMAL,
                           NULL); // nicht OVERLAPPED, wir holen uns den Port exclusiv
    
       if (hComm == INVALID_HANDLE_VALUE) // hat es geklappt? Bei Fehler ist hier Schluss!
       {
          MessageBox (NULL, "Fehler beim Öffnen des COM-Ports!\nCreateFile()", NULL, NULL);
          return (FALSE);
       }
       // Alte Timeouts merken. Bei Fehler ist hier Schluss!
       if (!GetCommTimeouts(hComm, &timeouts_alt)) 
       {
          Close ();
          MessageBox (NULL, "Fehler beim Öffnen des COM-Ports!\nGetCommTimeouts()", 
                      NULL, NULL);
          return (FALSE);
       }
    
       // Eine Struktur vom Typ COMMTIMEOUTS erzeugen und neue Timeouts setzen
       COMMTIMEOUTS timeouts; 
       timeouts.ReadIntervalTimeout         = 200;
       timeouts.ReadTotalTimeoutMultiplier  = 200;
       timeouts.ReadTotalTimeoutConstant    = 200;
       timeouts.WriteTotalTimeoutMultiplier = 200;
       timeouts.WriteTotalTimeoutConstant   = 200;
    
       // Neue Timeouts setzen. Bei Fehler ist hier Schluss!
       if (!SetCommTimeouts(hComm, &timeouts)) 
       {
          Close ();
          MessageBox (NULL, "Fehler beim Öffnen des COM-Ports!\nSetCommTimeouts()", 
                      NULL, NULL);
          return (FALSE);
       }
    
       DCB dcb; // Struktur vom Typ DCB erzeugen
    
       ZeroMemory (&dcb, sizeof(dcb)); // ..und schön löschen (wichtig!)
       // Die bestehenden Parameter holen. Bei Fehler ist hier Schluss!
       if (!GetCommState (hComm, &dcb)) 
       {
          Close ();
          MessageBox (NULL, "Fehler beim Öffnen des COM-Ports!\nGetCommState()", 
                      NULL, NULL);
          return (FALSE);
       }
    
       dcb_alt = dcb; // alte Parameter sichern
       dcb.DCBlength         = sizeof(DCB);
       dcb.fBinary           = TRUE; // muss immer "TRUE" sein!
       dcb.fParity           = TRUE;
       dcb.fOutxCtsFlow      = FALSE;
       dcb.fOutxDsrFlow      = FALSE;
       dcb.fDtrControl       = DTR_CONTROL_ENABLE;
       dcb.fDsrSensitivity   = FALSE;
       dcb.fTXContinueOnXoff = TRUE;
       dcb.fOutX             = FALSE;
       dcb.fInX              = FALSE;
       dcb.fErrorChar        = FALSE;
       dcb.fNull             = FALSE;
       dcb.fRtsControl       = RTS_CONTROL_ENABLE;
       dcb.fAbortOnError     = FALSE;
       dcb.wReserved         = 0; // muss immer "0" sein!
    
       // neue Parameter in die Struktur kopieren (Baud: z.B. 9600)
       dcb.BaudRate = nBaud; 
       // neue Parameter in die Struktur kopieren (Bits: z.B. 7 oder 8)
       dcb.ByteSize = (BYTE)nBits; 
       // neue Parameter in die Struktur kopieren (Parität:(siehe MSDN))
       dcb.Parity   = (BYTE)nParity; 
       // Anzahl Stoppbits (siehe MSDN)
       dcb.StopBits = (BYTE)nStopp; 
       dcb.fParity = (dcb.Parity != NOPARITY);
    
       // neue Parameter setzen. Bei Fehler ist hier Schluss!
       if (!SetCommState (hComm, &dcb)) 
       {
          Close ();
          MessageBox (NULL, "Fehler beim setzen der COM-Port Parameter\nSetCommState()", 
                      NULL, NULL);
          return (FALSE);
       }
    
       return(TRUE);
    }
    
    //---------------------------------------------------------------------------
    
    BOOL CSerial::Close (void)
    {
       if (INVALID_HANDLE_VALUE == hComm) // COM-Port überhaupt geöffnet?
           return(TRUE);
    
       if (!SetCommTimeouts(hComm, &timeouts_alt))
       {
          MessageBox (NULL, "Fehler beim Schließen des COM-Ports\nSetCommTimeouts()", 
                      NULL, NULL);
          return (FALSE);
       }
       // alte Parameter zurückschreiben. Bei Fehler ist hier Schluss!
       if (!SetCommState (hComm, &dcb_alt)) 
       {
          MessageBox (NULL, "Fehler beim Schließen des COM-Ports\nSetCommState()", 
                      NULL, NULL);
          return (FALSE);
       }
       CloseHandle (hComm); // Port schließen
       hComm = INVALID_HANDLE_VALUE; // das Handle zurücksetzen
    
       return (TRUE);
    }
    
    //---------------------------------------------------------------------------
    
    int CSerial::ReadData(char *buffer) // Buffer (*buffer), der die Zeichen bekommt
    {  
       if (INVALID_HANDLE_VALUE == hComm) // COM-Port überhaupt geöffnet?
           return(0);
    
       DWORD dwRead = 0;
       char chRead;
       int i = 0;
    
       while (ReadFile(hComm, &chRead, 1, &dwRead, NULL)) // wurde ein Zeichen gelesen?
       {
           if (dwRead != 1) // ..wenn nicht, dann ist hier Schluß
               break;
    
           fputc(chRead,pFile); // wann ja, dann das Zeichen in die txt schreiben
       }
       return (i); // die Anzahl der gelesenen Bytes zurückgeben
    }
    
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
    

    und meine CPP:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include <windows.h>
    #include "Unit1.h" // Headerdefinitionen
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
            Edit1->Text="";
            Edit2->Text="";
            nBaud=9600;
            nParity=0;
            nBits=8;
            nStopp=1;
            pFile=fopen("C:\\messergebnis.txt","w");
    }
    
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {  int bytes;
    
    if(RadioButton1->Checked)               //Abfrage über RadioButtons welcher
            nPort=1;                        //COMPORT verwendet wird. Falls keiner
    else if (RadioButton2->Checked)         //der beiden Radiobuttons gedrückt wird
            nPort=2;                        //erfolgt eine Fehlermeldung.
    else
            Application->MessageBoxA("Please select a Comport","Error",MB_OK);
    
    CSerial();     //aufruf des konstruktors der klasse CSerial
    
    BOOL ModeSet(int nBaud, int nBits, int nStopp, int nParity);
    BOOL Open(int nPort, int nBaud, int nBits, int nStopp, int nParity);
    bytes=CSerial::ReadData(*buffer);  //Diese FUnktion krieg ich nich aufgerufen!!
    
    BOOL Close();
    Edit1->Text=IntToStr(bytes);
    
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::About1Click(TObject *Sender)
    {
    Application->MessageBox("::Comport-Reader Beta 1  ::by fotsucker", "About Comport-Reader", MB_OK);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Exit1Click(TObject *Sender)
    {
    exit(1);        
    }
    //---------------------------------------------------------------------------
    

    also wir haben uns alle gesritten und viel probiert:

    bytes=CSerial::ReadData(*buffer);
    [C++ Fehler] Unit1.cpp(41): E2283 Verwenden Sie . oder -> zum Aufruf von 'CSerial::ReadData(char *)'

    bytes=CSerial.ReadData(*buffer);
    [C++ Fehler] Unit1.cpp(41): E2108 Ungültige Verwendung von typedef 'CSerial'

    bytes=CSerial->ReadData(*buffer);
    //is das selbe wie oben.....

    ich verzweifel hier gerade, weil ich die funktion nicht aufgerufen kriege...



  • CSerial ist eine Klasse. Deshalb mußt Du diese Klasse, die du zuvor deklariert hast, erstmal definieren (also eine "lebensfähige" Instanz erzeugen). Eine Deklaration beschreibt praktisch nur ein Objekt. Eine Definition gibt an, daß ein neues Objekt vom Compiler angelegt werden soll.

    In Deiner Button1Click Methode mußt Du also möglichst am Anfang der Methode erstmal ein

    CSerial MeineSerielleKlasse();
    

    codieren. Dann hast Du eine Instanz der Klasse CSerial erstellt, die genau so lange lebt, wie die Methode Button1Click durchlaufen wird. Endet die Methode, wird automatisch der Destruktor von CSerial gerufen und das Objekt wieder verworfen.

    Nun kannst Du mittels "MeineSerielleKlasse" auf die Eigenschaften und Methoden dieser Klasse zugreifen. Also

    MeineSerielleKlasse.ReadData(*buffer);
    

    codieren.

    An Stelle eines '.' muß man "->" benutzen, wenn in "MeineSerielleKlasse" ein Zeiger auf eine Klasseninstanz gespeichert ist. Aber das liest Du besser in einem C++ Buch nach.

    Das Verfahren mit den :: sieht man manchmal, um eine Eigenschaft oder Methode einer Klasse anzusprechen. So ist es möglich, bei der Ableitung einer Klasse eine Methode in der abgeleiteten Klasse zu überschreiben. Um nun noch die "alte" Methode der ursprünglichen Klasse erreichen zu können, wird dann "::" verwendet.

    Bei der Definition von Methoden wiederum wird "::" gebraucht, damit der Compiler weiß, zu welcher Klasse diese Methodendefinition gehört.



  • hmm.. also ich hab das probiert...
    hab im button ganz am anfang CSerial MeineSerielleKlasse; gemacht.

    ja das klappt auch ganz gut.. doch unten bei dem:

    bytes=MeineSerielleKlasse->ReadData(*buffer); kommt nur das:

    [C++ Fehler] Unit1.cpp(42): E2288 Zeiger auf Struktur auf linker Seite von -> oder von ->* erforderlich*

    und ich weiß wieder nicht so wirklich was der liebe builder von mir will

    aber danke für die hilfe!!!!!



  • Dann ließ doch, was ich geschrieben habe. Das "->" darfst Du nur verwenden, wenn Du in einer Variablen einen Zeiger auf eine Klasse hast. Du hast aber keinen Zeiger auf eine Klasse erzeugt, sondern eine Klasseninstanz direkt erstellt.

    In Deinem Fall mußt Du an Stelle des "->" den Punkt '.' verwenden. Dann wird der Compiler auch nicht mehr meckern. Was Du in dem Programm aber so alles machst, hab ich mir nicht angekuckt...



  • fotsucker: vielleicht solltest dud ir nochmal die Grundlagen von C/C++ zu Gemüte führen, bevor du weiter rumexperimentierst. So grundlegende Syntaktische Fragen sollten eigentlich nichtmehr offen sein (schon gar nicht wenn man mit einem Framework wie der VCL arbeiten will!)

    -junix


Anmelden zum Antworten