Forum: PC-Programmierung MFC SDI View/Doc Architektur 2 Fenster


von A. R. (redegle)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe in der MFC mit der Voreinstellung SDI ein Programm 
programmiert, dass 2 verschiedene Fenster verwendet.

Hierbei habe ich mich von den folgenden Links inspirieren lassen.
http://msdn.microsoft.com/de-de/library/cc468015%28v=vs.71%29.aspx
http://www.codeguru.com/Cpp/W-D/doc_view/viewmanagement/article.php/c6121/

Um das ganze etwas zu verdeutlichen habe ich 2 Bilder angehangen.
Umgeschaltet wird über die Menüleiste.

Die eigendliche Frage bezieht sich auf das Speicherprinzip. Bei einer 
"normalen" SDI-Anwendung schreibt die Litertur vor, dass die 
Dokument-Klasse alle Daten speichert und die View-Klasse die Daten 
anzeigt.

Um aus der View-Klasse herraus auf die Daten der Dokument-Klasse 
zugreifen zu können gibt es folgenden Befehl:
1
CDocument* pDoc = GetDocument();

Bei meiner Applikation wird es nun später notwendig sein, das 
Einstellungen sozusagen global vorgenommen werden müssen. Also es ist 
notwendig, dass Daten zwischen den beiden View-Klasse ausgetauscht 
werden. Desweiteren werden mehrere Klassen angelegt auf die beide 
Fenster zugreifen müssen.

Frage 1: Wie kann ich das am sinnvollen realisieren?

Ich wollte es so machen, dass beide View-Klasse die selbe Doc-Klasse 
verwenden und ich in dieser alle Daten speicher auf die beide Fenster 
zugreifen müssen. In der Doc-Klasse würde ich dann z.B. weitere Klassen 
anlegen und beiden Fenstern einen Pointer auf diese Klasse übergeben.

Hierbei trat ein Problem auf. Für dieses sind 3 Klassen relevant.

CProjekt1Doc, CProjekt1View und CChartView
Die ersten beiden wurden von der Entwicklungsumgebung erstellt. Das 3te 
wird dynamisch während der Laufzeit erstellt (Links am Anfang).

In der .cpp von CProjekt1View kann ich mit folgender Funktion auf den 
Pointer von CProjekt1Doc zugreifen.
1
CProjekt1Doc* pDoc = GetDocument();

In der .cpp von CChartView kann ich nur auf einen "allgemeinen" Pointer 
der Klasse dokument zugreifen. Von hier müsste auch ein Zugriff auf 
CProjekt1Doc möglich sein.
1
CDocument* pDoc = GetDocument();

Gibt es eine Möglichkeit, auch in der .cpp Datei der Klasse CChartView 
auf den Pointer des Dokuments zuzugreifen?

Ich könnte nun etliche Sachen versuchen mit globalen Variablen oder ich 
könne der Klasse CChartView den Pointer von der Dokument-Klasse 
ausgehend mit einer Settermethode übergeben. Aber mich beschleicht die 
Frage ob ich nicht einen grundlegenden Fehler bei der MFC Struktur 
gemacht habe.

Bin für sämtlichen Ratschläge und Tipps sehr dankbar.

von MFC1 (Gast)


Lesenswert?

Beim Erzeugen eines View wird doch gewöhnlich ein CCreateContext* als 
einer der Parameter übergeben?! Wenn man nun 
CCreateContext::m_pCurrentDoc vorher mit dem Pointer zum Document 
initialisiert erhalten alle mit diesem CreateContext erzeugten Views das 
gleiche Dokument.

von A. R. (redegle)


Lesenswert?

Richtig,

genau das mache ich auch. Bzw. genau das macht das Programmfragment das 
ich von MSDN kopiert haben.

