24/01/2024 - oregon ha scritto:
Da Windows Vista (parzialmente) e poi sempre più dal 7 al 10 e 11, esiste uno strato di controllo del rendering chiamato DWM che si frappone e controlla, tra le altre cose, il ridisegno della Non Client Area.
Non è disattivabile perché parte integrante di Windows ma è possibile impostare un attributo che consenta di far gestire alle applicazioni direttamente il PAINT della NC area.
Quindi, devi inserire la dichiarazione delle API opportuna
<DllImport("dwmapi.dll")>
Private Shared Function DwmSetWindowAttribute(ByVal hwnd As IntPtr, attr As Integer, ByRef attrValue As Integer, ByVal attrSize As Integer) As Integer
End Function
e nel Load la chiamata relativa per tale attributo
Const DWMWA_ALLOW_NCPAINT As Integer = 4
DwmSetWindowAttribute(Handle, DWMWA_ALLOW_NCPAINT, 1, Len(New Integer))
Inoltre devi chiamare in maniera opportuna la FillRectangle e non con valori casuali. Per riempire tutta l'area non client, puoi utilizzare questa riga d'esempio
g.FillRectangle(Brushes.Green, New Rectangle(0, 0, Width, Height))
Adesso sta a te calcolare un Rectangle opportuno, partendo da quello che ti ho indicato, per gestire solo la barra del titolo. Ricorda che dovrai fare tutto tu dato che stai gestendo tu quell'area e non Windows.
P.S. Systemred32 … “Fammi sapere se ti va di continuare, la facciamo insieme.” … non funziona così un forum, non si discute a richiesta e tra te e l'op. Se si ha qualcosa da suggerire si fa “a prescindere” da una “richiesta personale”. Queste richieste non hanno senso in un forum di discussione pubblica.
Non volevo postare il codice, volevo aiutarlo ad arrivarci da solo, questo è il mio se ti interessa, su Windows 11 funziona:
Partial Class Form1
Inherits System.Windows.Forms.Form
Private drag As Boolean
Private mouseX As Integer
Private mouseY As Integer
Private Const WM_NCHITTEST As Integer = &H84
Private Const HTLEFT As Integer = 10
Private Const HTRIGHT As Integer = 11
Private Const HTTOP As Integer = 12
Private Const HTTOPLEFT As Integer = 13
Private Const HTTOPRIGHT As Integer = 14
Private Const HTBOTTOM As Integer = 15
Private Const HTBOTTOMLEFT As Integer = 16
Private Const HTBOTTOMRIGHT As Integer = 17
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Private components As System.ComponentModel.IContainer
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
PanelTitleBar = New Panel()
MinimizeButton = New Button()
CloseButton = New Button()
PanelTitleBar.SuspendLayout()
SuspendLayout()
'Pannello che sostituisce la titlebar
PanelTitleBar.AccessibleName = ""
PanelTitleBar.BackColor = Color.Blue
PanelTitleBar.Controls.Add(MinimizeButton)
PanelTitleBar.Controls.Add(CloseButton)
PanelTitleBar.Dock = DockStyle.Top
PanelTitleBar.Location = New Point(0, 0)
PanelTitleBar.Name = "PanelTitleBar"
PanelTitleBar.Size = New Size(902, 49)
PanelTitleBar.TabIndex = 0
' Bottone per minimizzare
MinimizeButton.Anchor = AnchorStyles.Top Or AnchorStyles.Right
MinimizeButton.Location = New Point(831, 12)
MinimizeButton.Name = "MinimizeButton"
MinimizeButton.Size = New Size(31, 34)
MinimizeButton.TabIndex = 2
MinimizeButton.Text = "-"
MinimizeButton.UseVisualStyleBackColor = True
' Bottone per chiudere
CloseButton.Anchor = AnchorStyles.Top Or AnchorStyles.Right
CloseButton.Location = New Point(868, 12)
CloseButton.Name = "CloseButton"
CloseButton.Size = New Size(31, 34)
CloseButton.TabIndex = 1
CloseButton.Text = "x"
CloseButton.UseVisualStyleBackColor = True
' Form1
ClientSize = New Size(902, 589)
Controls.Add(PanelTitleBar)
FormBorderStyle = FormBorderStyle.None
Name = "Form1"
PanelTitleBar.ResumeLayout(False)
ResumeLayout(False)
End Sub
'Questo codice serve per usare il panel per spostare la finestra
Private Sub PanelTitleBar_MouseDown(sender As Object, e As MouseEventArgs) Handles PanelTitleBar.MouseDown
drag = True
mouseX = Cursor.Position.X - Me.Left
mouseY = Cursor.Position.Y - Me.Top
End Sub
Private Sub PanelTitleBar_MouseMove(sender As Object, e As MouseEventArgs) Handles PanelTitleBar.MouseMove
If drag Then
Me.Top = Cursor.Position.Y - mouseY
Me.Left = Cursor.Position.X - mouseX
End If
End Sub
Private Sub PanelTitleBar_MouseUp(sender As Object, e As MouseEventArgs) Handles PanelTitleBar.MouseUp
drag = False
End Sub
' Evento Click sul pulsante di chiusura
Private Sub CloseButton_Click(sender As Object, e As EventArgs) Handles CloseButton.Click
Me.Close()
End Sub
' Evento Click sul pulsante per minimizzare
Private Sub MinimizeButton_Click(sender As Object, e As EventArgs) Handles MinimizeButton.Click
Me.WindowState = FormWindowState.Minimized
End Sub
'Questo codice serve per ridimensionare il form senza bordi
Protected Overrides Sub WndProc(ByRef m As Message)
MyBase.WndProc(m)
If m.Msg = WM_NCHITTEST Then
Dim pt As Point = Me.PointToClient(Cursor.Position)
If pt.Y < 5 Then
If pt.X < 5 Then
m.Result = CType(HTTOPLEFT, IntPtr)
ElseIf pt.X > Width - 5 Then
m.Result = CType(HTTOPRIGHT, IntPtr)
Else
m.Result = CType(HTTOP, IntPtr)
End If
ElseIf pt.Y > Height - 5 Then
If pt.X < 5 Then
m.Result = CType(HTBOTTOMLEFT, IntPtr)
ElseIf pt.X > Width - 5 Then
m.Result = CType(HTBOTTOMRIGHT, IntPtr)
Else
m.Result = CType(HTBOTTOM, IntPtr)
End If
ElseIf pt.X < 5 Then
m.Result = CType(HTLEFT, IntPtr)
ElseIf pt.X > Width - 5 Then
m.Result = CType(HTRIGHT, IntPtr)
End If
End If
End Sub
Friend WithEvents PanelTitleBar As Panel
Friend WithEvents MinimizeButton As Button
Friend WithEvents CloseButton As Button
End Class
Le costanti HTTOP, HTTOPLEFT, HTTOPRIGHT puoi rimuoverle e modificare il codice in basso che sovrascrive il metodo WndProc se usi il panel attaccato ai lati alti del form, perchè il cursore passa sopra al panel e non te lo fa ridimensionare, dovresti lasciare un po' di spazio fra il pannello e i 3 lati alti del form, bastano pochi pixel.