AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[module] Dock 1.0        (testing 2.0 b3)
Goto page Previous  1, 2, 3 ... 16, 17, 18, 19  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Thu Jan 10, 2008 2:24 pm    Post subject: Reply with quote

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 Very Happy

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 Very Happy
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
View user's profile Send private message MSN Messenger
tic



Joined: 22 Apr 2007
Posts: 1355

PostPosted: Thu Jan 10, 2008 5:08 pm    Post subject: Reply with quote

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
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Thu Jan 10, 2008 6:20 pm    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
comtts
Guest





PostPosted: Fri Jan 11, 2008 1:36 am    Post subject: Reply with quote

To majkinetor.

Your scrpts always come in really handy!
Well documented, easy to use and very imaginative Smile

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

PostPosted: Fri Jan 11, 2008 9:16 am    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Sun Jan 13, 2008 3:07 am    Post subject: Reply with quote

New version. See history for downloads and info.
_________________
Back to top
View user's profile Send private message MSN Messenger
bmcclure



Joined: 24 Nov 2007
Posts: 446

PostPosted: Sun Jan 13, 2008 4:04 am    Post subject: Reply with quote

Perfect! You rock! That will help me create the new SteamLab docks (tabs and overlays) immensely. Thanks Very Happy

(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
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Sun Jan 13, 2008 1:00 pm    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
Murp|e



Joined: 12 Jan 2007
Posts: 240
Location: Norway

PostPosted: Sun Jan 13, 2008 3:05 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
bmcclure



Joined: 24 Nov 2007
Posts: 446

PostPosted: Sun Jan 13, 2008 8:36 pm    Post subject: Reply with quote

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
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Sun Jan 13, 2008 8:38 pm    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
bmcclure



Joined: 24 Nov 2007
Posts: 446

PostPosted: Sun Jan 13, 2008 8:44 pm    Post subject: Reply with 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.

That was missing from SteamLab till 30 seconds ago Smile

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
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Sun Jan 13, 2008 8:56 pm    Post subject: Reply with quote

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 Very Happy 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 Smile
_________________
Back to top
View user's profile Send private message MSN Messenger
bmcclure



Joined: 24 Nov 2007
Posts: 446

PostPosted: Sun Jan 13, 2008 9:08 pm    Post subject: Reply with quote

I already had updated the wording of my post (oh, you just saw that Smile ), 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
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Sun Jan 13, 2008 9:18 pm    Post subject: Reply with quote

Myabe that animatewindow again Smile

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
View user's profile Send private message MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3 ... 16, 17, 18, 19  Next
Page 17 of 19

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group