Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Attach window to another window...


Best Answer Jackie Sztuk _Blackholyman , 14 October 2015 - 08:45 AM

Go to the full post »


  • Please log in to reply
6 replies to this topic
blondedude092
  • Members
  • 77 posts
  • Last active: Oct 15 2015 04:51 PM
  • Joined: 07 Jan 2009

The effect I want is SIMILAR to this:

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
Gui, +AlwaysOnTop
Gui, Show , NoActivate w100 h30 , POC AttachToCalc

loop
{
	
	SetToPos()
	
	
}

SetToPos()
{
	WinWait, Calculator
	
	
	WinGetPos,X_Pos,Y_Pos, , , A
	WinMove, POC AttachToCalc,, X_Pos, Y_Pos
}

However, as you can see it will be laggy as you move the window. I have seen the EXACT effect done by TeamViewer the main window and the Computer List Window next to it. 

Here is an example:
MS0kZ.jpg

If you move the main window the other one moves without any lag.

That is exactly what I want. 



Exaskryz
  • Members
  • 3249 posts
  • Last active: Nov 20 2015 05:30 AM
  • Joined: 23 Aug 2012

SetWinDelay, -1



blondedude092
  • Members
  • 77 posts
  • Last active: Oct 15 2015 04:51 PM
  • Joined: 07 Jan 2009

That will only create a larger delay. I want no delay such as done by TeamViewer

 

EDIT:

 

UPDATE:

 

I have figured out how it is done. It seems that It cannot be done with an external window since there is too much latency working with the external windows. Also listening to the events of another window and attaching a hook to it in managed code requires marshaling thus itself causes latency.

 

However, since I was able to recreate it with windows owned by same exe. 

 

Preveiw: https://social.msdn..../getfile/732981

 

The issue is still that I have to be able to achieve this with another window.

 

If I can embed a control onto another window and get events via the embedded control and handle them to change the location of the second window.



Exaskryz
  • Members
  • 3249 posts
  • Last active: Nov 20 2015 05:30 AM
  • Joined: 23 Aug 2012

When I did not include SetWinDelay, I had a notable visual lag on my script.

 

Decreasing it to -1 made it appear seamless if I moved the window slowly, but of course there would be some small lag (not bothersome to me) when moving the window rapidly. This was my exact code to test on a calculator:

SetWinDelay, -1
 
^8::
WinGet, output, ID, ahk_exe calc.exe
Gui, New
Gui, Add, Text,,Test
Gui, +HwndTestID
Gui, Show
SetTimer, move, 10
return

move:
WinGetPos, x, y, w, h, ahk_exe calc.exe
If (x=xo) && (y=yo) && (w=wo) && (h=ho)
return
WinMove, ahk_id %TestID%,, % x+w, % y+5,,% h-10
return
 
#c::Run C:\Windows\System32\calc.exe

I have never used TeamViewer with a second window appearance, so I do not know how perfectly it works being attached. There may be some different technique that gets better results, but I could not find one.



blondedude092
  • Members
  • 77 posts
  • Last active: Oct 15 2015 04:51 PM
  • Joined: 07 Jan 2009

I have found another program that does exactly the effect I want however I would like to be able to do it myself. 
AquaSnap Window Manager

 

If you look under the "Move Windows Together" section that is exactly what I want to be able to do. 



Jackie Sztuk _Blackholyman
  • Spam Officer
  • 3757 posts
  • Last active: Apr 03 2016 08:47 PM
  • Joined: 28 Feb 2012
✓  Best Answer
Here is an example of hooking the LocationChange event
#Persistent
#SingleInstance, force


hookProcAdr := RegisterCallback("HookProc")
hHook := SetWinEventHook(0x800B,0x800B,0,hookProcAdr,0,0,0)	; EVENT_OBJECT_LOCATIONCHANGE 

Gui, +hwndChildhWnd
Gui, add, text,,some text in a small gui that will move around with a notepad window
Gui, add, Button,,Button

Run notepad.exe
WinWait, ahk_class Notepad
MainhWnd := WinExist("ahk_class Notepad")

WinGetPos, mX, mY, mW, mH, ahk_id %MainhWnd%
offset := mW
cX := mX + offset
cY := mY

Gui, show, x%cX% y%cY%

return

;#######################################################################

HookProc(hWinEventHook, event, hwnd) 
{ 
	global   MainHwnd, ChildhWnd 
	if (hwnd = MainHwnd)
	{
		SetWinDelay, -1 
		WinGetPos hX, hY, hW, hH, ahk_id %MainhWnd% 
		WinGetPos cX, cY, cW, cH, ahk_id %ChildhWnd% 

		X := hX + hW
		Y := hY

		WinMove ahk_id %ChildhWnd%,,X,Y 
	}
} 

SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags) { 
   DllCall("CoInitialize", "uint", 0) 
   return DllCall("SetWinEventHook", "uint", eventMin, "uint", eventMax, "uint", hmodWinEventProc, "uint", lpfnWinEventProc, "uint", idProcess, "uint", idThread, "uint", dwFlags) 
}
Also have a look at the Dock function by majkinetor
Helping%20you%20learn%20autohotkey.jpg?d

[AHK] Version. 1.1+ [CLOUD] DropBox ; Copy [WEBSITE] Blog ; About

blondedude092
  • Members
  • 77 posts
  • Last active: Oct 15 2015 04:51 PM
  • Joined: 07 Jan 2009

Here is an example of hooking the LocationChange event

#Persistent
#SingleInstance, force


hookProcAdr := RegisterCallback("HookProc")
hHook := SetWinEventHook(0x800B,0x800B,0,hookProcAdr,0,0,0)	; EVENT_OBJECT_LOCATIONCHANGE 

Gui, +hwndChildhWnd
Gui, add, text,,some text in a small gui that will move around with a notepad window
Gui, add, Button,,Button

Run notepad.exe
WinWait, ahk_class Notepad
MainhWnd := WinExist("ahk_class Notepad")

WinGetPos, mX, mY, mW, mH, ahk_id %MainhWnd%
offset := mW
cX := mX + offset
cY := mY

Gui, show, x%cX% y%cY%

return

;#######################################################################

HookProc(hWinEventHook, event, hwnd) 
{ 
	global   MainHwnd, ChildhWnd 
	if (hwnd = MainHwnd)
	{
		SetWinDelay, -1 
		WinGetPos hX, hY, hW, hH, ahk_id %MainhWnd% 
		WinGetPos cX, cY, cW, cH, ahk_id %ChildhWnd% 

		X := hX + hW
		Y := hY

		WinMove ahk_id %ChildhWnd%,,X,Y 
	}
} 

SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags) { 
   DllCall("CoInitialize", "uint", 0) 
   return DllCall("SetWinEventHook", "uint", eventMin, "uint", eventMax, "uint", hmodWinEventProc, "uint", lpfnWinEventProc, "uint", idProcess, "uint", idThread, "uint", dwFlags) 
}
Also have a look at the Dock function by majkinetor

 

 

 

 

Thank you, I really appreciate this.

I'll have to try to see if I can create a dll of this and just try to call the hook and set events to it. 

 

Update:

 

I was able to recreate this in .NET and it works great. Thank you! My previous attempts in .NET were setting the global hook for window location change event which global hooks in .NET are limited and thus marshaling is required to make a workaround. Marshaling causes too much lag and this makes it work beautifully. Thank you.


Edited by blondedude092, 15 October 2015 - 12:20 AM.