Home Course Index C3 Code Comments C3 FAQs

Course 2D_MFC: 2D-Computer Graphics with C++/MFC
Chapter C3: The Animation Project


Copyright © by V. Miszalok, last update: 25-09-2002

Mail me...
Let me know
what you think
  Projekt anim1 mit leerem Fenster
  Präprozessorbefehle und Deklarationen in ChildView.h
  Behandlungsroutinen für Windows-Nachrichten
  Einfügen von Code
  Experimente
  Vereinfachungen
  Weitere Aufgaben

Projekt anim1 mit leerem Fenster

Microsoft Visual Studio starten
File – New – Project – Project Types: Visual C++ Projects, Templates: MFC Application
Name: anim1
Location: C:\temp
Button OK unten Mitte klicken
Es meldet sich der MFC Application Wizard - anim1 mit der Seite Overview, die uninteressant ist.
Links unter Overview auf Application Type klicken.
Schritt1: Single document einschalten
Schritt 2: Document/View architecture support Checkbox ausschalten
Schritt 3: Finish     Visual Studio legt nun unter C:/temp ein Directory anim1 an und schreibt dorthin jede Menge Files, die insgesamt das Projekt anim1 bilden.
Klicken Sie Debug in der Menü-Zeile oberhalb des Hauptfensters
Es öffnet sich ein Untermenü. Klicken Sie auf Start Without Debugging Ctrl F5
Es erscheint eine Message Box: These project configuration(s) are out of date: anim1 - Debug Win 32. Would you like to build them ?
Sie antworten mit Yes

Falls alles ok, dann anim1.exe erst beenden, bevor der erste Code eingegeben wird !

 

Präprozessorbefehle und Deklarationen in ChildView.h

Klicken Sie im Hauptmenu von Visual Studio auf den Menupunkt View und dann auf den Unterpunkt Class View Ctrl+Shift+C.
Sie sehen im rechten Bereich des Visual Studio-Hauptfensters das Unterfenster Class View - draw1.
An dessen unteren Rand die Registerkarte Klassen klicken.
Darin sehen Sie die Zeile + anim1 , klicken Sie das Pluszeichen.
Sie sehen u.a. + CChildView, doppelklicken Sie diesen Klassennamen.
Sie editieren jetzt das File ChildView.h, Schreiben Sie dort vor die Klasse class CChildView : public CWnd am besten unter die Zeile #pragma once die Präprozessoranweisungen:

#define nMax 100
#include < math.h >

Schreiben Sie in die Klasse direkt unter die sich öffnende geschweifte Klammer noch vor //Construction die Deklarationen:

private:
   CPoint old_vertex, m;
   CPoint p[nMax];
   typedef struct { float x; float y; } FPoint;
   FPoint f[nMax];
   int n, t;
   BOOL done;
   CRect minmax;
   float zoom, sinus, cosinus;

Sie sehen nun diese Member-Variablen im Klassenbaum von CChildView im rechten ClassView - anim1 - Fenster, wenn Sie das Pluszeichen vor CChildView klicken.

 

Behandlungsroutinen für Windows-Nachrichten

Klicken Sie im Klassenbaum von CChildView mit der rechten Maustaste auf CChildView ( nicht verwechseln mit dem gleichnamigen Konstruktor CChildView(void) ).
Es öffnet sich ein Kontextmenü. Klicken Sie ganz unten im Kontextmenü auf Properties.
Es öffnet sich unter dem Class View - draw1 - Fenster ein Properties - Fenster mit der Überschrift CChildview VCCodesClass.
Im Toolbar dieses Fensters klicken Sie rechts neben dem gelben Blitz auf das Messages - Symbol, das aussieht wie ein weißer Topf mit blauem Deckel.
Sie sehen nun die Liste der Windows-Messages von CChildView.
Klicken Sie auf WM_CREATE      und dann auf das schwarze Abwärtsdreieck rechts in dieser Zeile und dann auf Add OnCreate.
Klicken Sie auf WM_LBUTTONDOWN und dann auf das schwarze Abwärtsdreieck rechts in dieser Zeile und dann auf Add OnLButtonDown.
Klicken Sie auf WM_MOUSEMOVE   und dann auf das schwarze Abwärtsdreieck rechts in dieser Zeile und dann auf Add OnMouseMove.
Klicken Sie auf WM_LBUTTONUP   und dann auf das schwarze Abwärtsdreieck rechts in dieser Zeile und dann auf Add OnLButtonUp.
Klicken Sie auf WM_TIMER       und dann auf das schwarze Abwärtsdreieck rechts in dieser Zeile und dann auf Add OnTimer.
Sie sehen nun u.a. die Methoden OnCreate(...), OnLButtonDown(..), OnMouseMove(..), OnLButtonUp(..) und OnTimer(...) im Klassenbaum von CChildView, und Sie sehen die fünf fast leeren Funktionsrümpfe in CChildView.cpp, die Visual Studio automatisch generiert hat.
Die ziemlich leeren Funktionshülsen stehen in ChildView.cpp unterhalb der fertigen Funktion void CChildView::OnPaint(). Verschieben Sie die Funktionshülsen samt Inhalt und geschweiften Klammern per Drag und Drop so, dass diese eine logisch vernünftige Reihenfolge bilden (das ist wichtig für den Überblick).

BOOL CChildView::PreCreateWindow(...)
int CChildView::OnCreate(...)
void CChildView::OnPaint()
void CChildView::OnLButtonDown(...)
void CChildView::OnMouseMove(...)
void CChildView::OnLButtonUp(...)
void CChildView::OnTimer(...)

 