Das sieht dann so aus:
1
CCreateContext newContext;
2
newContext.m_pNewViewClass = NULL;
3
newContext.m_pNewDocTemplate = NULL;
4
newContext.m_pLastView = NULL;
5
newContext.m_pCurrentFrame = NULL;
6
newContext.m_pCurrentDoc = pCurrentDoc;
7
8
m_pNewView->Create(NULL, _T("AnyWindowName"), WS_CHILD, rect, m_pMainWnd, viewID, &newContext);

Nun ist es aber so, dass die von mir erstelle Klasse CChartView 
automatisch eine Methode GetDocument erstellt, welche als Rückgabewerte 
einen Pointer auf CDocument hat.
1
CDocument* pDoc = GetDocument();

Dieser Pointer zeigt natürlich auf mein Dokument. Aber mein Dokument hat 
eigendlich den Pointer CProjekt1Doc und nur wenn ich diesen Pointer 
verwende erkennt Intellitrace, dass die Klasse weitere von mir erstelle 
Attribute und Methoden hat. Das heißt also, dass ich eine Typeumwandlung 
machen muss.
1
CDocument* pDoc = (CProjekt1Doc*)GetDocument();

Das klappt auch. Nur sollte die Methoden GetDocument() schon direkt den 
passenden Pointer zurückliefern.

von Karl H. (kbuchegg)


Lesenswert?

A. R. schrieb:

>
>
1
> CDocument* pDoc = (CProjekt1Doc*)GetDocument();
2
>
>
> Das klappt auch. Nur sollte die Methoden GetDocument() schon direkt den
> passenden Pointer zurückliefern.

Kann sie nicht, denn GetDocument ist eine Memberfunktion, die deine 
Viewklasse von der Basisklasse CView geerbt bekommt.

Es ist ok, wenn du dir den Pointer entsprechend zurechtcastest. Was 
anderes macht der vom Wizzard generierte Code im anderen View auch 
nicht. Sinnvollerweise wirst du dir eine GetDocument Funktion in deine 
eigene Viewklasse machen, die diesen Cast verbirgt.

von Karl H. (kbuchegg)


Lesenswert?

> Ich wollte es so machen, dass beide View-Klasse die selbe
> Doc-Klasse verwenden und ich in dieser alle Daten speicher auf
> die beide Fenster zugreifen müssen.

Endlich mal jemand, der das Doc/View Prinzip kapiert hat.

Genau so macht man das:

 Im Document werden die Daten einer Anwendung gehalten und manipuliert.

 Die Views sind dafür zuständig diese Daten anzuzeigen, manipulieren
 die Daten selber aber nicht. Wohl aber können sie Befehlsempfänger
 von zb einem Menü oder einem Mausklick sein, welches dann den Befehl
 weiterreicht an das Document. Das Document führt die Manipulation durch
 und benachricht dann wiederrum alle Views, dass sich die Daten geändert
 haben.

von A. R. (redegle)


Lesenswert?

>Es ist ok, wenn du dir den Pointer entsprechend zurechtcastest. Was
>anderes macht der vom Wizzard generierte Code im anderen View auch
>nicht. Sinnvollerweise wirst du dir eine GetDocument Funktion in deine
>eigene Viewklasse machen, die diesen Cast verbirgt.

Danke für den Tipp.

>Endlich mal jemand, der das Doc/View Prinzip kapiert hat.

Danke das freut mich. Ich werde das also so realisieren. Wobei das zum 
Teil nicht ganz einfach ist Daten nicht von der VIEW-Klasse aus zu 
manipulieren. Ich habe zum Teil vor im Dokument mehrere Klasse 
anzulegen, welche Daten speichert. Diese Klasse verwaltet die Daten und 
von dem VIEWs ausgehend würde ich auf diese Klasse zugreifen. Aber im 
Endeffekt wird die eigendliche Änderung dann von den Klassen ausgeführt.

Im Moment bekomme ich nur noch ein Problem bei einem verschatelten 
inkludieren von Headern. Das kann ich aber spätestens heute Abend näher 
Erleutern.

von A. R. (redegle)


