|
-
May 28th, 2000, 07:03 PM
#1
Thread Starter
Lively Member
Hello,
for a program I'm currently working on, I need to know, when my form is moved.
I haven't been able to find a solution (event, which indicates that my form is being/was moved) so far, although I've been looking around on the Internet and MSDN.
Maybe anyone of you can give me any tips??
Thanks
-
May 28th, 2000, 09:33 PM
#2
Fanatic Member
Put this is a module:
Code:
Global FormTop As Integer
Global FormLeft As Integer
Public Function HasFormMoved()
If Form1.Top <> FormTop Or Form1.Left <> FormLeft Then
'Do something if it has been moved
MsgBox "Form has been moved"
'reset values if you'd like
FormTop = Form1.Top
FormLeft = Form1.Left
Else
'Do something if it hasn't been moved
MsgBox "Form has not been moved"
End If
End Function
Put this in your form_load event:
Code:
FormTop = Form1.Top
FormLeft = Form1.Left
Whenever you want to know if your form has moved, just call the HasFormMoved function.
-
May 28th, 2000, 09:52 PM
#3
Thread Starter
Lively Member
that's not really what I need ...
but thanks for trying to help me
the program consists of 2 forms which are displayed together (I can't put into just one form), next to each other ...
... so when one form is moved, I want the other form to be moved too, and placed directly next to the first form
... as there is no FormMove event I'm looking for some code which tells when the form is moved
-
May 28th, 2000, 10:00 PM
#4
how would that work?
how would you call it, when the form was moved?
you would have to put it in a form_move event, one does not exist...
-
May 28th, 2000, 10:01 PM
#5
Lively Member
Just use the code posted above, but you would add code to move your second form whenever the first form is moved. If you want the second form right next to the first form on it's right had side then just do this:
'add this to the code above
frmSecond.Left = frmFirst.left + frmFirst.width
frmSecond.Top = frmFirst.Top
this will attach the second form to the right hand side of the first form.
-
May 28th, 2000, 10:02 PM
#6
Fanatic Member
Well... Off the top of my head I cann't think of anything that would be super affective. You could use a timer to check on the form position using the same code I gave you however it would not be real accurate and it would each memory. Give me a few minutes and I'll what I kind find for you.
-
May 28th, 2000, 10:05 PM
#7
Lively Member
Response to Dennis' question:
You would just stick it into a do until loop.
Public Sub CheckForMovement()
do until HasFormMoved
doevents
loop
'can write code here to do stuff if the form has moved.
'then call the sub recursively
CheckForMovement
end sub
-
May 28th, 2000, 10:05 PM
#8
Fanatic Member
denniswrenn:
That code works fine as long as it doesn't need to be an instantanious change. I've used it before to save the position to the registry and to open other windows in relation to that window. But you're right, we need a form_move event.
-
May 28th, 2000, 10:15 PM
#9
Thread Starter
Lively Member
I know, I really would like to avoid using a timer...
... I found something about hooks just a few minutes ago - with them I should be able to do it ... but I haven't been using the API a lot ... only easy functions
... so right now I don't really know what to do ... but I'm working on it
maybe anyone of you knows a little bit about it???
-
May 28th, 2000, 10:44 PM
#10
Does your form use a title bar? If you use a label to move the form, you can easily detect if its moving .
-
May 29th, 2000, 05:55 AM
#11
Guru
You can create a SubClass.
This is kinda tough to explain (so just accept it!), and it may crash if you debug your code and press the End button from the toolbar, or if you use the End statement anywhere in your code.
Form code:
Code:
Option Explicit
Private Sub Form_Load()
Call HookUsUpScotty
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Call HookUsDownScotty
End Sub
Public Sub Form_FormMove()
' What??? FormMove???
' Yes!!! Woo hoo!!!
' Just leave it as a Public Sub, will you? This one doesn't like being Private.
End Sub
Don't get excited yet. This lovely module code will work if the above form is called Form1, but that can easily be changed.
Code:
Option Explicit
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 Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Const GWL_WNDPROC = (-4)
Public Const WM_MOVE = &H3
Public Const WM_MOVING = &H216
Dim lpfnPrevWndProc As Long
Public Sub HookUsUpScotty()
lpfnPrevWndProc = SetWindowLong(Form1.hWnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Public Sub HookUsDownScotty()
Call SetWindowLong(Form1.hWnd, GWL_WNDPROC, lpfnPrevWndProc)
End Sub
Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If (uMsg = WM_MOVE) Or (uMsg = WM_MOVING) Then Call Form1.Form_FormMove
WindowProc = CallWindowProc(lpfnPrevWndProc, hWnd, uMsg, wParam, lParam)
End Function
I HAVEN'T TESTED IT! So I am not sure whether or not it works. But I think it does.
-
May 29th, 2000, 04:40 PM
#12
Thread Starter
Lively Member
Hi Yonatan,
thanks for your help.
Yesterday evening I was also able to find something that works - even if I don't exactly how ...
On the website of VbAccelerator is an example, using Windows Hooks, for keystrokes and mouse moves.
I modified it a little so now it works quite well for my purpose.
Code:
Option Explicit
Implements IWindowsHook
Private Type POINTAPI
x As Long
y As Long
End Type
Dim xi, yi As Long
'-----------------------
Private Function IWindowsHook_HookProc(ByVal eType As EHTHookTypeConstants, ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long, bConsume As Boolean) As Long
Dim ctlOver As Control
Dim bS As Boolean
Dim lC As Long
Dim lhWNd As Long
Dim bSkip As Boolean
Static ctlIgnore As Control
With MouselParam(lParam)
Select Case wParam
Case WM_MOUSEMOVE
If Me.Left <> xi Or Me.Top <> yi Then
If frKalibrBericht.Visible Then
frKalibrBericht.Left = Me.Left
frKalibrBericht.Top = Me.Top
End If
If frKalibrSet.Visible Then
frKalibrSet.Left = Me.Left
frKalibrSet.Top = Me.Top
End If
If frStammDatenShow.Visible Then
frStammDatenShow.Left = Me.Left - frStammDatenShow.Width
frStammDatenShow.Top = Me.Top
End If
End If
xi = Me.Left
yi = Me.Top
Case WM_LBUTTONUP, WM_LBUTTONDOWN
xi = Me.Left
yi = Me.Top
End Select
End With
End Function
'-----------------------
Private Sub Form_Load()
xi = Me.Left
yi = Me.Top
InstallHook Me, WH_MOUSE
End Sub
'-----------------------
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
RemoveHook Me, WH_MOUSE
End Sub
You just need to have their DLL in your system32 directory
(http://vbaccelerator.com/codelib/hook/vbalhook.htm)
-
May 29th, 2000, 05:17 PM
#13
Guru
Do you really want to use a DLL?
I always hate distributing any kind of DLL with my applications. If you want that exact same code with no DLL requirement, try this:
Form code:
Code:
Option Explicit
Private Sub Form_Load()
xi = Left
yi = Top
Call InstallHook
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Call RemoveHook
End Sub
Module code:
Code:
Option Explicit
Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const WH_MOUSE = 7
Public Const WM_MOUSEMOVE = &H200
Public Const WM_LBUTTONDOWN = &H201
Public Const WM_LBUTTONUP = &H202
Dim hHook As Long
Public xi As Long, yi As Long
Public Sub InstallHook()
hHook = SetWindowsHookEx(WH_MOUSE, AddressOf MouseProc, App.hInstance, App.ThreadID)
End Sub
Public Sub RemoveHook()
Call UnhookWindowsHookEx(hHook)
End Sub
' The "ByVal lParam As Long" should really be "lParam As MOUSEHOOKSTRUCT"
' but we don't need to access lParam so we can just use a pointer and skip the type declarations.
Public Function MouseProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Select Case wParam
Case WM_MOUSEMOVE
' Replace Form1 with the naForm1 of the form
' in which you put the code from the beginning of this post.
If Form1.Left <> xi Or Form1.Top <> yi Then
If frKalibrBericht.Visible Then
frKalibrBericht.Left = Form1.Left
frKalibrBericht.Top = Form1.Top
End If
If frKalibrSet.Visible Then
frKalibrSet.Left = Form1.Left
frKalibrSet.Top = Form1.Top
End If
If frStammDatenShow.Visible Then
frStammDatenShow.Left = Form1.Left - frStammDatenShow.Width
frStammDatenShow.Top = Form1.Top
End If
End If
xi = Form1.Left
yi = Form1.Top
Case WM_LBUTTONUP, WM_LBUTTONDOWN
xi = Form1.Left
yi = Form1.Top
End Select
' If lParam wasn't a Long pointer, then the ByVal wouldn't have been here:
MouseProc = CallNextHookEx(hHook, nCode, wParam, ByVal lParam)
End Function
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|