Scrollen (Grundlegende Fragen)
-
Dankeschön, Martin! Du hast mir wiedereinmal weitergeholfen!
Aber ich habe immer noch ein Problem: Du hast mir vor längerer Zeit einen Code gegeben, der automatisch "mitscrollt" wenn ich mit der Tab- oder den Pfeiltasten durch meine GUI navigiere:
m_LastControl = m_CurControl; m_CurControl = GetFocus(); if( m_CurControl != m_LastControl && IsChild(m_CurControl) && NULL != m_CurControl ) { int iDelta = 0; CRect rcControl, rcParent; GetClientRect(&rcParent); m_CurControl->GetWindowRect(rcControl); ScreenToClient(&rcControl); CPoint ptScrollPosition = GetScrollPos(SB_HORZ); CPoint ptNewScrollPosition = ptScrollPosition; CSize sOffset = CSize(m_iSpaceOffset, m_iSpaceOffset); if (rcControl.top < rcParent.top) { iDelta += rcControl.top-rcParent.top-sOffset.cy; ptNewScrollPosition.y += iDelta; } else if (rcControl.bottom > rcParent.bottom) { iDelta += rcControl.bottom-rcParent.bottom+sOffset.cy; ptNewScrollPosition.y += iDelta; } rcControl.OffsetRect(ptScrollPosition-ptNewScrollPosition); if (rcControl.left < 0) ptNewScrollPosition.x += rcControl.left; if (rcControl.top < 0) ptNewScrollPosition.y += rcControl.top; if (ptScrollPosition!=ptNewScrollPosition) { m_iScrollPos += iDelta; SetScrollPos(SB_VERT, m_iScrollPos); ScrollWindow(0, -iDelta); } }Den Code führe ich in einem Timer mit einem Intervall von 50 ms. Wenn ich nun meine Anwendung starte ist der Scrollbalken immer an dem Element das zuletzt (dynamisch) auf meine Gui bei der initiaisierung hinzugefügt wurde.
Ich hab mir gedacht, dass ich in der OnShow (beim ersten Aufruf) den Fokus auf das Tab-Control setze, weil die Reiter ganz oben sind. Leider funktioniert das nicht.
Wie kann ich das unterdrücken?
Danke und Lg
Kerberos
-
Tab Control ? Rollbalken ? Dialog ?
Kanst Du mir sagen was überhaupt wie hier zusammen gebaut ist?
Ich verstehe nicht wie das alles zusammenhängt...Der Code setzt doch sowiso nur ein wen es sich um ein Child Control handelt. Ist dieser Code, denn für die Fehlpositionierung verantwortlich? Hast Du das geprüft?
-
Hi,
Also sobald ich das Codestück entferne ist der Scrollbalken ganz oben nach dem Start der Anwendung (so wie gewünscht).
Also ich habe einen Dialog, der es mir erlaubt zu scrollen. Wenn ich durch die dynamisch erzeugten Komponenten (unterschiedliche Anzahl) navigiere und in einen nicht sichtbaren Bereich komme, scrollt das das Fenster nicht automatisch mit.
Genau das macht der gepostete Code. Ich glaube dass der code irgendwie automatisch zu der Komponente scrollt, die zuletzt hinzugefügt wurde. Und jetzt würde ich gerne wissen wie ich das vermeiden kann?
Danke!
Kerberos
-
Dann setzt jemand eben den Focus auf eines der Controls weiter unten...
Dieser rollt doch nur zu dem Control, das den Focus hat. Also sorge dafür, dass das richtige Control den Focus hat.
-
Hi Martin,
ich hab folgendes Probiert:
Ich hab mir gedacht, dass ich in der OnShow (beim ersten Aufruf) den Fokus auf das Tab-Control setze, weil die Reiter des Tab-Controls ganz oben sind. Leider funktioniert das nicht.
OnShowWindow()
m_TabCtrl.SetFocus();OnInitDialog()
m_TabCtrl.SetFocus();Funktioniert auch nicht.
Danke!
Lg Kerberos
-
Evtl. nimmt das Tab-Control gar keinen Focus an und transferiert den sofort auf das erste Child Control! Geprüft? Für so etwas gibt es Spy++.
Solange WS_EX_CONTROLPARENT für ein Tab Control gesetzt ist, wird es niemals den Focus annemen. IMHO muss auch WS_TABSTOP gesetzt sein.
-
Hi Martin,
das ist aber sehr seltsam, weil WS_TABSTOP ist gesetzt und wenn ich mit der Tab-Taste "durchscrolle" dann bekommt das TabCtrl auch den Fokus und ich kann zwischen den einzelnen Reitern umher schalten.
Danke!
Lg Kerberos
-
Hi,
ich habe jetzt eine neue Vermutung: wenn ich das TabControl den Fokus hat, dann wird immer nach ganz unten gescrollt (bis zum Ende des TabControls).
Ich möchte aber, wenn das Tab-Control den Fokus hat, Ganz nach oben zu den Reitern des Tab-Controls scrollen.
Bekomm das aber nicht ganz hin.
Danke!
Lg Kerberos
-
Dann bauch doch Trace Ausgaben in Dein Programm ein. damit Du eingrenzen kannst wer wann scrolled.
Prüfe doch einfach wer, wann, wie den Focus hat...
Debug Ausgaben sind doch schnell bewerkstelligt.Ich vermute Du hast soviele Stellen in Deiem Programm die scrollen, dass dann einfach Chaos passiert.
-
Hi Martin,
nein, ich habe ein anderes Problem!
Ich habe das Problem dass, wenn mein TabCtrl den Fokus bekommt, an das ende (bottom) meines TabCtrls gescrollt wird.
Das hab ich jetzt gelöst, aber dann hab ich natürlich immer noch das Problem, dass IMMER ein Control selektiert ist und es wird automatisch dort hin gescrollt, sobald das fenster aktiviert wird.
D. h. Wenn ich im Fenster nur nach unten scrolle, aber den fokus nicht verändere, dann zu einem anderen Fenster wechsel und dann wieder mein Fenster aktiviere scrollt der algorithmus wieder an das Control das standardmäßig den Fokus hat.
Obwohl es eigentlich an dieser Position stehen bleiben sollte.
Das Problem ist, soblad ich MyDialog.SetFocus() aufrufe, bekommt automatisch mein CTabCtrl den Fokus (vllt. weil das das erste Element ist das hinzugefügt wird)
Lg Kerberos
-
Ich verstehe es dennoch nicht ganz. Alle Standard-Implementierungen von CDialog und CFormView merken sich das letzte Control, dass den Focus hat uns setzen diesen.
Hast Du hier etwas komplett selbst gebasteltes?Dann ändere doch die Reihenfolge, wenn das eine Lösung ist (SetWindowPos)!
-
Hi Martin!
Ich habe einen nicht modalen CDialog. Mein Dialog merkt sich auch das zuletzt aktive Control.
Das Problem liegt darin, wenn noch kein Control vom Benutzer selektiert wurde. Dann ist irgendwie automatisch mein TabCtrl selektiert.
Scrollt der Benutzer nach unten, aber selektiert dabei kein Control und verlässt das Fenster, dann scrollt der Altorihmus wieder automatisch nach oben sobald das Fenster aktiviert wird.
Danke
Lg Kerberos
-
Wenn OnIniotDialog mit TRUE verlassen wird, dann wird das erste Control mit WS_TABSTOP für den Focus bestimmt.
Setze den Fokus wie Du es möchtest und gib FALSE zurück!
-
Hi Martin,
das löst mein Problem leider auch nicht.
Das Problem ist, wenn ich
1. Ein Control selektiere
2. In einen Bereich Scrolle, in dem das selektierte Control nicht sichtbar ist
3. Das Fenster aktivieredann wird durch den Altorithmus wieder in den Bereich, wo das selektierte Control liegt gescrollt.
Ich denke dass das evtl. mit dieser Abfrage zusammenhängt
m_LastControl = m_CurControl; m_CurControl = GetFocus(); if( m_CurControl!=m_LastControl && NULL!=m_CurControl && IsChild(m_CurControl) ) { ... }Danke!
Lg Kerberos
-
Kann mir denn keiner weiterhelfen?
Grüße Kerberos
-
Debugge... Versuch Breakpoint gut zu setzen. Wer sezt wann welche Handles...
Das ist keine allgemeine Frage, die Du hier zu einem allgemeinen Problem stellst... Wie soll man hier helfen, wnen man nicht mal das genau Umfeld kennt.
Fakt ist: Es gibt Code der scrollt, Du mäöchtest das nicht, OK dann verhindere, dass der Code ausgeführt wird...
Ist doch bereits alles gesagt, oder?
-
Hi,
hab das Problem jetzt gelöst, bin zu lange an diesem scroll-problem gessesen. Nach einer längeren Pause kam die "Erläuchtung".
(...lag übrigens schon an diesem Code, den ich gepostet habe)
Lg Kerberos