Angehängte Dateien:

Lesenswert?

Nun möchte ich gerne das Problem mit dem verschachtelten Includieren 
erklären. Vielleicht findet sich jemand der versteht was dort vorgeht. 
Vielleicht hilft es mir auch schon das hier ausführlich zu schildern.

Es existiert die Klasse Projekt1Doc

Projekt1Doc.h:
1
#pragma once
2
#include "Daten_abrufen.h"
3
#include "Mycug.h"
4
#include "CGraph.h"

Projekt1Doc.cpp:
1
#pragma once
2
// Projekt1Doc.cpp: Implementierung der Klasse CProjekt1Doc
3
//
4
5
#include "stdafx.h"
6
#include "Daten_abrufen.h"
7
// SHARED_HANDLERS können in einem ATL-Projekt definiert werden, in dem Vorschau-, Miniaturansichts- 
8
// und Suchfilterhandler implementiert werden, und die Freigabe von Dokumentcode für das Projekt wird ermöglicht.
9
#ifndef SHARED_HANDLERS
10
#include "Projekt1.h"
11
#endif
12
13
#include "Projekt1Doc.h"
14
15
#include <propkey.h>
16
17
#ifdef _DEBUG
18
#define new DEBUG_NEW
19
#endif

Wie zu sehen ist werden in dem Header "Projekt1Doc.h" 3 Header 
eingefügt. Hierbei handelt es sich um Klassen welche in der Headerdatei 
statisch erstellt werden.
1
MyCug m_grid;
2
CDaten_abrufen Daten_abrufen;
3
CGraph Graph;

Das Problem ist, dass sobald ich in dem Header "CGraph.h" den Header 
"Projekt1Doc.h" inkludiere bekomme ich 10 Fehlermeldungen (siehe 
Anhang).
Diese beziehen sich auf die letzte Zeile des Programmfragments.
1
MyCug m_grid;
2
CDaten_abrufen Daten_abrufen;
3
CGraph Graph;

von Karl H. (kbuchegg)


Lesenswert?

A. R. schrieb:

> Das Problem ist, dass sobald ich in dem Header "CGraph.h" den Header
> "Projekt1Doc.h" inkludiere bekomme ich 10 Fehlermeldungen (siehe
> Anhang).

Ist das jetzt ein Tippfehler?

Im Allgemeinen ist es nicht sinnvoll bzw. weißt des öfteren auf einen 
Fehler hin, wenn du einen Zirkelinclude baust.


a.h
1
*** File a.h
2
#include "b.h"
3
4
....


und
b.h
1
*** File b.h
2
#include "a.h"
3
4
....

braucht deine Graph Klasse wirklich Zugang zum Dokument? Warum braucht 
sie das? Du bindest damit die Graph Klasse an diesen einen speziellen 
Dokument Typ. Auf der anderen Seite ist Graph ein so schön allgemeiner 
Name, das ich mir nicht vorstellen kann, dass der an ein bestimmtes 
Dokument gekoppelt sein sollte.


Man kann allerdings so einen Zirkelinclude mit einer Forward-Deklaration 
durchbrechen. Eine Forward-Deklaration sagt nur aus: Es gibt eine Klasse 
mit einem bestimmten Namen, sagt aber nichts darüber aus, wie die Klasse 
aussieht (welche Member sie hat, etc). Das macht aber nichts, zur 
Deklaration eines Pointers reicht es aus, wenn der Compiler weiß, dass 
es den Klassennamen auch wirklich gibt. Wie groß ein Pointer darauf sein 
muss, weiß er ohnehin.


a.h
1
*** File a.h
2
#include "b.h"
3
4
class MyClassA
5
{
6
  public:
7
    void foo( MyClassB * pPointerToB );
8
};


und
b.h
1
*** File b.h
2
3
class MyClassA;    // es gibt eine Klasse namens MyClassA
4
5
class MyClassB
6
{
7
  public:
8
    void foo( MyClassA * pPointerToA );
9
};

