Shakie
Erfahrenes Mitglied
Hallo,
ich möchte ein Control schreiben, bei dem der Benutzer mit der Maus die Größe des Controls verändern kann.
Dazu fange ich in WndProc die WM_NCCALCSIZE-Nachricht ab und setze das Ergebnis (m.Result) zum Beispiel auf HTLEFT, damit der Benutzer den linken Rand verschieben kann.
Das funktioniert auch soweit ganz gut. (Code siehe unten, kommt teilweise aus diesem Beispiel)
Das Ganze hat aber einen Haken: Windows verändert die Z-Order des Controls, wodurch mein ganzes Layout durcheinander kommt. Die Z-Reihenfolge wird derart verändert, dass das Control nun Z-Order Null hat (also selber Effekt wie Control.BringToFront).
Daraufhin wollte ich auch nocht WM_WINDOWPOSCHANGING abfangen und den Flag SWP_NOZORDER setzen, damit die Z-Order-Reihenfolge beibehalten wird. Aber das setzen des Flags bewirkt einfach gar nichts. Ich merke keine Veränderung im Verhalten, egal ob ich den Flag setze oder nicht. Hier der gesamte Code:
Kann mir jemand sagen, was ich falsch mache oder kennt jemand eine bessere Möglichkeit? Mein Ziel ist eigentlich nur ein Control, dessen Dock-Eigenschaft ich auf irgend einen Rand setze und der Benutzer dann mit der Maus die Größe des Controls verändern können soll.
ich möchte ein Control schreiben, bei dem der Benutzer mit der Maus die Größe des Controls verändern kann.
Dazu fange ich in WndProc die WM_NCCALCSIZE-Nachricht ab und setze das Ergebnis (m.Result) zum Beispiel auf HTLEFT, damit der Benutzer den linken Rand verschieben kann.
Das funktioniert auch soweit ganz gut. (Code siehe unten, kommt teilweise aus diesem Beispiel)
Das Ganze hat aber einen Haken: Windows verändert die Z-Order des Controls, wodurch mein ganzes Layout durcheinander kommt. Die Z-Reihenfolge wird derart verändert, dass das Control nun Z-Order Null hat (also selber Effekt wie Control.BringToFront).
Daraufhin wollte ich auch nocht WM_WINDOWPOSCHANGING abfangen und den Flag SWP_NOZORDER setzen, damit die Z-Order-Reihenfolge beibehalten wird. Aber das setzen des Flags bewirkt einfach gar nichts. Ich merke keine Veränderung im Verhalten, egal ob ich den Flag setze oder nicht. Hier der gesamte Code:
Code:
Imports System.Runtime.InteropServices
Public Class ResizableControl
Inherits Control
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Const Randbreite As Integer = 10
Dim LeftR As New Rectangle(0, Randbreite, Randbreite, Me.Height - 2 * Randbreite)
If m.Msg = WM_Messages.WM_NCHITTEST Then
' Position des Mauszeigers auslesen
Dim MausPos As Point = Me.PointToClient(New Point(m.LParam.ToInt32))
' Überprüfen, ob sich der Mauszeiger im linken Rand des Controls befindet
' (Analog Prüfungen, ob sich der Mauszeiger in einem anderen Rand befindet, habe ich weggekürzt)
If LeftR.Contains(MausPos) And (Me.Dock = DockStyle.Right Or Me.Dock = DockStyle.None) Then
' Control links resizable machen
m.Result = New IntPtr(WM_NCHITTEST.HTLEFT)
Else
MyBase.WndProc(m)
End If
ElseIf m.Msg = WM_Messages.WM_WINDOWPOSCHANGING Then
Dim WindowPosition As Windowpos = DirectCast(Marshal.PtrToStructure(m.LParam, GetType(Windowpos)), Windowpos)
Const SWP_NOZORDER As UInteger = &H4
' Flag zum Beibehalten der Z-Order setzen, was aber nicht funktioniert
WindowPosition.flags = SWP_NOZORDER Or WindowPosition.flags
Marshal.StructureToPtr(WindowPosition, m.LParam, True)
Else
MyBase.WndProc(m)
End If
End Sub
Private Enum WM_Messages As Integer
WM_NCHITTEST = &H84
WM_WINDOWPOSCHANGING = &H46
End Enum
Public Structure Windowpos
Public hwnd As IntPtr
Public hwndInsertAfter As IntPtr
Public x As Integer
Public y As Integer
Public cy As Integer
Public flags As UInteger
End Structure
Private Enum WM_NCHITTEST As Integer
HTBOTTOM = 15
HTLEFT = 10
HTRIGHT = 11
HTTOP = 12
End Enum
End Class
Zuletzt bearbeitet: