Nicht modaler Dialog Erweiterung 1

Eingabefeld, Drehfeld und Slider


Einleitung

Um diese Anleitung nicht zu lang werden zu lassen, schreibe ich immer nur die Dinge auf, die verändert werden müssen. Bei Codeabschnitten werden die Teile, die von mir verändert wurden fett geschrieben.

Beispiel

Aufgabe

Das Programm nonmodal soll erweitert werden:
Auf dem Dialog sollen 3 Steuerelemente eingefügt werden: Eingabefeld, Drehfeld und Slider.
Diese hängen alle 3 zusammen, das heißt das Verändern eines Steuerelementes verändert auch die anderen. Es können die Zahlen von 1 bis 10 ausgewählt werden.

Lösung in Prosa

  1. Zuerst müssen dem Dialog die Steuerelemente hinzugefügt werden:
    -> Auf die Ressourcenansicht wechseln

  2. Member Variablen für die Steuerelemente hinzufügen:
    -> Klassenassistent, Member-Variablen
    -> für das Drehfeld (SPIN) wird nur wegen eines MFC-Fehlers eine MemberVariable benötigt: Die Nummer wird größer, wenn man nach unten drückt und umgekehrt :-)

    -> da die Variable für das Eingabefeld den Datentyp UINT hat, kann wie bei allen numerischen Datentypen, bei kleinster und größter Wert eine Wertbeschränkung eingegeben werden, in unserem Fall 1 und 10.

  3. Um das Drehfeld mit dem Eingabefeld zu verbinden, braucht man nur folgende Schritte ausführen:
    -> Menü Layout, Tabulator-Reihenfolge
    -> Eingabefeld und Drehfeld müssen in der Reihenfolge hintereinander sein z.B.: Eingabefeld=1, Drehfeld=2
    -> In den Eigenschaften des Drehfelds auf Formate wechseln und die Punkte 'Autom. Buddy' und 'Buddy-Ganzzahl setzen' aktivieren.
  4. Um den MFC-Fehler des Drehfelds zu beseitigen muss noch die Funktion OnInitDialog überschrieben werden:
    -> Klassenassistent
    -> Klassenname : dialog
    -> Nachricht : WM_INITDIALOG
    -> Funktion hinzufügen
    -> Code bearbeiten

    BOOL dialog::OnInitDialog() 
    {
        CDialog::OnInitDialog();
    
        // Anfangswert setzen
        m_eingabefeld = 1;
        // In den Dialog schreiben
        UpdateData(false);
    
        // Beseitigen des MFC-Fehlers
        // Nach unten drücken Zahl wird aber größer
        // Parameter 1 : Kleinster Wert des Drehfelds
        // Parameter 2 : Größter Wert des Drehfelds
        m_spin.SetRange(1,10);
        
        // Die Werte werden eingegrenzt,
        // wichtig für die grafische Darstellung des sliders
        m_slider.SetRange(1,10);
    
        return TRUE;  // return TRUE unless you set the focus to a control
                      // EXCEPTION: OCX-Eigenschaftenseiten sollten FALSE zurückgeben
    }
    
  5. Das Drehfeld und das Eingabefeld arbeiten nun schon zusammen, jetzt müssen noch Eingabefeld und Slider zusammenarbeiten. Zuerst programmiere, dass sich das Eingabefeld automatisch verändert, wenn der Slider bewegt wird.
    Dazu muss der Handler überschrieben werden, der aufgerufen wird, wenn der Slider bewegt wird : WM_HSCROLL.
    Achtung: Dieser Handler wird für alle horizontalen Slider und Bildlaufleisten aufgerufen. Sind mehrere vorhanden, muss entweder jedes Mal geprüft werden welcher den Handler ausgelöst hat, oder die einfachere Variante ist einfach alle zu bearbeiten (so mach ich's :-).
    -> Klassenassistent
    -> Klassenname : dialog
    -> Nachricht : WM_HSCROLL
    -> Funktion hinzufügen...
    -> Code bearbeiten

    void dialog::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
    {
        // TODO: Code für die Behandlungsroutine für Nachrichten hier einfügen und/oder Standard aufrufen
        int wert;
    
        // Aktuellen Wert des Sliders auslesen
        wert = m_slider.GetPos();
    
        // Wert in das Eingabefeld speichern
        m_eingabefeld = wert;
        // Weil eingabefeld eine uint Variable ist
        // und keine Controlvariable
        // muss noch UpdateData aufgerufen werden,
        // für das wirkliche Darstellen der Zahl im Dialog
        UpdateData(false);
        
        CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
    }
    
  6. Jetzt muss noch der Handler des Eingabefeldes bearbeitet werden, der jedes Mal bei Änderung des Eingabefeldes die Position des Sliders korrigiert:
    -> Klassenassistent
    -> Klassenname : dialog
    -> Objekt-ID : IDC-EDIT1
    -> Nachricht : EN_CHANGE
    -> Funktion hinzufügen, Code bearbeiten

    void dialog::OnChangeEdit1() 
    {
        // TODO: Wenn dies ein RICHEDIT-Steuerelement ist, sendet das Steuerelement diese
    
        // Nur wenns den Slider schon gibt
        // stürzt sonst ab, wenn mans nicht abfragt
        if (m_slider.GetSafeHwnd() != NULL)
        {
            // Eintragen der Werte am Dialog in die
            // dazugehörigen Member-Variablen
            UpdateData(true);
    
            // Slider neu setzen
            m_slider.SetPos(m_eingabefeld);
        }
    
        // Benachrichtigung nicht, bevor Sie nicht die Funktion CDialog::OnInitDialog()
        // überschreiben und CRichEditCtrl().SetEventMask() aufrufen, wobei
        // eine ODER-Operation mit dem Attribut ENM_CHANGE und der Maske erfolgt.
        
        // TODO: Fügen Sie hier Ihren Code für die Benachrichtigungsbehandlungsroutine des Steuerelements hinzu
    }
    
  7. Fertig
Programmierecke.NET