Ich würd mir aber trotzdem besser überlegen, ob und wozu ein Graph 
Objekt Kentniss vom Document haben soll.

von Karl H. (kbuchegg)


Lesenswert?

A. R. schrieb:

> Teil nicht ganz einfach ist Daten nicht von der VIEW-Klasse aus zu
> manipulieren.

Kommt drauf an, was du exakt unter "manipulieren" verstehst. Natürlich 
darf ein View sein Document befragen um zb einen Mausklick zuordnen zu 
können.
Es spricht auch nichts dagegen, wenn der View einen Mausklick erst mal 
in Dokument-gerechte Koordinaten umrechnet und dann dem Document 
aufträgt, zum Datenwert, der zu diesen Koordinaten gehört, 100 
dazuzuzählen.
Es kann auch sein, dass das Dokument für jeden Datenpunkt eine 
Identifikation bereitstellt (eindeutige Nummer), die der View irgendwie 
benutzt um damit einen Mausklick wieder dem Datenpunkt zuordnen zu 
können.
Oder ....

Die Möglichkeiten sind da vielfältig. Wo ein Wille da auch ein Weg. Aber 
im Prinzip läuft es immer aufs gleiche raus: Der View identifiziert 
welchen Daten ein Mausklick entspricht und fordert das Document auf, den 
Datensatz mit dieser Identifikation dieser und jener Manipulation zu 
unterziehen.

> anzulegen, welche Daten speichert. Diese Klasse verwaltet die Daten und
> von dem VIEWs ausgehend würde ich auf diese Klasse zugreifen. Aber im
> Endeffekt wird die eigendliche Änderung dann von den Klassen ausgeführt.

Ja, ist doch super.
Der View fragt in seiner OnPaint Methode das Document nach den Klassen 
und benutzt die Werte, die er von denen bekommt um die Anzeige zu 
erzeugen.

von A. R. (redegle)


Lesenswert?

Erst einmal vielen vielen Dank für die Mühe,

aber ich befürchte, dass ich jetzt ein paar etwas dumme Fragen stelle. 
Also ich hoffe, dass du die Geduld mit mir nicht verlierst.

Ich verwende z.B. die Bilbiothek Ultimate Grid.

http://www.codeproject.com/KB/MFC/UltimateGrid_FAQ.aspx

Dies ist ein Art kleine Datenbank mit Oberfläche ähnlich wie in Excel. 
Man kann einzelnen Zeilen und Spalten Werte zuweisen und auch wieder 
abfragen, Spalten und Zeilen verschieben, austauschen ...

Die Klasse erstelle ich im Dokument.
1
MyCug m_grid;
Später führe ich dann in einer VIEW-Klasse im OnCreate folgenden 
Programmcode aus.
1
pDoc->m_grid.CreateGrid( WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, ID_GRID );
sowie
1
void CProjekt1View::OnSize(UINT nType, int cx, int cy)
2
{
3
  CView::OnSize(nType, cx, cy);
4
  CProjekt1Doc* pDoc = GetDocument();
5
  pDoc->m_grid.MoveWindow( 0, 0, cx, cy );
6
}

Dadurch, dass ich der Klasse MyCug den this Pointer des VIEWs übergeben 
habe ist diese Klasse in der Lage in meinem VIEW zu zeichnen. Dies wird 
auch getan ohne das ich in der OnDraw Methode eine Methode der Klasse 
aufrufen muss. Die Klasse ist auch in der Lage Tastendrücke sowie 
Aktionen mit der Maus zu erkennen, so dass in dieser Klasse Funktionen 
ergänzt werden könne die auf Perepherie reagieren.
Gleichzeitig werden in der Klasse aber auch alle Daten wie Zeilenbreite, 
Zeilenhöhe, Inhalt der Felder etc. gespeichert.
Das bedeutet doch quasi, dass diese Bibliothek das View/Doc Prinzip 
verletzt!? (Wie das mit der Abfrage der Perepherie und dem fehlenden 
OnDraw Aufruf funktioniert weiß ich noch nicht würde ich aber später 
gerne durch reverse engineering herausbekomme)

