Forum: PC-Programmierung Visual C++ untergeordnete Fenster


von Sebastian (Gast)


Angehängte Dateien:

Lesenswert?

Hey,
ich bin auf dem Gebiet der Oberflächen Programmierung unter Visual C++ 
leider noch ein totaler Neuling.
Leider muss ich nun für ein Projekt "schnell" eine Oberfläche 
programmieren.

Das Problem liegt nun darin, das ich ein Hauptfenster habe und im 
Arbeitsbereich des Hauptfenster sollen 3 untergeordnete Fenster 
verschiedene Auswertungen darstellen.
Nun hab ich die untergeordneten Fenster als nicht-modale Dialoge 
eingefügt, was soweit auch funktioniert. Nur leider kann ich diese 
Dialoge natürlich auf dem kompletten Desktop nach Lust und Laune 
verschieben.
Die Dialoge sollten aber nur im Arbeitsbereich des Hauptfensters 
verschiebbar sein.

Mein zweiter Ansatz bestand darin, eine Klasse von "generic CWnd" 
abzuleiten und dadurch meine Unterfenster zu realisieren. Funktioniert 
auch wunderbar, so wie ich es eigetnlcih haben wollte. Hier besteht halt 
das Problem darin, das ich dann 2 leere Unterfenster hab und ich nicht 
weiß wie ich die jetzt "befüllen" kann. Also wie ich die jeweiligen 
Steuerelemente auf das jeweilige Fenster bekomm.

Ich hab die Oberfläche mal mit Visio so in etwa nachgestellt und ein 
Bild als Anhang angehängt.

Vielen Dank schonmal

von Karl H. (kbuchegg)


Lesenswert?

Sebastian wrote:

> Das Problem liegt nun darin, das ich ein Hauptfenster habe und im
> Arbeitsbereich des Hauptfenster sollen 3 untergeordnete Fenster
> verschiedene Auswertungen darstellen.

Ich denke mal, du bist auf der Suche nach einem CSplitterWnd.
Damit kannst du den einen View, den du hast, in mehrere Bereiche
aufteilen und in jedem Bereich was anderes anzeigen.

Fang hier mal mit der Recherche an.
http://msdn2.microsoft.com/en-us/library/1d7781f1(VS.80).aspx

von Sebastian (Gast)


Lesenswert?

danke mal, werd ich dann morgen im geschäft recherchieren gehn
jetzt hab ich aber erstmal feierabend ^^

von Markus V. (valvestino)


Lesenswert?

Hi Sebastian,

