 |
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: Thu Jan 10, 2008 2:24 pm Post subject: |
|
|
News
Sean discovered a better way to set window on top another window, that will simplify Dock a lot and make it 100% reliable. It will make clients topmost only relative to the host.
There is a catch though. It is using SetWindowLong in the forbiden way:
| MSDN wrote: | | You must not call SetWindowLong with the GWL_HWNDPARENT index to change the parent of a child window |
I will update Dock soon nevertheless, but keep old version if above statement turnes out to produce sideffects.
EDIT: Acctually, Sean also discovered this
| ms vb api wrote: | (In)famous misleading statement. Almost as misleading as the choice of
GWL_HWNDPARENT as the name. It has nothing to do with a window's
parent. It really changes the Owner, which (in VB5 or later) is
exactly the same thing as including the Owner argument in the Show
statement.
A more accurate version might be..
"SetWindowLong with the GWL_HWNDPARENT will not change the parent of a
child window. Instead, use the SetParent function. GWL_HWNDPARENT
should have been called GWL_HWNDOWNER, but nobody noticed it until
after a bazillion copies of the SDK had gone out. This is what happens
when the the dev team lives on M&Ms and CocaCola for to long. Too bad.
Live with it."
|
So, tompost clients will shine in next version
Actually, there will be no non-topmost clients. Every client will be set on-top the host as there is no point in allowing the window to go behind the Host, IMO. _________________
 |
|
| Back to top |
|
 |
tic
Joined: 22 Apr 2007 Posts: 1355
|
Posted: Thu Jan 10, 2008 5:08 pm Post subject: |
|
|
| of course there are very necessary reasons for placing a window behind the host. say you want a window with a border, and the border is a png (so you are creating an alpha blended gui with a normal gui as the host) then you would need to place the alpha blended behind, and wouldnt want to have to edit the png specifically for 1 purpose. the only reason i looked to dock was for that reason. it wouldnt allow me to do it so i decided to write my own version to do it, so it would be very handy. and for instance say you have a few windows hosted by one window, and then you want all of those windows to be hosted by another at some time, then currently they all have to be on top |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Thu Jan 10, 2008 6:20 pm Post subject: |
|
|
That scenario could be done with 4 topmost clients.
Anyways, it seems bakcground windows may be useful after all, after carefull thinking...
I will see what can I do.
| Quote: | | the only reason i looked to dock was for that reason. it wouldnt allow me to do it so |
You probably did something wrong, as Dock alows you to do so. You just need to carefuly design dock parameters with resizable windows. _________________
 |
|
| Back to top |
|
 |
comtts Guest
|
Posted: Fri Jan 11, 2008 1:36 am Post subject: |
|
|
To majkinetor.
Your scrpts always come in really handy!
Well documented, easy to use and very imaginative
And about Libuilder...
I guess you stopped the job 'cause it took so much work not because there was any problem you can't handle, right? |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Fri Jan 11, 2008 9:16 am Post subject: |
|
|
| Quote: | | I guess you stopped the job 'cause it took so much work not because there was any problem you can't handle, right? |
Right.
It also requires lot of includable modules, and you know that this is community with relaxed approach to programming, and that is more or less mirror image of its author, Chris, who never envisioned AHK to be remotely close to general programming language, but n00b oriented 10liner script language. _________________
 |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Sun Jan 13, 2008 3:07 am Post subject: |
|
|
New version. See history for downloads and info. _________________
 |
|
| Back to top |
|
 |
bmcclure
Joined: 24 Nov 2007 Posts: 446
|
Posted: Sun Jan 13, 2008 4:04 am Post subject: |
|
|
Perfect! You rock! That will help me create the new SteamLab docks (tabs and overlays) immensely. Thanks
(ps. with _bmcclure.ahk in Vista I had to add a Sleep, 1000 to wait for the print window to actually get drawn first, otherwise the dock didn't work. It can probably be less than that, but that was the first thing I tried and that fixed it for me.) _________________ -Ben
SteamLab
SteamLab Wiki
[Broken] - My industrial music [on GarageBand] |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Sun Jan 13, 2008 1:00 pm Post subject: |
|
|
This 1000 ms timeout problem is probably cuz of the way the bmcclure.ahk is instantiatintiating the dock.
I noticed that changing the value in
| Code: | OnHostDeath:
SetTimer, FindTC, 50
return
|
will improve reliability on startup. If you set to 200, it will work ok.
The test script can be done better. It now instantiate dock just to fail imediately (as host Dock_HostID isn't set). This is probably the reason for the problem.
For instance, this verison works better on my computer (only the message box is removed and message is placed in the client):
| Code: | SetBatchLines, -1
DetectHiddenWIndows, on
#SingleInstance, force
CoordMode, mouse, screen
Run, Notepad
WinWait, Untitled
Send !Fp
Send !n
host := "Print"
Gui +LastFound +ToolWIndow -Caption
c1 := WinExist()
Gui, Add, Button, gOnBtn 0x8000, something
Gui, Add, Button,gOnBtn x+10 0x8000, something 2
Gui, Add, Button, gOnBtn x+10 0x8000, %c1%
Gui, Add, DropDownList, xm gOnBtn 0x8000, 1|2|3|5
Gui, Add, Text, xm yp+100 gOnBtn 0x8000, Press F12 to toggle dock on/off
Dock(c1)
Dock_OnHostDeath := "OnHostDeath"
return
F12::
if Dock_Toggle()
DllCall("ShowWindow", "uint", c1, "uint", 4)
else WinHide, ahk_id %c1%
return
FindTC:
if Dock_HostID := WinExist(host)
{
SetTimer, FindTC, OFF
ControlGetPos, x,y,w,h, SysTabControl321, ahk_id %Dock_HostID%
WinGetPos, wh, wy, ww, wh, ahk_id %Dock_HostID%
x+=10, y+=25, h-=30, w-=15
;, w := w/ww
def = x(,,%x%) y(,,%y%) w(,%w%) h(,%h%) t
Dock( "+" c1, def)
DllCall("ShowWindow", "uint", c1, "uint", 4)
Dock_Toggle(true)
}
return
OnBtn:
; WinActivate, ahk_id %Dock_HostId%
; sleep 5
s := A_GuiControl " "
Control, EditPaste, %s%, Edit1, ahk_id %Dock_HOstID%
; Send, %A_GuiControl%
return
OnHostDeath:
SetTimer, FindTC, 50
return
#include Dock.ahk |
----
Due to the changes in internals of topmost clients (wich are not topmost windows any more, but windows owned by the host) it would be good to check out how Dock behaves on startup when DockHost id a) exists, b) doesn't exist, c) is in the background, visible, d) is minimized, etc....
So far I had problems only on startup or when reenableing again. Once clients are set as owned windows, there must be some change so this come into the effect (so client jump infront of the host). It shows that simulating user clicking the Hosts title does the job:
| Code: | DllCall("SetWindowLong", "uint", Dock_aClient[%A_Index%], "int", -8, "uint", Dock_HostId) ;set topmost window as owned by the Host (removes its taskbar button too)
Sendmessage, 0x112, 0xf010+12, 0,, ahk_id %Dock_HostId% ;WM_SYSCOMMAND , SC_MOVE + HTTOP=0xf010+12 |
WIthout blue code, the topmost clients are not bring infront of the host. I accidently discovered this, by trying 20 different messages 1 by 1, that all happen when user clicks the Host title (and it had to be the last one....)
I still want to see if there are some side-effects of such line. For instnace using HTCAPTION (user clicked in caption) instead HTTOP (user clicked caption top border) had side effect when host is minimized (system menu was shown)
However, latest dock works so well that its unbeleivable as there are no more mumbo jumbo with seting clients always on top and restoring them back. This change introduced better visual updates so you can now run sample script in parallel without problems - for instance, you can run tittlebuttons ahk and two toolbars at the same time wich create 10 clients, most of them topmost and it works pretty good, although I don't suggest such usage when both scripts are handling the same host. _________________
 |
|
| Back to top |
|
 |
Murp|e
Joined: 12 Jan 2007 Posts: 240 Location: Norway
|
Posted: Sun Jan 13, 2008 3:05 pm Post subject: |
|
|
I've successfully managed to dock my AutoHotkey script to a host window, it appears/disappears nicely and docks/resizes nicely as well. Everything is peachy.
But what is the best way of ensuring that a docked window pops up when it should and uses minimial resources when it shouldn't. The worst possible way is probably what I have currently: I run my script at startup and it checks for the existence of a certain window every second, if a specific window exists it will dock to it, if not it does nothing.
Another alternative I have considered is replacing the shortcut to the host application with my script. My script gets called and runs itself in the background then runs the host program. If a certain "child" window exists, it will dock to it and if the host program is closed, my script exits.
Is there a better way to achieve this? Is there a way to run my script only if a certain window exists? Or run my script each time a new window is created perhaps? How do you normally implement these docks? Hope this wasn't too stupid of a question to ask... |
|
| Back to top |
|
 |
bmcclure
Joined: 24 Nov 2007 Posts: 446
|
Posted: Sun Jan 13, 2008 8:36 pm Post subject: |
|
|
I use a timer in SteamLab, if the SteamDock is enabled the timer checks every 500 ms if the host process exists. If not, the timer doesn't do anything else, so it's not performance intensive. If it does exist, the timer enables the dock and turns itself off.
I'd like to know if there's a better way, too, but that's the best I've found.
Then you'll need to start the timer again in the OnHostDeath label, if it's supposed to be a consistent dock. _________________ -Ben
SteamLab
SteamLab Wiki
[Broken] - My industrial music [on GarageBand] |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Sun Jan 13, 2008 8:38 pm Post subject: |
|
|
Monitoring host existance needs obviously process running all the time. The only other way is replacing the shortuct and exiting the script in OnHostDeath procedure, wich is as efficient as it can be.
The another way would be to have timer executing like demonstrated in sample scritpt and turning it off when you are docking. Dock is basicly iddle when not docking, and iddle most of the time as host is never moved so rapidly, so it is efficient enough to let it stay resident all the time. Resident all the time means in Dock's case that it will be toggled off and on when needed, so only timer is run when host is not alive. You can make this as efficent as possible in that moment, as timer can be arbitrary fast/slow, and it executes only 1 command (ifWinExist)
When multihost feature is implemented, you will be able to use single script to instantiate as many docks as you want.
Dock will also automate showing/hidding of its clients, so you can totaly forget about it. You will instantiate the dock and not think about it ever again (hopefuly). It will know when to hide windows, when to show them, how to find host of specific class or nature automaticaly etc... with some clever parameters. Current syntax will just slightly be changed to support this. Lets hope it can go as I imagined.
Notice that when Dock is toggled off, it uses 0% of CPU and that is always when Host is not alive. _________________

