statusbar bleibt hängen?



  • nabend leutz,
    hab an nem programm rumgebastelt, welches ein von mir erfundenes primitives bildformat speichern und anzeigen soll. Dieses Programm hat am unteren Rand ne statusbar. Doch leider scheint die irgendwie hängen zu bleiben, denn erneutes ändern des Texts funzt nicht. Auf der Statusbar hab ich noch ne progressbar, welche auch nicht mehr reagiert.

    bool ReadArrayFromFile(HWND hwnd)
    {
      char p[260]={0};
      int x=0, y=0, t;
      OPENFILENAME ofn;
      ZeroMemory(&ofn, sizeof(OPENFILENAME));
    
      ofn.lStructSize=sizeof(OPENFILENAME);
      ofn.hwndOwner=hwnd;
      ofn.lpstrFile=p;
      ofn.lpstrFilter="Picture Dateien\0*.pic\0\0";
      ofn.nMaxFile=260;
      ofn.Flags=OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
    
      if (!GetOpenFileName(&ofn)) // Datei öffnen Dialog
        return true;
    
      ifstream f(p);
    
      ShowWindow(progress, SW_NORMAL); // Das macht er noch
      if (status)
        SendMessage(status, SB_SETTEXT, 0, (LPARAM)"Datei wird geladen..."); // Das auch
    
      while (!f.eof())
      {
        f >> t;
        if (t==2)
        {
          y++;
          x=0;
          // SendMessage(progress, PBM_STEPIT, 0, 0);
          continue;
        }
    
        if (x>300 || y>400)  // Schutz vor Buffer-Overflows
          break;
    
        pixel[x][y]=t;
        x++;
        SendMessage(progress, PBM_STEPIT, 0, 0); // Das scheint er nur noch beim ersten Durchlauf zu machen, denn die Progressbar hat noch einen balken
      }
      f.close();
    
      SendMessage(progress, PBM_SETPOS, 120000, 0); // Das macht er nicht mehr Message wird zwar gesendet (funktion kehrt zurück), aber wohl nicht mehr verarbeitet
      if (status)
        SendMessage(status, SB_SETTEXT, 0, (LPARAM)""); // Das macht er auch nicht mehr (gleiches Problem
    
      HDC hdc=GetDC(hwnd);
      DrawArray(hdc);
      ReleaseDC(hwnd, hdc);
      return true;
    }
    

    hoffe ihr seht da was
    grüsse 😉



  • Du brauchst eine ProcessMessages() aufrufen gleich nach PBM_STEPIT (oder fast egal wo in der Schleife, mimimal einmal/second):

    void ProcessMessages()
    {
    	MSG msg;
    	while (PeekMessage(&msg,0,0,0,PM_REMOVE))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    }
    


  • danke, aber funzt leider auch nicht. immer noch genau wie vorher


  • Mod

    Wenn es nur um den Prograssbar geht muss man keine Messageloop haben. Es genügt ein Aufrud von UpdateWindow/RedrawWinodw für den Progressbar.



  • hilft alles nichts statusbar und progressbar sind einfach wie eingefroren. es lässt sich nichts mehr darauf anwenden. In einer anderen Funktion habe ich aber auch eine schleife welche das gleiche macht und dort funktioniert alles. Da wird folgendes gemacht: text in statusbar wird geändert, progressbar wird eingeblendet, und in der schleife erhöht. danach wird der text in der statusbar wieder geändert und die progressbar auf 100% gesetzt.
    Ein Programmierfehler meinerseits ist das meines erachtens nach nicht.


  • Mod

    1. Sehe ich kein SETPOS nach dem Anzeigen.
    2. Da SendMessage zurückkehrt wird auch die Nachricht verarbeitet.
    3. Was Du höchstens eben nicht wahrnimsst ist die Aktualisierung, weil kein WM_PAINT ausgelöst wird.

    Ich gehe 100% von einem fehler bei Dir aus und nicht von Windows 😉



  • 1. das setpos habe ich auch in der anderen funktion
    2. ja das weiss ich aber man müsste doch ne wirkung sehen
    3. wenn man keine aktualisierung wahrnimmt wäre das ja sowieso unnötig (?) 😉

    ich glaube nicht dadran, in der anderen funktion mache ich es genauso und da funzts
    edit: ok, ich hab schon die merkwürdigsten phänomene (hoffentlich richtig geschrieben) beim programmieren erlebt stimmt vielleicht.


  • Mod

    Wenn man nur eine Nachricht sendet, heißt, das nicht das man etwas sieht. Aktualisierungen in der Ansicht werden nur durch WM_PAINT ausgelöst. WM_PAINT aber wird nur ausgelöscht, wenn UpdateWindow/RedrawWindow aufgerufen wird, oder eine MessageLoop läuft.

    Da Du weder eine Message Loop hast, noch UpdateWindow/RedrawWindow ausführst kann es gut sein, dass Deine Nachrichten verarbeitet werden, aber keine visuelle Veränderung bewirken.



  • wie gesagt ich hab es schon mit UpdateWindow probiert, aber es hilft leider nicht. auch ein neuzeichnen bringt nichts


  • Mod

    Dann musst Du mehr Code zeigen. Evtl. ist das Control nicht sichtbar, oder nicht komplett sichtbar.
    Ich habe ähnlichen Codee in meinen Programmen uns es klappt prima.



  • gut hier noch etwas:

    das ist jetzt die funktion in der alles funktioniert

    bool WriteArrayToFile(HWND hwnd)
    {
      int x=0, y=0;
      char pa[260]={0};
      OPENFILENAME op;
      ZeroMemory(&op, sizeof(OPENFILENAME));
    
      op.lStructSize=sizeof(OPENFILENAME);
      op.hwndOwner=hwnd;
      op.lpstrDefExt="pic";
      op.lpstrFilter="Picture Dateien (*.pic)\0*.pic\0\0";
      op.lpstrFile=pa;
      op.nMaxFile=260;
      op.Flags=OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_OVERWRITEPROMPT;
      if (!GetSaveFileName(&op)) // Dialog zum speichern
        return true;
    
      ofstream f(pa);
    
      ShowWindow(progress, SW_NORMAL); //macht er
      if (status)
        SendMessage(status, SB_SETTEXT, 0, (LPARAM)"Speichern..."); // macht er auch
    
      for (int i=0;i<120000;i++)
      {
        if (x==300)
        {
          f << " " << static_cast<int>(pixel[x][y]);
          f << " " << 2;  // Neue Zeile
          x=0;
          y++;
        }
    
        f << " " << static_cast<int>(pixel[x][y]);
        x++;
        SendMessage(progress, PBM_STEPIT, 0, 0); // das macht er
      }
      if (f.fail())
        return false;
    
      f.close(); 
      if (status)
        SendMessage(status, SB_SETTEXT, 0, (LPARAM)pa); // das macht er auch
      SendMessage(progress, PBM_SETPOS, 120000, 0); // hier füllt er die progressbar zu 100%
      return true;
    }
    

    hier noch die wm_command in der beide funktionen aufgerufen werden

    case WM_COMMAND:
        {
          switch (LOWORD(wparam))
          {
            case menuitem_save:
              if (!WriteArrayToFile(hwnd))
                MessageBox(hwnd, "Fehler beim schreiben in die Datei", "Fehler", MB_OK);
            break;
    
            case menuitem_close:
              SendMessage(hwnd, WM_CLOSE, 0, 0);
            break;
    
            case menuitem_new:
              clean(hwnd);
            break;
    
            case menuitem_\1:
              about(hwnd);
            break;
    
            case menuitem_black:
            case menuitem_red:
              SetCheck(hwnd, LOWORD(wparam));
            break;
    
            case menuitem_open:
              ReadArrayFromFile(hwnd);
            break;
          }
        return 0;
        }
    

Anmelden zum Antworten