Ich wollte diese Bibliotheksfunktion in so weit Verwenden, dass ich 
später auch die Daten in der Bibiothek abfrage (Daten sind nicht im 
Dokument).
Sprich über die Symbolleiste wird eine Funktion aufgerufen die 
Informationen über mehrere Dateien auf der Festplatte sammelt und in die 
Datenbank schreibt. Auf diese Daten soll später zugegriffen werden 
(Daten sind nicht im Dokument sondern in einer Klasse, die wiederum im 
Dokument ist aber auch das Zeichen übernimmt).


So ähnlich wollte ich auch meine Klasse CGraph aufbauen. Also der Klasse 
CGraph hätte ich den Pointer auf eine Viewobjekt übergeben, sodass die 
Klasse CGraph in dem View-Fenster zeichnen kann. Gleichzeitig hätte ich 
aber auch die zu zeichnenden Daten an die Klasse CGraph übergeben 
(CGraph verfügt später über eine Kettenliste mit der sich weitere 
Funktionsverläufe ergänzen lassen). Dies hätte den Vorteil, dass ich die 
Klasse CGraph später auch für andere Projekte verwenden kann.

Ich hoffe das war einigermaßen verständlich formulier. Manchmal reicht 
schon eine unterschiedliche Wortwahl um aneinander vorbeizuredn.

Dieser Aufbau bereitet mir auch das Problem mit dem verschachtelten 
Inkludieren. Die Klasse CGraph wird im Dokument erstellt soll aber 
später auch über das Dokument in der Lage sein auf die Datenbank 
zuzugreifen. Also muss das Dokument die Klasse kennen um diese erstellen 
zu können und gleichzeitig muss die Klasse das Dokument kennen um auf 
anderen Klassen in diesem zugreifen zu können.

Das Problem könnte man wahrscheinlich mit einer Forward-Deklaration 
durchbrechen, da das Dokument vorerst nicht wissen muss welche Methoden 
und Attribute die Klasse CGraph hat.

von MFC1 (Gast)


Lesenswert?

Das Nachvollziehen solcher Gedankengänge ist sehr mühsam. Deshalb diesen 
Tipp: Stell dir einfach vor du hast zur gleichen Zeit zwei identische 
Views offen, die mit dem einen Dokument arbeiten. Z.B. durch ein 
CSplitterWnd oder CTabCtrl realisiert. Auch in dieser Konfiguration muss 
das funktionieren.

Das Grid deiner Applikation erscheint mir unter dieser Betrachtung mehr 
als ein visuelles Element, gehört also ins View, nicht ins Dokument. Ins 
Dokument gehört ein mehrdimensionales Daten-Array, welches nach jeder 
Änderung im Grid aktualisiert wird.

von Karl H. (kbuchegg)


Lesenswert?

MFC1 schrieb:
> Das Nachvollziehen solcher Gedankengänge ist sehr mühsam. Deshalb diesen
> Tipp: Stell dir einfach vor du hast zur gleichen Zeit zwei identische
> Views offen, die mit dem einen Dokument arbeiten. Z.B. durch ein
> CSplitterWnd oder CTabCtrl realisiert. Auch in dieser Konfiguration muss
> das funktionieren.
>
> Das Grid deiner Applikation erscheint mir unter dieser Betrachtung mehr
> als ein visuelles Element, gehört also ins View, nicht ins Dokument. Ins
> Dokument gehört ein mehrdimensionales Daten-Array, welches nach jeder
> Änderung im Grid aktualisiert wird.

So würde ich das Prinzipiell auch sehen.

