过了一会儿,但它就这样了:
a) 您必须删除表单的主题
SetWindowTheme(Me.Handle, String.Empty, String.Empty)
b) 对于 m.WParam = 1,GetDCEx 失败。因此,GetWindowDC 就是您所需要的。你的覆盖是这样的
Protected Overrides Sub WndProc(ByRef m As Message)
MyBase.WndProc(m)
If (m.Msg = 133) Then
If m.WParam = 1 Then
Dim g As Graphics = Graphics.FromHdc(GetWindowDC(Me.Handle))
Using g
g.DrawLine(Pens.Red, New PointF(0, 0), New PointF(30, 30)) 'Draw Here
End Using
Me.Refresh()
Else
Dim DCX_CACHE As Integer = 2
Dim DCX_WINDOW As Integer = 1
Dim g As Graphics = Graphics.FromHdc(GetDCEx(Me.Handle, m.WParam, (DCX_WINDOW Or DCX_CACHE)))
Using g
g.DrawLine(Pens.Red, New PointF(0, 0), New PointF(30, 30)) 'Draw Here
End Using
Me.Invalidate()
Me.Refresh()
End If
End If
End Sub
你需要的另外两个声明如下
<Runtime.InteropServices.DllImport("user32.dll")>
Private Shared Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
End Function
<Runtime.InteropServices.DllImport("uxtheme.dll")>
Private Shared Function SetWindowTheme(ByVal hWnd As IntPtr, ByVal appName As String, ByVal partList As String) As Integer
End Function
我在 form_load 事件中调用了 SetThemeWindow,它运行良好。 Using 语句用于 GC 处理图形(清理),而 Me.Refresh() 用于客户区在调整表单大小(或最大化)时不会受到影响。
感谢 Mike(来自 How to set the client area (ClientRectangle) in a borderless form?)的 C# 代码,该代码相当完整且方向不同。他的编码针对 NC 区域大小,但也针对它们进行绘制。这里更多的是绘画。
希望对你有帮助!
[编辑]
我进行了第一次编辑,但进一步调查表明它可能在特定情况下有效,而不是实际的“最终解决方案”!
最近的发现也是如此。 GetDCEx 函数实际上失败了,因为 m.WParam 没有提供所需的信息,并且要让 GetDCEx 函数工作,您不需要“m.WParam = 1” IF 测试。只需使用以下内容:
Using g As Graphics = Graphics.FromHdc(GetDCEx(Me.Handle, IntPtr.Zero, (DeviceContextValues.Window Or DeviceContextValues.Cache)))
g.ExcludeClip(New Rectangle((Me.Width - Me.ClientSize.Width) / 2, (Me.Height - Me.ClientSize.Height) - ((Me.Width - Me.ClientSize.Width) / 2), Me.ClientRectangle.Width, Me.ClientRectangle.Height))
g.FillRectangle(Brushes.DarkRed, New Rectangle(0, 0, Me.Width, Me.Height))
g.DrawRectangle(Pens.Blue, New Rectangle(0, 0, Me.Width - 1, Me.Height - 1))
g.DrawString(Me.Text, New Font("Tahoma", 10), Brushes.LightCyan, New PointF(Me.Width / 2 - Len(Me.Text) / 2, 4))
End Using
而不是您拥有的 IF 块,并将 GetDCEx 的第二个参数作为 Intptr.Zero 传递。你永远不会得到一个空返回值。这也绘制了一个边框(有点像某些 Office 或 MS 软件)和水平居中的表单文本(或标题)标题栏。这幅画有一个不包括客户区的附加物。这样,这个区域(客户端)就没有问题了。希望对您有所帮助。