Author |
Topic |
|
mschott14
2 Posts |
Posted - 04/30/2013 : 10:52:59
|
A simple call to acSendWindowToBottom() changes the size and the position of the underlying window. I'd expect it to just wander down the z-axis though, and not change any of the other positional values. Is this per design or a bug?
Thanks, Michael |
|
Rob
USA
2615 Posts |
Posted - 04/30/2013 : 13:11:36
|
It's bug, so to speak. Looks like I put that code in really early and it looks like my call to SetWindowPos had some test values, I probably intended to get back to it at some point but didn't!
I'll update the code base, but I'm not sure when I'll make another release. In the interim, this is one workaroundlocal hWnd = acGetOwnerWindowByPoint(gsx, gsy)
local iLeft = acGetWindowLeft(hWnd)
local iWidth = acGetWindowRight(hWnd)-acGetWindowLeft(hWnd)
local iTop = acGetWindowTop(hWnd)
local iHeight = acGetWindowBottom(hWnd)-acGetWindowTop(hWnd)
acSendWindowToBottom(hWnd)
acMoveWindow(hWnd, nil, nil, iLeft, iTop)
acSetWindowSize(hWnd, nil, nil, iWidth, iHeight) Another would be to use alien to call SetWindowPos directly, but I'm on a lunch break, so not digging into that right now |
|
|
Rob
USA
2615 Posts |
Posted - 04/30/2013 : 18:48:39
|
Ok, here's the necessary alien code to define the direct call to SetWindowPos (which is all S+ is doing behind the scenes).
In Global Lua Tab: (adjust accordingly if you already have user32 defined)
aliencore = alien.core
user32 = aliencore.load("user32.dll")
-- ************ SetWindowPos ************
HWND_BOTTOM = 0x01
SWP_NOSIZE = 0x01
SWP_NOMOVE = 0x02
gSetWindowPos = user32.SetWindowPos
gSetWindowPos:types{ ret = 'long', abi = 'stdcall', 'long', 'long', 'long','long','long','long','long'}
function aSetWindowPos(hwnd, cmd, left, top, width, height, options)
local val = gSetWindowPos(hwnd, cmd, left, top, width, height, options)
return val
end Action Lua Script:
aSetWindowPos(acGetOwnerWindowByPoint(gsx, gsy), HWND_BOTTOM, nil, nil, nil, nil, bit32.bor(SWP_NOSIZE,SWP_NOMOVE)) You can get more details on MSDN here: SetWindowPos, including the other possible commands and options. |
|
|
mschott14
2 Posts |
Posted - 05/01/2013 : 02:26:14
|
Thanks Rob,
fast and very helpful reply indeed!
I used your alien code and it works almost as expected:
My final intention actually is to toggle through all open windows (not(!) the minimized ones though!), e.g. lets say I have three open windows - one behind the other. Now with a single mouse-gesture I'd like to send the foreground window to the back activating at the same time the window which was in second place. Gesturing again should send the second window to the background activating the third and so on.
With your code so far I can send the activated window back but I need an additional step to activate the second window so I can send this one to the background too, which I'd like to avoid.
Hope I am clear to what I mean and intend to do .
Thanks, Michael |
|
|
Rob
USA
2615 Posts |
Posted - 05/01/2013 : 13:32:20
|
I hear what you're saying. There are some lame hacks that could be used (like getting the window on top at a certain mouse position and activating), but believe it or not, z-order is not something which can be easily queried via any API call of which I'm aware.
Really, you have to enumerate all windows (they're enumerated by Windows from the top down) and determine what window is the one you want to activate. The necessary pieces to accomplish this are detailed in the scripts here: http://www.strokesplus.com/scripts/26, but it will require some work to set it up exactly how you want. Off the top of my head, I would make the call to get the handle of the window I drew the gesture on, then make the GetAllWindows call, loop through until I found the window I drew on, send it to bottom, then activate the next window in the loop; though I haven't really thought it all the way through.
However, for Windows 8, you'll have to also do some additional checks/exclusions since Metro apps/charms/most things Metro are considered above the Desktop (and the within within).
Like I said, it's all there, just have to do some playing around; this is a decent script to loop through all top-level windows:acGetAllWindows(1)
for num, handle in pairs(sp_all_windows) do
acMessageBox(acGetWindowTitle(handle),"Title")
end Note that the script link I provided above does some filtering out of some Metro windows, but not all (intentionally). The first messagebox will be the top-most window (z-order-wise), bearing in mind that Metro apps are above desktop apps. |
|
|
|
Topic |
|
|
|