Glücklicherweise haben die Designer mitgedacht und das ganze dort 
2-geteilt: Das eine ist der Grid, der die Anzeige und das Handling macht 
(also im Prinzip der View) und das andere ist die Datasource, die die 
Daten hält. Und schon sind wir wieder bei Doc/View

Ich stell mir bei solchen Dingen meistens einfach vor
* ein View zeigt die Daten grafisch an
  Balkendiagramm, Tortendiagramm, wie auch immer
* der andere in Tabellenform


> So ähnlich wollte ich auch meine Klasse CGraph aufbauen. Also der
> Klasse CGraph hätte ich den Pointer auf eine Viewobjekt übergeben,
> sodass die Klasse CGraph in dem View-Fenster zeichnen kann.

Kann man so machen.
Aber: entscheidet wirklich die CGraph Klasse (die, wenn ich das richtig 
verstanden habe, die Daten hält), WIE die Daten darzustellen sind.
Oder ist es nicht eher so, dass der View eigentlich wissen sollte wie er 
die Daten darstellen soll? Er holt sich vom Dokument die Daten in Form 
eines Zugangs durch ein CGraph Objekt und holt sich dann aus diesem die 
Werte, die er für eine Darstellung benötigt.

Diese Grid Klasse ist aber schon recht heftig (wie die meisten 
derartiger Grids) und ich bin mir nicht sicher, ob das für einen MFC 
Neuling, der sich das erste mal an MFC wagt, überhaupt sinnvoll ist. 
Wenn ich dein Lehrer wäre, würde ich dir einen CFormView unterjubeln, wo 
du das GUI mit 2 Buttons (Add, Delete), ein paar Edit-Boxen und einem 
CListView Control realisieren sollst.
Also Vorübung das ganze mal 2-geteilt
  der View zeigt das ganze grafisch an und zum Ändern der Daten klickt
  der Benutzer in der Toolbar auf einen Button (oder wählt einen Menü-
  eintrag) woraufhin sich ein Dialog öffnet, der mit den genannten
  Elementen die Eingabe und Manipulation der Daten erlaubt. (Denn dann
  hat man die wichtigsten Dinge in einer App: Doc/View, Einstelldialoge,
  Toolbars + Menüs)

Dann machen wir erst mal unsere Hausaufgaben
* Datei speichern
* Datei speichern unter
* Datei lesen
* Document modified Flag
* wie geht das, dass sich Controls in einem Dialog gegenseitig
  sperren oder freigeben, je nach Benutzerinteraktion und Daten-
  situation
* App soll sich ihre letzte Einstellung/Größe/Position merken: Registry
* Daten/Bild in die Zwischenablage
* Daten/Bild drucken
* ...


und dann geht es los sich damit zu beschäftigen, wie man den Dialog los 
werden kann. Ein 2-ter View ist nur eine Möglichkeit. Denkbar ist auch, 
dass der View seinen Anzeigemodus umschalten kann, oder die 
Änderungselemente in ihn integriert werden, oder er gesplittet wird oder 
für die Anzeige ein eigenes Zeichen-Control implementiert wird, welches 
auf den FormView geschoben wird, ...

Da gibts viele Varianten. Aber sich gleich mal einem fremden Control 
auszuliefern, find ich nicht gut im Hinblick auf das Lernen wie man mit 
der MFC arbeitet bzw. wie Document/View funktioniert. Woher weißt du 
denn, wonach du (zb zur Beurteilung ob du es überhaupt verwenden willst) 
in der Doku suchen sollst, wenn du nicht weißt, wie typische Dinge in 
der MFC (zb Drucken, Daten speichern) funktionieren und MFC konform 
angebunden werden.

Du merkst schon: Ich bin ein Verfechter der Schule "Wer 
CNC-Programmierer werden will, muss trotzdem lernen mit einer Feile 
umzugehen"

von A. R. (redegle)


Lesenswert?

Danke für die Hilfe,

