Veröffentlicht 22. Oktober 200123 j Hallo zusammen! Ich muß in ein Programm einen Fortschrittsbalken einbinden! Leider hab ich absolut keine Ahnung wie ich das am besten mache! Wie mache ich ein Update des Balkens? :confused: Weiß vielleicht jemand wo ich hierzu mehr Infos finde? Bin wirklich dankbar für jeden Tip! Schonmal danke und bis dann **DeBrainBoy**
23. Oktober 200123 j Ziehe eine Statusanzeige aufs Edit-Window, Links-Strg-W: Member-Variable m_Progress1 (z.B.) vergeben. zum Austesten, damit man mal sieht, ob auch alles richtig klappt, habe ich einen Slider m_slider1 und ein Edit-Fenster m_edit1 genauso erstellt. Beim Slider im Register Nachrichtenzuordnung NM_CUSTOMDRAW auswählen. Doppelklick auf den Slider fügt die DDX-Routine entsprechend in den Source ein. Dort schreibst Du dann nur noch: m_slider1.SetRange(0,100,true); // um den Bereich für den Slider festzulegen int pos=m_slider1.GetPos(); // Slider Position abfragen CString String1; itoa(pos,String1.GetBuffer(3),10); // 10 ist der Radix, d.h. Zahlenbasis 10=normale Dezimalzahlen; 16=Hexadezimalausgabe. Die Zahl bei Getbuffer gibt an, wieviel Stellen im CString fürs Konvertieren verwendet werden dürfen. Ist die Ausgabe größer als diese Zahl, stürzt das Programm ab, also immer passend oder größer wählen! m_Edit1.SetWindowText(String1); // Text ausgeben m_Progress1.SetRange(0,100); // Bereich vom Fortschrittsbalken setzen m_Progress1.SetPos(pos); // Position des Balkens festlegen Jetzt kannst Du schon das Programm starten. Ziehst Du nun am Slider rum, siehst Du wie der Fortschrittbalken entsprechend verändert wird und der Wert unten noch im Klartext ausgegeben wird. Man kann natürlich das ganze auch Hard-Coden, aber das verbraucht nur irre Zeit, man muß sich direkt mit den Resourcen rumschlagen und verbringt mehr Zeit damit das Drumrum zum Laufen zu bringen, als die simple Abfrage fertigzustellen. Also soweit möglich mit Controls und Direct-Data-Exchange arbeiten empfehle ich (auch bei Pop-Up-Windows). Vielleicht noch als Anmerkung: Möchte man einen pixelgenauen Fortschrittsbalken kann man das mit Blitting-Routinen machen, z.B. so: // m_Progress1.SetPos(pos); // diese Zeile rauswerfen und stattdessen sowas reinschreiben: RECT newrect; CDC*pcdc=m_Progress1.GetWindowDC(); // Display-Kontext holen pcdc->GetWindow()->GetClientRect(&newrect); // Den Bereich in newrect setzen pcdc->FillSolidRect(&newrect,0); // erst mal mit schwarz ausfüllen (0xBBGGRR=blau, grün, rotanteil) newrect.right=(newrect.right-newrect.left)*pos/100; // da pos mit 100 berechnet wird einfach so die richtige Größe rausfinden pcdc->FillSolidRect(&newrect,0xffffff); // mit weiß nochmal den selektierten Bereich nachzeichnen. So lassen sich auch übrigens wunderbar Farb-Einstellungen erstellen: alle FillSolidRect()-Zeilen mit // ausklammern und statt dem ersten das hier reinschreiben: pcdc->FillSolidRect(&newrect,255/100*pos<<16); // blau hoch und runterzählen ... aber ich glaube jetzt schweife ich zuviel vom Thema ab! <FONT COLOR="#a62a2a" SIZE="1">[ 23. Oktober 2001 09:15: Beitrag 7 mal editiert, zuletzt von Crush ]</font>
24. Oktober 200123 j Wunderbar das hat soweit funktioniert! Hab jetzt nur noch ein Problem! Ich muß Logfiles abarbeiten (Textdateien mit bis zu 50MB). Um nun eine genau Größe des Balkens festlegen zu können, müßte ich ja jetzt das Log einmal durchlaufen lassen um die genaue Anzahl der Zeilen zu bekommen! Beispiel: Ich habe ein Log das 75124 Zeilen hat. Wenn ich es richtig verstanden hab müßte ich ja jetzt mit SetRange die Länge des Balkens bestimmen. Ungefähr so: m_ctrlFortschritt.SetRange(0, 75124) Danach lege ich noch die Schrittweite fest (m_ctrlFortschritt.SetStep(1)) und dann kann ich mit StepIt den Balken zum Leben erwecken! Diese Methode kommt für mich leide nicht in Frage, da ich nicht jedes Log vorher durchlaufen lassen kann! Die Zeilen haben auch alle unterschiedliche Längen, so daß ich auch nicht von der Dateigröße auf die Anzahl der Zeilen schließen kann! :confused: Jemand da ne Idee?? Schonmal danke **DeBrainBoy**
24. Oktober 200123 j Mist ich habe hier kein Visual, es muesste eine Funktion in der Klasse CFile geben die dir die Groesse des Files zurueckgibt...
24. Oktober 200123 j Hallo Hasi! Ja von der Funktion hab ich gestern auch schon gehört! Aber wie gesagt, die einzelnen Zeilen haben unterschiedliche Längen! So kann ich natürlich über die Dateigröße nie genau sagen wieviele Zeilen die Datei denn nun wirklich hat! Oder hab ich da jetzt was falsch verstanden?? :confused: **DeBrainBoy**
24. Oktober 200123 j <BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica, sans-serif">Zitat:</font><HR>Original erstellt von DeBrainBoy: <STRONG>Ja von der Funktion hab ich gestern auch schon gehört! Aber wie gesagt, die einzelnen Zeilen haben unterschiedliche Längen! So kann ich natürlich über die Dateigröße nie genau sagen wieviele Zeilen die Datei denn nun wirklich hat! Oder hab ich da jetzt was falsch verstanden?? </STRONG>
24. Oktober 200123 j Sorry aber das versteh ich nicht ganz! Ich brauch die Anzahl der Zeilen ja vorher! Was Du beschreibst liefert mir doch nur die Anzahl während der Verarbeitung! Oder?? **DeBrainBoy**
24. Oktober 200123 j <BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica, sans-serif">Zitat:</font><HR>Original erstellt von DeBrainBoy: <STRONG>Sorry aber das versteh ich nicht ganz! Ich brauch die Anzahl der Zeilen ja vorher! Was Du beschreibst liefert mir doch nur die Anzahl während der Verarbeitung! Oder??</STRONG>
24. Oktober 200123 j ALso ich würde einfach halt die Zeilen durchzählen. Ich habe mal ein ziemlich verschwenderisches Beispiel gemacht, aber das kann man ja auch mit kleinem Puffer speicherfreundlich arrangieren: int gesamtlaenge=0,Zeilenzahl=0; if (CFile myfile("c:\\temp\\x.txt",CFile::modeRead|CFile::typeBinary)) { gesamtlaenge=myfile.SeekToEnd(); // Länge ermitteln myfile.SeekToBegin(); // zurücksetzen void*fbuffer=malloc(gesamtlaenge); // Speicher reservieren myfile.ReadHuge(fbuffer,gesamtlaenge); // einlesen short*cnt=(short*)fbuffer; counter for (int i=0;i<gesamtlaenge;i++) { if (cnt==0x0a0d) Zeilenzahl++; } myfile.Close(); free(fbuffer); also hier sucht er nach der Folge 0d0a (0a0d, weil das halt anders rum im Speicher steht) hier wird ein 2-byte Wert gesucht, mit einem Byte braucht man den Kern nur so zu ändern: char*cnt=(char*)fbuffer; for (int i=0;i<gesamtlaenge;i++) { if (cnt=='|') // für Excel-Export z.B. Zeilenzahl++; } ... und wenn sich jetzt jemand frägt, warum ich malloc und free verwendet habe anstatt new und delete, dann muß ich sagen: Keine Ahnung, mit new und delete hatte ich gerade irgendwelche komischen Asserts verursacht, also dann halt mit Gewalt, wenn´s gerade anders nicht will =;-]
Archiv
Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.