Einfügen von Code

Doppelklicken Sie im Klassenbaum auf OnCreate(...). (oder gehen Sie direkt in den Code in die Funktion void CChildView::OnCreate(...)). Ändern Sie die Funktion bis sie so aussieht:

int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{   if (CWnd ::OnCreate(lpCreateStruct) == -1) return -1;//from Microsoft
    done = false;
    zoom = 0.995f;
    double arcus = 3.14159 / 180.;
    sinus   = float( sin( arcus ) );
    cosinus = float( cos( arcus ) );
    SetTimer( 1, 1, NULL );
    return 0;
}

Füllen Sie die anderen Funktionen nach diesem Muster, bis sie so aussehen:

void CChildView::OnPaint()
{   CPaintDC dc(this);
    dc.TextOut( 0, 0, "Press the left mouse button and draw something !");
}
void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{   done = false;
    old_vertex = p[0] = point;
    n = t = 1;
    Invalidate();
}
void CChildView::OnMouseMove(UINT nFlags, CPoint point)
{   if ( !nFlags ) return;
    int dx = point.x - old_vertex.x;
    int dy = point.y - old_vertex.y;
    if ( dx*dx + dy*dy  < 100 ) return;
    if ( n > nMax - 2 ) return;
    CClientDC dc( this );
    dc.MoveTo( old_vertex ); dc.LineTo( point );
    old_vertex = p[n++] = point;
}
void CChildView::OnLButtonUp(UINT nFlags, CPoint point)
{   // minmax = surrounding rectangle
    minmax.left = minmax.right  = p[0].x;
    minmax.top  = minmax.bottom = p[0].y;
    for ( int i = 1; i < n; i++ )
    {   int x = p[i].x;
        int y = p[i].y;
        if ( x < minmax.left   ) minmax.left   = x;
        if ( x > minmax.right  ) minmax.right  = x;
        if ( y < minmax.top    ) minmax.top    = y;
        if ( y > minmax.bottom ) minmax.bottom = y;
    }
    m.x = ( minmax.left + minmax.right )/2;
    m.y = ( minmax.top + minmax.bottom )/2;
    for ( i = 0; i < n; i++ )
    {   f[i].x = float(p[i].x - m.x);
        f[i].y = float(p[i].y - m.y);
    }
    done = true;
}
void CChildView::OnTimer(UINT nIDEvent)
{   if ( !done ) return;
    int i, ix, iy, ixmax=m.x, ixmin=m.x, width;
    CClientDC dc (this );
    for ( i = 0; i < n; i++ )
    {   float x = f[i].x * zoom;
        float y = f[i].y * zoom;
        f[i].x = cosinus * x - sinus * y;
        f[i].y = sinus * x + cosinus * y;
        ix = int(f[i].x) + m.x;
        iy = int(f[i].y) + m.y;
        if ( !i ) dc.MoveTo( ix, iy );
        else      dc.LineTo( ix, iy );
        if ( ix < ixmin ) ixmin = ix;
        if ( ix > ixmax ) ixmax = ix;
    }
    width = ixmax - ixmin;
    CRect r; GetClientRect( r );
    if ( width > r.right - r.left ) { MessageBeep(-1); Invalidate(); zoom = 0.95f; };
    if ( width < 20               ) { MessageBeep(-1); Invalidate(); zoom = 1.05f; };
    CString blabla;
    blabla.Format("Timer=%d, Width=%d, Zoom=%f    ", t++, width, zoom );
    dc.TextOut( 0,20, blabla );
}

anim1 ist damit fertig, ausführen, erproben, beenden.

 

Experimente

Beenden Sie anim1.
Untersuchen Sie folgende Methoden zur Verlangsamung der Animation:
1. Setzen Sie den 2. Parameter von SetTimer von 1 Millisekunde auf 500 Millisekunden.
2. Setzen Sie die Zahl der Vertices hoch: Arrays länger machen + Mindestabstand auf 1.
3. Setzen Sie die beiden Zooms von 5 Prozent auf 5 Promille (von 0.95 / 1.05 auf 0.995 / 1.005).
4. Setzen Sie den Drehwinkel auf 1/2 Grad und niedriger.
5. Setzen Sie die maximale Breite des Polygons hoch auf 2*(r.right - r.left).
6. Setzen Sie die minimale Breite des Polygons herab auf 1.
7. Ändern Sie die Drehrichtung durch vertauschen der Vorzeichen vor den beiden sinus - Konstanten in OnTimer(...).

 

Vereinfachungen

Vereinfachen Sie das Programm, indem Sie das Malen mit der Maus ganz weglassen und ein festes Dreick, Viereck etc. vorprogrammieren. Experimentieren sie mit anderen Umkehrbedingungen für den Zoom.

 

Weitere Aufgaben

Klicken Sie auf Help in der Menüleiste von Visual Studio. Klicken Sie auf das Untermenü Index.
Suchen Sie die Schlüsselwörter der Ihnen unbekannten Sprachelemente. Lesen Sie die Hilfetexte.
Beenden Sie Visual Studio, starten sie den Explorer, löschen Sie die gesamte Directory C:\temp\anim1
Starten Sie Visual Studio wieder und erzeugen dasselbe Programm so oft, bis Sie das Programm ohne Anleitung und schnell von Null an erstellen, verändern und bedienen können.
Erfinden und erproben Sie neue Varianten des Programms.

top of page: