 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed May 23, 2007 11:02 pm Post subject: |
|
|
| Quote: | | the client window gets behind others, and disappears. |
If you put gui always on top it will not desapear. If you don't put it , you must send it to the top of the Z-order. Any of these are not the hook problem. _________________
 |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed May 23, 2007 11:12 pm Post subject: |
|
|
2Laszlo
This helped to me, so now your dock example works without any problems:
| Code: | Dock_Update:
WinSet, AlwaysOnTop, on, ahk_id %Dock_ClientId%
WinSet, AlwaysOnTop, off, ahk_id %Dock_ClientId%
Return |
_________________
 |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4033 Location: Pittsburgh
|
Posted: Wed May 23, 2007 11:35 pm Post subject: |
|
|
Yes, that works. However, the window movement is not as smooth as before, and there is considerable flickering, when the window is moved under the taskbar. Maybe, it could be better if it can be done with dll calls directly, or some other, less drastic means.
Otherwise, your docking solution is getting to really useful. Just a little more tweaking… |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed May 23, 2007 11:42 pm Post subject: |
|
|
| Quote: | | Otherwise, your docking solution is getting to really useful. Just a little more tweaking… |
Indeed. I too can't wait to put this to full working version 1.0
I uploaded new script on the first page. Check it out. I updated your version and removed F12 as there is no need for that now.
I don't see any flickering here. _________________
 |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Thu May 24, 2007 12:04 am Post subject: |
|
|
I tried to remove ALwaysOnTop solution with something faster so I tried this:
| Code: | ; WinSet, AlwaysOnTop, on, ahk_id %Dock_ClientId%
; WinSet, AlwaysOnTop, off, ahk_id %Dock_ClientId%
Tooltip % API_SetWindowPos(Dock_ClientId, Dock_HostId, 0, 0, 0, 0, 2 | 1 )
API_SetWindowPos(hWnd, hwndInsertAfter, x, y, cx, cy, uFlags){
return DllCall("SetWindowPos", "uint", hWnd, "uint", hwndInsertAfter, "int", x, "int", y, "int", cx, "int", cy, "uint", uFlags)
} |
but this doesn't work either well. Strange thing is that tooltip always show 1 which means function was succesiful. _________________
 |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Thu May 24, 2007 12:21 am Post subject: |
|
|
This is kind a cool
| Code: | Gui Show
WinSet, Region, 0-0 150-0 50-150, ahk_id %Dock_ClientID% |
_________________
 |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4033 Location: Pittsburgh
|
Posted: Thu May 24, 2007 3:30 am Post subject: |
|
|
| Maybe my laptop is too slow, but the window pair does not move very smoothly for me. Just thinking… If we had too hooks, one for window movement and resize – which does not need the AlwaysOnTop trick, and one for window activation (object state change, system foreground), which does not need the code for window movement, then the movement could be smoother. |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Thu May 24, 2007 11:21 am Post subject: |
|
|
Well, just add this code
| Code: | If Dock_event = 3
WinSet , AlwaysOnTop.... |
I updated first post with this.
Its interesting that all atempts to set Z-order for dockClient in hook handler other then using AOT fail - WinSet, Top , SetWinPos, etc...
So, thats it, we have functional final dock version, consuming 0 CPU, and you can dock anything to anything (like Notepad to Explorer)
If you don't see more problems, I will make this 1.0 and use this as a base for more robust wrapper.
BTW, Laszlo, you are the topic master when expressions are in question so it would be good to see what we can do here to enable expressions with A_DockClientWidth/Height (like the last screenshot). We need something fast, if possible without manual parsing, and it is enough to have only basic math operations (+-*/).
2Sean
Do you happen to know is there any kind of COM class in Win doing expressions ? _________________
 |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4033 Location: Pittsburgh
|
Posted: Thu May 24, 2007 9:30 pm Post subject: |
|
|
The last version seems to work OK, and fast enough. (Checking Dock_event = 3 was clever!) I made a few changes. Keep the ones you see fit.
- There is no need any more for API_ShowWindow(Dock_ClientId, 8) in the Dock_Update subroutine.
- It is a little cleaner to list explicitly the global variables a function needs, albeit longer.
- We don't need to load the hook dll repeatedly.
- It is enough to determine the script's process ID only once.
- The return value of the function Dock was better the logic AND of the handles, which is 0 if any one of them is 0. (Bitwise AND can be 0 otherwise, too.)
- Undock does not need GoSub Dock_Update
- I made the calling syntax of the dock function faster and more flexible, but also more complex (beginners choose one of a few listed options). There are 10 parameters: (xhw,xw,xd, yhh,yh,yd, whw,wd, hhh,hd)
--- The x coordinate of the top, left corner of the client window is computed as
HostX + xhw*HostWidth + xw*ClientWidth + xd, with the parameters xhw, xw and xd
--- The y coordinate of the top, left corner of the client window is computed as
HostY + yhh*HostHeight + yh*ClientHeight + yd, with the parameters yhh, yh and yd
--- The width ClientWidth of the client window is computed as whw*HostWidth + wd, with the parameters whw and wd.
--- The height ClientHeight of the client window is computed as hhh*HostHeight + hd, with the parameters hhh and hd. | Code: | #SingleInstance Force
#NoEnv
SetBatchLines -1
SetWinDelay -1
OnExit Close
HookDll = wineventhook.dll
Run notepad,,,nPID
WinWait ahk_pid %nPID%
Dock_HostID := Dock_HookHwnd := WinExist("ahk_pid " . nPID)
Gui +LastFound -Caption +ToolWindow +Border
Dock_ClientID := WinExist()
Gui Add, Text,,Docked Window
Gui Show
; dx = (HostWidth*, ClientWidth*, Offset)
; dy = (HostHeight*,ClientHeight*,Offset)
; w = (HostWidth*, Constant)
; h = (HostHeight*,Constant)
;Dock(0,0,0, 1,0,-2, 1,0, 0,30) ; below, full width
;Dock(.5,-.5,0, 1,0,10, .5,0, 0,30) ; below, centered, half width
;Dock(0,-1,-10, 0,0,0, 0,63, 1,0) ; left, top
;Dock(1,0,10, 0,0,50, 0,63, 1,-50) ; right, bottom
Dock(0,0,0, 0,-1,-5, 0,120, 0,30) ; above, left, fixed width
Dock_Update:
If (Dock_HookHwnd != Dock_HostID)
Return
WinGetPos hX, hY, hW, hH, ahk_id %Dock_HookHwnd%
W := whw*hW + wd, H := hhh*hH + hd
WinMove ahk_id %Dock_ClientId%,,hX + xhw*hW + xw*W + xd, hY + yhh*hH + yh*H + yd, W, H
If (Dock_event = 3) {
WinSet AlwaysOnTop, On, ahk_id %Dock_ClientId%
WinSet AlwaysOnTop, Off, ahk_id %Dock_ClientId%
}
Return
Close:
Undock()
WinClose ahk_id %Dock_HostID%
ExitApp
Dock(_xhw,_xw,_xd, _yhh,_yh,_yd, _whw,_wd, _hhh,_hd) {
Global HookDll, xhw,xw,xd, yhh,yh,yd, whw,wd, hhh,hd
Static hwnd, Dock_hHookDll, Dock_msg := 0x550
If Dock_hHookDll=
Dock_hHookDll := API_LoadLibrary(HookDll)
If hwnd=
hwnd := WinExist("ahk_pid " . DllCall("GetCurrentProcessId"))
xhw:=_xhw, xw:=_xw, xd:=_xd, yhh:=_yhh, yh:=_yh, yd:=_yd, whw:=_whw, wd:=_wd, hhh:=_hhh, hd:=_hd
Dock_hHook0 := Hook(hwnd, Dock_msg, 3) ; EVENT_SYSTEM_FOREGROUND
Dock_hHook2 := Hook(hwnd, Dock_msg, 10, 11) ; EVENT_SYSTEM_MOVESIZESTART 10 EVENT_SYSTEM_MOVESIZEEND 11
Dock_hHook3 := Hook(hwnd, Dock_msg, 0x800A, 0x800B, "Dock_HookHandler") ;EVENT_OBJECT_STATECHANGE 0x0000800a, EVENT_OBJECT_LOCATIONCHANGE 0x0000800b
Return Dock_hHook3 && Dock_hHook2 && Dock_hHook0 && Dock_hHookDll
}
Dock_HookHandler(wParam, lParam, msg, hwnd) {
Global Dock_event, Dock_HookHwnd
GetHookParams(lparam, Dock_event, Dock_HookHwnd)
GoSub Dock_Update
}
GetHookParams(lparam, ByRef event, ByRef hwnd="", ByRef idObject="", ByRef idChild="", ByRef dwEventThread="", ByRef dwmsEventTime="") {
DllCall("RtlMoveMemory", UIntP,event , UInt,lParam+ 4, UInt, 4)
DllCall("RtlMoveMemory", UIntP,hwnd , UInt,lParam+ 8, UInt, 4)
DllCall("RtlMoveMemory", UIntP,idObject , UInt,lParam+12, UInt, 4)
DllCall("RtlMoveMemory", UIntP,idChild , UInt,lParam+16, UInt, 4)
DllCall("RtlMoveMemory", UIntP,dwEventThread, UInt,lParam+20, UInt, 4)
DllCall("RtlMoveMemory", UIntP,dwmsEventTime, UInt,lParam+24, UInt, 4)
}
Hook(comm_hwnd, comm_msg, s_event, e_event="", function="", wparam=0) {
Global HookDll
r := DllCall(HookDll "\reghook", UInt,comm_hwnd, UInt,COMM_MSG, UInt,s_event, UInt,e_event ? e_event : s_event, UInt,wparam)
If (function)
OnMessage(COMM_MSG, function)
Return r
}
Undock() {
Unhook(Dock_hHook, Dock_msg)
API_FreeLibrary(HookDll)
}
Unhook(handle, com_msg) {
OnMessage(com_msg)
Return DllCall("UnhookWinEvent", "UInt", handle)
}
API_ShowWindow(hwnd, flag){
return DllCall("ShowWindow", "UInt", hwnd, "int", flag)
}
API_LoadLibrary( dll ) {
Return DllCall("LoadLibrary", "str", dll)
}
API_FreeLibrary( h ) {
Return DllCall("FreeLibrary", "uint", h)
} |
|
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Thu May 24, 2007 10:07 pm Post subject: |
|
|
I have no objections to such changes. I intended to do all that myself, the script above is created out of great number of trials and mistakes so it is nor optmised nor done like it should be.
I will test a lil more your version and update the above code with it, if it works OK.
Thx for improvements.
| Quote: | | - Undock does not need GoSub Dock_Update |
I think it does , but that was before. Without it, dock window sometimes doesn't position correctly. _________________
 |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Thu May 24, 2007 10:16 pm Post subject: |
|
|
Yeah, works great, I like the syntax too.
One thing needs to be done: to hook application termination and to call appropriate user function so it can shutdown the gui or do whatever he likes with it.
| Code: | Dock(....., "OnHostTerminate")
OnHostTerminate:
Msgbox I am off too
ExitApp
return |
Also, ability to specify host classes would be great to have. Like, monitor all ahk_class Notepad windows (jumping on active one, which original model has) _________________
 |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Fri May 25, 2007 10:27 am Post subject: |
|
|
New version
2Laszlo
After some usage, I think your interface doesn't provide more benefits then original except allowing expressions (Dock parameters). Its just different, and I like the idea as long as we can extend it a liltle.
- ability to let the Dock client keep its original width & height (should be trivial) without repeating its w & h in Dock call. For instance, its not possible now to create default values for Dock function as Client W & H must be known at call.
- ability to anchor X & Y, so for instance, dock can always keep its width & height but stay at bottom right when resizing. (should be trivial too)
Also, we should start to think about multiple dock clients and host classes. (not trivial) _________________
 |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4033 Location: Pittsburgh
|
Posted: Fri May 25, 2007 4:26 pm Post subject: |
|
|
If the client window does not move with the host, it is not docking, is it? Still, if it is visible, when the host is, the client can be useful for status messages, or building a private task bar of selected applications. It is easily achieved with two more parameters (coefficients of HostX and HostY), but 10 parameters look already too many and confusing, so adding two more makes the function scary. I would add instead another function: Link(X,Y,W,H), with fixed coordinates for the client. It does not even have to inquire the position of the host. | Code: | | WinGetPos X, Y, W, H, ahk_id %Dock_ClientId% | give the necessary values explicitly.
| Code: | ; .. ..
WinGetPos X, Y, W, H, ahk_id %Dock_ClientId%
Link(A_ScreenWidth-W,0,W,H) ; pin window to upper right corner of screen
WinGetPos X, Y,,,ahk_id %Dock_HostID%
WinMove ahk_id %Dock_HostID%,,X+1,Y
WinMove ahk_id %Dock_HostID%,,X,Y ; instead of calling Dock_Update
Return
; .. ..
Link_Update:
If (Dock_HookHwnd = Dock_HostID && Dock_event = 3) {
WinSet AlwaysOnTop, On, ahk_id %Dock_ClientId%
WinSet AlwaysOnTop, Off, ahk_id %Dock_ClientId%
}
Return
Link(x, y, w, h) {
Global HookDll, Dock_ClientId
Static hwnd, Dock_hHookDll, Dock_msg := 0x550
If Dock_hHookDll=
Dock_hHookDll := API_LoadLibrary(HookDll)
If hwnd=
hwnd := WinExist("ahk_pid " . DllCall("GetCurrentProcessId"))
WinMove ahk_id %Dock_ClientId%,,x, y, w, h
Dock_hHook0 := Hook(hwnd, Dock_msg, 3) ; EVENT_SYSTEM_FOREGROUND
Dock_hHook2 := Hook(hwnd, Dock_msg, 10, 11) ; EVENT_SYSTEM_MOVESIZESTART 10 EVENT_SYSTEM_MOVESIZEEND 11
Dock_hHook3 := Hook(hwnd, Dock_msg, 0x800A, 0x800B, "Link_HookHandler") ;EVENT_OBJECT_STATECHANGE 0x0000800a, EVENT_OBJECT_LOCATIONCHANGE 0x0000800b
Return Dock_hHook3 && Dock_hHook2 && Dock_hHook0 && Dock_hHookDll
}
Link_HookHandler(wParam, lParam, msg, hwnd) {
Global Dock_event, Dock_HookHwnd
GetHookParams(lparam, Dock_event, Dock_HookHwnd)
GoSub Link_Update
} |
If you want to keep the original width and height of the client window (which might look ugly), we can have special values for the corresponding parameters, like "W" and "H" in the Dock function. (In Link() this does not save much work, unless more complicated parameter structure is introduced.) | Code: | ; .. ..
Dock(0,0,0, 0,-1,-5, 0,"W", 0,"H") ; above, left, fixed width
; .. ..
Dock(_xhw,_xw,_xd, _yhh,_yh,_yd, _whw,_wd, _hhh,_hd) {
Global HookDll, xhw,xw,xd, yhh,yh,yd, whw,wd, hhh,hd, Dock_ClientId
Static hwnd, Dock_hHookDll, Dock_msg := 0x550
If Dock_hHookDll=
Dock_hHookDll := API_LoadLibrary(HookDll)
If hwnd=
hwnd := WinExist("ahk_pid " . DllCall("GetCurrentProcessId"))
WinGetPos,,,W, H, ahk_id %Dock_ClientId%
wd := _wd = "W" ? W : _wd
hd := _hd = "H" ? H : _hd
xhw:=_xhw, xw:=_xw, xd:=_xd, yhh:=_yhh, yh:=_yh, yd:=_yd, whw:=_whw, hhh:=_hhh
Dock_hHook0 := Hook(hwnd, Dock_msg, 3) ; EVENT_SYSTEM_FOREGROUND
Dock_hHook2 := Hook(hwnd, Dock_msg, 10, 11) ; EVENT_SYSTEM_MOVESIZESTART 10 EVENT_SYSTEM_MOVESIZEEND 11
Dock_hHook3 := Hook(hwnd, Dock_msg, 0x800A, 0x800B, "Dock_HookHandler") ;EVENT_OBJECT_STATECHANGE 0x0000800a, EVENT_OBJECT_LOCATIONCHANGE 0x0000800b
Return Dock_hHook3 && Dock_hHook2 && Dock_hHook0 && Dock_hHookDll
} |
|
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Fri May 25, 2007 5:45 pm Post subject: |
|
|
| Quote: | | If the client window does not move with the host, it is not docking, is it? | Why do you tell this ? OF course its not.
| Quote: | | Still, if it is visible, when the host is, the client can be useful for status messages, or building a private task bar of selected applications. It is easily achieved with two more parameters |
Both applications are useful. Thats why we need handler so the one can choose what is going to happen when dock host dies.
| Quote: | | It is easily achieved with two more parameters (coefficients of HostX and HostY), but 10 parameters look already too many and confusing, so adding two more makes the function scary. |
I think number of parameters function has isn't important. We can easily transmit parameters via string thus omiting those not used by user. Also, if it has 20 parameters its not important. U call this function once now only, its not problem to determine paramters correctly.
Along this line, I wanted to note is that docking scenarios will be more or less the same for all users. There are like 10-20 docking setups ppl will use all the time, those that need more can create their own preset itself. So, we can create new function that will call Dock.
| Code: | | DockIndirect( "preset" ) |
THis func can hold list of presets like "topleft" "rightbottom" "fancy" "bottom midle". IT can also load them from ini file, we can keep presets here.
| Quote: | | If you want to keep the original width and height of the client window (which might look ugly) |
U can't say that. Its up to the user. Check out LilBuilder. I have dock client that is made like it is and I don't want to resize it, just dock it.
I don't understand quite purpose of Link function. I will try to concentrate more later. _________________
 |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4033 Location: Pittsburgh
|
Posted: Fri May 25, 2007 8:00 pm Post subject: |
|
|
| majkinetor wrote: | | Quote: | | If the client window does not move with the host, it is not docking, is it? | Why do you tell this ? | To justify the new function named Link, instead of overloading the Dock function.
| majkinetor wrote: | | I think number of parameters function has isn't important. | It also adds two more multiplications for handling each event. On my slow laptop any speedup is welcome.
| majkinetor wrote: | | We can easily transmit parameters via string thus omitting those not used by user. | True, but using variables in those string parameters (commonly read from an ini file or the registry) makes the parameters horrible looking.
| majkinetor wrote: | | There are like 10-20 docking setups ppl will use all the time, those that need more can create their own preset itself. So, we can create new function that will call Dock. | Yes, like DockLeft(), DockBottomCenter(), etc. This is similar to cut and paste the right sequence of parameters or DockIndirect( "preset" ). Use what you like.
| majkinetor wrote: | | Quote: | | If you want to keep the original width and height of the client window (which might look ugly) | U can't say that. Its up to the user. | If he is not careful, mismatched size windows might look bad. Just wanted to note that keeping the touching sides of equal length often looks nicer. Of course, not always.
| majkinetor wrote: | | I don't understand quite purpose of Link function. | If the client window does not move, the handler is much simpler. With the corresponding Link function the user can save code space and processor power. It only assures that the client is visible, when the host is. |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|