讓窗體始終處于最前面
應用SetWindowPos函數可以設置一個窗口的位置和狀態,本例正是利用此函數來把一個窗體放在所有窗體之上,使之總是處于最前面。
我們先來看看SetWindowPos函數的定義和參數:
使用API函數之前必須先在程序中聲明如下:
| Private Declare Function 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) As Long |
其中各參數的意義如下:
| 參數 | 意義 |
| hwnd Long | 欲定位的窗口 |
| hWndInsertAfter Long | 窗口句柄。在窗口列表中,窗口hwnd會置于這個窗口句柄的后面 |
| x,y Long | 窗口新的x,y坐標 |
| cx,cy Long | 指定新的窗口寬度和高度 |
| wFlags Long | 包含了旗標的一個整數,是下列之一 |
| 返回值 Long | 非零表示成功,零表示失敗 |
下面是部分wFlags參數和它們的意義:
| 參數 | 意義和使用方法 |
| SWP_DRAWFRAME | 圍繞窗口畫一個框 |
| SWP_HIDEWINDOW | 隱藏窗口 |
| SWP_NOACTIVATE | 不激活窗口 |
| SWP_NOMOVE | 保持當前位置 (x和y設定將被忽略) &H2 |
| SWP_NOREDRAW | 窗口不自動重畫 |
| SWP_NOSIZE | 保持當前大小 (cx和cy會被忽略) &H1 |
| SWP_NOZORDER | 保持窗口在列表的當前位置 (hWndInsertAfter將被忽略) |
| SWP_SHOWWINDOW | 顯示窗口 &H40 |
| SWP_FRAMECHANGED | 強迫一條WM_NCCALCSIZE消息進入窗口,即使窗口的大小沒有改變 |
函數的使用很簡單,我們只須在Form_Load中加入如下語句即可:
| retValue = SetWindowPos(Me.hwnd, HWND_TOPMOST, Me.CurrentX, Me.CurrentY, 300, 300, SWP_SHOWWINDOW) |
這樣窗體就能保持在所有窗體的前面了。
為了學習方便,下面提供了源碼:
| '------------------------------------------- ' 讓一個窗體總是處于最前的例子 '------------------------------------------- '程序說明: '本例應用SetWindowPos函數,設置窗體的顯示屬性 '來實現讓一個窗體總是處于其他窗體的前面而不會 '被其他窗體所遮住。 '------------------------------------------- Option Explicit '【VB聲明】 ' Private Declare Function 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) As Long '【說明】 ' 這個函數能為窗口指定一個新位置和狀態。它也可改變窗口在內部窗口列表中的位置。該函數與DeferWindowPos函數相似,只是它的作用是立即表現出來的(在vb里使用:針對vb窗體,如它們在win32下屏蔽或最小化,則需重設最頂部狀態。如有必要,請用一個子類處理模塊來重設最頂部狀態 '【返回值】 ' Long,非零表示成功,零表示失敗。會設置GetLastError '【備注】 ' 窗口成為最頂級窗口后,它下屬的所有窗口也會進入最頂級。一旦將其設為非最頂級,則它的所有下屬和物主窗口也會轉為非最頂級。Z序列用垂直于屏幕的一根假想Z軸量化這種從頂部到底部排列的窗口順序 '【參數表】 ' hwnd ----------- Long,欲定位的窗口 ' hWndInsertAfter - Long,窗口句柄。在窗口列表中,窗口hwnd會置于這個窗口句柄的后面。也可能選用下述值之一: ' HWND_BOTTOM 將窗口置于窗口列表底部 ' HWND_TOP 將窗口置于Z序列的頂部;Z序列代表在分級結構中,窗口針對一個給定級別的窗口顯示的順序 ' HWND_TOPMOST 將窗口置于列表頂部,并位于任何最頂部窗口的前面 -1 ' HWND_NOTOPMOST 將窗口置于列表頂部,并位于任何最頂部窗口的后面 -2 ' x -------------- Long,窗口新的x坐標。如hwnd是一個子窗口,則x用父窗口的客戶區坐標表示 ' y -------------- Long,窗口新的y坐標。如hwnd是一個子窗口,則y用父窗口的客戶區坐標表示 ' cx ------------- Long,指定新的窗口寬度 ' cy ------------- Long,指定新的窗口高度 ' wFlags --------- Long,包含了旗標的一個整數,是下列之一: ' SWP_DRAWFRAME 圍繞窗口畫一個框 ' SWP_HIDEWINDOW 隱藏窗口 ' SWP_NOACTIVATE 不激活窗口 &H10 ' SWP_NOMOVE 保持當前位置 (x和y設定將被忽略) &H2 ' SWP_NOREDRAW 窗口不自動重畫 ' SWP_NOSIZE 保持當前大小 (cx和cy會被忽略) &H1 ' SWP_NOZORDER 保持窗口在列表的當前位置 (hWndInsertAfter將被忽略) ' SWP_SHOWWINDOW 顯示窗口 &H40 ' SWP_FRAMECHANGED 強迫一條WM_NCCALCSIZE消息進入窗口,即使窗口的大小沒有改變 Private Declare Function 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 _ ) As Long Const HWND_TOPMOST = -1 Const SWP_SHOWWINDOW = &H40 Private Sub Form_load() Dim retValue As Long '將窗體設置為處于所有窗口的頂層,注意在 VB 中運行時, ’可能不行,但編譯成EXE后就可以了 retValue = SetWindowPos(Me.hwnd, HWND_TOPMOST, Me.CurrentX, Me.CurrentY, 300, 300, SWP_SHOWWINDOW) End Sub |