Klasse in Borland Builder übernehmen



  • Hallo,

    nach meinen Zeitproblemen siehe hier: Kürzere Pause als Sleep(1)???

    möchte ich gerne das Beispiel aus diesem Link übernehmen: http://www.codeguru.com/system/CreatingAHigh.html

    Dazu habe ich eine neue Unit erstellt. Den ganzen Class-Teil habe ich in unit.h kopiert. Das Class-Beispiel steht nun in unit.cpp. Ist das richitg soweit?

    Wenn ich nun veruche mit meiner Anwendung (mit #include unit.h) die Funktion delay(x) zu benutzen, bekomme ich einen Haufen Fehlermeldungen von der neuen Klasse, z.B.:

    - Typname erwaret (MMRESULT mRes)
    - in Deklaration fehlt ;
    - mRes ist keine eindeutige Basisklasse von 'PreciseTimer'
    - Aufruf der undefinierten Funktion 'timesetevent'
    ...
    - Aufruf der undefinierten Funktion 'timekillevent'
    etc.

    Muß ich den irgendetwas besonderes beachten? Warum kennt er z.B. die API- Funktionen timesetevent und timekillevent nicht?
    Ich hoffe mir kann geholfen werden. Danke schon mal.

    Grüße
    Franky



  • Vermutlich fehlt ne Headerdatei die Du noch includen musst. Die weiteren Fehlermeldungen sind nur Folgefehler aufgrund der 1.Fehlermeldung.



  • Hast du die Api denn dem C Builder Projekt hinzugefügt ? 🙄



  • Ich ebenutze den Borland Builder 6. Ich dachte, die APIs müssen nicht extra hinzugefügt werden. Bei anderen Anwendungen brauche ich das nicht?

    Wenn doch, was muß ich denn genau machen?

    Grüße
    Franky



  • #include <mmsystem.h> 🙄

    [ Dieser Beitrag wurde am 07.02.2003 um 10:59 Uhr von Peter editiert. ]



  • mit projekt->demprojekthinzufügen
    kannst du noch libs etc einbinden .. und apis !



  • #include <mmsystem.h>

    Genau das war´s. Danke.

    Aber leider ist jetzt die Funktion Delay meiner Anwundung nich bekannt. Wo muß ich ihm das denn sagen? Ich habe doch #inlcude delay.h schon einegegeben. Und da steht unter class - public:

    void Delay(unsigned int val);
    

    Also müßte er die Funktion Delay doch kennen, oder?



  • in der Unit, in welcher du die Methode Delay() aufrufst musst du auch die Headdatei includen!



  • Ich habe alles "includet" was geht. Leider keine Besserung:

    E2268 Aufruf der undefinierten Funktion 'Delay'

    Und nun?

    Grüße
    Franky



  • Dann zeig mal deinen Code.



  • OK.
    Die Anwendung:

    #include <vcl.h>
    #pragma hdrstop
    
    #include "uhr.h"
    #include "delay.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    TClock *MyClock;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::StartButtonClick(TObject *Sender)
    {
    Delay(10);
    }
    

    Die neue Klasse (delay.h)

    #ifndef delayH
    #define delayH
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <mmsystems.h>
    #include <Forms.hpp>
    #include "uhr.h"
    //---------------------------------------------------------------------------
    class PreciseTimer
    {
    public:
       void __fastcall Delay(unsigned int val);
       __fastcall PreciseTimer() : mRes(0), toLeave(false), stopCounter(-1)
       {
          InitializeCriticalSection(&crit);
          mRes = timeSetEvent(1, 0, &TimerProc, (DWORD)this,
                              TIME_PERIODIC);
       }
       virtual ~PreciseTimer()
       {
          mRes = timeKillEvent(mRes);
          DeleteCriticalSection(&crit);
       }
    
       ///////////////////////////////////////////////////////////////
       // Function name   : Wait
       // Description     : Waits for the required duration of msecs.
       //                 : Timer resolution is precisely 1 msec
       // Return type     : void  :
       // Argument        : int timeout : timeout in msecs
       ///////////////////////////////////////////////////////////////
       void __fastcall Wait(int timeout)
       {
          if ( timeout )
          {
             stopCounter = timeout;
             toLeave = true;
             // this will do the actual delay - timer callback shares
             // same crit section
             EnterCriticalSection(&crit);
             LeaveCriticalSection(&crit);
          }
       }
       ///////////////////////////////////////////////////////////////
       // Function name   : TimerProc
       // Description     : Timer callback procedure that is called
       //                 : every 1msec
       //                 : by high resolution media timers
       // Return type     : void CALLBACK  :
       // Argument        : UINT uiID :
       // Argument        : UINT uiMsg :
       // Argument        : DWORD dwUser :
       // Argument        : DWORD dw1 :
       // Argument        : DWORD dw2 :
       ///////////////////////////////////////////////////////////////
       static void CALLBACK TimerProc(UINT uiID, UINT uiMsg, DWORD
                                      dwUser, DWORD dw1, DWORD dw2)
       {
          static volatile bool entered = false;
    
          PreciseTimer* pThis = (PreciseTimer*)dwUser;
          if ( pThis )
          {
             if ( !entered && !pThis->toLeave )   // block section as
                                                  // soon as we can
             {
                entered = true;
                EnterCriticalSection(&pThis->crit);
             }
             else if ( pThis->toLeave && pThis->stopCounter == 0 )
                                                  // leave section
                                                  // when counter
                                                  // has expired
             {
                pThis->toLeave = false;
                entered = false;
                LeaveCriticalSection(&pThis->crit);
             }
             else if ( pThis->stopCounter > 0 )   // if counter is set
                                                  // to anything, then
                                                  // continue to drop
                                                  // it...
                --pThis->stopCounter;
          }
       }
    
    private:
       MMRESULT         mRes;
       CRITICAL_SECTION crit;
       volatile bool    toLeave;
       volatile int     stopCounter;
    };
    #endif
    

    und delay.cpp

    #pragma hdrstop
    
    #include "delay.h"
    #include "uhr.h"
    
    //---------------------------------------------------------------------------
    
    //----------------------------------------------------------------
    // Class usage example
    //----------------------------------------------------------------
    void __fastcall PreciseTimer::Delay(unsigned int val)
    {
       static LARGE_INTEGER freq = {0};
       static double average = 0;
       static int count = 0;
    
       ++count;
       LARGE_INTEGER iStart, iStop;
       if ( freq.QuadPart == 0 )
          QueryPerformanceFrequency(&freq), freq.QuadPart /= 1000;
                          // convert to msecs counter
    
       double sleep = 0;
       QueryPerformanceCounter(&iStart);
    
       //timer.
       Wait(val); // is there anything to wait on? ... then wait
    
       QueryPerformanceCounter(&iStop);
       sleep = ((double)iStop.QuadPart - (double)iStart.QuadPart)
                                       / (double)freq.QuadPart;
       average += (val ? 100.0*(sleep-val)/(double)val : 0);
       //printf("Waited for %6.3f (%ld). error = %5.2f\n", sleep, val,
       //                                average/(double)count);
    }
    #pragma package(smart_init)
    

    Ich hoffe, das hilft. Danke schon mal.

    Grüße
    Franky



  • Klar.
    Du kannst nicht einfach auf eine Funktion Delay() so zugreifen.
    Du musst zuerst ein Objekt von deiner Klasse PreciseTimer erstellen und dann über das Objekt die Methode Delay aufrufen.

    z.B.

    PreciseTimer *ATimer = new PreciseTimer();
    ATimer->Delay(10);
    

    Nachdem du ATimer nicht mehr brauchst, delete nicht vergessen!

    [ Dieser Beitrag wurde am 07.02.2003 um 12:55 Uhr von JeGr editiert. ]



  • War zu lahm. 🙂

    [ Dieser Beitrag wurde am 07.02.2003 um 12:58 Uhr von DJ BlackEagle editiert. ]



  • Danke Dir (Euch) vielmals.
    Da habe ich doch gleich wieder etwas dazugelernt. Nur leider funktioniert die Klasse nicht so richtig, also irgendwie wird an der Stelle keine Pause eingelegt. Aber das ist ein ganz anderes Thema...

    Grüße
    Franky

    [ Dieser Beitrag wurde am 07.02.2003 um 13:05 Uhr von Franky editiert. ]



  • Aha, ich glaube ich weiß wo der Fehler liegt.

    In der Funktion Delay wird die KlassenFunktion Wait aufgerufen.

    timer.Wait(val); // is there anything to wait on? ... then wait
    

    Ich habe es aber so ausgeührt (s.o.)

    //timer.
       Wait(val); // is there anything to wait on? ... then wait
    

    Mit timer.Wait bekomme ich die Fehlermeldung:
    E2451 Undefiniertes Symbol 'timer'

    Was ist das denn nun wieder???

    Grüße
    Franky



  • Lass den Aufruf so, wie du ihn am Anfang hattest.

    Schau dir mal genau die Klasse PreciseTime an.

    Dort gibt es eine Methode namens Wait:

    ///////////////////////////////////////////////////////////////
       // Function name   : Wait
       // Description     : Waits for the required duration of msecs.
       //                 : Timer resolution is precisely 1 msec
       // Return type     : void  :
       // Argument        : int timeout : timeout in msecs
       ///////////////////////////////////////////////////////////////
       void Wait(int timeout)
       {
          if ( timeout )
          {
             stopCounter = timeout;
             toLeave = true;
             // this will do the actual delay - timer callback shares
             // same crit section
             EnterCriticalSection(&crit);
             LeaveCriticalSection(&crit);
          }
       }
    

    Wie man der Beschreibung entnehmen kann, wartet die Methode in im Übergabeparameter angegebene Zeit in Millisekunden!

    Vielleicht solltest du einfach mal den Wert in der Delay-Methode erhöhen, um zu prüfen, ob die Anwendung wirklich verzögert wird.



  • Ich benutze also jetzt einfach

    Wait(val);
    

    Irgendwie funktioniert die Verzögerung nur zufällig. Damit meine ich nicht während der Anwendung, sondern zwischen den Anwendungen. Also einmal compilieren und es funktioniert, dabei auch wirklich sehr genau. Danach habe ich die Anwendung geschlossen und neu compiliert. Und jetzt wird wieder überhaupt nicht verzögert. Dabei tritt dieser Fall aber wesentlich öfter ein, als der andere.
    Ich kann nicht wirklich feststellen, woran das nun liegt, ob verzögert wird oder nicht.

    Grüße
    Franky


Anmelden zum Antworten