Προς το περιεχόμενο

Διάφορες ερωτησεις για πρόγραμμα σε C++...


SweetChild

Προτεινόμενες αναρτήσεις

Δημοσ.

Κάνω μια εργασία κι έχω κάποια μικροπροβληματάκια στο πρόγραμμα, διάσπαρτα..

Όποιος γνωρίζει οτιδήποτε απ' αυτά ας βοηθήσει όσο μπορεί..

 

Πως:

  • διαγράφω ένα πεδίο από ένα ListBox (έστω1) και το ίδιο (αντίστοιχο) πεδίο να διαγράφω αυτόματα και στο ListBox (έστω 2)?
  • "καθαρίζω" ένα DBGrid? (Δεν εχει εντολη DBGrid1->Clear() )
  • βάζω volume bar σε έναν mediaPlayer? (Δεν βρήκα πουθενα παρόμοιο κώδικα)
  • αρχικοποιώ το βιντεάκι να παίζει από το σημείο που βρίσκει στο DBGrid στην γραμμή 2 π.χ.

 

Ευχαριστω!!!! ;)

Αναμένω απαντησεις....)

Δημοσ.

Ενδιαφέρον ερώτημα....

 

Το TMediaPlayer δεν υποστηρίζει εξ ορισμού προσωπικό του Volume Control, οπότε θα πρέπει να χρησιμοποιήσεις είτε τον Audio Mixer των MS-Windows (sndvol32.exe) ή τις ανάλογες Multimedia Windows API ρουτίνες, όπως τις waveOutGetVolume για να πληροφορηθείς την στάθμη του Wave audio device που επιθυμείς και την waveOutSetVolume για να τροποποιήσεις την στάθμη αυτή.

 

Το Multimedia API είναι δυστυχώς αρκετά στρυφνό όσον αφορά την διαχείριση Mixers, που θα ήταν ιδανικό στην περίπτωση σου, οπότε αν περιορισθείς στις waveOutGetVolume/waveOutSetVolume να έχεις υπόψη σου ότι οι αλλαγές που κάνεις στο Wave volume με την τελευταία function δεν θα αντανακλώνται αυτόματα στα knobs του Windows mixer (sndvol32.exe) διότι γίνονται απευθείας προσπερνώντας το Mixer interface (μικρό το κακό βέβαια).

 

Πριν ξεκινήσουμε, καλό είναι να θυμόμαστε πως το 0 = με σιγή ενώ το FFFF (65535) = με την μέγιστη δυνατή ένταση του Wave Out device.

Επίσης θα χρειασθούμε ένα TTrackBar control με TTrackBar->Max τιμή = 65 και Min = 0 & Frequency = 1 (φυσικά αυτά μπορούν να τροποποιηθούν αφού εξηγηθεί ο τρόπος λειτουργίας των εντολών Wave Out Volume audio).

 

Ακολουθεί η πρώτη ρουτίνα:

>
bool __fastcall GetSndVolume(TTrackBar *Owner)
{
   /*
    * Request current device (0) wave audio volume level
    * and display it on Owner.
    */
   DWORD dwVolume;

   if(waveOutGetVolume(0, &dwVolume) == MMSYSERR_NOERROR)
    {
       // Convert Left speaker volume value to a TTrackBar position
       Owner->Position = LOWORD(dwVolume) / 1000;

       // Done!
       return  true;
    }

   // Failure!
   return  false;
}

 

Η GetSndVolume ζητά από την τρέχουσα Wave Out (0) συσκευή την στάθμη του ήχου και την περνά ως θέση Knob στο Owner (ένα TTrackBar control).

Η στάθμη ήχου που επιστρέφει η waveOutGetVolume είναι μορφής DWORD με το LOWORD να αφορά το αριστερό κανάλι ήχου και το HIWORD το δεξί (2 κανάλια ήχου - στερεοφωνική αναπαράσταση).

Εμείς χρησιμοποιούμε την τιμή του αριστερού καναλιού διότι υπάρχουν ορισμένα Wave Out devices που δεν υποστηρίζουν στερεοφωνική έξοδο οπότε αγνοούν κάθε τιμή στο HIWORD.

