www.mikrocontroller.net

Forum: PC-Programmierung Visual C++ untergeordnete Fenster

Autor: Sebastian (Gast)
Datum: 28.04.2008 18:35
Dateianhang: Oberfl_che.JPG (80,6 KB, 49 Downloads)
preview image for Oberfl_che.JPG

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
Autor: Karl heinz Buchegger (kbuchegg) (Moderator)
Datum: 28.04.2008 19:14

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(...
Autor: Sebastian (Gast)
Datum: 28.04.2008 20:40

danke mal, werd ich dann morgen im geschäft recherchieren gehn
jetzt hab ich aber erstmal feierabend ^^
Autor: Markus Volz (valvestino)
Datum: 28.04.2008 21:31

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
Autor: Sebastian (Gast)
Datum: 29.04.2008 09:03

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.
Autor: Karl heinz Buchegger (kbuchegg) (Moderator)
Datum: 29.04.2008 09:25

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.
Autor: Sebastian (Gast)
Datum: 29.04.2008 10:31

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
Autor: Sebastian (Gast)
Datum: 29.04.2008 10:34

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
Autor: Sebastian (Gast)
Datum: 29.04.2008 11:16

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.
Autor: Sebastian (Gast)
Datum: 29.04.2008 11:19

Ok das mit der TemplateList hat sich erledigt, wäre nur noch das Problem
mit der Größe.
Autor: Karl heinz Buchegger (kbuchegg) (Moderator)
Datum: 29.04.2008 11:50

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.
Autor: Sebastian (Gast)
Datum: 29.04.2008 11:59

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.
Autor: Sebastian (Gast)
Datum: 29.04.2008 12:04

hmmmmm.....nun wird mein Dialog zwar verwenden, aber die Titel werden
immernoch abgeschnitten. Es werden immer genau 6 Zeichen angezeigt, der
Rest fehlt.
Autor: Karl heinz Buchegger (kbuchegg) (Moderator)
Datum: 29.04.2008 12:49

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
  windowTitle,        // default window title
  docName,            // user visible name for default document
  fileNewName,        // user visible name for FileNew
                      // for file based documents:
  filterName,         // user visible name for FileOpen
  filterExt,          // user visible extension for FileOpen
                      // for file based documents with Shell open support:
  regFileTypeId,      // REGEDIT visible registered file type identifier
  regFileTypeName,    // Shell visible registered file type name
Autor: Sebastian (Gast)
Datum: 29.04.2008 12:58

Ok so funktioniert es.  Vielen Dank Karl Heinz.
MS Mitarbeiter muss ja schon langweilig sein, das sie sich noch so
scheiß ausdenken.
Autor: Karl heinz Buchegger (kbuchegg) (Moderator)
Datum: 29.04.2008 13:11

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 :-)

Antwort schreiben

Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos verwenden, Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net