WindowsApi在VB中的妙用
Windows API作為一套功能強大的應用程序接口,使VB可以實現對Windows底層的控制,完成VB不具有的功能。下面介紹幾種使用API函數的方法。
一、制作特殊窗口
1.各種形狀的窗口(僅給出了函數名,具體定義可以查閱API Viewer)
1)CreateEllipticRgn 建立一個橢圓形的區域;
2)CreateRoundRectRgn 建立一個圓角矩形的區域;
3)CreatePolygonRgn 建立一個多邊形區域;
4)CreatePolyPolygonRgn建立多個可重疊的多邊形區域;
5)CreateRectRgn 建立一個矩形區域;
6)CombineRg連接兩個區域,通過代入不同的參數可以實現多種合并方式;
7)SetWindowRgn 設定窗口的范圍,使用前邊創建的區域;
8)FrameRgn 在指定區域畫上邊框。
下邊的程序就是建立一個形如“棒槌”的窗口:
| Private Sub Form1_Load() Dim p, q As Long p = CreateEllipticRgn(0, 0, 200, 200) ′通過制定左上角和右下角的坐標建立一個圓 q = CreateRoundRectRgn(40, 120, 160, 400, 20, 20) ′通過制定左上角和右下角的坐標以及圓角的寬度建立一個圓角矩形 CombineRgn p, q, p, RGN_OR ′聯合兩個區域,使用或(就是取并集)運算 SetWindowRgn hWnd, p, True ′設置窗口區域 Me.Refresh ′刷新窗口 End Sub |
2.浮動窗口
Delphi中實現浮動窗口非常容易,只要在屬性欄中設置就可以。用VB實現就只有借助于API函數:
SetWindowPos hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE+SWP_NOSIZE+SWP_SHOWWINDOW就可以了。其中hWnd是窗口的句柄,HWND_TOPMOST指定了窗口的位置—總是在最上邊。如果你要取消這個屬性,只要把TOPMOST改成NOTOPMOST就可以了。后面4個參數指定了窗口的位置和大小,和VB提供的MOVE方法一樣。不過最后一個參數如果指定了SWP_NOMOVE(不改變位置)和 SWP_NOSIZE(不改變大小),那么這四個參數就會被忽略。
3.透明窗口
去年的《電腦報》上提供了一個制作透明窗口的辦法,這里再介紹另一種方法:
| Private Sub Form1_Load() Dim p As Long p = GetWindowLong(hWnd,GWLEXSTYLE) ′取得當前窗口屬性 SetWindowLong hWnd, GWL_EXSTYLE,p + WS_EX_TRANSPARENT ′加上一個透明屬性 Me.Refresh End Sub |
GetWindowLong 和 SetWindowLong 配合使用還可以更改窗口的不少屬性,有興趣的讀者不妨一試。
二、讀取外部圖標
下面的一段程序就顯示了如何讀取程序中的圖標,其中Picture1是一個圖像框,dlgOpen是一個標準對話框,Command1是一個按鈕;ExtractIcon函數有三個參數,第一個參數指定調用的應用程序,一般都用App.hInstance;第二個參數指定圖標文件,可以是DLL、EXE和ICO。第三個參數的不同就決定了其返回值的不同:如果代入-1,就返回文件中包含的圖標數,代入0則返回第一個圖標的句柄,其余依次類推。
| Private Sub Command1_Click() Static total As Long,p(50) As Long,i As Integer dlgOpen.Filter = ″圖標|*.Exe; *.Ico;*.Dll″ dlgOpen.ShowOpen If Dir(dlgOpen.filename)<>″″ Then If ExtractIcon(App.hInstance, dlgOpen.filename, -1) = 0 Then ′如果沒有圖標 MsgBox ″No Icon!″ Else total = ExtractIcon(App.hIns tance, dlgOpen.filename, -1) ′取得總圖標數 For i = 0 To total - 1 p(i) = ExtractIcon(App.hIn stance, dlgOpen.filename, i) ′讀取每個圖標 Next i For i = 0 To total - 1 ′依次顯示每個圖標 DrawIcon Picture1.hdc, 34 * i, 0, p(i) Next i End If End If End Sub |
三、在桌面上畫圖
下面一段程序就是使用API函數在屏幕上畫圖標。(注:p是圖標的句柄,可以由ExtractIcon取得)
| deskhwnd = GetNextWindow(hwnd, GW_HWNDLAST) ′取最下面一個窗口 deskdc = GetWindowDC(deskhwnd) ′取窗口的情景設備 For i=0 To Screen.Width/32/15 ′將屏幕坐標單位換算成“Pixel”,并計算可畫的圖標數 For j=0 To Screen.Height/32/15 DrawIcon deskdc, 32*i, 32*j, p ′在桌面上畫圖 Next j Next i |
用函數GetNextWindow取得其句柄,用函數GetWindowDC取出它的虛擬設備。不過,一旦窗口被覆蓋,圖標就會消失。
四、屏蔽系統功能鍵
在去年《電腦報》第22期上介紹了一種在Delphi中屏蔽系統功能鍵的方法。可是在VB中無論你怎么設置數據類型,系統總是提示“數據類型不匹配”, 下面就是API Viewer中給出的定義:
| Declare Function SystemParametersInfo Lib ″user32″ Alias “SystemParametersInfoA” (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Any, ByVal fuWinIni As Long) As Long |
筆者經過反復思考,終于恍然大悟:看到黑體的“ByVal”了嗎?問題就出在這里。原來該函數使用的lpvParam 參數應該按地址傳送而非按值傳送,然而VB Viewer 中使用的是按值傳送,所以會出現錯誤提示。