Problem bei MDI Anwendung mit Fenster, wie bekomme ich einen CDC-Pointer?



  • Hall Zusammen, ich hab mal wieder eine Frage!
    Also ich möchte eine MDI Anwendung schreiben und habe dafür unter Visual6.0 ein Standart MFC-Projekt das MDI unterstützt angelegt.
    Dann habe ich mir noch schnell ein Menü gestrickt und möchte nun folgendes realisieren. Wenn man z.B. auf den Button "Diagramm" im Menü klickt dann soll sich ein neues Fenster öffnen wenn es noch kein Diagramm Fenster gibt. Dannach werden Funktionen wie

    CDC::LineTo()
    

    oder

    CDC::MoveTo()
    

    ausgeführt damit das Diagramm gezeichnet werden kann.
    Damit das geht benötige ich natürlich einen CDC-Pointer.

    Nun mein Verständnis Problem!
    Wenn ich in der Anwendung die Membervariable

    CMultiDocTemplate m_pTemplateDummy;
    

    anlege und dann unter den Button folgenden Code lege:

    CMDIChildWnd* pActivChild = MDIGetActiv();
    CDocument* pDocument;
    pDocument = pActivChild->GetActivDocument();
    
    CDocTemplate* pTemplate = ((DummyApp*) AfxGetApp())->m_pTemplateDummy;
    CFrameWnd* pFrame = pTemplate->CreateNewFrame(pDocument, pActivChild);
    

    Nun dachte ich wenn ich mir mit

    CDC* pDC = pFrame->GetDC()
    

    einen CDC*-Pointer hole dass ich dann in dem neuen Fenster rummalen kann aber leider wird gar nix gemalt, zumindest bleibt das Fenster weiss!

    Kann mir da jemand weiter helfen???


  • Mod

    Man malt nicht in einem Fenster herum :D, man wartet darauf, dass eine WM_PAINT Nachricht eintrifft, die einem höflich mitteilt, dass das Windows System Deines Einschreitens bedarf um den Inhalt eines Fensters anzuzeigen. D.h. in Deinem View wird OnDraw aufgerufen (die Du überschreibst) und dort bekommst Du einen DC frei Haus mitgeliefert.



  • Also ich hab mal eine SDI Anwendung geschrieben in der ich eine CEditView benutzt habe. Dann habe ich über den Wizard dort eine Picture Umgebung eingefügt und dann über Buttons gesteuert un der Umgebung gezeichnet. Daher fand ich das eine Sehr gut Lösung so wie ich das oben beschrieben habe.
    Als ich das Ganze in OnDraw untergebracht habe war das Tool so ziemlich die ganze Zeit damit beschäftigt zu zeichnen da ich das Gefühl habe das WM_PAINT ziemlich häufig ausgelöst wird.


  • Mod

    CEditView und OnDraw ist aber auch nicht unbedingt ein Design das Sinn macht.
    Ein EditView ist ein eigenständiges Control, dass selbst weiß wie es zu zeichnen ist. Wenn Du selbst dann auch noch eingreifen willst musst Du in jedem Fall darauf achten, die Parent OnDraw Funktion aufzurufen!

    OnPaint/OnDraw/WM_PAINT ist der Bereich in dem ein Fenster sein Update erfahren soll! Das ist nun mal so in dem Design von Windows. Solltest Du in anderen Bereichen Zeichnen, dann ist nicht gewährleistet, dass wenn Dein Fenster verdeckt und wieder sichtbar wird korrekt dargestellt wird.



  • Ganz verstehen tu ich das immer noch nicht, aber ich glaube langsam komme ich der ganzen Sache auf den Grund!!

    1. Damit ich in einem neu Fenster bei OnDraw etwas zeichnen kann, erstelle ich zuerst eine neu Klasse z.B. 'Diagramm' die z.B. von CView abgeleitet ist.
    2. In dieser Klasse editiere ich dann die OnDraw Funktion mit dem was ich für das Zeichnen meines Diagrammes benötige.
    3. Dannach editiere ich die OnButton Methode des Menü eintrages mit so ca. dem Code den ich ganz oben beschrieben habe.
    4. Dann muss der obrige Code nur noch so angepasst werden das ein Fenster von der Klasse 'Diagramm' erstellt wird.

    CDocTemplate* pTemplate = ((Diagramm*) AfxGetApp())->m_pTemplateDiagramm;
    

    Ist das richtig so???


  • Mod

    Ja!



  • Alles hat wunderbar geklappt ausser das sich da nur eine neue View und kein Frame aufmacht aber das ist ersteinmal nicht so schlimm.
    Aber jetzt habe ich ein neues Problem:
    Der sich neuaufmachenden View habe ich eine ToolBar angehängt. Bei drücken der Knöpfe soll sich das dargestellte Diagramm ändern. Allerdings passiert nichts, da ja nur eine Message 'Button gedrückt' geworfen wird und keine OnDraw(). Aber wie schaffe ich das jetzt das nachdem ein Wert geändert worden ist OnDraw() wieder ausgelöst wird oder wie bekomme ich einen CDC-Pointer mit dem ich dann OnDraw manuell auslösen kann? Oder kann man die Methode OnDram nicht manuell aufrufen?


  • Mod

    Der normale Weg ist UpdateAllViews aufrufen, wenn Deine Daten im Dokument gespeichert sind.

    Wenn dieser Toolbar in Deinem View alleine für Einstellungen dient dan einfach Invalidate aufrufen. Dadurch wird ein neu Zeichnen ausgelöst.



  • Danke für deine Antwort, auch das hat mir weiter geholfen!
    Aber nun habe ich festgestellt das ich mit der aktuellen Lösung nicht zufrieden bin! Statt von einem aktiven MDI Kind möchte ich lieber ein neues erzeugen um darin die Diagramme anzuzeigen. Also statt:

    CMDIChildWnd* pActivChild = MDIGetActiv();
    

    möchte ich

    CMDIChildWnd* pActivChild = new CMDChildWnd;
    

    benutzen.
    allerdings läuft werden dabei nicht alle Werte von pActivChild gesetzt (wenn man sich das im Debugger anschaut).
    Wie schaffe ich das es ein vollständiges Fenster erhalte, wo nicht nie meisten werte NULL sind?


Anmelden zum Antworten