Hint: Θα μπορούσαμε να ελέγξουμε αν η Wave Out device μας υποστηρίζει στερεοφωνικό waveOutGetVolume αλλά αυτό θα περιέπλεκε λίγο περισσότερο τον κώδικα μας.

Τέλος ο αριθμός του LOWORD διαιρείται με το 1000 ώστε να επιστρέψει μια τιμή από 0 ως 65.

Σε περίπτωση λάθους η waveOutGetVolume επιστρέφει τιμή διάφορη του MMSYSERR_NOERROR.

 

Ακολουθεί η δεύτερη ρουτίνα:

>
bool __fastcall SetSndVolume(TTrackBar *Owner)
{
   // Set current device (0) wave audio volume label from Owner.
   return  (waveOutSetVolume(0,
                             MAKELONG(Owner->Position * 1000,
                                      Owner->Position * 1000))
                                      == MMSYSERR_NOERROR) ? true:false;
}

 

Η SetSndVolume τροποποιεί την στάθμη ήχου της τρέχουσας Wave Out (0) συσκευής με βάση την θέση Knob του Owner (TTrackBar) κοντρόλ μας.

Η στάθμη ήχου για την waveOutSetVolume ορίζεται ως ένα DWORD, όπως και στην περίπτωση της waveOutGetVolume, όταν η Wave Out device μας είναι μονοφωνική τότε η στάθμη ήχου ορίζονται με βάση την πρώτη παράμετρο της MAKELONG (δηλαδή βάση του LOWORD).

Τέλος η θέση του TTrackBar->Position knob πολλαπλασιάζεται με 1000 ώστε να μετατραπεί στην κλίμακα 0 ως 65535 που υποστηρίζει η waveOutSetVolume (περίπου βέβαια διότι λόγο στρογγυλοποίησης των τιμών υπάρχει μια μικρή αλλά ανεπαίσθητη απώλεια στην στάθμη ήχου).

Σε περίπτωση λάθους η waveOutSetVolume επιστρέφει τιμή διάφορη του MMSYSERR_NOERROR.

 

Για να χρησιμοποιείς τις ρουτίνες, ενδεικτικά δημιούργησε ένα νέο TTrackBar κοντρόλ στην φόρμα σου και στο OnChange event του δώσε:

>
   SetSndVolume(TrackBar1);

ώστε να καλείται η SetSndVolume κάθε φορά που αλλάζει θέση το Knob.

 

Για να ανανεώνεις συνεχώς την στάθμη ήχου του TTrackBar κοντρόλ, δημιούργησε στην φόρμα σου ένα TTimer και στον OnTimer event του δώσε:

>
   GetSndVolume(TrackBar1);

ώστε να ανανεώνει συνεχώς την θέση του TTrackBar knob με βάση την στάθμη ήχου το Wave Out device.

 

Αυτό το Interface είναι λίγο μπακαλίστικο (ελπίζω επίσης να δουλεύει σε κάθε περίπτωση). Ο καλύτερος τρόπος είναι η χρήση του Mixer Interface αλλά εκεί μπλέκουμε με αρκετές δομές κτλ. Τέλος υπάρχει και ένα τρικ που μας οδηγεί δια τις πλαγίας οδού στο Mixer Interface αλλά δεν είναι ιδιαίτερα κομψό (αν σε ενδιαφέρει, μου λες).

 

Καλή συνέχεια.

 

Υ.Γ.

1. Όταν λες πεδίο εννοείς μάλλον Item, σωστά;

2. Δεν μπορείς να καθαρίσεις ένα DBGrid καθώς είναι άμεσα συνδεδεμένο με την Database σου (θυμάσαι όμως διάφορα κόλπα με Owning Draw - μπορεί να σε βοηθήσουν ;)).

3. Αυτό δεν είναι δύσκολο, δες την TMediaPlayer->Position (βέβαια έχει περάσει κάποιος καιρός από την τελευταία φορά που ασχολήθηκα με το TMediaPlayer control).

Δημοσ.