nachdem ich mir die halbe Woche noch sehr viele Gedanken über die 
Strukturierung gemacht habe bin ich zu dem Entschluss gekommen, dass ich 
meine Klasse zum Zeichnen des Charts in 2 oder 3 Klassen aufgliedere.

Eine Klasse wird die ganzen Daten halten und sich im Dokument befinden. 
Die andere Klasse erstellt die gesamte Visuallisierung und befindet sich 
im View. Dies ermöglicht es theoretisch, dass ich der Klasse im View 
einen anderen Objektpointer aus dem Dokument übergebe und das View dann 
andere Daten visualisieren kann bzw. ander Optionen erhält. Dies ist 
zwar nich notwendig, währe aber theoretisch möglich.

>Glücklicherweise haben die Designer mitgedacht und das ganze dort
>2-geteilt: Das eine ist der Grid, der die Anzeige und das Handling macht
>(also im Prinzip der View) und das andere ist die Datasource, die die
>Daten hält. Und schon sind wir wieder bei Doc/View

Das kann durchaus sein, dass eine solche Unterteilung intern gemacht 
worden ist. Aber nach außen hin wird nur eine Klasse eingefügt. Diese 
soll sich laut Anleitung im VIEW befinden. Dies macht auch Sinn, solange 
die Klasse nur zum Anzeigen von Daten verwendet wird. Jedoch ermöglicht 
die Klasse es auch Daten über das VIEW zu ändern. Diese Änderung der 
Daten bezieht sich dann jedoch auf die Daten, welche in der Ultimate 
Grid Klasse gespeichert sind. Wenn ich das Doc/View Konzept verstehe 
dürften nur Daten verändert werden die sich im Dokument befinden. Da 
dies nicht eingehalten wird kann eine andere VIEW Klasse nicht über das 
Dokument auf die geänderten Daten zugreifen. Es muss ein Zugriff auf die 
VIEW Klasse mit dem Ultimate Grid OBjekt erfolgen.
Dies lässt sich dann so umgehen, dass man den Dokument den Pointer zu 
dem Ultimate Grid Objekt übergibt.

>Diese Grid Klasse ist aber schon recht heftig (wie die meisten
>derartiger Grids) und ich bin mir nicht sicher, ob das für einen MFC
>Neuling, der sich das erste mal an MFC wagt, überhaupt sinnvoll ist.

Das ganze ist sehr gut dokumentiert. Also bis jetzt bin ich ganz gut 
zurecht gekommen. Also das Einfügen von Zeilen, Spalten, Formatierung 
der Felder (Text und Hintergrundfarbe sowie Schriftart...) klappt schon. 
Habe auch nicht erst gestern damit angefangen sondern eher November 
2011. Ich gehe auch davon aus, dass ich später den Code noch abändern 
muss, da ich jetzt noch nicht überschauen kann welcher Ansatz am besten 
ist. Gerade wegen fehlenden Kenntnissen.

>Du merkst schon: Ich bin ein Verfechter der Schule "Wer
>CNC-Programmierer werden will, muss trotzdem lernen mit einer Feile
>umzugehen"

Macht auch durchaus Sinn! Ich habe auch zuerst angefangen mehrere 
Tutorials durchzuarbeiten. Das Problem ist nur, dass das zum Teil sehr 
anstrengen ist wenn keiner da ist den man Fragen kann. Viele Tutorials 
haben auch nur sehr simple gehalten Beispiele und lassen sehr viele 
Fragen offen.

>Dann machen wir erst mal unsere Hausaufgaben
>* Datei speichern
>* Datei speichern unter
>* Datei lesen
>* Document modified Flag
>* wie geht das, dass sich Controls in einem Dialog gegenseitig
>  sperren oder freigeben, je nach Benutzerinteraktion und Daten-
>  situation
>* App soll sich ihre letzte Einstellung/Größe/Position merken: Registry
>* Daten/Bild in die Zwischenablage
>* Daten/Bild drucken
>* ...

Das ist eine sehr schöne Auflistung.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.