CEdit neu zeichnen
-
Hallo Zusammen
In einem Thread möchte ich ein Editfeld (IDC_EDIT1) neu zeichnen. Ich probierte bisher alle Möglichkeiten aus, aber keine Funktionierte.
Weder pEdit->Invalidate(); noch pEdit->UpdateWindow() noch pEdit->RedrawWindow(...); ..
Bei UpdateWindow erhalte ich während der Programmlaufzeit eine "Assert in validation" Fehlermeldung in der winocc.cpp
pEdit ist abgeleitet von CEdit* und das Control hat die Membervariable Control m_ctlEditWarn.
Wenn ich pEdit->Invalidate(TRUE); oder pEdit->Invalidate(FALSE);nehme, dann wird der gesamte Text im Editfeld verstaucht und ist nicht mehr lesbar. Ebenfalls erhalte ich dann ein SetWindowTextFehler des Debuggers in:
void CWnd::SetWindowText(LPCTSTR lpszString) { ENSURE(this); ENSURE(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL)); if (m_pCtrlSite == NULL) ::SetWindowText(m_hWnd, lpszString); else m_pCtrlSite->SetWindowText(lpszString); }
Dieser obige Fehler tritt, so ist mir gerade aufgefallen, je nach Lust und Laune auf. Ein paar mal ist alles korrekt, ein ander mal wieder nicht und ich weiss nicht wo der Fehler liegt! Als ich die PreTranslateMsg Funktion entfernte, war alles wieder normal. Jetzt hab ich aber nur normal gespeichert und wieder ausgeführt und schon wieder kommt die Fehlermeldung mit dem zerdrücktem Text.
Das hier hab ich in OnInitDialog:
LPVOID pParam = &m_ctlEditWarn; ::AfxBeginThread(WarnList,pParam); m_ctlEditWarn.SetTextColor(RGB(255,255,255)); m_ctlEditWarn.SetBackColor(TRANSPARENT); m_CtrlsResize.SetParentWnd(this); m_CtrlsResize.AddControl(IDC_EDIT1, BIND_BOTTOM | BIND_RIGHT | BIND_LEFT); m_CtrlsResize.AddControl(IDC_BACKGROUND, BIND_TOP | BIND_LEFT | BIND_RIGHT | BIND_BOTTOM); m_CtrlsResize.FixControls();
Entferne ich obigen Code (ausser den Thread-Start), dann geht es wieder normal. Bisher bereitete mir aber CtrlsResize KEINE Probleme und jetzt plötzlich aber.. wieso das denn? Mit CtrlsResize (hab ich von hier: http://visualcpp.net/index.php?qID=29 ) sollten die Controls bei Maximieren und Minimieren automatisch angepasst werden was auch klappt.
UINT CHauptDlg::WarnList(LPVOID pParam) { CString somecode, s; CString a; CInternetSession session("WarnList",1,INTERNET_OPEN_TYPE_PRECONFIG); CStdioFile* pFile = NULL; CString strUrl("http://www.nfws.ch/inc/warnlist_scmt.php"); CEdit *pEdit = (CEdit*)pParam; do { try { pFile = session.OpenURL(strUrl,1,INTERNET_FLAG_TRANSFER_BINARY,NULL,0); if(pFile) { while (pFile->ReadString(somecode) != NULL) { a = s + somecode; a.Replace(_T("\\r\\n"), _T("\r\n")); a.Delete(0,1); } pFile->Close(); } } catch (CInternetException* e) { e->Delete(); session.Close(); CloseHandle(session); } pEdit->SetWindowTextA(a); //Hier übte ich jenste Versuche... } while(1+1); return 0; }
Gibt es andere Möglichkeiten? Ein UpdateData(TRUE) im Thread hineinzuschreiben bringt Compiler-Fehler a la CWnd::UpdateData is not a Member of CHauptDlg...
Mir wurde mal etwas gesagt betreffend MessageLoop. Wie stelle ich das an? Wenn es mit PreTranslateMessage passieren sollte, diese Funktion beschert mir ein verzerrter Text und ein SetWindowText-Debug Fehler...Im Moment komme ich nicht mehr draus was nun das alles soll..
lg
Wolf
-
UpdateWindow erzewingt ein neues zeichnen.
Wenn Du einen ASSERT bekommst, dann sag uns genau wo und was der Callstack anzeigt.
Ich würde sagen, dass entweder das Objektoder das Fenster ungültig (d.h. nicht erzeugt oder attached, oder zerstört) ist.Ich würde Dir raten einfach etwas mahr MFC Grundlagen zu erlernen.
-
Weil du immer noch aus deinem Thread auf die GUI zugreifst, das macht man nicht. Dafür gibt es send-/paostMessage und und due entsprechenden UserMessages die du dir dafür einrichten kannst, damit kannst du deinen Text an die GUI senden welche dann den Text in dein Edit rein schreibt. Sollte nicht all zu schwer sein wenn man sich mal damit auseinander setzt.
PreTranslateMessage, braucht man eigentlich fast nie (geht mir zumindest so), also richtig machen und dem Thread keinen Zeiger auf irgendein objekt mitgeben und das sollte laufen.