新聞| | PChome| 登入
2007-10-25 23:52:53 | 人氣87| 回應0 | 上一篇 | 下一篇
推薦 0 收藏 0 轉貼0 訂閱站台

不讓Form的左端出螢幕


來源:cww

這也就是讓Form.Left 最小=0,不過這似乎不是一件簡單的事,因為Form的移動與移動
之後,在VB裡沒有相對應的Event來做,所以就不知道何時來判斷Form.Left < 0;
原本我想要讓Form移動時(Mouse還按在Form的Title時),就不讓Form的左邊界出螢幕的
左邊,不過失敗了,不知道是我沒有找到比較好的方式還是怎樣,至少我們做到在真正
定位前攔截到Form的位置,進而更改其左邊界,而重點就在於Window重新定位之前會傳
出WM_WINDOWPOSCHANGING這個訊息,而lParam指向一個WINDOWPOS的STRUCTURE。

Type WINDOWPOS
        hwnd As Long
        hWndInsertAfter As Long
        x As Long    '即將定位的X座標
        y As Long    '即將定位的Y座標
        cx As Long   '即將定位的寬度
        cy As Long   '即將定位的高度
        flags As Long
End Type
我們可更動之,而使原本的定位加以改變。

Option Explicit

'以下程式在module1.bas
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
   (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
   (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
   (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, _
    ByVal wParam As Long, ByVal lParam As Long) As Long

Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" ( _
    lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Public Const GWL_WNDPROC = (-4)
Public Const WM_WINDOWPOSCHANGING = &H46
Type WINDOWPOS
        hwnd As Long
        hWndInsertAfter As Long
        x As Long
        y As Long
        cx As Long
        cy As Long
        flags As Long
End Type

Public preWinProc As Long

Public Function wndproc(ByVal hwnd As Long, ByVal Msg As Long, _
                          ByVal wParam As Long, ByVal lParam As Long) As Long
  Dim lwd As Long, hwd As Long
  If Msg = WM_WINDOWPOSCHANGING Then
     Dim WPOS As WINDOWPOS
     CopyMemory WPOS, ByVal lParam, Len(WPOS)
     If WPOS.x < 0 Then
        WPOS.x = 0
        CopyMemory ByVal lParam, WPOS, Len(WPOS)
     End If
  End If
  '將之送往原來的Window Procedure
  wndproc = CallWindowProc(preWinProc, hwnd, Msg, wParam, lParam)
End Function

'以下在form
Sub Form_Load()
  Dim ret As Long
  '記錄原本的Window Procedure的位址
  preWinProc = GetWindowLong(Me.hwnd, GWL_WNDPROC)
  ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf wndproc)
End Sub

Private Sub Form_Unload(Cancel As Integer)
  Dim ret As Long
  '取消Message的截取,而使之又只送往原來的Window Procedure
  ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, preWinProc)
End Sub


台長: Kenny
人氣(87) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 教育學習(進修、留學、學術研究、教育概況) | 個人分類: 程式設計 |
此分類下一篇:如何使Mouse的右鍵無效(Mouse Hook)
此分類上一篇:SHELL具WAIT功能

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文