das Stichwort, nach dem Du bei MS 
(http://search.msdn.microsoft.com/Default.aspx?locale=de-DE) suchen 
mußt, ist MDI (Multiple Document Interface).

Gruß
Markus

von Sebastian (Gast)


Lesenswert?

Kann ich mit MDI dann auch verschiedenen "Dokumente" einfügen oder 
einfach von einem mehrere Instanzen?
Hab bisher noch leider auch in msdn nichts gefunden.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian wrote:
> Kann ich mit MDI dann auch verschiedenen "Dokumente" einfügen

Ja.
MDI heist ja "Multiple Document Interface"

Die Applikation kann also mehrere Dokumente gleichzeitig
geöffnet haben und von jedem Dokument gleichzeitig mehrere
Views offen haben. Diesen Teil erledigt der Wizard selbsttätig.
Wenn dann auch noch verschiedenartige Views (also zb einmal
eine Tabellenansicht und einmal eine Grafik) für dasselbe
Dokument angezeigt werden sollen, dann muss man allerdings
selbst Hand anlegen.

von Sebastian (Gast)


Lesenswert?

Irgendwie komm ich damit immernoch nicht zurecht.
Ich erstell eine MDI-Anwendung mithilfe des Assistenten, dieser erstellt 
mir fünf Klassen ( CAboutDlg; CChildFrame; CChildFrame; CTestApp; 
CMainFrame).

Der Assistent erstellt ja für das Menü schon die Funktion in der neue 
Dokumente erstellt werden, diese funktioniert. Der Code dafür sieht so 
aus.


+-+-+-+-+-+-+-+-CODE-+-+-+-+-+-+-+-+-+-+-+

CMainFrame* pFrame = STATIC_DOWNCAST(CMainFrame, m_pMainWnd);
// Neues untergeordnetes MDI-Fenster erstellen
pFrame->CreateNewChild(
RUNTIME_CLASS(CChildFrame), IDR_KGTESTTYPE, m_hMDIMenu, m_hMDIAccel);

+-+-+-+-+-+-+-+-CODE-+-+-+-+-+-+-+-+-+-+-+


Das Problem ist das CChildFrames "leere" Dokumente sind. Also erstelle 
ich durch Rechtsklick auf den Klassenbaum ein "Neues Formular" und nenn 
es mal CTestFrame, als Basisklassen wähle ich CFormView. Wie schaffe ich 
es nun, das bei einem Klick auf "New" kein "leeres" CChildFrame erzeugt 
wird, sondern eines meiner CTestFrames?

Grüße Sebastian

von Sebastian (Gast)


Lesenswert?

Ok jetzt tuts komischerweise. Nun kann ich bei einem Klick auf "New" 
auswählen was er mir erstellen soll. Obwohl ich nun nichts weiter 
gemacht hab als das "Neue Formular" eingefügt. Also keine Ahnung warum 
aber wenigstens tuts jetzt

von Sebastian (Gast)


Lesenswert?

Weiß jmd wie ich den Anfangsdialog, in dem ich die verschiedenen 
Dokumente auswählen kann, größer darstellen kann? Leider zeigt der nur 
die Hälfte meiner Dokumentennamen an.
Dann noch ne Frage. Wenn ich auf "New" klicke, dann kann ich meine 
Dokumente auswählen aber auch noch das "leere" Anfangsdokument. Wie kann 
ich das aus der Liste löschen? Die werden ja irgendwie in ner 
TemplateList angemeldet und diese Liste wird in dem Dialog dargestellt. 
Leider finde ich den Eintrag für die Registrierung in der TemplateListe 
nicht.

von Sebastian (Gast)


Lesenswert?

Ok das mit der TemplateList hat sich erledigt, wäre nur noch das Problem 
mit der Größe.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian wrote:
> Ok das mit der TemplateList hat sich erledigt, wäre nur noch das Problem
> mit der Größe.

Das ist ein bischen tricky.

Aber wie hab ich die Dinge rausgefunden?

Ausgangspunkt der ganzen Chose mit der MFC ist immer, dass
du ja den Quelltext der MFC auf der Platte hast.

Nun weiss ich, dass die Aktion mit einem Menüpunkt beginnt.
Das Menü schickt eine Message an die Applikation, die dort
unter Umständen wieder weiter verteilt wird.
Im konkreten Fall ist es eine ID_FILE_NEW Benachrichtigung, die
abgeschickt wird.
Die fange ich als erstes mal auf, indem ich den Wizard in die
Applikation einen Menühandler für ID_FILE_NEW einbauen lasse.
In diesem Handler rufe ich dann ganz einfach die Funktion
der Basisklasse auf. In meinem Beispiel war das

void CFensterApp::OnFileNew()
{
  CWinApp::OnFileNew();
}

Sinn der Sache ist es einen Angriffspunkt zu bekommen, an dem ich
einfach mit dem Debugger einen Breakpoint installieren kann. Ein
eigener Menühandler ist wesentlich schneller installiert, als sich
die Funktion CWinApp::OnFileNew() zu suchen.

Jetzt lasse ich das Pgm (mit dem Breakpoint) laufen und steppe
von dort ausgehend in die MFC hinein. CWinApp::OnFileNew() delegiert
sofort an den Document Manager und nach ein paar Schritten erzeugt
der einen CNewTypeDlg. Dort mal in den Konstrukor hineingesteppt und
schon sieht man, dass dieser Dialog eine Dialog-resource mit der Id
AFX_IDD_NEWTYPEDLG benötigt.

Als: Programm gestoppt und einen entsprechenden Dialog erzeugt und dem
als Id AFX_IDD_NEWTYPEDLG zugeordnet.

Programm neu gestartet und es kommt eine Assertion. An der Stelle
an der die Assertion ausgelöst wird, sehe ich, dass der Dialog nach
einer Listbox mit der Id AFX_IDC_LISTBOX im Dialog sucht. Die hab ich
natürlich in meinem Dialog noch nicht, ist aber kein Problem.

Im Resourceeditor eine Listbox im Dialog erzeugen und der die Id
AFX_IDC_LISTBOX verpassen.

Programm erneut starten und .... der angezeigte Dialog ist meiner
und in der Listbox stehen auch die Dokument Templates drinnen.

Zusammengefasst:
Neuen Dialog erzeugen. Dem eine ID von AFX_IDD_NEWTYPEDLG geben
Auf dem Dialog eine Listbox mit der Id AFX_IDC_LISTBOX platzieren.
Fertig.

Den Rest hab ich dir nur erzählt, damit du siehst wie man solche
Dinge in der MFC in kurzer Zeit finden kann.

von Sebastian (Gast)


Lesenswert?

Oh vielen Dank für die Mühe. Werd das gleich probieren. Dein Ansatz zum 
rausfinden der Problem Ursachen ist wirklich hilfreich. Hab das auch 
schon  mit debuggen probiert rauszufinden aber da die richtige Stelle 
für nen Breakpoint zu finden ist echt kacke.

von Sebastian (Gast)


Lesenswert?

hmmmmm.....nun wird mein Dialog zwar verwenden, aber die Titel werden 
immernoch abgeschnitten. Es werden immer genau 6 Zeichen angezeigt, der 
Rest fehlt.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian wrote:
> hmmmmm.....nun wird mein Dialog zwar verwenden, aber die Titel werden
> immernoch abgeschnitten. Es werden immer genau 6 Zeichen angezeigt, der
> Rest fehlt.

Schau mal in den Resourcen in die Stringtabelle.
Einer der ersten Einträge in der Stringtabelle (irgendwas mit IDR_xxxx)
enthält die Texte.
Bei mir sieht der so aus:
IDR_FENSTETYPE    129  \nFenste\nFenste\n\n\nFenster.Document\n....

Der 2-te Text ist der Text, der im Dialog angezeigt wird. Du kannst
ihn ändern:

IDR_FENSTETYPE    129  \nFenste\nMein tolles Fenster\n\n ...

und der Dialog zeigt daraufhin den korrekten Text an.
Keine Ahnung warum dort nur 6 Zeichen hinterlegt wurden. War wohl
wieder irgendeine Idee eines MS Mitarbeiters.


Die Reihenfolge der Einzeltexte (aus AFXWIN.H), offensichtlich durch
\n getrennt, ist
1
  windowTitle,        // default window title
2
  docName,            // user visible name for default document
3
  fileNewName,        // user visible name for FileNew
4
                      // for file based documents:
5
  filterName,         // user visible name for FileOpen
6
  filterExt,          // user visible extension for FileOpen
7
                      // for file based documents with Shell open support:
8
  regFileTypeId,      // REGEDIT visible registered file type identifier
9
  regFileTypeName,    // Shell visible registered file type name

von Sebastian (Gast)


Lesenswert?

Ok so funktioniert es.  Vielen Dank Karl Heinz.
MS Mitarbeiter muss ja schon langweilig sein, das sie sich noch so 
scheiß ausdenken.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian wrote:
> Ok so funktioniert es.  Vielen Dank Karl Heinz.
> MS Mitarbeiter muss ja schon langweilig sein, das sie sich noch so
> scheiß ausdenken.

Ehrenrettung: Die MFC ist schon alt, uralt.

Aber: Da gibt es noch viel größeren Scheiß in der MFC.
Ich seh zb. nicht ein, warum ein CSplitterWnd die Mouse Messages
bezüglich des Scrollrades nur dann an den aktiven View weiterleitet,
wenn dieser von einem CScrollView abgeleitet wird.
Als ob MS das was angeht, ob ich mein Scrolling über CScrollView
oder mit eigener Funktionalität mache oder die Maus vielleicht für
etwas ganz anderes nutze. Hat mich damals Tage gekostet
rauszufinden warum mein Graphikview nicht auf Mausrad Messages
reagiert, wenn er in einem CSplitterWnd eingesetzt wird. Der
View verwendet das Mausrad fürs Zoomen :-)

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.