vb.net的窗體屬性中,有個屬性叫TransparencyKey,它能決定在窗體上,哪種顏色所在的區域透明。
注意:TransparencyKey屬性對窗體標題欄和外框無效。
如果我們想讓窗體透明,如果你的窗體背景顏色是默認的,只要在窗體的Load事件加入一句代碼就行:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.TransparencyKey=SystemColors.Control
End Sub
運行后,你會發現窗體除標題欄和外框都透明了。
如果你的窗體背景色是別的顏色,比如是紅色,就將代碼
Me.TransparencyKey=SystemColors.Control
改成:
Me.TransparencyKey=Color.Red
這么看來,建立一個透明窗體看來是很容易的一件事。但窗體透明有什么用呢?我首先想到就是做一個不規則的窗體。
我是這樣設想的:
我準備的圖片是一個小黑狗,狗周圍的顏色值=Color.FromArgb(255, 0, 255) 。如下圖。
我這個黑狗圖片在我的電腦路徑是: d:\test.png
代碼如下:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
PictureBox1.ImageLocation="d:\test\1.png" '設置圖片
Me.FormBorderStyle=FormBorderStyle.None '設置窗體的無標題欄,無邊框樣式
PictureBox1.SizeMode=PictureBoxSizeMode.AutoSize '讓圖片控件尺寸隨圖片大小自動變化
PictureBox1.Location=New Point(0, 0)
Me.TransparencyKey=Color.FromArgb(255, 0, 255) '設置窗體需要透明的顏色
End Sub
Private Sub PictureBox1_SizeChanged(sender As Object, e As EventArgs) Handles PictureBox1.SizeChanged
'讓窗體跟圖片框尺寸一樣大小
Me.Width=PictureBox1.Width
Me.Height=PictureBox1.Height
End Sub
Private Sub PictureBox1_DoubleClick(sender As Object, e As EventArgs) Handles PictureBox1.DoubleClick
Close()
End Sub
按F5測試運行,窗體上就會出現一條小黑狗,一個不規則的窗體就根據這個黑狗的圖片就成功生成了。鼠標雙擊這個黑狗就可以關閉程序,只可惜不能用鼠標移動這只黑狗。
我們再導入相應API,再加上PictureBox1的鼠標移動事件,就可以實現用鼠標移動這條小狗,全部代碼如下:
Public Class Form1
'以下是移動無標題欄窗體
Declare Auto Function ReleaseCapture Lib "user32.dll" Alias "ReleaseCapture" () As Boolean
'API ReleaseCapture函數是用來釋放鼠標捕獲的
Declare Auto Function SendMessage Lib "user32.dll" Alias "SendMessage" (ByVal hWnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr
'向windows發送消息
Public Const WM_SYSCOMMAND As Integer=&H112&
Public Const SC_MOVE As Integer=&HF010&
Public Const HTCAPTION As Integer=&H2&
'以上是移動無標題欄窗體
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
PictureBox1.ImageLocation="d:\test\1.png" '設置圖片
Me.FormBorderStyle=FormBorderStyle.None '設置窗體的無標題欄,無邊框樣式
PictureBox1.SizeMode=PictureBoxSizeMode.AutoSize '讓圖片控件尺寸隨圖片大小自動變化
PictureBox1.Location=New Point(0, 0)
Me.TransparencyKey=Color.FromArgb(255, 0, 255) '設置窗體需要透明的顏色
End Sub
Private Sub PictureBox1_SizeChanged(sender As Object, e As EventArgs) Handles PictureBox1.SizeChanged
'讓窗體跟圖片框尺寸一樣大小
Me.Width=PictureBox1.Width
Me.Height=PictureBox1.Height
End Sub
Private Sub PictureBox1_DoubleClick(sender As Object, e As EventArgs) Handles PictureBox1.DoubleClick
Close()
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
If e.Button=MouseButtons.Left Then '移動無標題欄窗體
ReleaseCapture()
SendMessage(Me.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0)
End If
End Sub
End Class
以上代碼在 visual studio 2022 測試成功。運行結果就是出現下面這只小黑狗。
根據圖片生成不規則窗體
是Microsoft公司開發的一種通用的基于對象的程序設計語言,為結構化的、模塊化的、面向對象的、包含協助開發環境的事件驅動為機制的可視化程序設計語言。
VB是微軟曾經大力推薦過的編程語言,微軟創始人比爾蓋茨非常鐘情于Basic編程語言。這種語言集成在Visual Studio開發套件中打包發布,從VB1.0版發展到VB6版本,后來被號稱VB殺手的delphi打敗,停止更新。這種語言以開發快速、上手快著稱。用戶可以非常快速的設計出標準windows窗體界面。它可以在windows系統綠色化運行,無需安裝,因為它是微軟官方語言,系統中已經自帶了msvbvm60.dll之類的運行時支持庫。注意它的名稱中有個vm,大家也可以把它理解成vb的運行虛擬機。
是Visual Basic的一種宏語言,主要能用來擴展Windows的應用程序功能,特別是Microsoft Office軟件,它也可以用于其他支持VBA的環境中。
VBA是VB的一個子集。必須寄生于已有的應用程序,不能編譯成EXE可執行文件,也不離開宿主環境獨立運行。比如excel中的VBA,它就不能離開excel環境獨立運行。
而VB是完整的編譯語言,內部代碼經過編譯成exe后解釋執行,運行速度更快,可以離開宿主環境獨立運行,應用面更廣。VBA代碼比如模塊、類模塊可以簡單改動成為VB的模塊
比較以上兩者,我們就發現VBA相對于VB來說功能上都弱很多。如果從VBA向VB方向遷移,可以發現很多相似之處,升級成本最小。
上圖就是我用VB制作的一個讀取EXCEL表格數據的演示程序。后期我將基于這個框架,分享一些VB操作excel的示例。有同學說VBA這么好,這么方便,為什么不用VBA?我的意見是VBA代碼和數據混雜在一起,比如一個表格中有表格數據也有VBA代碼,這些VBA代碼容易被用戶以宏安全性為由關閉,再說這種方法也不符合代碼和數據分離的原則。我前面也發過一些圖文,大家看我做的那些工具需要演示數據嗎?代碼和數據是可以分離的。
VB.NET是集成在Visual studio.NET開發套件中的一種語言,與它相伴成生的還有C #。微軟官方推薦首選C#,但是為吸引更多VB老用戶,仍然保留了VB語言在Visual studio.NET平臺中,VB.NET從此擺脫了鄙視鏈低端角色,平步青云,成為完全面向對象的新語言。依托于.NET平臺,或者說依賴net framework框架,VB.net獲得了長足發展。
上圖為VS2012環境中編寫VSTO的起始頁。
上圖是我使用VBNET開發Excel的一個演示,它引用了我自己編寫的一個excel類,代碼只兩行
Dim v As New excel
v("工作簿2.xlsx")("sheet1")(4, 5)="df45df"
創建excel對象,并把工作簿2.xlsx的sheet1工作表中的第4行第5列單元格中寫入“df45df"字符串,當然這個自建excel類還可以完成更多完成,由于集成度更高,所以很多功能雖然只一句代碼,但是后面可能有100句代碼在執行。這就是積木疊加的增量效果。
用VB6代替VBA,升級成本最小,如果在適用夠用的情況下,VB6完全能勝任excel開發。但VB6太老了,很多新功能都不支持,需要加裝很多第三方支持。
VB.net一行代碼效率勝過VB很多行,這也是很多開發者轉向VSTO的原因 。
VSTO相對于VB.NET,類似于VBA相對于VB6
這四胞胎同宗同源,系出同門。它們之間的差異,你分清了嗎?
般情況下,代碼生成的窗體都是有標題欄的,當鼠標點擊這個窗體的任何地方,這個窗體就會擁有焦點;當窗體失去焦點時,標題欄是灰色的。
我們有時希望這個窗體是一個無焦點的窗口,就算你用鼠標點擊它,它也不會得到焦點,比如,我們常見的輸入法窗口就是一個無焦點的窗口。
如果我們通過代碼做一個無焦點的窗體,那么,再加上相應的代碼,就可以通過鍵盤或鼠標點擊向別的程序窗口發送字符,就像一個外掛的輸入法一樣。
下面,我就通過vb.net來做一個無焦點的窗體。
首先,在窗體里建立2個控件,一個是TextBox控件,一個是Button控件。
接著,寫入相關代碼,代碼很簡單,先導入相關的API,然后在窗體的Load事件寫入相應代碼就可以了。全部代碼如下:
Public Class Form1
'無焦點的窗體:
Private Const GWL_STYLE=(-16)
Private Const HWND_TOPMOST=-1
Private Const HWND_NOTOPMOST=-2
Private Const SWP_NOSIZE=&H1
Private Const SWP_NOMOVE=&H2
Private Const SWP_NOACTIVATE=&H10
Private Const SWP_SHOWWINDOW=&H40
Private Const WS_EX_NOACTIVATE=&H8000000
Private Const GWL_EXSTYLE=(-20)
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Sub SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'無焦點的窗體:
Dim style As Integer
style=GetWindowLong(Me.Handle.ToInt32, GWL_EXSTYLE)
style=style Or WS_EX_NOACTIVATE
Call SetWindowLong(Me.Handle.ToInt32, GWL_EXSTYLE, style) '這一句代表有焦點
SetWindowPos(Me.Handle.ToInt32, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE)
End Sub
End Class
寫好代碼,按F5調試運行,運行結果界面如下:
噫?怎么會還有焦點?這是在visual studio 2022測試的結果,難道代碼有誤?
不用急,當你去點擊別的程序,讓這個測試窗體Form1失去焦點,然后,你再想讓這個失去焦點的窗體再得到焦點,就不可能了,無論是像點擊窗體上的2個控件,還是點擊窗體的標題欄,就不會讓這個無焦點的窗體再得到焦點。
你這時一定在想,能不能讓窗體一啟動就失去焦點呢?答案是:當然可以。
具體做法是:點擊VS2022的“項目”菜單的最后一個“屬性”菜單項,或者如下圖所示,鼠標右鍵點擊應用程序,點擊最后一個菜單,進入屬性對話框。
在屬性對話框中,在“應用程序框架”項里,要取消勾選第一個選項:“為此項目啟用Visusal Basic" 應用程序 框架。
取消勾選第一個選項后,再F5運行,好了,一啟動程序就是無焦點的窗體,成功!如下圖所示:
但是,你會發現實現窗體啟動即無焦點,也付出了代價,即窗體樣式只能是經典的樣式了,你看看,TextBox控件,一個是Button控件都是經典樣式了,不再是XP樣式了。