MDI Parent Bereich nach eigenem Zeichnen einer Form neu setzen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von Bagplatt.

    MDI Parent Bereich nach eigenem Zeichnen einer Form neu setzen

    Hallo zusammen,

    Ich habe eine eigenes Formdesign für eines meiner Programmprojekte erstellt. Nun soll dieses ein MDI Parent sein.
    Nun, da ich ja die Formstyle auf None habe, wird beim Einstellen der MDIParent Eigenschaft die komplette Form als Parent angezeigt.

    Hat dass evt. etwas mit den Clientrectangle und NonClientRectangle was zu tun? Wie kann ich diese korrekt setzen?

    Zusätzlich würde mich interessieren, da ich von der Klasse Form erbe, wie ich nicht benötigte FormPropertys ausbelden kann.
    Ich weiß dass ich diese Überschreiben kann, aber komplett ausblenden?

    LG

    #Edit

    Wie ich ein Property ausblende habe ich gerade in Erfahrung gebracht :/

    VB.NET-Quellcode

    1. <Browsable(False), EditorBrowsable(EditorBrowsableState.Never)> _


    Bleibt aber immer noch bei dem Problem mit dem MDIParent

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Bagplatt“ ()

    @Eddy

    Ich bin gerade dabei das Beispiel zu übersetzen, CodeKonverter funktionieren bei dem Beispiel nicht.

    Habe gerade ein Problem

    Quellcode

    1. 0x0083
    entspricht welchem IntegerWert ? Bzw. wie kann ich den Konvertieren?

    #Nachtrag

    Ist die Variabel evt. der Wert um den der Bereich verschoben werden soll?
    Wenn ja funktioniert es nicht so ganz. Erst hab ich eine Exception-AccesViolation bekommen, und dann nach ein paar weiteren Versuchen passierte gar nichts weiter.

    VB.NET-Quellcode

    1. ​#Region "CLientAre"
    2. Structure RECT
    3. Public Top As Integer
    4. Public Left As Integer
    5. Public Bottom As Integer
    6. Public Right As Integer
    7. End Structure
    8. Structure NCCALCSIZE_PARAMS
    9. Public rcNewWindow As RECT
    10. Public RcOldWindow As RECT
    11. Public rcClient As RECT
    12. Public lppos As IntPtr
    13. End Structure
    14. Private Sub AdjustClientRect(ByRef rcClient As RECT)
    15. rcClient.Left += 10
    16. rcClient.Top += 10
    17. rcClient.Right -= 10
    18. rcClient.Bottom -= 10
    19. End Sub
    20. Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    21. MyBase.WndProc(m)
    22. Const WM_NCCALCSIZE As Integer = 10
    23. If m.Msg = WM_NCCALCSIZE Then
    24. If Not m.WParam = IntPtr.Zero Then
    25. Dim rcSize As NCCALCSIZE_PARAMS = CType(System.Runtime.InteropServices.Marshal.PtrToStructure(m.LParam, GetType(NCCALCSIZE_PARAMS)), NCCALCSIZE_PARAMS)
    26. AdjustClientRect(rcSize.rcNewWindow)
    27. System.Runtime.InteropServices.Marshal.StructureToPtr(rcSize.rcNewWindow, m.LParam, False)
    28. Else
    29. Dim rcSize As RECT = CType(System.Runtime.InteropServices.Marshal.PtrToStructure(m.LParam, GetType(RECT)), RECT)
    30. AdjustClientRect(rcSize)
    31. System.Runtime.InteropServices.Marshal.StructureToPtr(rcSize, m.LParam, False)
    32. End If
    33. m.Result = New IntPtr(1)
    34. Return
    35. End If
    36. End Sub
    37. #End Region

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Bagplatt“ ()

    Eddy schrieb:

    Also &H83



    Jop, jetzt "passiert" schon etwas. Zumindest ein Rand wird jetzt um den ClientBereich gezeichnet. Jedoch werden meine Paint Anweisungen nicht mehr gezeichnet.?

    Bin gerade überfragt. Erfolgt der Aufruf Paint vor dem verschieben oder danach?

    #Edit

    Zur Zeit ist dass ganze total verbuggt.

    Schaut euch dass Bild dazu an :

    Bilder
    • mdi.png

      86,35 kB, 984×614, 336 mal angesehen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Bagplatt“ ()

    Also die Groesse wird nicht mit diesem Wert geaendert, schaur die das hier mal an:

    VB.NET-Quellcode

    1. Private Sub AdjustClientRect(ByRef rcClient As RECT)
    2. rcClient.Left += 10
    3. rcClient.Top += 10
    4. rcClient.Right -= 10
    5. rcClient.Bottom -= 10
    6. End Sub

    Mach aus jeder 10 mal eine 20, dann hast du einen rand von 20px;

    Um nun den Rand bemalen zu koennen, also den NC-Bereich, schau hier rein.
    customerborderform.codeplex.com/wikipage?title=Painting NonClient Area&referringTitle=Home
    And i think to myself... what a wonderfuL World!
    Ja bin auch schon darauf gekommen :)

    @Eddy ob du´s glaubst oder nicht. Die Seite hatte ich vorhin schon mal offen. Hab mir aber gedacht dass es da doch bestimmt etwas kürzeres gibt, bzw dass man das in einer einzigen Zeile bewerkstelligen kann.

    Gut, dann werd ich dass auch mal dazu schreiben.

    Noch eine Frage :

    Habe in den ganzen Block WndProc noch´ne If Abfrage gesetzt ob überhaupt ein MDI vorliegt.

    Wenn jetzt vorher dass ClientRectangle bearbietet wurde, und ich jetzt die MDI zu False ändere, dann muss ich warscheinlich wieder die Funktion aufrufen und den Bereich wieder "verkleinern".

    Könnte ich dazu ganz einfach dass Property IsMIDI in meine Klasse holen und darin dann die Funktion zum bearbeiten der Größe aufrufen; sofern vonn True auf False gestellt wird, damit dass ursprüngliche Fenster wieder erstellt wird?
    Ja habe ich bereits.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    2. MyBase.WndProc(m)
    3. Const WM_NCCALCSIZE As Integer = &H83
    4. If MyBase.IsMdiContainer Then
    5. If m.Msg = WM_NCCALCSIZE Then
    6. If Not m.WParam = IntPtr.Zero Then
    7. Dim rcSize As NCCALCSIZE_PARAMS = CType(System.Runtime.InteropServices.Marshal.PtrToStructure(m.LParam, GetType(NCCALCSIZE_PARAMS)), NCCALCSIZE_PARAMS)
    8. AdjustClientRect(rcSize.rcNewWindow)
    9. System.Runtime.InteropServices.Marshal.StructureToPtr(rcSize.rcNewWindow, m.LParam, False)
    10. Else
    11. Dim rcSize As RECT = CType(System.Runtime.InteropServices.Marshal.PtrToStructure(m.LParam, GetType(RECT)), RECT)
    12. AdjustClientRect(rcSize)
    13. System.Runtime.InteropServices.Marshal.StructureToPtr(rcSize, m.LParam, False)
    14. End If
    15. m.Result = New IntPtr(1)
    16. Return
    17. End If
    18. End If
    19. End Sub

    Mir ging es um dass erneute verschieben. Sprich wenn die Property isMidi verändert wird. Der Rand bleibt ja tzd. bestehen, auch wenn MDI=False ist.

    Ich würde dass Property von MyBase überschreiben bzw. in meine Klasse holen, und von dort aus wenn auf False gesetzt wird die Form wieder in die Ursprüngliche Größe verwandeln.
    Evtl. ist der bereich weg, aber es wurde nicht neu gezeichnet und wirkt somit optisch als noch da. Du koenntest die Property IsMdiContainer ueberschreiben und im setter Invalidate callen. Wenn das nicht bringt, weiss ich es so auch nicht, koennte dann aber morgen mal im Archiv schauen, ich hatte so etwas mal gemacht.

    Mit SendMessage ist es auch moeglich, das neu zeichnen "in Auftrag zu geben", wenn das so nicht geht, schau ich dann noch mal.
    And i think to myself... what a wonderfuL World!