Hi, any1 know how to stick 2 forms together?
kinda like how winamp & the equaliser stick together
Printable View
Hi, any1 know how to stick 2 forms together?
kinda like how winamp & the equaliser stick together
Did you ever figure this out? I've seen many links that do not link to the code they should.
Try doing a search for WINAMP and forms.
good luck
j
I can move the forms together, this might help...
Put this in the declarations section of the main form
Function Mve(SIDE As String)
Form2.Show
If SIDE = "right" Then 'check what side
Form2.Move Form1.Left + Form1.Width, Form1.Top 'move it
ElseIf SIDE = "left" Then
Form2.Move Form1.Left - Form2.Width, Form1.Top
ElseIf SIDE = "top" Then
Form2.Move Form1.Left, Form1.Top - Form2.Height
ElseIf SIDE = "bottom" Then
Form2.Move Form1.Left, Form1.Top + Form1.Height
End If
End Function
Then just all that function Eg.
command1_click()
Mve("right")
end sub
Hope this helps:) :)
I have done for work, so can't give away the code, but in essence you have to use subclassing, here is the windows proc to get you started, then combine it with the approach AGB provided. Can get tricky.
Code in module:
Code in form:VB Code:
Option Explicit Private lHWndProc As Long Private lHWnd As Long Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _ (ByVal hwnd As Long, ByVal nIndex As Long) As Long 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 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 Private Declare Function CopyFromLParamToRect Lib "user32" Alias "CopyRect" (lpDestRect As RECT, ByVal lpSourceRect As Long) As Long Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type Dim r As RECT Const GWL_WNDPROC = (-4) Const WM_MOVING = 534 Const WM_ENTERSIZEMOVE = 561 Const WM_EXITSIZEMOVE = 562 Public Sub HookForm(frmHandle As Long) lHWnd = frmHandle If lHWndProc = 0 Then lHWndProc = GetWindowLong(lHWnd, GWL_WNDPROC) 'get handle of old window proc SetWindowLong lHWnd, GWL_WNDPROC, AddressOf WndProc 'set to replacement wndproc End If End Sub Public Sub UnhookForm() If lHWndProc Then SetWindowLong lHWnd, GWL_WNDPROC, lHWndProc 'reset wnd proc to original lHWndProc = 0 End If End Sub Public Function WndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Select Case uMsg Case WM_ENTERSIZEMOVE Debug.Print "form started to move" 'Put any code you want when form starts to move here 'Debug.Print "Position: "; Form1.Left / Screen.TwipsPerPixelX, Form1.Top / Screen.TwipsPerPixelY Case WM_MOVING Debug.Print "Form moving..." 'Put any code you want while form is moving here Call CopyFromLParamToRect(r, lParam) 'Debug.Print "Position: "; r.Left, r.Top Case WM_EXITSIZEMOVE Debug.Print "Form stopped moving" 'Debug.Print "Position: "; Form1.Left / Screen.TwipsPerPixelX, Form1.Top / Screen.TwipsPerPixelY 'Put any code you want when form finishes moving here End Select WndProc = CallWindowProc(lHWndProc, hwnd, uMsg, wParam, lParam) End Function
VB Code:
Private Sub Form_Load() HookForm (Me.hwnd) End Sub
my way is easier than Nucleus way but works pretty cheap, but works =P
i have a timer with interval of 10~20, and on each timer event, it checks to see if the form.top = form2.top and form.left+formwidth = form2.left, if not, then move it there.
then i have 2 buttons which one will enable timer, and one to disable it, which will make it "dock and undock"
you will notice a slight gap in between them if you move the form relatively fast, since the timer of 10, even 1 is not fast enough? though there is not much difference between 1 and 20, so i use 10~20.
heres a beginner sort of code for when it loads up:
dim form1L as integer
dim form1H as integer
dim form2H as integer
dim i as integer
form1.show
form2.show
form1H = form1.height
form1L = form1.left
form2H = form2.height
i = form1H - form2H
form2.left = form1L
form2.Height = i
Nucleus:
Your code have a compile error in
It said "Invilad use of AddressOf operator".Code:SetWindowLong lHWnd, GWL_WNDPROC, AddressOf WndProc 'set to replacement wndproc
And i also met such problem when i use AddressOf operator.
Can U explain this???:confused:
What version of VB are you using?
In order for you to use SetWindowLong and the call back function API to subclass, it has to be (declared as Public) in a module.
AGB your code is great but the form2 have all the time the focus so it's not very usefull :(
Serge, are you sure, that code wortks fine on my box?
Yes, I am sure.
This is straight from MSDN
Quote:
Error: Invalid use of AddressOf operator
The AddressOf operator modifies an argument to pass the address of a function rather than passing the result of the function call. This error has the following cause and solution:
· You tried to use AddressOf with the name of a class method.
Only the names of Visual Basic procedures in a .bas module can be modified with AddressOf. You can't specify a class method.
· The procedure name modified by AddressOf is defined in a module in a different project.
· You tried to modify the name a DLL function or a function defined in a type library with AddressOf.
· DLL and type library functions can't be modified with AddressOf.
The procedure definition must be in a module in the current project. Move the definition to a module in this project or include its current module in the project.
What I was getting at was that I don't think it has to be declared as public.
No, it doesn't, if you create your own public function in the module that calls SetWindowLong.