[CDialog] Nichtmodal ruft Modal, Modal versteckt sich ..
-
Hab es auf die folgende Art versucht, was aber nichts geändert hat:
void PatternDialog::OnStnDblclickColor() { COLORREF cr; // .. CColorDialog dlg(cr); dlg.SetParent(this); if (dlg.DoModal()==IDOK) { // .. } }
Der aufrufende nichtmodale Dialog verliert den Focus, aber der modale Dialog wird nicht (sofort) angezeigt.
// EDIT:
Jetzt komt noch der folgenden Assert hinzu:_AFXWIN_INLINE CWnd* CWnd::SetParent(CWnd* pWndNewParent) { ASSERT(::IsWindow(m_hWnd)); return CWnd::FromHandle(::SetParent(m_hWnd, pWndNewParent->GetSafeHwnd())); }
Scheinbar hat der aufrufende Dialog kein Fenster-Handle?
-
Hmmm..... ich muss ganz ehrlich sagen.... ich bin gerade überfragt ob das so überhaupt geht was Du da vorhast...
Du hast doch irgend ein Modales-Fenster (deine Anwendung). Vermutlich setzt die MFC den Dialog automatisch vor dieses Fenster und vermutlich ist Dein nicht-modales Fenster auch auf dieser Ebene...
Du kannst versuchen das nicht-modale Fenster in der Z-Ebene ganz nach hinten zu tun:
SetWindowPos mit HWND_BOTTOM
-
Ich komme nicht weiter. Hab keine Ahnung, wie der Assert zu interpretieren ist (welches m_hWnd wird untersucht? Das Handle des Aufrufers (nichtmodaler Dialog) ist nicht NULL).
Ich habe eine MFC-Anwendung ohne Doc-View-Architektur, also nur eine View und das Mainframe. Über einen Menüeitrag öffne ich weiter nichtmodale Fenster, über die Eigenschaften der View eigestellt werden. Diese Dialoge benötigen zB. den CColorDialog, welcher mit doModal() nicht sichtbar ist, erst nachdem man [alt] gedrückt hat, springt der Dialog nach vorn und wird sichtbar.
Wie bzw. wo muss ich nach dem Problem suchen?
-
don_basto schrieb:
Diese Dialoge benötigen zB. den CColorDialog, welcher mit doModal() nicht sichtbar ist, erst nachdem man [alt] gedrückt hat, springt der Dialog nach vorn und wird sichtbar.
Wie bzw. wo muss ich nach dem Problem suchen?
Haar genau das gleiche Problem hab ich seit gestern abend in meiner Anwendung! Bis gestern hat es noch funktioniert. Jetzt kommen bei mir die modalen Dialoge auch nur nach vorne, wenn ich Alt drücke. Ich weiß nicht wieso.
Wer eine Lösung hat, immer her damit.
-
So, nachdem ich endlich die richtigen Suchwörter in Google rausgefunden habe, um vernünftige Ergebnisse für das Problem zu finden, habe ich das hier gefunden:
http://www.codeguru.com/forum/printthread.php?t=305602
In dem Thread wird beschrieben, das das Problem auftaucht, wenn der GUI-Thread eine volle CPU-Auslastung verursacht. Genau das habe ich nach einem Blick in meinem Taskmanager feststellen können.
Nur habe ich komischerweise nichts in meiner GUI am laufen (keine Berechnung, keine Animationen oder so).
Also habe ich mal in meine GUI-Klassen für das Hauptfenster geschaut, welches die 100% CPU-Last verursachen soll. Habe den Fehler gefunden: in meiner OnPaint()-Methode habe ich keine Codezeile mehr stehen gehabt. Ich hatte da vorher was anderes drin, habe es aber auskommentiert.
Anscheinend muß in OnPaint() irgend etwas stehen, damit es keine 100% Auslastung gibt.
Jetzt rufe ich als Ausgleich einfach OnPaint() aus der Superklasse auf.
Aber im Prinzip gilt folgendes: 100% CPU-Auslastung bringt modale Dialog nicht autom. nach vorne.
-
Hab das Problem wie im dem Link beschrieben: Ich zeichne in die View mit OpenGL. Allerdings hab ich nur eine CPU-Auslastung von 65%.
Beim Versuch, die Framerate zu drosseln, hat sich das Programm merkwürdig verhalten. Eigentlich sollte OnPaint() nur aufgerufen werden, wenn das Fenster irgendwie Invalidate() ist. Und ich nehme an, das durch den SwapBuffers()-Befehl dieser Zustand ausgelöst wird.
Wenn ich aber nun nur noch aller 100 msek. zeichen (ansonsten überspringe ich zeichnen und swappen), sollte eigentlich die CPU-Last sinken, aber plötzlich ist sie bei 100%.
// wird in CChildView::OnPaint() aufgerufen void CChildView::DrawGL() { static DWORD lastTickCount = 0; DWORD tickCount = GetTickCount(); if (tickCount-lastTickCount>100) { lastTickCount = tickCount; glClear(GL_COLOR_BUFFER_BIT); // .. SwapBuffers(m_clientDC->m_hDC); } }
Eigentlich sollte keine flüssige Animation zustande kommen, da OnPaint() nicht mehr ständig über das Swappen ausgelöst wird. Aber des OnPaint() wird trotzdem ständig aufgerufen.
Versteh ich grad nicht..
-
don_basto schrieb:
Wenn ich aber nun nur noch aller 100 msek. zeichen (ansonsten überspringe ich zeichnen und swappen), sollte eigentlich die CPU-Last sinken, aber plötzlich ist sie bei 100%.
// wird in CChildView::OnPaint() aufgerufen void CChildView::DrawGL() { static DWORD lastTickCount = 0; DWORD tickCount = GetTickCount(); if (tickCount-lastTickCount>100) { lastTickCount = tickCount; glClear(GL_COLOR_BUFFER_BIT); // .. SwapBuffers(m_clientDC->m_hDC); } }
Wie oft rufst Du denn diese Methode "DrawGL" auf??? Zeig mal den Code dazu...
Du solltest Dir mal timeSetEvent anschauen...
-
Haste mal versucht die OnPaint() aus der Superklasse aufzurufen?
void CChildView::OnPaint() { CWnd::OnPaint(); // CWnd, wenn CChildView von CWnd abgeleitet ist. DrawGL(); }
Ich hab das wie gesagt gemacht, seit dem gibts keine unnötige Auslastung. Vielleicht hilfts auch bei dir?
-
void CChildView::OnPaint() { //CWnd::OnPaint(); if (m_renderContext) { wglMakeCurrent(NULL, NULL); wglMakeCurrent(m_clientDC->m_hDC, m_renderContext); DrawGL(); } }
Füge CWnd::OnPaint() hinzu, verhält sich mein Programm so, wie ich es erwarten würden: Es aktuallisert sich nur, wenn ich des Fenster bewege etc. (Machmal erscheint nur ein weises Bild, da ja nichts in DrawGL() gezeichnet wird..)
-
Also dieses CWnd::OnPaint() hat geholfen.
Hab mir einen Timer gesetzt und aktualisiere darüber alle 10ms das Fenster.
Mit dem Kode:void CChildView::OnTimer(UINT nIDEvent) { if (nIDEvent==m_timer) { OnPaint(); } else { CWnd::OnTimer(nIDEvent); } } void CChildView::OnPaint() { CWnd::OnPaint(); if (m_renderContext) { // .. } } void CChildView::DrawGL() { glClear(GL_COLOR_BUFFER_BIT); // .. SwapBuffers(m_clientDC->m_hDC); }
Ich danke euch für die Tipps!
Bis demnächst,
don_basto