Last edited by majkinetor on Sun Jan 13, 2008 8:44 pm; edited 1 time in total |
|
| Back to top |
|
 |
bmcclure
Joined: 24 Nov 2007 Posts: 446
|
Posted: Sun Jan 13, 2008 8:44 pm Post subject: |
|
|
I forgot that you have to add Dock_Toggle(false) to the OnHostDeath label if you want to be able to re-open it again when the process starts.
That was missing from SteamLab till 30 seconds ago
Update With the latest Dock version, the host process has some odd behavior; when the dock opens, it actually puts the host process (and itself) in back of the other windows, even if it was in front of them before. Is this intended?
Actually, that's probably my WinActivate code backfiring. I be that's it. False alarm I think. _________________ -Ben
SteamLab
SteamLab Wiki
[Broken] - My industrial music [on GarageBand]
Last edited by bmcclure on Sun Jan 13, 2008 8:58 pm; edited 1 time in total |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Sun Jan 13, 2008 8:56 pm Post subject: |
|
|
| Quote: | | I forgot that you have to add Dock_Toggle(false) to the OnHostDeath label if you want to be able to re-open it again when the process starts. |
No you don't. You have to add Dock_Toggle() when in timer as Dock automaticaly toggles itself off before calling OnHostDeath.
| Quote: | | Actually, that's probably my WinActivate code backfiring. I be that's it. False alarm I think. |
Oh, don't give me false alarms please. I am going insange here Tweaking the dock was hell of a job it had to be done to the extremes in every single line. Bugs are very difficult to correct, need lot of experimenting. Please test well your eventual bugs  _________________
 |
|
| Back to top |
|
 |
bmcclure
Joined: 24 Nov 2007 Posts: 446
|
Posted: Sun Jan 13, 2008 9:08 pm Post subject: |
|
|
I already had updated the wording of my post (oh, you just saw that ), and it was an issue with my activation code. But it's still odd behavior I think.
I had code which got the id of the active window before the dock opened, then opened the dock, then used WinActivate to bring the old window back to the front. However now when I use that and the dock opens, the host and dock both go to the back. I don't know if it's just a timing thing or what.
It seems to work fine when I take that code out, so I don't mind that much if Steam brings itself to the front when the dock loads.
This was what I was using:
| Code: | Dock_HostID := WinExist("STEAM - ahk_class " . curClass) ; Set Steam's ID to the host
If Dock_HostID { ; Make sure we got a valid ID
curActiveWinID := WinGet("ID","A") ; Get currently activated window ID
SetTimer, WaitSteamDock, Off ; Turn off the timer while the dock is showing
GoSub,ShowSteamDock ; Show the actual GUI window
Dock_HostDied := 0 ; Reset the Dock() function's HostDied setting
Dock_OnHostDeath := "SteamDockClose"
Result := Dock(Dock_s2, "x() y(1) w(1) h(,30)") ; Show the dock right below the Steam window
;DllCall("AnimateWindow","UInt",Dock_s2,"Int",500,"UInt","0xa0000") ; Fade the dock in nicely
WinActivate, ahk_id %curActiveWinID% ; Re-activate previously activated window
} |
ps: and thank you very much for all your hard work on the dock code and putting together that example of an overlay with the new version. I do really appreciate it! _________________ -Ben
SteamLab
SteamLab Wiki
[Broken] - My industrial music [on GarageBand] |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Sun Jan 13, 2008 9:18 pm Post subject: |
|
|
Myabe that animatewindow again
Perhaps some bug, we will see if anybody else experience it....
You don't need this:
| Code: | | Dock_HostDied := 0 ; Reset the Dock() function's HostDied setting |
And you can set this only once
| Code: | | Dock_OnHostDeath := "SteamDockClose" |
When dock toggles it remember everything so you don't need this
| Code: | | Result := Dock(Dock_s2, "x() y(1) w(1) h(,30)") ; Show the dock right below the Steam window |
You need to repeat everything only if you used Shutdown. Toggle remembers everything so you just need to show windows again and instantiate dock at the start of the script. If host is not there it will toggle itself off imediately and your timer routine will start.
You can see that in some samples.
EDIT:
WHen host is in the background it is activated, i forgot to notice that. I can change it the way it was probably, this is little side-effect of new topmost method.
I can't manage it to be pushed back as you say... it doesn't have such code I think. I will check it out. _________________
 |
|
| 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
|