Το έκανα αλλά δεν έτρεξε.... :rolleyes:

 

Λογικα κάτι κάνω λάθος....

Σε περίπτωση που έχεις λίγο χρόνο και δεν έχεις πρόβλημα να ασχοληθείς, μπορώ να στο στείλω στο Mail να το κοιτάξεις λίγο..

 

Υ.Γ.,

1. Όταν λες πεδίο εννοείς μάλλον Item, σωστά;

 

Ναι σωστα...

 

2. Δεν μπορείς να καθαρίσεις ένα DBGrid καθώς είναι άμεσα συνδεδεμένο με την Database σου (θυμάσαι όμως διάφορα κόλπα με Owning Draw - μπορεί να σε βοηθήσουν ).

 

Τέτοια κόλπα δεν γνωρίζω, ομολογώ, αλλά θα τα ψάξω!..

 

3. Αυτό δεν είναι δύσκολο, δες την TMediaPlayer->Position (βέβαια έχει περάσει κάποιος καιρός από την τελευταία φορά που ασχολήθηκα με το TMediaPlayer control).

 

Δεν έχει ακριβώς σχέση με τον mediaplayer.. Πρέπει να διαβάζει από το DBGrid την Αρχή και το Τέλος της σκηνής του βίντεο...

 

 

Σε ευχαριστω πολυ!!!

Δημοσ.

Η παρακάτω ρουτίνα διαγράφει τα επιλεγμένα items ενός TListBox (θα το λέμε Owner) και ενός επίσης TListBox (θα το λέμε Secondary) εφόσον τα items αυτά υπάρχουν καταχωρημένα και σε αυτό.

 

Το κόλπο είναι να βρίσκουμε με την βοήθεια της IndexOf του Secondary κοντρόλ την θέση του item που έχουμε επιλέξει στο Owner κοντρόλ και ύστερα να την διαγράφουμε από το Secondary κοντρόλ -μην ξεχνάμε ότι τα Items του TListBox δεν είναι τίποτε περισσότερο από AnsiStrings οργανωμένα σε μια λίστα TString.

 

Στο τέλος, η ρουτίνα διαγράφει αυτόματα, με την βοήθεια της TListBox->DeleteSelected() όλα τα επιλεγμένα Items του Owner κοντρόλ.

 

>
void __fastcall EraseDbl(TListBox *Owner, TListBox *Secondary)
{
   // Delete Owner selected items & delete them also from Secondary TListBox control
   for(int nItemCount = 0; nItemCount < Owner->Count; nItemCount++)
       if(Owner->Selected[nItemCount])
        {
           // Find the same item position on the Secondary TListBox ...
           int nItemPos = Secondary->Items->IndexOf(Owner->Items->Strings[nItemCount]);
           if(nItemPos != -1) // Anything found?
               Secondary->Items->Delete(nItemPos); // Yes - delete it!
        }

   // Clean-up Owner items (as well)
   Owner->DeleteSelected();
}

 

Για δοκιμή, τοποθέτησε δυο TListBox κοντρόλ στην φόρμα σου και ένα TButton. Ύστερα πρόσθεσε τον παρακάτω κώδικα στο constructor του Form σου:

 

>
   for(int nData = 0; nData < 10; nData++)
    {
       ListBox1->Items->Add(nData);
       ListBox2->Items->Add(nData - 5);
    }

 

Και μετά στο OnClick event του TButton αυτό:

 

>
   EraseDbl(ListBox1, ListBox2); 

 

Ύστερα τρέξε το πρόγραμμα και επέλεξε τα Items (ή το Item αν δεν έχεις θέσει true το MultiSelect του κοντρόλ) από το ListBox1 που θέλεις να σβήσεις και πάτησε το Button.

 

Για τα υπόλοιπα, που είναι πιο περίπλοκα & εξαρτάται ο κώδικας σου τι κάνει, στείλε μου για μεγαλύτερη διευκόλυνση, e-mail, πάντως η αναπαραγωγή γίνεται με βάση το Position ως το σημείο διακοπής που επιθυμείς (παρακολούθησε το με Event).

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...