SetRedraw(FALSE) und CWaitCursor



  • Hallo,

    ich habe da ein kleines Problem: Ich locke meinen MDI MainFrame mit SetRedraw(FALSE) und öffne dann ein weiteres Kind-Fenster. Nachdem das Fenster erzeugt wurde erlaube ich das Neuzeichnen mit SetRedraw(TRUE). Während der Aktion soll der WaitCursor gesetzt sein.

    Das Problem ist nun, dass bei Aufruf von SetRedraw(FALSE) der WaitCursor flöten geht und der Cursor des darunter liegenden Fensters angezeigt wird. LockWindowUpdate() funktioniert in diesem Fall nicht, da das neu aufgemachte Kind-Fenster dabei trotzdem angezeigt wird.

    Ich verstehe nun nicht, warum das so ist und wie man das beheben kann. Weiß jemand Rat?

    Kurz gesagt:

    void CMainFrame::Something()
    {
       CWaitCursor cur; // Hourglass
       SetRedraw( FALSE ); // Cursor für window unter dem MainFrame
       ...                 // längere Operation zeigt nun "falschen" Cursor
       SetRedraw( TRUE );  // wieder Hourglass
    }
    

  • Mod

    Dürfte eigentlich nicht passieren. Solange keine Nachrichten Loop eine Nachricht pullt und keine Mausnachricht einkommt, wird auch der Mauscursor nicht verändert, außer irgendjemand setzt den Mauscursor neu...

    IMHO manipuliert nur WM_SETCURSOR den Mauscursor fensterspezifisch und diese nachricht wird nur durch einen Maus-Move ausgelöst.



  • Danke für den Hinweis.
    Da ist sicherlich eine Message-Pumpe während der Aktion, bei der der WaitCursor gesetzt werden soll. CMainFrame::OnSetCursur wird in der Zeit nicht angesprungen, CMainFrame::PreTranslateMessage allerdings schon.

    Kann man vielleicht auf diesem Wege den Mauscursor "erzwingen"?


  • Mod

    Ich würde mal den Spy++ aktivieren und mir mal ansehen, was da für Nachrichten wirklich behandelt werden...



  • Wenn ich den Breakpoint auf SetRedraw(FALSE) setze, dann ist der Waitcursor noch gesetzt. Steppe ich darüber, dann empfängt der MainFrame laut Spy++ nur die WM_SETREDRAW -Nachricht und der WaitCursor geht schlagartig verloren und der Cursor für den Desktop (bzw. das darunter liegende Fenster) wird sichtbar. Dieses erhält dann auch eine WM_SETCURSOR -Nachricht.


  • Mod

    Dürfte aber nicht sein. Denn Mausnachrichten dürften ja gar nicht ankommen, weil Du ja gerade eben was tust und keine Messageloop läuft.
    Das ganze müsstest Du per Remote Debugging testen auf einer Maschine wirst Du das nicht korrekt simulieren können.

    WM_SETCURSOR wird ja eben nur im Kontext einer Nachrictenbehandlung aufgerufen.

    Mal was ganz anderes. Warum setzt Du das CMainFrame auf SetRedraw(FALSE)?
    Du kannst doch das MDI-Frame selbst einfach auf Hide-setzen oder dort den SetRedraw(FALSE)...

    Laut gedacht: Evtl. ist das auch ein Standardverhalten von Windows. Wenn das ganze Fenster keine Nachrichten und keinen Redraw annimmt wird einfach eine Mausnachricht transparent an das unterliegende Fenser gereicht...



  • Ja, wahrscheinlich wird es sowas sein.

    Ich setzte das SetRedraw(FALSE) auf den MainFrame, weil in einem Zyklus mehrere ChildFrames geöffnet werden. Das flackert dann zu heftig, so dass ich es erst öffnen lasse und danach neu zeichnen lasse.

    Ich habe mir jetzt erstmal mit einem transparenten Fenster geholfen. Dieses lege ich vor den MainFrame so dass der WaitCursor nun ordentlich angezeigt wird.

    Danke nochmal für die Denkanstöße und Tipps.


  • Mod

    Warum benutzt Du nicht das MDI-ChildFrame das im Mainframe liegt?



  • Das Problm ist, dass der MainFrame auch die Tabs zeichnet, die ich ja auch unterdrücken will. Deshalb geht es wirklich nur, wenn man den MainFrame "stumm schaltet".


  • Mod

    Naja. Das Tabfenster auch noch separat mit einem SetRedraw(FALSE) zu belegen wäre auch nicht das Problem wenn Du dann Dein WaitCursor Problem löst.


Anmelden zum Antworten