正如標題所述,是否有可能/如何創建自定義窗口來繪製?通常情況下,你只需要使用一個窗體和表單控件,但是我希望自己的窗口具有一個可以掛鉤並處理繪製事件等的句柄。這可能嗎?從本質上講,我只需要一個容器來存放我的程序的圖像,而不是一個Form。如果不在VB.Net中,是否可以在C#中使用?如何在VB.net中創建自定義窗口(不是表單對象)?
編輯: 我只是不是很喜歡窗口如何繪製(即使對繪畫事件的控制)。我刪除了窗體邊框和控件欄,並用我自己的函數(放置最大/最小/退出按鈕,標題,窗體邊框和尺寸等)替換它們,所以我使用的窗體基本上只是一個浮動面板 - 雖然內置掛鉤,當然很好。但形式依然閃爍過多,所以我想自己處理所有事情。我在所有使用的控件上使用doublebuffering,我使用setbounds來移動/調整控件的大小,而不是單獨設置寬度/高度(減少一些閃爍)。我在窗體的繪畫事件中繪製窗體邊框,其餘部分繪製爲控件(包括窗體的頂部欄)。
我大多討厭我擴展窗體時看到的黑盒子(通常在縮小窗口大小時看不到,但仍有一些閃爍)。另一種方法,或許是一種不同的繪製方式(在VB 2010中)或者其他的方法,我猜也可以。
編輯(再次): 不管窗體上有多少個控件,都會發生黑框問題。如果我嘗試手動調整它的大小(從表單繼承的下面發佈的自定義空表單控件),在單擊和拖動事件期間在每個鼠標移動過程中使用setbounds(不會在沒有預期的情況下發生,所以我知道它沒有運行超過它必須)。
EDIT(代碼):沒有控制 http://img211.imageshack.us/img211/900/j9c.png 因此,即使在空白的「SimpleForm」(如張貼在第一個答案「),當調整爲較大(在PIC,調整東北),黑匣子在那裏的形式將畫繪製的ControlStyles/backbuffering做,張貼在第二個答案,以及張貼漢斯的CreateParams這是我用來設置形式界限:。
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or &H2000000
cp.Style = cp.Style Or &H2000000
Return cp
End Get
End Property 'CreateParams
Public Sub New(ByRef ContentFolder As String, ByRef x As Integer, ByRef y As Integer, ByRef w As Integer, ByRef h As Integer)
FormBorderStyle = FormBorderStyle.None
'Note, I have tried the original suggested control styles in many combinations
Me.SetStyle(ControlStyles.OptimizedDoubleBuffer Or ControlStyles.ResizeRedraw Or ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint
UpdateStyles()
OL = x 'Used for resizing, to know what the original bounds were - especially in maximizing, didn't like the standards maximize call
OT = y
OW = w
OH = h
BackColor = Color.White
BorderColor = New Pen(BarColor.Color)
MinimumSize = New Size(200, 200)
TransparencyKey = Color.FromArgb(255, 255, 0, 128)
CF = ContentFolder
ControlBar = New FormBar(Me, "Explorer woo", CF)
AddHandler Me.Load, AddressOf EF_Load
AddHandler Me.MouseUp, AddressOf EF_MouseUp
AddHandler Me.MouseDown, AddressOf EF_MouseDown
AddHandler Me.MouseMove, AddressOf EF_MouseMove
AddHandler Me.LostFocus, AddressOf EF_LostFocus
End Sub
Public Sub EF_Load(ByVal sender As Object, ByVal e As EventArgs)
SetFormBounds(OL, OT, OW, OH)
End Sub
Protected Overrides Sub OnSizeChanged(ByVal e As EventArgs)
ControlBar.SetBar(Width) 'Sets the width of controlbar to new width, and updates position of the 3 top-right form buttons
If Not (_backBuffer Is Nothing) Then
_backBuffer.Dispose()
_backBuffer = Nothing
End If
RaiseEvent Resized(Me, e) 'Resizes controls in custom handler, in this example, it is unused - with controls, they don't flicker when resized though
MyBase.OnSizeChanged(e)
End Sub
Private Sub SetFormBounds(ByRef l As Integer, ByRef t As Integer, ByRef w As Integer, ByRef h As Integer)
If w < Me.MinimumSize.Width Then
w = Me.MinimumSize.Width
l = Left
End If
If h < Me.MinimumSize.Height Then
h = Me.MinimumSize.Height
t = Top
End If
If l = Left AndAlso t = Top AndAlso w = Width AndAlso h = Height Then Exit Sub
ControlBar.SetBar(w)
SetBounds(l, t, w, h)
'Used for detecting if user coords are on the form borders with L-shaped areas so as to not include too much of the interior of the bar, Borderthickness = pixel width of border
CornerRects = New List(Of Rectangle) From {{New Rectangle(0, 0, BorderThickness, 15)}, {New Rectangle(0, 0, 15, BorderThickness)}, {New Rectangle(Width - 15, 0, 15, BorderThickness)}, {New Rectangle(Width - BorderThickness, 0, BorderThickness, 15)}, {New Rectangle(0, Height - 15, BorderThickness, 15)}, {New Rectangle(BorderThickness, Height - BorderThickness, 10, BorderThickness)}, {New Rectangle(Width - BorderThickness, Height - 15, BorderThickness, 15)}, {New Rectangle(Width - 15, Height - BorderThickness, 10, BorderThickness)}}
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
If _backBuffer Is Nothing Then
_backBuffer = New Bitmap(Me.ClientSize.Width, Me.ClientSize.Height)
End If
Dim g As Graphics = Graphics.FromImage(_backBuffer)
g.Clear(SystemColors.Control)
'Draw Control Box
g.TextRenderingHint = Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit
g.FillRectangle(BarColor, 0, 0, Width, ControlBar.Height)
If ControlBar.Title <> "" Then g.DrawString(ControlBar.Title, ControlBar.Font, ControlBar.FontBrush, ControlBar.TextLeft, ControlBar.TextTop)
g.DrawImage(FormBar.bmpCorners(0), 0, 0) 'Makes transparent corner, very small bitmap created at run-time
g.DrawImage(FormBar.bmpCorners(1), Width - FormBar.bmpCorners(0).Width, 0)
'Draw Control Box buttons top right
If ControlBar.ExitButton.Enabled = True Then g.DrawImage(ControlBar.ExitButton.Img, ControlBar.ExitButton.Rect.X, ControlBar.ExitButton.Rect.Y)
If ControlBar.MaximizeButton.Enabled = True Then g.DrawImage(ControlBar.MaximizeButton.Img, ControlBar.MaximizeButton.Rect.X, ControlBar.MaximizeButton.Rect.Y)
If ControlBar.MinimizeButton.Enabled = True Then g.DrawImage(ControlBar.MinimizeButton.Img, ControlBar.MinimizeButton.Rect.X, ControlBar.MinimizeButton.Rect.Y)
If Not ControlBar.Ico Is Nothing Then g.DrawImage(ControlBar.Ico, 5, 5) 'Draw Control Box icon (program icon) if it is set
'Draw the form border
For i = 0 To BorderThickness - 1
g.DrawLine(BorderColor, i, ControlBar.Height, i, Height - 1)
g.DrawLine(BorderColor, Width - 1 - i, ControlBar.Height, Width - 1 - i, Height - 1)
g.DrawLine(BorderColor, BorderThickness, Height - 1 - i, Width - BorderThickness, Height - 1 - i)
Next
g.Dispose()
e.Graphics.DrawImageUnscaled(_backBuffer, 0, 0)
End Sub
Protected Overrides Sub OnPaintBackground(ByVal pevent As PaintEventArgs)
End Sub
這是非常* *不清楚爲什麼你正在尋找一種替代。 Form類是一個很好的.NET封裝類,用於本地窗口,並允許任何你想用窗口做的事情。具體說明你想要解決什麼問題。 –
是什麼讓你認爲「自己處理所有事情」不會引起閃爍?這是孩子窗戶工作方式的先天,你會做一堆工作,最終會遇到完全相同的問題。只是不要使用兒童窗戶。檢查[這個答案](http://stackoverflow.com/questions/2612487/how-to-fix-the-flickering-in-user-controls/2613272#2613272)快速修復。 –
嗯,我看到這個問題已經編輯,因爲我寫了我的答案。在這種情況下,漢斯是對的:如果你做錯了,你自己畫的東西仍然會閃爍。有更好的方法來解決這個問題。我認爲它可以作爲[XY問題]的一般示例(http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem),以及爲什麼你應該解釋所有這些細節你第一次嘗試完成什麼。 –