Shakie
Erfahrenes Mitglied
Ich habe ein Control, dessen Rand ich selber zeichne. Dafür ändere ich den ClientBereich des Controls, wie hier beschrieben. Funktioniert auch soweit.
Nun möchte ich aber die Dicke des Randes zur Laufzeit ändern, d.h. einmal soll ein dicker Rand gezeichnet werden, später vielleicht ein dünner Rand. Das funktioniert nur zur Hälfte: der Rand wird zwar gezeichnet, wenn ich seine Dicke ändere (im Code die Variable "Randbreite"), aber die Child-Controls von meinem Control werden nicht neu angeordnet. Sie sitzen daraufhin im Rand!
Code zum Ändern der ClientSize sieht ungefähr so aus:
Also ich ändere jetzt zur Laufzeit den Wert von "Randbreite" von beispielsweise 5 auf 10 Pixel. Damit der Rand neu gezeichnet wird rufe ich die API RedrawWindow auf. Funktioniert auch soweit.
Aber:
Sagen wir ich habe ein Child-Control mit Location (0,0) auf meinem Control, also eines das oben links in der Ecke hocken soll. Nachdem sich die Dicke des Randes ändert, Befindet sich die Ecke mit den Client-Coordinaten (0,0) nicht mehr dort, wo sie vorher war, sondern 5 Pixel weiter rechts und weiter unten. Das Child-Control bekommt davon aber nichts mit und hockt jetzt halb im NonClient-Bereich (und überdeckt meinen selbst gezeichneten Rand).
Ich habe versucht PerformLayout aufzurufen, damit das Child-Control neu angeordnet wird. Aber der Aufruf hilft nichts!
Frage: Wie kann ich dem Control mitteilen, dass es seinen ClientBereich neu berechnen soll?
Nun möchte ich aber die Dicke des Randes zur Laufzeit ändern, d.h. einmal soll ein dicker Rand gezeichnet werden, später vielleicht ein dünner Rand. Das funktioniert nur zur Hälfte: der Rand wird zwar gezeichnet, wenn ich seine Dicke ändere (im Code die Variable "Randbreite"), aber die Child-Controls von meinem Control werden nicht neu angeordnet. Sie sitzen daraufhin im Rand!
Code zum Ändern der ClientSize sieht ungefähr so aus:
Code:
Private Sub AdjustClientRect(ByRef rect As RECT)
rect.Top += Randbreite
rect.Left += Randbreite
rect.Right -= Randbreite
rect.Bottom -= Randbreite
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_Messages.WM_NCCALCSIZE Then
' Größe des Client-Bereichs berechnen und nach m.LParam kopieren
If m.WParam <> IntPtr.Zero Then
Dim rcsize As NCCALCSIZE_PARAMS = DirectCast(Marshal.PtrToStructure(m.LParam, GetType(NCCALCSIZE_PARAMS)), NCCALCSIZE_PARAMS)
AdjustClientRect(rcsize.rcNewWindow)
Marshal.StructureToPtr(rcsize, m.LParam, False)
Else
Dim rcsize As RECT = DirectCast(Marshal.PtrToStructure(m.LParam, GetType(RECT)), RECT)
AdjustClientRect(rcsize)
Marshal.StructureToPtr(rcsize, m.LParam, False)
End If
m.Result = New IntPtr(1)
ElseIf m.Msg = WM_Messages.WM_NCPAINT Then
' code zum Zeichnen...
End If
Aber:
Sagen wir ich habe ein Child-Control mit Location (0,0) auf meinem Control, also eines das oben links in der Ecke hocken soll. Nachdem sich die Dicke des Randes ändert, Befindet sich die Ecke mit den Client-Coordinaten (0,0) nicht mehr dort, wo sie vorher war, sondern 5 Pixel weiter rechts und weiter unten. Das Child-Control bekommt davon aber nichts mit und hockt jetzt halb im NonClient-Bereich (und überdeckt meinen selbst gezeichneten Rand).
Ich habe versucht PerformLayout aufzurufen, damit das Child-Control neu angeordnet wird. Aber der Aufruf hilft nichts!
Frage: Wie kann ich dem Control mitteilen, dass es seinen ClientBereich neu berechnen soll?
Zuletzt bearbeitet: