Nochmal Zeichnung soll im Dialog erhalten bleiben



  • Hi, nochmal das Problem.
    Also ich lasse etwas in einem Dialogfeld zeichnen und nun möchte ich diese Zeichnung so speichern, daß sie nach einem Minimieren wieder da ist.
    Ich habe es bis jetzt so weit, daß ich die Zeichnung auf eine Bitmap speichere und dann mit einem Button nach dem minimieren wieder abrufen kann.

    So gefällt es mir aber überhaupt nicht. Es muß doch irgendwie möglich sein, daß das automatisch passiert. Es funktioniert bloß nicht. Habe schon alles mögliche versucht.( so ähnlich wie bei einer SDI-Anwendung mit OnDraw() )

    Es sollte eigentlich auch so gehen, daß es bei minimiertem Fenster weiter zeichnet. also irgendwie in den Speicher. Bei mir muß ich immer so lange warten, bis das Bild fertig ist und dann ist es auch vollständig wieder abrufbar, anders nur unvollständig.

    Bitte um Hilfe ist echt wichtig!!!!

    Gruß



  • Was willst du denn Zeichnen? Einen Graphen und Kurvenvelauf? Dann speichere die Punkte in einen Array und in der OnDraw/OnPaint - Funktion lässt du diesen per Schleife wieder zeichnen.



  • Ich zeichne eine Wellenform einer wav-Datei und das passiert ja bereits in einem Thread und einer Schleife. Diese Zeichnung wird während der Laufzeit erstellt und man kann sehen wie sich die Zeichnung aufbaut. Aber dann soll auch Schluß sein. Wenn ich das ganze in OnPaint() nochmal als Schleife laufen lasse, würde das doch wieder viel zu lange dauern, Oder?

    Und wie soll das eigentlich funktionieren?

    Gruß



  • Tut mir leid hat nichts mit der Lösung zu deinem Problem zu tun, aber was ist eine Welchenform? Meinst du Wellenform? Über was für einen Algorithmus machst du das? Wie liest du die Wave aus? Weil ich sollte auch bald ein Projekt mit Waves machen und hab da noch keinen Plan.
    Danke



  • Wellenform ist die Darstellung der Wav-Datei als Schwingung mit Amplitude und Zeit. (War natürlich ein Schreibfehler!!)
    Ich habe dafür eine Klasse mit der ich die Wavedatei einlese und dann bestimmte Werte der Wav-Datei ermitteln kann. Und dann noch eine Schleife für die Zeichnung. (stichwörter:mmioOpen, WAVEFORMATEX,mmsystem)



  • Du nimmst deine Funktion also z.B. void ZeichneKurve(CDC *pDC);

    und die fügst du in OnPaint() ein:

    ...::OnPaint(...)
    {
    ZeichneKurve(&dc);
    }



  • @evil-peter: Ich danke dir recht herzlich und werde dann bald nochmal auf dich zurück kommen *gg* 😉



  • DKlay schrieb:

    Du nimmst deine Funktion also z.B. void ZeichneKurve(CDC *pDC);

    und die fügst du in OnPaint() ein:

    ...::OnPaint(...)
    {
    ZeichneKurve(&dc);
    }

    Das dauert doch dann aber wieder so lange bis die Zeichnung fertig ist. Das wollte ich ja mit dem Thread vermeiden. Er soll es ja nicht nochmal zeichnen müssen!



  • Ich würde einfach ein CArray machen in dem ich die Koordinaten der bereits ermittelten Bildpunkte speichere. Also deine jetzige Zeichnekurve()-Methode quasi in eine BerechneKurve() umbennen 😃
    Und dann in OnPaint einfach jedes mal das Array durchlaufen und und alle Bildpunkte die bisher errechnet wurden zeichnen. Da das Array dynamisch ist und als Template ausgelegt ist kannst du auch für die "Datensätze" des Array ein struct machen, dann kannst du zum Beispiel sogar die Farbe innerhalb der Berechnungs-Methode mit angeben.

    Das sollten so die benötigten Funktionen sein:

    CArray<T,T>
    CArray::Add();
    CArray::GetSize();
    CArray::GetAt();
    

    Ich habe das so bei einer Software implementiert die Daten vom Serial-Port liest und grafisch darstellt, da musste ich auch die Datenerstellung (bei dir Berechnung, bei mir Empfangen) von der Zeichnung trennen..

    hoffe das hilft dir 😉



  • Um das mal klarzustellen. Es bleibt dir nicht anderes über als jedesmal neu zu zeichen.
    Nicht nur wenn du deine Anwednung minimierst sondern auch wenn sich ein anderen Fenster drüber legt.
    Immer wenn eine Painnachricht kommt zeichnet sich der Dialog neu. Wenn du in diesem Fall deine Zecihnung nicht neu zeichnest ist sie weg.
    Jedes Programm in Windows muss das machen.



  • Würde ich auch so sehen. 😉 🤡



  • @Paul_C: Oh, du hattest ja quasi das gleiche schon im zweiten Post geschrieben, hab ich voll überlesen 😉
    Naja wenigstens war meins etwas ausführlicher und daher vllt. trotzdem hilfreich 🙂



  • Du hast es wenigstens erklärt mit der WM_PAINT Nachricht.
    Das ist in der Tat einleuchtender als einfach zu sagen, dass man das so macht. 😉



  • Danke für die Hilfe, ich hatte das mit dem Array schon so gemacht. Dadurch wurde die ganze Sache aber viel zu langsam, weil der Speicher überfüllt wurde.

    @Unix-Tom danke für die Erklärung, doch es muß doch möglich sein das Bild zu speichern und dann einfach immer nach einem Minimieren wieder abzurufen. Mit meinem Button funktioniert es doch auch ( also ich speichere die Zeichnung nach dem zeichen auf eine Bitmap und kann sie dann per Button abrufen. Aber in OnPaint() funktioniert das nicht, WIESO????

    Bitte mal erklären



  • Ich denke das du was falsch macht bei deinem Bild. Auch ein Button wird neu gezeichnet und die paar Bildpunkte sind so minimal das man es nicht sieht. Weiters kann man in den Speicher zeichenn und das Bild dann fertig blitten. Auch Spiele machen das so. Die Zeichnen auch immer neu.
    Du solltest eher deine Zeichenroutine überprüfen.
    Im Buch VC++ 6 in 21 Tagen ist das auf einfache weise erklärt.



  • Ich glaube, du hast mich falsch verstanden. Die Zeichenroutine ist ja einigermaßen schnell. Aber bei einer Zeichnung der Wellenform einer wav-Datei dauert das halt ein wenig.
    Den Button neu zeichnen meine ich nicht sondern nach dem Buttonklick zeichnet er mir die Bitmap, die ich vorher (also wenn er mit dem zeichnen fertig ist) gespeichert habe, neu hin. Aber das macht er halt nicht bei OnPaint().

    Hier mal der Code beim Buttonklick:

    void CVorbisMFC_StaticDlg::OnBnClickedLoad()
    	{
    		// TODO: Fügen Sie hier Ihren Kontrollbehandlungscode für die Benachrichtigung ein.
    
    		CClientDC pDC(this);
    
    		pDC.BitBlt(20,234,700,400,pMemDC,0,0,SRCCOPY);
    
    	}
    

    Und was er da macht muß doch auch in OnPaint() funktionieren oder bin ich völlig auf dem Holzweg?



  • Danke für die Hilfe, ich hatte das mit dem Array schon so gemacht. Dadurch wurde die ganze Sache aber viel zu langsam, weil der Speicher überfüllt wurde.

    irgendwo hast du da wohl nen gewaltigen (Denk-)Fehler.. Du sollst doch nur die Koordinaten ins Array speichern die den zu zeichnenden Bildpunkten entsprechen. Und egal bei welcher Bildschirmauflösung du das dann durchführst bekommst du NIE Speicherprobleme, was sollen da Spiele sagen die manche Pixel x-mal durch Filter jagen und neuberechnen, und das in Echtzeit..
    Wieviel Pixel breit und hoch ist denn deine Kurve und welche stärke hat die Linie (wobei letztes total unerheblich ist, da man einfach nen "dickeren" brush wählen kann und somit nur eine 1-Pixel-Linie im Array speichern muss)..



  • Ich habe das auch nicht mit den Bildpunkten gemacht, sondern ich habe die einzelnen gezeichneten Linien in einem Array gespeichert. Also immer wenn meine Routine eine Linie gezeichnet hat, habe ich sie in das Array aufgenommen. Dann in OnPaint() als schleife neu gezeichnet. Und das hat die ganze Berechnung zu langsam gemacht.
    Wie soll ich denn dann die Bildpunkte speichern?

    Also mit ner Linie weiß ich es, da die Routine ja auch Linien zeichnet kann ich die auch speichern, aber Punkte?
    Gib mir mal ein Beispiel, wie ich eine Linie als Punkte in ein Array speichern soll!



  • einzelne Pixel kannst du mit SetPixel() setzen..

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_cdc.3a3a.cdc.asp

    Hast du mal gecheckt wieviel einträge in deinem Array sind? weil wenn deine Berechnungs-Routine so langsam wird muss es ja am einfügen in das Array liegen und von "so ein paar" Elementen wird es eigentlich nicht so extrem langsam.

    Achso, und das Berechnen packst du dann aber in einen eigenen Workerthread, oder? Also es bringt nämlich nix alles in einem Thread laufen zu lassen, weil wenn er rechnet kann er dann ja nicht malen 😉



  • Bei einer 1 min Wav sind es schon 2656000 Linien zum speichern.(und das ist nur ein Kanal)

    Das mit dem SetPixel habe ich noch nicht verstanden. Wie soll ich denn alle Pixel einer Linie setzten. Das geht doch auch wieder bloß mit einer Schleife, Oder?
    Das dauert ja dann nochmal ewig.

    Gib mir doch mal ein Beispiel mit dem ich was anfangen kann.


Anmelden zum Antworten